Blue-Green Deployment on AWS
ALB target groups and instant rollback.
Blue-Green Deployment on AWS
Blue-green deployment eliminates deployment downtime and provides instant rollback capability. By running two identical production environments and switching traffic between them, you can deploy with confidence — if anything goes wrong, rollback is a DNS or target group change away.
How It Works
Before deployment:
Route 53 → ALB → Blue (v1.0) [ACTIVE]
Green (idle)
During deployment:
Route 53 → ALB → Blue (v1.0) [ACTIVE]
Green (v1.1) [DEPLOYING + TESTING]
After validation:
Route 53 → ALB → Blue (v1.0) [STANDBY]
Green (v1.1) [ACTIVE]
Rollback (if needed):
Route 53 → ALB → Blue (v1.0) [ACTIVE again]
Green (v1.1) [ROLLED BACK]ALB Target Group Switching
The fastest blue-green implementation uses ALB target groups:
# Two target groups registered with the same ALB
Blue TG: arn:aws:elasticloadbalancing:...:targetgroup/blue/xxx
Green TG: arn:aws:elasticloadbalancing:...:targetgroup/green/yyy
# Deploy new version to Green
aws ecs update-service --cluster prod --service green-service \
--task-definition myapp:v1.1
# Wait for Green to be healthy
aws elbv2 describe-target-health --target-group-arn $GREEN_TG_ARN
# Switch traffic: modify ALB listener to point to Green
aws elbv2 modify-listener --listener-arn $LISTENER_ARN \
--default-actions Type=forward,TargetGroupArn=$GREEN_TG_ARN
# Rollback: switch back to Blue
aws elbv2 modify-listener --listener-arn $LISTENER_ARN \
--default-actions Type=forward,TargetGroupArn=$BLUE_TG_ARNWeighted Target Groups (Canary-Style)
Gradually shift traffic instead of all-at-once:
aws elbv2 modify-listener --listener-arn $LISTENER_ARN \
--default-actions '[{
"Type": "forward",
"ForwardConfig": {
"TargetGroups": [
{"TargetGroupArn": "'$BLUE_TG_ARN'", "Weight": 90},
{"TargetGroupArn": "'$GREEN_TG_ARN'", "Weight": 10}
]
}
}]'
# Monitor for 10 minutes, then increase
# 10% → 25% → 50% → 100%ECS Blue-Green with CodeDeploy
# appspec.yaml
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: "arn:aws:ecs:...:task-definition/myapp:v1.1"
LoadBalancerInfo:
ContainerName: "web"
ContainerPort: 80
# Deployment configuration
aws deploy create-deployment-group \
--application-name myapp \
--deployment-group-name prod \
--deployment-config-name CodeDeployDefault.ECSLinear10PercentEvery1Minutes \
--ecs-services clusterName=prod,serviceName=myapp \
--load-balancer-info targetGroupPairInfoList=[{targetGroups=[{name=blue},{name=green}],prodTrafficRoute={listenerArns=[$LISTENER_ARN]}}]Database Migrations
The biggest challenge with blue-green is database schema changes:
- Backward-compatible changes only — Add columns (don't rename or delete)
- Two-phase migration — Phase 1: Add new column + deploy Green. Phase 2: Remove old column after Blue is decommissioned.
- Expand-contract pattern — Expand the schema (add new), deploy, contract (remove old)
Pre-Deployment Checklist
- Green environment deployed and healthy
- Smoke tests passing on Green (via test endpoint or header-based routing)
- Database migration applied (backward-compatible)
- Monitoring dashboard open and baseline metrics noted
- Rollback procedure documented and tested
- On-call engineer aware of deployment
Monitoring During Switch
- Error rate — Should not increase after switch
- Latency — P95 should remain stable
- Health check status — All Green targets must be healthy
- Application logs — Watch for new error patterns
Eazy SaaS Tip: We implement blue-green deployments with ALB weighted target groups for every ECS production service. The 10% → 25% → 50% → 100% traffic shift with 5-minute observation periods catches issues that instant cutover would miss. Rollback is one API call away.