Data Layer
This guide covers the installation of data storage components that provide persistent storage for AI/Run CodeMie application data, logs, and user content.
Overview
The data layer consists of two components:
- Elasticsearch - Document storage and search engine for application logs, embeddings, and search functionality
- PostgreSQL - Cloud-managed relational database for application metadata
These components must be installed in the order presented.
Elasticsearch Installation
Elasticsearch provides document storage and full-text search capabilities for AI/Run CodeMie. It stores conversation history, embeddings, logs, and provides search functionality.
Step 1: Create Elasticsearch Namespace
Create a dedicated namespace for Elasticsearch:
kubectl create namespace elastic
Check if the namespace already exists: kubectl get namespace elastic
Step 2: Create Elasticsearch Credentials Secret
Generate and store Elasticsearch authentication credentials:
kubectl -n elastic create secret generic elasticsearch-master-credentials \
--from-literal=username=elastic \
--from-literal=password="$(openssl rand -base64 12)" \
--type=Opaque \
--dry-run=client -o yaml | kubectl apply -f -
Secret Structure:
apiVersion: v1
kind: Secret
metadata:
name: elasticsearch-master-credentials
namespace: elastic
type: Opaque
data:
username: <base64-encoded-username>
password: <base64-encoded-password>
Save the generated password for troubleshooting: kubectl get secret elasticsearch-master-credentials -n elastic -o jsonpath='{.data.password}' | base64 -d
Step 3: Install Elasticsearch Helm Chart
Deploy Elasticsearch using Helm:
helm upgrade --install elastic elasticsearch/. \
-n elastic \
--values elasticsearch/values-aws.yaml \
--wait \
--timeout 900s \
--dependency-update
Step 4: Verify Elasticsearch Deployment
Check that Elasticsearch is running:
# Check pod status
kubectl get pods -n elastic
# Check StatefulSet
kubectl get statefulset -n elastic
# Verify persistent volumes
kubectl get pvc -n elastic
Expected output:
- Pods should be in
Runningstate (typically 3 pods for a cluster) - StatefulSet should show desired replicas match ready replicas
- PVCs should be in
Boundstate
Step 5: Test Elasticsearch Health
Verify Elasticsearch cluster health:
# Port-forward to Elasticsearch
kubectl port-forward -n elastic svc/elasticsearch-master 9200:9200
# Check cluster health (use saved password from Step 2)
curl -u elastic:<password> http://localhost:9200/_cluster/health?pretty
# Stop port-forward when done
Expected response should show "status" : "green" or "status" : "yellow" (yellow is acceptable for single-node clusters).
PostgreSQL Configuration
CodeMie uses AWS RDS PostgreSQL (created during infrastructure deployment) rather than running PostgreSQL in the cluster. This section configures the connection credentials.
dbadmin) stays password-based and is only used for administrative bootstrap tasks (such as creating the dedicated user below). A separate PostgreSQL role — codemie_admin by default (Terraform output codemie_rds_iam_username / CODEMIE_IAM_DATABASE_USER) — is granted the rds_iam role and used exclusively for IAM token authentication. codemie-api generates a short-lived IAM auth token per connection instead of using a stored password.Retrieve Database Credentials
Get your AWS RDS PostgreSQL connection details from the infrastructure deployment outputs:
# From your deployment_outputs.env file, note these values:
# - CODEMIE_POSTGRES_DATABASE_HOST
# - CODEMIE_POSTGRES_DATABASE_NAME
# - CODEMIE_POSTGRES_DATABASE_USER
# - CODEMIE_POSTGRES_DATABASE_PASSWORD
# - CODEMIE_IAM_DATABASE_USER (dedicated IAM-auth database user)
Your deployment_outputs.env file was created during Infrastructure Deployment. It should be located in your Terraform working directory.
Create the IAM Authentication Database User
Before creating the connection secret, bootstrap the dedicated codemie_admin role that codemie-api will use for IAM authentication. This connects as the master user dbadmin (password auth) to create the new role, grant it rds_iam, and grant it full access to the codemie database:
kubectl run pg-iam-setup --rm -i --restart=Never \
--image=alpine/psql:18.3 \
--namespace codemie \
--env="PGPASSWORD=<CODEMIE_POSTGRES_DATABASE_PASSWORD>" \
--env="PGSSLMODE=require" \
-- \
-h <CODEMIE_POSTGRES_DATABASE_HOST> \
-U <CODEMIE_POSTGRES_DATABASE_USER> \
-d <CODEMIE_POSTGRES_DATABASE_NAME> \
-c "CREATE USER <CODEMIE_IAM_DATABASE_USER>; GRANT rds_iam TO <CODEMIE_IAM_DATABASE_USER>; GRANT ALL PRIVILEGES ON DATABASE <CODEMIE_POSTGRES_DATABASE_NAME> TO <CODEMIE_IAM_DATABASE_USER>; GRANT ALL ON SCHEMA public TO <CODEMIE_IAM_DATABASE_USER>; GRANT ALL ON ALL TABLES IN SCHEMA public TO <CODEMIE_IAM_DATABASE_USER>; GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO <CODEMIE_IAM_DATABASE_USER>; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO <CODEMIE_IAM_DATABASE_USER>; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO <CODEMIE_IAM_DATABASE_USER>;" < /dev/null
Replace every CODEMIE_* placeholder with the actual value from deployment_outputs.env. PGSSLMODE=require is required — RDS rejects unencrypted connections once IAM database authentication is enabled on the instance.
If codemie_admin was already created (e.g. by a prior deployment run), CREATE USER fails with role "codemie_admin" already exists. This is safe to ignore — re-run the command without the CREATE USER ...; clause to (re-)apply the grants only.
Upgrading an Existing Deployment to IAM Authentication
Migration steps for existing deployments
To move an existing deployment from password-based authentication to IAM database authentication:
- Apply the updated Terraform configuration to enable IAM database authentication on the RDS instance.
- Create the
codemie_adminrole as described above. - Add
PG_IAM_USERto the existingcodemie-postgresqlsecret instead of recreating it:
kubectl -n codemie patch secret codemie-postgresql --type merge \
-p "{\"data\":{\"PG_IAM_USER\":\"$(echo -n <CODEMIE_IAM_DATABASE_USER> | base64)\"}}"
- Update
codemie-api/values-aws.yamland redeploycodemie-api:- Add
PG_IAM_AUTH_PROVIDER:
- Add
- name: PG_IAM_AUTH_PROVIDER
value: "aws"
- Change
POSTGRES_USERto read fromPG_IAM_USERinstead ofPG_USER:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: codemie-postgresql
key: PG_IAM_USER
- Remove the
POSTGRES_PASSWORDandPG_URLentries (IAM token auth replaces password-based connection).
Create PostgreSQL Connection Secret
Create a secret with the cloud-managed PostgreSQL credentials:
kubectl create secret generic codemie-postgresql \\
--from-literal=PG_PASS=<CODEMIE_POSTGRES_DATABASE_PASSWORD> \\
--from-literal=PG_USER=<CODEMIE_POSTGRES_DATABASE_USER> \\
--from-literal=PG_HOST=<CODEMIE_POSTGRES_DATABASE_HOST> \\
--from-literal=PG_NAME=<CODEMIE_POSTGRES_DATABASE_NAME> \\
--from-literal=PG_IAM_USER=<CODEMIE_IAM_DATABASE_USER> \\
--namespace codemie
Replace all <CODEMIE_POSTGRES_DATABASE_*> placeholders with actual values from your deployment_outputs.env file. Do not use angle brackets in the actual command. PG_USER/PG_PASS keep the master dbadmin credentials (still needed by other components such as LiteLLM); PG_IAM_USER is what codemie-api actually connects with, via IAM tokens.
Example with Real Values:
kubectl create secret generic codemie-postgresql \
--from-literal=PG_PASS='MySecureP@ssw0rd!' \
--from-literal=PG_USER='dbadmin' \
--from-literal=PG_IAM_USER='codemie_admin' \
--from-literal=PG_HOST='codemie-postgres.abc123.us-west-2.rds.amazonaws.com' \
--from-literal=PG_NAME='codemie' \
--namespace codemie
Secret Structure:
apiVersion: v1
kind: Secret
metadata:
name: codemie-postgresql
namespace: codemie
type: Opaque
data:
PG_HOST: <base64-encoded-host>
PG_NAME: <base64-encoded-db-name>
PG_PASS: <base64-encoded-password>
PG_USER: <base64-encoded-user>
PG_IAM_USER: <base64-encoded-iam-user>
Verify PostgreSQL Secret
Confirm the secret was created correctly:
# Check secret exists
kubectl get secret codemie-postgresql -n codemie
# Verify secret contents (decode to check values)
kubectl get secret codemie-postgresql -n codemie -o jsonpath='{.data.PG_HOST}' | base64 -d
kubectl get secret codemie-postgresql -n codemie -o jsonpath='{.data.PG_USER}' | base64 -d
Post-Installation Validation
After completing all data layer installations, verify the following:
# Elasticsearch is running
kubectl get pods -n elastic | grep Running
kubectl get statefulset -n elastic
# PostgreSQL secret exists
kubectl get secret codemie-postgresql -n codemie
# Check all PVCs are bound
kubectl get pvc -n elastic
All checks should return successful results before proceeding.
Next Steps
Once the data layer is configured, proceed to Security and Identity installation to deploy Keycloak and OAuth2 Proxy components.