Blue-Green Deployments in AWS: ECS, EC2, Route 53 & Rollback

A blue-green deployment runs two identical production environments simultaneously. Blue serves all live traffic. You deploy the new version to green, verify it is healthy, then switch all traffic from blue to green in one step. If something breaks, you switch back instantly. Blue is still running. This approach eliminates deployment downtime and makes rollback a matter of seconds rather than minutes. The main cost is paying for two environments during the cutover window, typically 15 to 30 minutes.

Blue-green deployments explained simply#

Analogy

Think of a restaurant that wants to renovate its kitchen without closing. They build a second kitchen next door, train the staff on the new equipment, and run test orders through it. Only once everything works perfectly do they redirect all incoming orders to the new kitchen. If the new kitchen has a problem on day one, they flip orders straight back to the old one. The old kitchen is still fully set up and running.

Blue-green deployments work the same way. Blue is the kitchen handling all orders right now. Green is the fully built, tested new kitchen waiting in the wings. You flip the switch only when you are confident green is ready.

In practice: you spin up a completely separate set of servers called green, deploy the new version there, and run your checks. Users still hit blue the whole time. Once green is confirmed healthy, you flip the switch. All traffic goes to green. Blue sits idle.

If green starts throwing errors after the switch, you flip back to blue. No reinstalling, no rollback scripts, no downtime.

One-sentence takeaway: Blue-green lets you deploy without risk because you never touch the live environment until after the new one is verified.

How blue-green deployment works in AWS#

Every blue-green deployment follows this sequence, whether you use ECS, EC2, or Route 53:

  1. Keep blue live. Blue is your current production environment. Users hit it normally throughout the entire deployment.
  2. Deploy to green. Provision the new environment: a new ECS task set, a new EC2 Auto Scaling Group, or a separate ALB target. Deploy the new version there.
  3. Run health checks and smoke tests. Wait for ALB health checks to pass. Test the green endpoint directly before touching live traffic.
  4. Switch traffic. Update the ALB listener rule, let CodeDeploy shift target groups, or update Route 53 weights to send all traffic to green.
  5. Monitor. Watch your CloudWatch alarms for error rates, latency spikes, and application-specific signals. This is your rollback window.
  6. Roll back instantly if needed. Reverse the traffic switch. Blue is still running, so rollback takes seconds with no rebuild required.
  7. Clean up blue. After the monitoring window closes without incident, terminate the blue environment and delete idle resources.

When to use blue-green deployments#

Blue-green is the right choice when:

For teams managing multiple environments through staging and production, blue-green is a natural fit for the final production promotion step.

When not to use blue-green deployments#

Blue-green is not always the right tool:

Blue-green with ECS and CodeDeploy#

For ECS services, AWS CodeDeploy manages blue-green deployments by maintaining two ECS task sets and shifting traffic between them using ALB target groups. The traffic switch happens at the Application Load Balancer level, instantly with no TTL delay, and CodeDeploy handles rollback automatically.

What CodeDeploy is doing: It starts a new task set (green) in the second target group, waits for ALB health checks to pass across all tasks, then updates the ALB listener rule to route production traffic from the blue target group to green. After a configurable wait period, it terminates the original task set.

Configure the ECS service for CodeDeploy deployments:

{
  "deploymentController": {
    "type": "CODE_DEPLOY"
  },
  "loadBalancers": [
    {
      "targetGroupArn": "arn:aws:elasticloadbalancing:...:targetgroup/my-app-1/...",
      "containerName": "my-app",
      "containerPort": 8080
    }
  ]
}

Create the CodeDeploy application and deployment group:

aws deploy create-application \
  --application-name my-app \
  --compute-platform ECS

aws deploy create-deployment-group \
  --application-name my-app \
  --deployment-group-name my-app-prod \
  --deployment-config-name CodeDeployDefault.ECSAllAtOnce \
  --service-role-arn arn:aws:iam::123456789012:role/CodeDeployRole \
  --ecs-services '[{"serviceName": "my-app", "clusterName": "prod-cluster"}]' \
  --load-balancer-info '{
    "targetGroupPairInfoList": [{
      "targetGroups": [
        {"name": "my-app-1"},
        {"name": "my-app-2"}
      ],
      "prodTrafficRoute": {
        "listenerArns": ["arn:aws:elasticloadbalancing:...:listener/..."]
      }
    }]
  }' \
  --auto-rollback-configuration '{
    "enabled": true,
    "events": ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_ALARM"]
  }'

CodeDeploy requires two ALB target groups, even though only one serves traffic at a time. The second group is the standby slot for the next deployment. If you configure only one target group, CodeDeploy cannot manage the traffic shift.

This is usually the best AWS-native approach for application-layer blue-green. The ALB handles the switch instantly, CodeDeploy automates rollback, and the whole process fits cleanly into a CI/CD pipeline for ECS where CodePipeline triggers CodeDeploy on each new image push.

