Lambda to RDS or Aurora: VPC, connections and credentials
Connecting Lambda functions to an RDS or Aurora database — the VPC attachment and security-group chain, why bursts of invocations exhaust connections and how RDS Proxy absorbs them, IAM database authentication to the proxy, and the known-bad configurations with their symptoms.
markdownpatternv4A444-3Z9Fstage: buildtrust: officialservice: lambdaservice: rdsinterface: iacinterface: sdkLambda RDSLambda AuroraLambda too many connectionsRDS Proxy LambdaLambda VPC databaseconnection reuse LambdaIAM auth RDS ProxyLambda database timeout
Lambda to RDS or Aurora
Attach the function to the database's VPC, let the database's (or proxy's) security group admit the function's security group, and put RDS Proxy between them. Each concurrent Lambda environment holds its own connection, and Lambda can add up to 1,000 environments every 10 seconds per function, so bursts exhaust max_connections unless something pools them.
What crosses the handoff
| Side | Provides / expects |
|---|---|
| Lambda | VPC config in the database's VPC (private subnets), the ENI permissions on its execution role, a security group allowing outbound traffic on the engine port. The DB client is created outside the handler, so warm invocations reuse the connection |
| RDS Proxy | In the same VPC, never public. Its security group admits the Lambda security group. It connects to the DB with Secrets Manager secrets or IAM auth, and can require IAM auth from clients |
| Database | Its security group admits the proxy's security group (or Lambda's if there is no proxy). Not publicly accessible |
Known-good
- Lambda → private subnets of the DB VPC,
lambda-sg(egress to 5432/3306). - RDS Proxy →
proxy-sg, inbound engine port fromlambda-sg. Target: the DB instance or cluster. Auth to the DB from a Secrets Manager secret. - DB →
db-sg, inbound fromproxy-sgonly. - Clients use IAM auth to the proxy. The execution role allows
rds-db:connectonarn:aws:rds-db:<region>:<account>:dbuser:<prx-id>/<db-user>, using the proxy's resource ID. Generate the token with@aws-sdk/rds-signeragainst the proxy endpoint (guides/rds/connect-securely.md). - The handler opens the connection lazily, once per environment, reuses it, and reconnects on error.
- If the function also calls AWS APIs or the internet: NAT or VPC endpoints, because a VPC-attached function has no internet access (
patterns/lambda-in-vpc.md). Use a Secrets Manager endpoint if you read secrets at start-up.
Known-bad
| Configuration | Symptom |
|---|---|
| Function not in the VPC, database private | Connection timeouts (Task timed out after …) |
| Database security group admits a CIDR, not the Lambda/proxy security group | Works in one subnet, times out from others |
| No proxy, bursty traffic | Errors about too many connections; incompatible-parameters if max_connections is raised too far |
| Connection opened inside the handler and never closed | Connection count climbs with concurrency, then refusals |
| IAM token generated against a custom DNS name or a cluster's reader alias in Route 53 | Authentication fails: use the RDS or proxy endpoint |
rds-db:connect resource uses the instance ID while connecting through the proxy | Denied: use the proxy's prx-… ID |
| Large prepared statements or session settings through the proxy | Pinning: the proxy stops pooling those clients |
| Secret rotated, function caches the old password forever | Auth failures until cold start. Refresh on auth error |
| Function timeout shorter than the DB query plus connection set-up | Timeouts that look like network issues: log timings |
Which side is wrong?
- Timeout before any database error → network: VPC attachment, security groups, subnets (
guides/vpc/diagnose-connection-timeout.md). - Authentication error → credentials: the token's endpoint and age,
rds-db:connectresource ID, the DB user's grants (reference/rds/errors.md). - Works at low traffic, fails in bursts → connections: add or size RDS Proxy, and reuse connections.