Deployment Guide
Overview
This guide covers deploying the AMT Backend to AWS using ECS (Elastic Container Service) with proper configuration management through SSM Parameter Store.
Prerequisites
- AWS Account with appropriate permissions
- AWS CLI configured
- Docker installed locally
- Node.js and npm installed
Environment Configuration
Development
- Local development setup
- Uses
.envfile for configuration - Direct database connections
Staging
- Pre-production testing environment
- AWS ECS deployment
- SSM Parameter Store for secrets
Production
- Live production environment
- AWS ECS with auto-scaling
- Full monitoring and alerting
AWS Infrastructure
Required AWS Services
-
ECS (Elastic Container Service)
- Container orchestration
- Service auto-scaling
- Load balancing
-
RDS MySQL
- Managed database service
- Multi-AZ deployment for production
- Automated backups
-
ElastiCache Redis
- Session management
- Queue processing with Bull
- Caching layer
-
S3 Buckets
- File uploads
- Static assets
- Backup storage
-
SSM Parameter Store
- Secure configuration management
- API keys and secrets
- Environment-specific settings
Docker Configuration
Dockerfile
FROM node:14-alpine
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Copy application code
COPY . .
# Build TypeScript
RUN npm run build
# Expose port
EXPOSE 8080
# Start application
CMD ["npm", "start"]
Building Docker Image
# Build image
docker build -t amt-backend:latest .
# Tag for ECR
docker tag amt-backend:latest [aws-account].dkr.ecr.[region].amazonaws.com/amt-backend:latest
# Push to ECR
docker push [aws-account].dkr.ecr.[region].amazonaws.com/amt-backend:latest
ECS Task Definition
{
"family": "amt-backend",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "1024",
"memory": "2048",
"containerDefinitions": [
{
"name": "amt-backend",
"image": "[aws-account].dkr.ecr.[region].amazonaws.com/amt-backend:latest",
"portMappings": [
{
"containerPort": 8080,
"protocol": "tcp"
}
],
"environment": [
{
"name": "NODE_ENV",
"value": "production"
},
{
"name": "PLATFORM_TARGET_ENVIRONMENT",
"value": "production"
}
],
"secrets": [
{
"name": "DB_HOST",
"valueFrom": "arn:aws:ssm:[region]:[account]:parameter/amt/prod/DB_HOST"
},
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:ssm:[region]:[account]:parameter/amt/prod/DB_PASSWORD"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/amt-backend",
"awslogs-region": "[region]",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}
SSM Parameter Configuration
Setting Parameters
# Database configuration
aws ssm put-parameter --name "/amt/prod/DB_HOST" --value "database.region.rds.amazonaws.com" --type "String"
aws ssm put-parameter --name "/amt/prod/DB_USER" --value "admin" --type "String"
aws ssm put-parameter --name "/amt/prod/DB_PASSWORD" --value "password" --type "SecureString"
# Redis configuration
aws ssm put-parameter --name "/amt/prod/REDIS_HOST" --value "redis.cache.amazonaws.com" --type "String"
aws ssm put-parameter --name "/amt/prod/REDIS_PORT" --value "6379" --type "String"
# API Keys
aws ssm put-parameter --name "/amt/prod/SGMAIL_APIKEY" --value "SG.xxxxx" --type "SecureString"
aws ssm put-parameter --name "/amt/prod/SENTRY_DSN" --value "https://xxx@sentry.io/xxx" --type "SecureString"
Retrieving Parameters
# Get all parameters for environment
aws ssm get-parameters-by-path --path "/amt/prod" --recursive --with-decryption
Deployment Process
1. Update Task Definition
# Register new task definition
aws ecs register-task-definition --cli-input-json file://task-definition.json
2. Update ECS Service
# Update service with new task definition
aws ecs update-service \
--cluster amt-cluster \
--service amt-backend-service \
--task-definition amt-backend:latest \
--force-new-deployment
3. Monitor Deployment
# Check service status
aws ecs describe-services \
--cluster amt-cluster \
--services amt-backend-service
# View logs
aws logs tail /ecs/amt-backend --follow
CI/CD Pipeline
GitHub Actions Example
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Login to ECR
run: |
aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY
- name: Build and push Docker image
run: |
docker build -t amt-backend .
docker tag amt-backend:latest $ECR_REGISTRY/amt-backend:latest
docker push $ECR_REGISTRY/amt-backend:latest
- name: Update ECS service
run: |
aws ecs update-service --cluster amt-cluster --service amt-backend-service --force-new-deployment
Health Checks
Application Health Endpoint
app.get('/health', (req, res) => {
res.json({
status: 'healthy',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
database: checkDatabaseHealth(),
redis: checkRedisHealth()
});
});
ECS Health Check Configuration
"healthCheck": {
"command": ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"],
"interval": 30,
"timeout": 5,
"retries": 3,
"startPeriod": 60
}
Monitoring
CloudWatch Metrics
- CPU utilization
- Memory utilization
- Request count
- Error rate
- Response time
CloudWatch Alarms
# High CPU alarm
aws cloudwatch put-metric-alarm \
--alarm-name amt-backend-cpu-high \
--alarm-description "Alert when CPU exceeds 80%" \
--metric-name CPUUtilization \
--namespace AWS/ECS \
--statistic Average \
--period 300 \
--threshold 80 \
--comparison-operator GreaterThanThreshold
Application Monitoring
- Sentry: Error tracking and performance monitoring
- CloudWatch Logs: Application logs
- X-Ray: Distributed tracing (optional)
Scaling
Auto-scaling Configuration
{
"targetTrackingScalingPolicies": [
{
"targetValue": 75.0,
"predefinedMetricType": "ECSServiceAverageCPUUtilization",
"scaleInCooldown": 300,
"scaleOutCooldown": 60
}
],
"minCapacity": 2,
"maxCapacity": 10
}
Backup and Recovery
Database Backups
- Automated daily backups
- 7-day retention for staging
- 30-day retention for production
- Point-in-time recovery enabled
Disaster Recovery
- Multi-AZ Deployment: Database and Redis in multiple availability zones
- Regular Snapshots: EBS volumes and RDS snapshots
- Cross-region Backups: Critical data replicated to another region
- Recovery Time Objective (RTO): 4 hours
- Recovery Point Objective (RPO): 1 hour
Security Best Practices
- Use IAM Roles: Never use access keys in production
- Encrypt Secrets: Use SSM SecureString for sensitive data
- Network Security: Use VPC with private subnets
- SSL/TLS: Enforce HTTPS for all endpoints
- Regular Updates: Keep dependencies and base images updated
- Audit Logging: Enable CloudTrail for API calls
- Security Groups: Restrict access to necessary ports only
Rollback Procedure
In case of deployment issues:
# Get previous task definition
aws ecs describe-task-definition --task-definition amt-backend
# Update service to previous version
aws ecs update-service \
--cluster amt-cluster \
--service amt-backend-service \
--task-definition amt-backend:previous-version
# Monitor rollback
aws ecs wait services-stable \
--cluster amt-cluster \
--services amt-backend-service
Troubleshooting
Common Issues
-
Container fails to start
- Check CloudWatch logs
- Verify environment variables
- Check database connectivity
-
High memory usage
- Review Node.js heap settings
- Check for memory leaks
- Increase task memory allocation
-
Database connection errors
- Verify security group rules
- Check RDS status
- Validate credentials in SSM
-
Redis connection issues
- Check ElastiCache status
- Verify security groups
- Review connection pool settings