BYO PostgreSQL database
Replace the built-in PostgreSQL database with an Amazon RDS PostgreSQL instance for production use.
By default, Solo Enterprise for agentregistry deploys a PostgreSQL database in to your cluster. The database is used to store registry server data, including published AI artifacts and deployments. Because the database is deployed as a single pod in your cluster, data is lost when the pod restarts or becomes unavailable.
For production environments, it is recommended to replace the built-in PostgreSQL database with your own external database instance that you manage and back up independently.
The instructions in this guide show how to provision an Amazon RDS for PostgreSQL instance in the same VPC as your EKS cluster and configure Solo Enterprise for agentregistry to use it.
Before you begin
Follow the AWS Bedrock AgentCore get started guide to connect to your AWS account and set up the Bedrock AgentCore runtime. Note that this guide installs Solo Enterprise for agentregistry with the built-in PostgreSQL database instance. You swap this database with your own AWS RDS for PostgreSQL instance as part of this guide.
Set your cluster name and AWS region as environment variables.
AWS_REGION=<your-aws-region> # AWS region of your EKS cluster EKS_CLUSTER_NAME=<your-eks-cluster-name> # AWS EKS cluster nameGet the VPC ID that your EKS cluster is deployed to.
VPC_ID=$(aws eks describe-cluster \ --name "$EKS_CLUSTER_NAME" \ --region "$AWS_REGION" \ --query "cluster.resourcesVpcConfig.vpcId" \ --output text) echo "VPC ID: $VPC_ID"Get the EKS cluster security group ID. EKS attaches this security group to all nodes and the control plane.
EKS_NODE_SG=$(aws eks describe-cluster \ --name "$EKS_CLUSTER_NAME" \ --region "$AWS_REGION" \ --query "cluster.resourcesVpcConfig.clusterSecurityGroupId" \ --output text) echo "EKS node security group: $EKS_NODE_SG"Set the remaining variables for the RDS instance and Kubernetes Secret.
DB_INSTANCE_ID=agentregistry-db DB_INSTANCE_CLASS=db.t3.medium DB_ENGINE_VERSION=16 PG_USER=agentregistry PG_PASS='<your-password>' # single-quote to protect shell-special chars PG_DB=agentregistry SECRET_NAME=agentregistry-db-creds SECRET_KEY=AGENT_REGISTRY_DATABASE_URL
Step 1: Create an AWS RDS for PostgreSQL instance
Create a security group for your RDS PostgreSQL instance.
RDS_SG_ID=$(aws ec2 create-security-group \ --group-name agentregistry-rds-sg \ --description "Allow PostgreSQL from EKS nodes" \ --vpc-id "$VPC_ID" \ --region "$AWS_REGION" \ --query "GroupId" --output text) echo "RDS security group: $RDS_SG_ID"Add an ingress rule to the RDS security group that allows TCP traffic on port 5432 from the EKS node security group.
aws ec2 authorize-security-group-ingress \ --group-id "$RDS_SG_ID" \ --protocol tcp \ --port 5432 \ --source-group "$EKS_NODE_SG" \ --region "$AWS_REGION"Retrieve the subnet IDs that your EKS cluster uses. Using the cluster’s own subnets is a convenient way to guarantee the DB subnet group covers at least two Availability Zones, which is the minimum RDS requires.
SUBNET_IDS=$(aws eks describe-cluster \ --name "$EKS_CLUSTER_NAME" \ --region "$AWS_REGION" \ --query "cluster.resourcesVpcConfig.subnetIds" \ --output text | tr '\t' ',') echo "Subnet IDs: $SUBNET_IDS"Create a database subnet group. RDS requires the group to cover subnets in at least two Availability Zones, but it does not need to include every subnet in the VPC. If you already have a subnet group for this VPC, skip this step and set
DB_SUBNET_GROUPto its name.DB_SUBNET_GROUP=agentregistry-db-subnet-group aws rds create-db-subnet-group \ --db-subnet-group-name "$DB_SUBNET_GROUP" \ --db-subnet-group-description "Subnet group for agentregistry RDS" \ --subnet-ids $(echo $SUBNET_IDS | tr ',' ' ') \ --region "$AWS_REGION"Set the details for your RDS instance.
DB_INSTANCE_ID=agentregistry-db DB_INSTANCE_CLASS=db.t3.medium DB_ENGINE_VERSION=16 PG_USER=agentregistry PG_PASS='<your-password>' # single-quote to protect shell-special charsCreate an AWS RDS for PostgreSQL instance in the subnet group and security group that you configured earlier.
aws rds create-db-instance \ --db-instance-identifier "$DB_INSTANCE_ID" \ --db-instance-class "$DB_INSTANCE_CLASS" \ --engine postgres \ --engine-version "$DB_ENGINE_VERSION" \ --master-username "$PG_USER" \ --master-user-password "$PG_PASS" \ --db-name postgres \ --allocated-storage 20 \ --storage-type gp3 \ --no-publicly-accessible \ --vpc-security-group-ids "$RDS_SG_ID" \ --db-subnet-group-name "$DB_SUBNET_GROUP" \ --backup-retention-period 7 \ --region "$AWS_REGION"The initial database is namedpostgres. You create theagentregistryapplication database in a later step. Creating it now is not supported because RDS does not allow the master database to be renamed during instance creation.Wait for the instance to reach the
availablestate. Note that the setup can take between 5–10 minutes.aws rds wait db-instance-available \ --db-instance-identifier "$DB_INSTANCE_ID" \ --region "$AWS_REGION" echo "RDS instance is available."Example output when the database is available:
RDS instance is available.Get the RDS connection details.
PG_HOST=$(aws rds describe-db-instances \ --db-instance-identifier "$DB_INSTANCE_ID" \ --region "$AWS_REGION" \ --query "DBInstances[0].Endpoint.Address" \ --output text) PG_PORT=5432 echo "RDS endpoint: $PG_HOST:$PG_PORT"Create the
agentregistrydatabase. To create the database, you must run a temporary pod in your cluster to connect to the RDS instance and create the application database.kubectl -n agentregistry-system run pg-setup --rm -it --image=postgres:16 --restart=Never -- \ psql "host=$PG_HOST port=$PG_PORT user=$PG_USER password='$PG_PASS' dbname=postgres sslmode=require" \ -c 'CREATE DATABASE agentregistry;'Example output:
CREATE DATABASEConfirm that a pod in the
agentregistry-systemnamespace can reach the new database before you upgrade the Helm release. Note that if this command times out or returns a connection error, check your security group rules and subnet settings.kubectl -n agentregistry-system run pg-probe --rm -it --image=postgres:16 --restart=Never -- \ psql "host=$PG_HOST port=$PG_PORT user=$PG_USER password='$PG_PASS' dbname=agentregistry sslmode=require" \ -c 'SELECT current_user, version();'Example output:
current_user | version current_user | version ---------------+--------------------------------------------------------------------------------------------------- agentregistry | PostgreSQL 16.13 on x86_64-pc-linux-gnu, compiled by x86_64-pc-linux-gnu-gcc (GCC) 12.4.0, 64-bit (1 row)
Step 2: Store the database connection details
Store the database connection string in a Kubernetes Secret. The registry server reads the connection string from this secret at startup. The connection string can be provided in the following formats:
- URL format (libpq): The connection string is provided in standard URI format with a
postgresql://orpostgres://prefix scheme. Note that special characters, such as@or!in passwords must be percent-encoded. Example connection string:postgresql://myuser:password@mydb.com:5432/agentregistry. Note that the@in the connection string separates the username and password from the database hostname. - DSN format (keyword/ value pairs): This format uses space-separated
key=valuepairs. If a value contains spaces or is empty, it must be wrapped in single quotes. Example connection string:host=mydb.com port=5432 user=myuser password='password' dbname=agentregistry sslmode=require.
The URL form uses a postgres:// connection string. Percent-encode any special characters in the password, such as $, @, /, or ?, before embedding them in the connection string URL.
Percent-encode special characters in your password.
ENCODED_PASSWORD=$(python3 -c \ "import urllib.parse, sys; print(urllib.parse.quote(sys.argv[1], safe=''))" \ "$PG_PASS") echo "Encoded password: $ENCODED_PASSWORD"Build the connection string in URL format.
URL="postgres://${PG_USER}:${ENCODED_PASSWORD}@${PG_HOST}:${PG_PORT}/agentregistry?sslmode=require" echo "Connection string in URL format: $URL"Create a Kubernetes secret with your connection string.
kubectl -n agentregistry-system create secret generic agentregistry-db-creds \ --from-literal=AGENT_REGISTRY_DATABASE_URL="$URL"Verify that the connection string is stored in the secret.
kubectl -n agentregistry-system get secret agentregistry-db-creds \ -o jsonpath="{.data.AGENT_REGISTRY_DATABASE_URL}" | base64 -d ; echo
The keyword/value format is easier to read and does not require special characters to be percent-encoded.
Build the connection string in DSN format.
DSN="host=$PG_HOST port=$PG_PORT user=$PG_USER password='$PG_PASS' dbname=agentregistry sslmode=require" echo "Connection string in DSN format: $DSN"Create a Kubernetes secret with your connection string.
kubectl -n agentregistry-system create secret generic agentregistry-db-creds \ --from-literal=AGENT_REGISTRY_DATABASE_URL="$DSN"Verify that the connection string is stored in the secret.
kubectl -n agentregistry-system get secret agentregistry-db-creds \ -o jsonpath="{.data.AGENT_REGISTRY_DATABASE_URL}" | base64 -d ; echo
Step 3: Upgrade Solo Enterprise for agentregistry
Optional: Save the current Helm values to a file for reference.
helm get values agentregistry --namespace agentregistry-system -o yaml > agentregistry-values.yamlUpgrade the Helm release to switch from the built-in PostgreSQL database to your AWS RDS instance.
The
--reuse-valuesflag re-applies all values from the previous release automatically, so you only need to pass the database settings that you are changing. If you previously stored the database connection string in a Kubernetes secret, provide the reference to the secret in your Helm values. To provide the database connection string inline with your Helm values, follow the Inline connection string path.helm upgrade -i agentregistry \ oci://us-docker.pkg.dev/solo-public/agentregistry-enterprise/helm/agentregistry-enterprise \ --namespace agentregistry-system \ --reuse-values \ --set database.postgres.type=external \ --set database.postgres.external.secretRef.name=agentregistry-db-creds \ --set database.postgres.external.secretRef.key=AGENT_REGISTRY_DATABASE_URL \ --wait --timeout=5mHelm value Description database.postgres.typeSet to externalto use your own database instance instead of the built-in PostgreSQL database instance that is provided by Solo Enterprise for agentregistry.database.postgres.external.secretRef.nameThe name of the Kubernetes secret that holds the connection string of your database instance. Mutually exclusive with database.postgres.external.url.database.postgres.external.secretRef.keyThe key in the secret that contains the connection string information. helm upgrade -i agentregistry \ oci://us-docker.pkg.dev/solo-public/agentregistry-enterprise/helm/agentregistry-enterprise \ --namespace agentregistry-system \ --reuse-values \ --set database.postgres.type=external \ --set database.postgres.external.url=${DSN} \ --wait --timeout=5mHelm value Description database.postgres.typeSet to externalto use your own database instance instead of the built-in PostgreSQL database instance that is provided by Solo Enterprise for agentregistry.database.postgres.external.urlThe connection string to use to connect to your database instance. Mutually exclusive with database.postgres.external.secretRef.name.
Step 4: Verify the connection
Verify that the Solo Enterprise for agentregistry control plane pods come up healthy and that you do not see an
agentregistry-enterprise-postgresql-*pod.kubectl get pods -n agentregistry-systemConfirm that the registry server pod has the secret reference set in its environment variables.
kubectl -n agentregistry-system describe pod -l app.kubernetes.io/component=server \ | sed -n '/AGENT_REGISTRY_DATABASE_URL/,/^$/p' | head -5Expected output:
AGENT_REGISTRY_DATABASE_URL: <set to the key 'AGENT_REGISTRY_DATABASE_URL' in secret 'agentregistry-db-creds'> Optional: falseCheck the server logs for successful migration and connection messages.
kubectl -n agentregistry-system logs deploy/agentregistry-enterprise-server --tail=50 \ | grep "migration"Expected output:
... {"time":"2026-06-03T21:28:33.530149351Z","level":"info","msg":"all migrations applied successfully","component":"default","component":"database.migrate"}List the tables that the registry created on the RDS instance.
kubectl -n agentregistry-system run pg-check --rm -it --image=postgres:16 --restart=Never -- \ psql "host=$PG_HOST port=$PG_PORT user=$PG_USER password='$PG_PASS' dbname=agentregistry sslmode=require" \ -c '\dt'Expected output:
List of relations Schema | Name | Type | Owner --------+--------------------+-------+--------------- public | aws_agents | table | agentregistry public | aws_connections | table | agentregistry public | gcp_connections | table | agentregistry public | gcp_resources | table | agentregistry public | issued_tokens | table | agentregistry public | kagent_connections | table | agentregistry public | kagent_resources | table | agentregistry public | schema_migrations | table | agentregistry public | secret_payloads | table | agentregistry public | signing_keys | table | agentregistry (10 rows)