AWS Lambda backend for AI chatbot with Bedrock (Llama 3.2) and PostgreSQL integration. Providing information on a database of CG production assets based on natural language queries.
- Architecture Overview
- Prerequisites
- AWS Setup Guide (Step-by-Step)
- Local Development
- Deployment
- API Documentation
- Troubleshooting
- Cost Monitoring
Gradio UI (Hugging Face) โ API Gateway โ Lambda โ Bedrock LLMs
โ
PostgreSQL (RDS)
Components:
- Lambda Function: Handles chatbot logic, streaming responses, semantic search
- Amazon Bedrock: Llama 3.2 11B Instruct model for AI responses
- RDS PostgreSQL with pgvector: Stores Blender file metadata + embeddings
- Embedding Models: sentence-transformers (text) + CLIP (images)
- API Gateway: REST API with Server-Sent Events (SSE) for streaming
- AWS Account - Sign up here
- AWS CLI - Installation guide
- Python 3.11+ - Download
- Git - Download
- Amazon Bedrock (Llama models)
- AWS Lambda
- Amazon RDS (PostgreSQL)
- Amazon API Gateway
- IAM (for permissions)
Important: Bedrock models must be enabled before use.
-
Log into AWS Console: https://console.aws.amazon.com/
-
Navigate to Bedrock:
- Search for "Bedrock" in the top search bar
- Click "Amazon Bedrock"
-
Select Region: Make sure you're in us-east-1 (top-right corner)
-
Enable Model Access:
- Click "Model access" in the left sidebar
- Click "Manage model access" (orange button)
- Find Meta section
- Check the boxes for:
- โ Llama 3.2 11B Instruct
- โ Llama 3.1 70B Instruct (optional, for complex queries)
- Click "Request model access" at the bottom
- Wait 1-2 minutes for approval (usually instant)
-
Verify Access:
- Refresh the page
- Status should show "Access granted" (green)
Note: If you already have your RDS PostgreSQL database set up, skip to Step 3.
-
Navigate to RDS:
- Search for "RDS" in AWS Console
- Click "Amazon RDS"
-
Create Database:
- Click "Create database" (orange button)
- Choose:
- Engine: PostgreSQL
- Version: PostgreSQL 15.x or later
- Template: Free tier (if eligible) or Dev/Test
- DB instance identifier:
cg-production-db - Master username:
postgres(or your choice) - Master password: Create a strong password (save this!)
-
Configure Instance:
- Instance class:
db.t3.micro(cheapest, ~$15/month) - Storage: 20 GB (default)
- Public access: Yes (for now, for easier setup)
- VPC security group: Create new โ name it
cg-db-security-group
- Instance class:
-
Create Database:
- Click "Create database"
- Wait 5-10 minutes for creation
-
Get Connection Details:
- Click on your database name
- Under "Connectivity & security":
- Copy Endpoint (e.g.,
cg-production-db.xxxxx.us-east-1.rds.amazonaws.com) - Note Port (usually
5432)
- Copy Endpoint (e.g.,
- Save these for later!
-
Configure Security Group:
- Click on the VPC security group link
- Click "Edit inbound rules"
- Add rule:
- Type: PostgreSQL
- Source: My IP (for testing) or Custom (Lambda's security group later)
- Click "Save rules"
Lambda needs permissions to access Bedrock and RDS.
-
Navigate to IAM:
- Search for "IAM" in AWS Console
- Click "Roles" in left sidebar
-
Create Role:
- Click "Create role"
- Trusted entity: AWS service
- Use case: Lambda
- Click "Next"
-
Attach Policies:
- Search and select these AWS managed policies:
- โ
AWSLambdaBasicExecutionRole(for CloudWatch logs) - โ
AWSLambdaVPCAccessExecutionRole(for RDS access)
- โ
- Click "Next"
- Search and select these AWS managed policies:
-
Name the Role:
- Role name:
cg-chatbot-lambda-role - Click "Create role"
- Role name:
-
Add Custom Bedrock Policy:
- Click on your new role
- Click "Add permissions" โ "Create inline policy"
- Click "JSON" tab
- Paste the contents of
iam_policy.jsonfrom this repo - Click "Review policy"
- Name:
BedrockAccess - Click "Create policy"
-
Navigate to Lambda:
- Search for "Lambda" in AWS Console
- Make sure you're in us-east-1 region
-
Create Function:
- Click "Create function"
- Choose "Author from scratch"
- Function name:
cg-production-chatbot - Runtime: Python 3.11
- Architecture: x86_64
- Permissions: Use existing role โ select
cg-chatbot-lambda-role - Click "Create function"
-
Configure Function:
- Scroll to "Configuration" tab
- Click "General configuration" โ "Edit"
- Memory: 512 MB
- Timeout: 30 seconds
- Click "Save"
-
Set Environment Variables:
- Click "Configuration" โ "Environment variables" โ "Edit"
- Add these variables (use your actual values):
DB_HOST = your-rds-endpoint.us-east-1.rds.amazonaws.com DB_NAME = your_database_name DB_USER = postgres DB_PASSWORD = your_password DB_PORT = 5432 AWS_REGION = us-east-1 BEDROCK_MODEL_ID = meta.llama3-2-11b-instruct-v1:0 - Click "Save"
-
Deploy Code (we'll do this in the Deployment section below)
-
Navigate to API Gateway:
- Search for "API Gateway" in AWS Console
-
Create API:
- Click "Create API"
- Choose "REST API" (not private)
- Click "Build"
- API name:
cg-chatbot-api - Endpoint Type: Regional
- Click "Create API"
-
Create Resource:
- Click "Actions" โ "Create Resource"
- Resource Name:
chat - Resource Path:
/chat - โ Enable CORS
- Click "Create Resource"
-
Create POST Method:
- Select
/chatresource - Click "Actions" โ "Create Method"
- Choose "POST" from dropdown
- Click the checkmark โ
- Integration type: Lambda Function
- โ Use Lambda Proxy integration
- Lambda Function:
cg-production-chatbot - Click "Save"
- Click "OK" on the permission popup
- Select
-
Enable CORS (for Gradio):
- Select
/chatresource - Click "Actions" โ "Enable CORS"
- Use default settings
- Click "Enable CORS and replace existing CORS headers"
- Click "Yes, replace existing values"
- Select
-
Deploy API:
- Click "Actions" โ "Deploy API"
- Deployment stage: [New Stage]
- Stage name:
prod - Click "Deploy"
-
Get API URL:
- You'll see "Invoke URL" at the top
- Copy this URL (e.g.,
https://abc123.execute-api.us-east-1.amazonaws.com/prod) - Your endpoint will be:
{Invoke URL}/chat - Save this URL! You'll need it for Gradio
cd backend
pip install -r requirements.txt
pip install python-dotenv # For local testing# Copy example environment file
cp .env.example .env
# Edit .env with your actual values
nano .env # or use any text editorFill in your PostgreSQL and AWS details.
# Run local tests
python test_local.pyThis will test:
- โ Database connectivity
- โ Bedrock API access
- โ Full Lambda function flow
Warning
ZIP deployment will not work due to large embedding models (~500MB). You must use container deployment.
# Install dependencies to package directory
pip install -r requirements.txt -t package/
# Copy function files
cp lambda_function.py bedrock_client.py database.py package/
# Create ZIP file
cd package
zip -r ../deployment.zip .
cd ..
# Upload to Lambda (using AWS CLI)
aws lambda update-function-code \
--function-name cg-production-chatbot \
--zip-file fileb://deployment.zip \
--region us-east-1# Get your AWS account ID
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REGION="us-east-1"
REPO_NAME="cg-chatbot"
# Create ECR repository
aws ecr create-repository --repository-name $REPO_NAME --region $REGION# Login to ECR
aws ecr get-login-password --region $REGION | \
docker login --username AWS --password-stdin \
$AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com# Build Docker image
docker build -t $REPO_NAME .
# Tag for ECR
docker tag $REPO_NAME:latest \
$AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME:latest
# Push to ECR
docker push $AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME:latest# Update Lambda to use container image
aws lambda update-function-code \
--function-name cg-production-chatbot \
--image-uri $AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME:latestTip
Cold Start Optimization: The first request after deployment may take 10-15 seconds due to model loading. Subsequent requests will be much faster as models are cached in Lambda memory.
POST https://your-api-id.execute-api.us-east-1.amazonaws.com/prod/chat
{
"query": "Show me all 4K renders from the lighting project",
"user_id": "optional-user-id"
}data: {"type": "start", "metadata_count": 5}
data: {"type": "chunk", "text": "I found "}
data: {"type": "chunk", "text": "3 files "}
data: {"type": "chunk", "text": "matching your criteria..."}
data: {"type": "metadata", "files": [{...}, {...}]}
data: {"type": "end"}
curl -X POST https://your-api-id.execute-api.us-east-1.amazonaws.com/prod/chat \
-H "Content-Type: application/json" \
-d '{"query": "Show me recent renders"}'Solution: Make sure you've enabled model access in Bedrock console (Step 1 above)
Solutions:
- Check RDS security group allows Lambda's IP
- Verify database is publicly accessible (for testing)
- Check environment variables are correct
Solutions:
- Increase timeout in Lambda configuration (max 15 minutes)
- Optimize database queries
- Use smaller Bedrock model
Solution: Make sure dependencies are in the deployment package:
pip install -r requirements.txt -t package/- Go to Lambda console
- Click "Monitor" tab
- Click "View CloudWatch logs"
- Check recent log streams for errors
| Service | Cost |
|---|---|
| Lambda | ~$0.30 |
| API Gateway | ~$0.004 |
| Bedrock (Llama 3.2 11B) | ~$1.13 |
| RDS PostgreSQL (t3.micro) | ~$15 |
| Total | ~$16.43/month |
- Use RDS Proxy - Reduce connection overhead
- Cache common queries - Store in Lambda memory
- Use smaller model - Llama 3.2 11B instead of 70B
- Set up billing alerts:
- AWS Console โ Billing โ Budgets
- Create budget with $20 threshold
- Get email alerts when exceeded
# Check current month costs (AWS CLI)
aws ce get-cost-and-usage \
--time-period Start=2024-01-01,End=2024-01-31 \
--granularity MONTHLY \
--metrics BlendedCost \
--group-by Type=SERVICEEnable semantic search:
-- In your PostgreSQL database
CREATE EXTENSION vector;
ALTER TABLE media_metadata
ADD COLUMN embedding vector(1536);Uncomment get_similar_files_vector() in database.py.
Uncomment store_conversation() in lambda_function.py and create DynamoDB table.
Use select_model() in bedrock_client.py to automatically choose between Llama 11B and 70B based on query complexity.
For issues or questions:
- Check CloudWatch logs
- Review AWS Lambda documentation
- Review Amazon Bedrock documentation
MIT License - See LICENSE file for details