Blue-green with EC2 Auto Scaling Groups#

For EC2-backed services, blue-green deployments use two separate Auto Scaling Groups. The blue ASG serves production traffic through the load balancer. You create a green ASG with a new launch template version, let it scale up and become healthy, attach it to the load balancer, then detach and eventually terminate blue.

# Step 1: Create green ASG with the new launch template version
aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name my-app-green \
  --launch-template LaunchTemplateId=lt-abc123,Version=2 \
  --min-size 2 \
  --max-size 10 \
  --desired-capacity 4 \
  --vpc-zone-identifier "subnet-abc,subnet-def"

# Step 2: Wait for green instances to pass health checks
aws autoscaling wait instance-in-service \
  --auto-scaling-group-name my-app-green

# Step 3: Attach green ASG to the load balancer target group
aws autoscaling attach-load-balancer-target-groups \
  --auto-scaling-group-name my-app-green \
  --target-group-arns arn:aws:elasticloadbalancing:...:targetgroup/my-app/...

# Step 4: Detach blue ASG (all traffic now flows to green)
aws autoscaling detach-load-balancer-target-groups \
  --auto-scaling-group-name my-app-blue \
  --target-group-arns arn:aws:elasticloadbalancing:...:targetgroup/my-app/...

# Step 5: Monitor for 15-30 minutes, then terminate blue
aws autoscaling delete-auto-scaling-group \
  --auto-scaling-group-name my-app-blue \
  --force-delete

The gap between step 4 and step 5 is your rollback window. If a monitoring alarm fires, reattach blue to the load balancer and detach green. Traffic is back on blue in seconds. Do not skip this window.

Do not delete blue immediately after cutover. Once blue is gone, instant rollback is gone with it. Keep blue running for at least 15 to 30 minutes. That waiting period is the entire point of the monitoring window.

Blue-green with Route 53 weighted records#

Route 53 weighted routing can split DNS queries between two endpoints: two ALBs, two CloudFront distributions, or two API Gateway stages. This enables blue-green deployments at the DNS level, useful when both environments cannot share a single ALB.

# Set blue to 100% and green to 0%; to cut over, reverse the weights
aws route53 change-resource-record-sets \
  --hosted-zone-id ZXXXXXXXXXXXXX \
  --change-batch '{
    "Changes": [
      {
        "Action": "UPSERT",
        "ResourceRecordSet": {
          "Name": "api.example.com",
          "Type": "A",
          "SetIdentifier": "blue",
          "Weight": 100,
          "AliasTarget": {
            "HostedZoneId": "Z35SXDOTRQ7X7K",
            "DNSName": "blue-alb.us-east-1.elb.amazonaws.com",
            "EvaluateTargetHealth": true
          }
        }
      },
      {
        "Action": "UPSERT",
        "ResourceRecordSet": {
          "Name": "api.example.com",
          "Type": "A",
          "SetIdentifier": "green",
          "Weight": 0,
          "AliasTarget": {
            "HostedZoneId": "Z35SXDOTRQ7X7K",
            "DNSName": "green-alb.us-east-1.elb.amazonaws.com",
            "EvaluateTargetHealth": true
          }
        }
      }
    ]
  }'

TTL lag is real. DNS responses are cached by resolvers for the record’s TTL. With a 300-second TTL, some clients keep hitting blue for up to 5 minutes after you change the weights. Lower your TTL to 60 seconds at least an hour before deployment to reduce this lag.

Route 53 weighted switching suits coarser scenarios: regional failover, switching between two completely separate stacks, or gradually shifting traffic between regions. For application-layer blue-green where you need precision and instant rollback, prefer ALB-level switching via CodeDeploy or a direct listener rule update. See DNS with Route 53 for more on TTL behaviour and weighted routing.

Application blue-green vs RDS Blue/Green Deployments#

These are two related but distinct concepts, and conflating them causes real problems.

Application blue-green is what most of this page covers: two versions of your application, one shared database, traffic switched at the ALB or DNS level. Both blue and green connect to the same RDS instance or Aurora cluster during the transition.

RDS Blue/Green Deployments is a separate AWS-managed feature for making changes to the database itself: engine version upgrades, major parameter group changes, or schema migrations that AWS manages end-to-end. AWS creates a synchronised green database, lets you test it, then switches the writer endpoint. It is a complementary tool, not a substitute for application-layer blue-green.

For application blue-green, the practical implication is this: schema changes must be backward-compatible. You cannot ship a column removal or rename in the same deployment as the application code that depends on it, because blue is still reading the old schema during the transition.

The standard approach is the expand-contract pattern:

  1. Deploy an additive schema migration first (add new columns, keep old ones).
  2. Deploy the application change so green uses the new schema while blue ignores it.
  3. After blue is terminated and the monitoring window closes, clean up the old columns in a follow-up migration.

