auth/docs/getting-started/AWS_DATABASE_MIGRATION.md

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

  1. AWS Account with access to Systems Manager Parameter Store
  2. IAM user/role with permissions to read SSM parameters:
    • ssm:GetParameter for /test/livingai/db/app
    • ssm:GetParameter for /test/livingai/db/app/readonly
  3. AWS PostgreSQL database instance (RDS or managed PostgreSQL)
  4. 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_USER
  • DB_PASSWORD
  • DATABASE_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: false is set for self-signed certificate support
  • Connection string includes ?sslmode=require

Migration Steps

Step 1: Update Environment Variables

  1. Remove any existing database credentials from .env:

    # Remove these if present:
    # DB_HOST=...
    # DB_USER=...
    # DB_PASSWORD=...
    # DATABASE_URL=...
    
  2. 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:

  1. Verify AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set
  2. Check IAM permissions for SSM access
  3. Verify AWS_REGION matches 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:

  1. Verify parameter path: /test/livingai/db/app
  2. Check parameter is in correct region
  3. 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

  1. Never commit .env files - Add .env to .gitignore
  2. Rotate credentials regularly - Update SSM parameters periodically
  3. Use least privilege - IAM user should only have SSM read permissions
  4. Monitor SSM access - Enable CloudTrail to audit SSM parameter access
  5. Use different credentials per environment - Separate SSM parameters for test/prod

Code Changes Summary

Files Modified

  1. 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
  2. src/db.js

    • Added SSL configuration for self-signed certificates
    • Updated to use buildDatabaseConfig instead of connection string
    • Improved error handling and logging
  3. src/config.js

    • Removed DATABASE_URL from required env vars when using SSM
    • Added AWS credentials validation

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
  • .env file has AWS credentials (no DB credentials)
  • USE_AWS_SSM=true in .env
  • Application starts without errors
  • Database connection established successfully
  • API endpoints respond correctly
  • Database queries execute successfully

Support

For issues or questions:

  1. Check application logs for detailed error messages
  2. Verify SSM parameters using AWS Console or CLI
  3. Test AWS credentials with AWS CLI
  4. Review IAM permissions for SSM access