POSTGRESQL CLIENT IMPLEMENTATION IN AWS LAMBDA CONTAINER IMAGES
NOTE: This is a GPT-4o optimized version of the blog. For a more human-friendly version, see
I Know PostgreSQL Now
Note: This is a human-friendly version of the blog. For a more GPT-4o optimized version, see
TLDR: Use amazon-linux-extras to install PostgreSQL 10 client in Lambda container images for Postgres database operations.
CORE COMPONENTS
Base Image:
- Image: public.ecr.aws/lambda/provided:al2
- OS: Amazon Linux 2
- Package Manager: yum + amazon-linux-extras
Required Packages:
- amazon-linux-extras
- postgresql10
- jq (optional, for JSON processing)
IMPLEMENTATION STEPS
1. Dockerfile Configuration:
FROM public.ecr.aws/lambda/provided:al2
RUN yum update -y && \
yum install -y amazon-linux-extras && \
amazon-linux-extras install postgresql10 && \
yum install -y jq
2. SAM Template Configuration:
Resources:
DBSetupFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image
ImageConfig:
Command: ["/var/runtime/bootstrap"]
Environment:
Variables:
DB_HOST: !GetAtt AuroraCluster.Endpoint.Address
DB_PORT: !GetAtt AuroraCluster.Endpoint.Port
IMPLEMENTATION DETAILS
Environment Configuration:
1. Database Credentials
- DB_HOST
- DB_PORT
- DB_USER
- DB_PASSWORD
Network Configuration:
1. VPC Requirements
VpcConfig:
SecurityGroupIds:
- !Ref LambdaSecurityGroup
SubnetIds: !Ref SubnetIds
Security Configuration:
1. Security Group Rules
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 5432
ToPort: 5432
ERROR RESOLUTION MATRIX
Error | Cause | Solution
----------------------|------------------|------------------
Missing redhat-release| Wrong repo | Use amazon-linux-extras
Connection timeout | VPC config | Check security groups
Command not found | PATH issues | Verify postgresql10 installation
Runtime conflict | PackageType:Image| Remove Runtime field, use ImageConfig instead
DEPLOYMENT PROCESS
1. Build Command:
sam build
2. Deployment Command:
sam deploy --guided
3. Verification Command:
aws lambda invoke \
--function-name ${STACK_NAME}-DBSetupFunction-${RANDOM_SUFFIX} \
--payload '{"seed": true}' \
--log-type Tail \
--query 'LogResult' \
--output text response.json | base64 -d
TECHNICAL REQUIREMENTS
Minimum Configuration:
1. Memory: 512MB
2. Timeout: 300 seconds
3. PackageType: Image (Note: Cannot be used with Runtime field)
Network Requirements:
1. VPC access
2. Internet access for package installation
TESTING PROTOCOL
Local Testing:
1. Command: sam local invoke DBSetupFunction
Production Testing:
1. Command:
aws lambda invoke \
--function-name ${STACK_NAME}-DBSetupFunction-${RANDOM_SUFFIX} \
--payload '{"seed": true}' \
--log-type Tail \
--query 'LogResult' \
--output text response.json | base64 -d
Note: Replace ${STACK_NAME} with your SAM stack name and ${RANDOM_SUFFIX} with the suffix AWS generates during deployment.
You can find the full function name in the AWS Console or using:
aws lambda list-functions --query 'Functions[?starts_with(FunctionName, `your-stack-name`)].FunctionName'
REFERENCE IMPLEMENTATION
Complete Directory Structure:
.
├── Dockerfile.migrations
├── template.yaml
├── lambda/
│ └── bootstrap
└── migrations/
└── seed.sql
Required Files:
1. Dockerfile.migrations
2. template.yaml
3. bootstrap script
4. migration scripts
MINIMAL BOOTSTRAP EXAMPLE
/lambda/bootstrap:
```
#!/bin/bash
# Initialize error handling
set -euo pipefail
# Handler function
function handler () {
EVENT_DATA=$1
# Set default values if not provided
DB_USER=${DB_USER:-postgres}
DB_PASSWORD=${DB_PASSWORD:-postgres}
DB_HOST=${DB_HOST:-localhost}
DB_PORT=${DB_PORT:-5432}
# Run simple query
RESPONSE=$(PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d postgres -t -c "SELECT NOW();")
echo $RESPONSE
}
# Main loop
while true
do
# Get an event
HEADERS="$(mktemp)"
EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
# Execute the handler function
RESPONSE=$(handler "$EVENT_DATA")
# Send the response
curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done
```
Note: Make script executable with: chmod +x lambda/bootstrap