If your database changes are complex, validate them in lower environments before touching production. See dev vs staging vs production for practices that help catch schema issues early.

Blue-green vs canary vs rolling update#

StrategyTraffic during deploymentRollback speedTemporary extra costBest fit
Rolling updateMixed old and new versions simultaneouslySlow (re-deploy the old version)NoneTolerant internal services, cost-sensitive workloads
CanarySmall % (5-10%) hits new version firstFast (remove canary traffic)Small (canary instances only)High-traffic services, gradual real-world validation
Blue-greenOne version at a time, clean switchInstant (flip traffic back)High (2x capacity for 15-30 min)Zero tolerance for downtime or mixed-version state

How to choose: If downtime or mixed-version behavior is unacceptable, use blue-green. If you want to validate the new version incrementally under real traffic before committing, use canary. If your service tolerates brief mixed-version state and cost is a constraint, use rolling. You can also combine strategies: blue-green to stand up the new environment, then a short canary phase before full cutover.

Common mistakes#

  1. Deleting blue immediately after switching traffic. Keep blue running for at least 15 to 30 minutes. That window is your rollback. Once you delete blue, instant rollback is no longer possible.
  2. Not configuring automatic rollback in CodeDeploy. Manual rollback requires someone to be watching when things go wrong. Configure CodeDeploy to roll back automatically on deployment failure or alarm breach. See rollbacks in CodeDeploy for the exact setup.
  3. Shipping breaking schema changes in the same deploy. During the transition, blue may still be draining connections while green handles new ones. A column removal that blue still reads causes errors on those draining connections. Deploy schema changes first, separately, as additive migrations.
  4. Switching Route 53 weights without lowering TTL first. With a 300-second TTL, clients ignore your weight change for up to 5 minutes. Lower TTL to 60 seconds at least an hour before deployment.
  5. Relying only on ALB health checks to validate green. Health checks confirm the process is responding. They do not confirm your application is actually working. Add smoke tests that hit real endpoints: a login, a key API call, a database read, before switching traffic.
  6. Forgetting to clean up after the monitoring window. Idle blue instances and unused target groups still cost money. EBS volumes on stopped EC2 instances continue to accrue charges. Automate cleanup after the safe window closes.

Pre-cutover checklist#

Before switching any traffic to green, confirm:

Frequently asked questions

How is blue-green different from a rolling deployment?

A rolling deployment replaces instances one at a time, meaning users hit a mix of old and new versions throughout the update. Blue-green keeps both environments fully separate and switches all traffic in one step. Rolling deployments are cheaper but harder to roll back. Blue-green costs more during the cutover window but gives you instant rollback with no reinstalling or waiting.

How is blue-green different from a canary deployment?

A canary deployment routes a small percentage of traffic (say 5 to 10 percent) to the new version and watches for errors before shifting the rest. Blue-green routes 100% of traffic to the new version all at once, after the new environment is verified healthy in isolation. Canary is better for gradual validation on high-traffic services. Blue-green is better when mixed-version behavior is risky or when you need a clean, instant rollback.

How much does a blue-green deployment cost?

During the cutover window (from when you deploy green until you confirm it is healthy and terminate blue) you pay for both environments simultaneously. For ECS Fargate, that is double the Fargate compute cost for roughly 15 to 30 minutes. For EC2-backed services, double the EC2 instance costs. For Lambda, there is no extra cost since Lambda billing is per invocation. Idle blue instances after cutover still accrue EBS volume charges, so clean up once the monitoring window closes without incident.

How do I handle database migrations with blue-green deployments?

Blue and green typically share the same database. During the transition, both environments may be live simultaneously: blue draining existing connections while green handles new ones. Schema changes must be backward-compatible. You cannot remove a column that blue still reads. The standard approach is to deploy additive schema changes first in a separate migration, confirm both versions work, then deploy the application change. For complex database changes, RDS Blue/Green Deployments is a separate AWS feature that manages database-level cutovers independently of your application layer.

Should I switch traffic at the Route 53 level or the ALB level?

ALB-level switching is faster and more precise. When CodeDeploy shifts target groups or you update an ALB listener rule, the change takes effect in seconds with no TTL delay. Route 53-based switching depends on DNS propagation, which can take 1 to 5 minutes even with a low TTL. Use ALB switching for application blue-green. Use Route 53 weighted records for coarser scenarios like regional failover or switching between two separate stacks that cannot share an ALB.

How long should I keep the blue environment running after switching traffic to green?

A minimum of 15 to 30 minutes is typical for most services. Business-critical or high-traffic services warrant an hour or more. The window should be long enough for your CloudWatch alarms and smoke tests to surface any post-cutover problems. Once the window closes without incident, terminate blue and clean up. Deleting blue immediately after cutover forfeits your rollback option; keeping it indefinitely wastes money.

Last verified: 25 April 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.