7.8 KiB
AWS Database Migration Guide
This guide explains how to migrate the authentication service from a local Docker PostgreSQL database to an AWS PostgreSQL database using AWS SSM Parameter Store for secure credential management.
Overview
Security Model: Database credentials are fetched from AWS SSM Parameter Store at runtime. NO database credentials are stored in .env files or code.
Prerequisites
- AWS Account with access to Systems Manager Parameter Store
- IAM user/role with permissions to read SSM parameters:
ssm:GetParameterfor/test/livingai/db/appssm:GetParameterfor/test/livingai/db/app/readonly
- AWS PostgreSQL database instance (RDS or managed PostgreSQL)
- Database users created:
read_write_user(for authentication service)read_only_user(optional, for read-only operations)
AWS Configuration
1. Set Up AWS SSM Parameters
Store database credentials in AWS SSM Parameter Store as SecureString parameters:
Read-Write User (Authentication Service)
Parameter Path: /test/livingai/db/app
Parameter Value (JSON format):
{
"user": "read_write_user",
"password": "your_secure_password_here",
"host": "db.livingai.app",
"port": "5432",
"database": "livingai_test_db"
}
Read-Only User (Optional)
Parameter Path: /test/livingai/db/app/readonly
Parameter Value (JSON format):
{
"user": "read_only_user",
"password": "your_secure_password_here",
"host": "db.livingai.app",
"port": "5432",
"database": "livingai_test_db"
}
2. Create IAM Policy
Create an IAM policy that allows reading SSM parameters:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:GetParameter",
"ssm:GetParameters"
],
"Resource": [
"arn:aws:ssm:ap-south-1:*:parameter/test/livingai/db/app",
"arn:aws:ssm:ap-south-1:*:parameter/test/livingai/db/app/readonly"
]
}
]
}
Attach this policy to your IAM user or role.
Environment Variables
Required Variables
Create or update your .env file with ONLY these AWS credentials:
# AWS Configuration (for SSM Parameter Store access)
AWS_REGION=ap-south-1
AWS_ACCESS_KEY_ID=your_aws_access_key_here
AWS_SECRET_ACCESS_KEY=your_aws_secret_key_here
# Enable AWS SSM for database credentials
USE_AWS_SSM=true
# JWT Configuration (REQUIRED)
JWT_ACCESS_SECRET=your_jwt_access_secret_here
JWT_REFRESH_SECRET=your_jwt_refresh_secret_here
Optional Variables
# Control which database user to use
# false = read_write_user (default for auth service)
# true = read_only_user
DB_USE_READONLY=false
# Database connection settings (auto-detected if not set)
DB_HOST=db.livingai.app
DB_PORT=5432
DB_NAME=livingai_test_db
⚠️ DO NOT Include
NEVER include these in your .env file:
DB_USERDB_PASSWORDDATABASE_URL(with credentials)- Any database credentials
Database credentials are fetched from AWS SSM at runtime.
Database Configuration
AWS PostgreSQL Settings
- Host:
db.livingai.app - Port:
5432 - Database:
livingai_test_db - SSL: Required (self-signed certificates supported)
SSL Configuration
The connection automatically handles SSL with self-signed certificates:
rejectUnauthorized: falseis set for self-signed certificate support- Connection string includes
?sslmode=require
Migration Steps
Step 1: Update Environment Variables
-
Remove any existing database credentials from
.env:# Remove these if present: # DB_HOST=... # DB_USER=... # DB_PASSWORD=... # DATABASE_URL=... -
Add AWS credentials to
.env:AWS_REGION=ap-south-1 AWS_ACCESS_KEY_ID=your_aws_access_key AWS_SECRET_ACCESS_KEY=your_aws_secret_key USE_AWS_SSM=true
Step 2: Verify SSM Parameters
Ensure your SSM parameters are set correctly:
# Using AWS CLI (if configured)
aws ssm get-parameter --name "/test/livingai/db/app" --with-decryption --region ap-south-1
Step 3: Test Database Connection
Start your application:
npm start
You should see:
✅ Successfully fetched DB credentials from SSM: /test/livingai/db/app (read-write user)
✅ Using database credentials from AWS SSM Parameter Store
Host: db.livingai.app, Database: livingai_test_db, User: read_write_user
✅ Database connection established successfully
Step 4: Run Database Migrations
If you have schema changes, run migrations:
node run-migration.js
Connection Pool Configuration
The connection pool is configured with:
- Max connections: 20
- Idle timeout: 30 seconds
- Connection timeout: 2 seconds
These can be adjusted in src/db.js if needed.
Troubleshooting
Error: "Cannot access AWS SSM Parameter Store"
Causes:
- Missing AWS credentials in
.env - IAM user doesn't have SSM permissions
- Wrong AWS region
Solutions:
- Verify
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYare set - Check IAM permissions for SSM access
- Verify
AWS_REGIONmatches your SSM parameter region
Error: "Database connection failed: SSL required"
Cause: Database requires SSL but connection isn't using it.
Solution: SSL is automatically configured. Verify your database security group allows SSL connections.
Error: "Parameter not found"
Cause: SSM parameter path doesn't exist or has wrong name.
Solution:
- Verify parameter path:
/test/livingai/db/app - Check parameter is in correct region
- Ensure parameter type is "SecureString"
Error: "Invalid credentials format"
Cause: SSM parameter value is not valid JSON.
Solution: Ensure parameter value is JSON format:
{
"user": "username",
"password": "password",
"host": "host",
"port": "5432",
"database": "dbname"
}
Local Development
For local development without AWS SSM, you can use DATABASE_URL:
# Disable AWS SSM for local development
USE_AWS_SSM=false
# Use local database
DATABASE_URL=postgresql://postgres:password@localhost:5432/farmmarket
Note: This should only be used for local development. Production must use AWS SSM.
Security Best Practices
- Never commit
.envfiles - Add.envto.gitignore - Rotate credentials regularly - Update SSM parameters periodically
- Use least privilege - IAM user should only have SSM read permissions
- Monitor SSM access - Enable CloudTrail to audit SSM parameter access
- Use different credentials per environment - Separate SSM parameters for test/prod
Code Changes Summary
Files Modified
-
src/utils/awsSsm.js- Updated to use correct SSM parameter paths
- Added support for read-only/read-write user selection
- Improved error handling and validation
-
src/db.js- Added SSL configuration for self-signed certificates
- Updated to use
buildDatabaseConfiginstead of connection string - Improved error handling and logging
-
src/config.js- Removed
DATABASE_URLfrom required env vars when using SSM - Added AWS credentials validation
- Removed
No Changes Required
- All business logic remains unchanged
- All API endpoints work as before
- All database queries work as before
- Only connection configuration changed
Verification Checklist
- AWS SSM parameters created with correct paths
- IAM user/role has SSM read permissions
.envfile has AWS credentials (no DB credentials)USE_AWS_SSM=truein.env- Application starts without errors
- Database connection established successfully
- API endpoints respond correctly
- Database queries execute successfully
Support
For issues or questions:
- Check application logs for detailed error messages
- Verify SSM parameters using AWS Console or CLI
- Test AWS credentials with AWS CLI
- Review IAM permissions for SSM access