IAM Database Connector
The IAM Database Connector feature allows virtual clusters to use a shared database server as their backing store and authenticate using workload identity.
This page describes how to set up a shared database connector for cloud providers, for general instructions on using database connectors, see the Database Connectors page.
AWS​
Prerequisites​
RDS database requirements​
- RDS instance running MySQL or PostgreSQL with IAM Database Authentication enabled
- PostgreSQL: version 9.6.9+, 10.4+, or 11+
- MySQL: version 5.6.34+, 5.7.16+, or 8.0+
- A database admin user with
CREATE DATABASE,CREATE ROLE, andGRANTprivileges
EKS requirements​
- EKS cluster with the EKS Pod Identity Agent add-on installed
- EBS CSI Driver add-on with IAM permissions (required for platform persistent storage)
To verify Pod Identity Agent is installed:
aws eks describe-addon --cluster-name YOUR_CLUSTER --addon-name eks-pod-identity-agent --query 'addon.status'
Expected output: "ACTIVE"
Network requirements​
Pods in the EKS cluster must be able to connect to the RDS instance. For clusters using private subnets, the following VPC endpoints are required:
| Endpoint | Service | Purpose |
|---|---|---|
com.amazonaws.<region>.rds | RDS API | RDS service access |
com.amazonaws.<region>.sts | STS | IAM token generation |
com.amazonaws.<region>.iam | IAM API | Platform IAM role/policy management |
com.amazonaws.<region>.eks | EKS API | Pod Identity (if private cluster) |
com.amazonaws.<region>.ec2 | EC2 API | ENI management |
Configure security groups​
The RDS security group must allow inbound connections from EKS pods. A common mistake is only allowing traffic from the EKS cluster security group, which may not cover pod traffic.
aws ec2 authorize-security-group-ingress \
--group-id YOUR_RDS_SG \
--protocol tcp \
--port 5432 \
--cidr 10.0.0.0/16 # Replace with your VPC CIDR
If you see no pg_hba.conf entry for host "10.0.x.x" errors, this typically indicates a security group or network connectivity issue, not a PostgreSQL configuration problem.
Setup and prepare RDS database​
Create an RDS Database and ensure it supports Password and IAM based Authentication.
Verify connectivity from EKS​
Before configuring IAM authentication, verify that pods can connect to RDS:
- PostgreSQL
- MySQL
kubectl run psql-test --rm -i --restart=Never --image=postgres:15 -- bash -c '
export PGPASSWORD="your-password"
export PGSSLMODE=require
psql -h YOUR_RDS_ENDPOINT -U postgres -c "SELECT version();"
'
Expected output: PostgreSQL version string (e.g., PostgreSQL 15.x on x86_64-pc-linux-gnu...)
If the connection fails:
- Timeout: Check security groups and VPC routing
- SSL error (
no pg_hba.conf entry... no encryption): RDS requires SSL. EnsurePGSSLMODE=requireis set - Authentication failed: Verify password. Use environment variables for passwords with special characters
kubectl run mysql-test --rm -i --restart=Never --image=mysql:8 -- bash -c '
mysql -h YOUR_RDS_ENDPOINT -u admin -p"your-password" --ssl-mode=REQUIRED -e "SELECT version();"
'
Expected output: MySQL version string (e.g., 8.0.x)
If the connection fails:
- Timeout: Check security groups and VPC routing
- SSL error: RDS requires SSL. Ensure
--ssl-mode=REQUIREDis set - Authentication failed: Verify password. Use
-p"password"format (no space) for special characters
Grant IAM authentication permissions​
Once connectivity is verified, grant the admin user permissions to connect via RDS IAM authentication.
- PostgreSQL
- MySQL
The default user for PostgreSQL RDS instances is postgres, adjust accordingly if a different admin user is used.
GRANT rds_iam TO postgres
Expected output: GRANT ROLE
If you see:
ERROR: role "rds_iam" does not exist- IAM Database Authentication is not enabled on the RDS instance. Enable it in the RDS console or via AWS CLI.ERROR: permission denied- The connected user lacks GRANT privileges.
The default user for MySQL RDS instances is admin, adjust accordingly if a different admin user is used.
ALTER USER IF EXISTS admin IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'
Expected output: Query OK, 0 rows affected
If you see:
ERROR 1524: Plugin 'AWSAuthenticationPlugin' is not loaded- IAM Database Authentication is not enabled on the RDS instance.ERROR 1227: Access denied- The connected user lacks ALTER privileges.
Once IAM authentication is granted to a user, password-based login for that user stops working. Before proceeding:
- Create a separate admin user for password-based access if needed for maintenance
- Or be prepared to use
aws rds generate-db-auth-tokenfor all future connections
Create IAM policies and role​
Next up, you need to allow the vCluster Platform to connect to the RDS instance using IAM authentication. This is done by creating an IAM Policy and attaching it to the IAM Role used by the vCluster Platform pods. It also needs permissions to manage IAM Roles, Policies, and EKS Pod Identity Associations for the virtual clusters.
A policy for each DB Connector / RDS Instance that the platform manages is required. The vCluster Platform must be restarted for newly attached policies to take effect.
RDS DB Connect Policy​
This policy is required to allow the vCluster Platform to connect as a database user. This user must be able to create and delete users and databases (AKA superuser). For convenience, the default admin user can be used. Consult the respective database documentation for the permissions required when not using the admin user.
A sample policy is shown below, where REGION, ACCOUNT, and DB_RESOURCE_ID are values specific to the RDS instance. DB_USER must match the admin user that the platform deployment will connect as.
The DB_RESOURCE_ID can be retrieved by running aws rds describe-db-instances --output json and looking for the DbiResourceId or DbClusterResourceId field in the output, depending on your RDS instance type.
For RDS Proxy, use the aws rds describe-db-proxies --output json command instead and look for the last part of the DbProxyArn field after the final colon (:).
For example, if the DbProxyArn is arn:aws:rds:us-east-1:123456789012:db-proxy:prx-0123a01b12345c0a, the DB_RESOURCE_ID is prx-0123a01b12345c0a.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "rds-db:connect",
"Resource": "arn:aws:rds-db:${REGION}:${ACCOUNT}:dbuser:${DB_RESOURCE_ID}/${DB_USER}"
}
]
}
IAM Management Policy​
This policy allows the vCluster Platform to manage policies that allow virtual clusters to connect to newly created virtual cluster databases. The vCluster Platform utilizes inline policies to avoid the need to manage many to one relationships between policies and roles.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:UpdateAssumeRolePolicy",
"iam:PassRole",
"iam:DeleteRolePolicy",
"iam:CreateRole",
"iam:DeleteRole",
"iam:UpdateRole",
"iam:PutRolePolicy",
"iam:GetRolePolicy"
],
"Resource": "*"
}
]
}
RDS Resource ID Lookup Policy​
This read only policy allows the vCluster Platform to look up the DB_RESOURCE_ID for each DB Connector.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["rds:DescribeDBInstances", "rds:DescribeDBProxies"],
"Resource": "*"
}
]
}
EKS Pod Identity Association Policy​
Manages EKS Pod Identity Associations for virtual clusters to allow them to assume the IAM Roles created for database access.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"eks:DescribePodIdentityAssociation",
"eks:ListPodIdentityAssociations",
"eks:CreatePodIdentityAssociation",
"eks:TagResource",
"eks:DeletePodIdentityAssociation",
"eks:UpdatePodIdentityAssociation"
],
"Resource": "*"
}
]
}
Assemble policies into role​
Now that the required policies have been created, they need to be attached to an IAM Role used by the vCluster Platform pods. Create a new IAM role that includes the four preceding policies and set up a trust policy that allows the EKS Pod Identity Agent to assume the role.
{
"RoleName": "vcluster-platform-iam-database-role",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "pods.eks.amazonaws.com"
},
"Action": ["sts:AssumeRole", "sts:TagSession"]
}
]
},
"Description": "Allows vCluster Platform running in Amazon EKS cluster to access RDS and IAM Resources."
}
Create Pod Identity Association​
Now that the database user and roles are configured, it"s time to assign the role to the vCluster platform pods by running the following command. Replace the placeholders EKS_CLUSTER_NAME and IAM_ROLE_ARN with your own values.
aws eks create-pod-identity-association \
--cluster-name $EKS_CLUSTER_NAME \
--role-arn $IAM_ROLE_ARN \
--namespace vcluster-platform \
--service-account loft
After the association is created, restart the vCluster Platform pods to pick up the new role.
Create connector secret​
A connector secret is a secret that can be used with a platform feature or integration.
For the platform to start using a database server, a secret must be created that contains admin credentials for the server. The secret must:
- Contain the
loft.sh/connector-typelabel with theshared-databasevalue - Reside in the same namespace as the platform
- Contain the fields:
- endpoint
- port
- user
- identityProvider (only for IAM based authentication)
To create a database connector secret in the UI, navigate to the sidebar and select Databases -> Connect Database Secrets. Then, select the AWS IAM authentication method and fill in the required fields.
Alternatively, a Secret YAML manifest can be applied to the platform's host cluster.
apiVersion: v1
kind: Secret
metadata:
name: <name> # Descriptive name, used to reference this connector in vCluster configs
namespace: <vcluster-platform-namespace> # Namespace where vCluster Platform is installed
labels:
loft.sh/connector-type: "shared-database"
stringData:
endpoint: <endpoint> # RDS endpoint (e.g., mydb.abc123.us-east-1.rds.amazonaws.com)
port: <port> # 5432 for PostgreSQL, 3306 for MySQL
user: <user> # Database user with rds_iam granted
type: <type> # "mysql" or "postgres"
identityProvider: "aws"
Use the following kubectl command to create the secret:
- PostgreSQL
- MySQL
kubectl create secret generic my-rds-connector \
--namespace=vcluster-platform \
--from-literal=endpoint="your-rds-endpoint.region.rds.amazonaws.com" \
--from-literal=identityProvider="aws" \
--from-literal=port="5432" \
--from-literal=type="postgres" \
--from-literal=user="postgres"
kubectl label secret my-rds-connector \
--namespace=vcluster-platform \
loft.sh/connector-type=shared-database
kubectl create secret generic my-rds-connector \
--namespace=vcluster-platform \
--from-literal=endpoint="your-rds-endpoint.region.rds.amazonaws.com" \
--from-literal=identityProvider="aws" \
--from-literal=port="3306" \
--from-literal=type="mysql" \
--from-literal=user="admin"
kubectl label secret my-rds-connector \
--namespace=vcluster-platform \
loft.sh/connector-type=shared-database
Verify the secret was created with the correct label:
kubectl get secrets -n vcluster-platform -l loft.sh/connector-type=shared-database
To use the secret in a virtual cluster, refer to the Database Connectors documentation.
Troubleshoot common issues​
Connection errors​
| Error | Cause | Solution |
|---|---|---|
FATAL: PAM authentication failed | IAM role not configured correctly | Verify Pod Identity Association exists and platform pods were restarted |
| Connection timeout | Network issue | Check VPC endpoints (for private subnets) and security groups |
no pg_hba.conf entry for host | Security group blocking OR SSL required | Allow VPC CIDR in RDS security group; ensure SSL is used |
permission denied for database | DB user lacks privileges | Grant CREATE DATABASE, CREATE ROLE privileges to the user |
IAM issues​
Test IAM authentication manually:
aws rds generate-db-auth-token \
--hostname YOUR_RDS_ENDPOINT \
--port 5432 \
--username postgres \
--region YOUR_REGION
If this fails with access denied, check:
- The IAM role has the
rds-db:connectpermission - The resource ARN in the policy matches your RDS instance's resource ID
- The database user matches the policy
Pod Identity issues​
Verify Pod Identity is working:
kubectl exec -it -n vcluster-platform deployment/loft -- env | grep AWS
Expected: AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE and AWS_CONTAINER_CREDENTIALS_FULL_URI should be set.
If not set:
- Verify Pod Identity Agent addon is installed:
aws eks describe-addon --cluster-name CLUSTER --addon-name eks-pod-identity-agent - Verify association exists:
aws eks list-pod-identity-associations --cluster-name CLUSTER - Restart the platform pods after creating the association