Skip to main content

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
Installation Order

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
Namespace Verification

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>
Retrieve 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 Running state (typically 3 pods for a cluster)
  • StatefulSet should show desired replicas match ready replicas
  • PVCs should be in Bound state

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.

AWS: IAM Database Authentication
On AWS, codemie-api authenticates to RDS using IAM database authentication instead of a static password. The RDS master user (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)
Finding Credentials

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 Placeholders

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.

Already exists

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:

  1. Apply the updated Terraform configuration to enable IAM database authentication on the RDS instance.
  2. Create the codemie_admin role as described above.
  3. Add PG_IAM_USER to the existing codemie-postgresql secret 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)\"}}"
  1. Update codemie-api/values-aws.yaml and redeploy codemie-api:
    • Add PG_IAM_AUTH_PROVIDER:
- name: PG_IAM_AUTH_PROVIDER
value: "aws"
  • Change POSTGRES_USER to read from PG_IAM_USER instead of PG_USER:
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: codemie-postgresql
key: PG_IAM_USER
  • Remove the POSTGRES_PASSWORD and PG_URL entries (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 Placeholders

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.