This comprehensive guide addresses the critical migration path from AWS CodeDeploy to Amazon ECS's native blue/green deployment capabilities, introduced in July 2025. Organizations currently using CodeDeploy for blue/green deployments on Amazon ECS can now leverage Amazon ECS's built-in deployment strategy, eliminating the complexity of managing separate CodeDeploy applications while gaining enhanced operational flexibility and improved AWS service integration. Readers will learn strategic migration approaches, understand architectural differences, master implementation techniques through hands-on labs, and discover cost optimization opportunities. This migration enables organizations to reduce operational overhead, improve deployment velocity, and leverage advanced ECS features like Service Connect and multiple target group support that weren't available with CodeDeploy integration.
Learning Objectives
- Understand Migration Drivers: Analyze the strategic benefits of migrating from CodeDeploy to ECS native blue/green deployments, including operational improvements and new capabilities
- Master Architecture Mapping: Map CodeDeploy concepts to ECS blue/green equivalents, including TaskSets to ServiceRevisions, lifecycle hooks, and load balancer configurations
- Implement Migration Strategies: Execute three distinct migration approaches (in-place update, new service with existing load balancer, and new service with new load balancer) based on specific organizational requirements
- Optimize Cost and Performance: Leverage ECS deployment features to reduce operational costs while improving deployment reliability and rollback capabilities
- Integrate Advanced Features: Utilize ECS Service Connect, multiple target groups, and flexible ALB listener configurations that weren't possible with CodeDeploy
Understanding the Migration Landscape
Why Migrate from CodeDeploy to ECS Blue/Green Deployments?
Amazon ECS's native blue/green deployment capability, launched in July 2025, represents a significant evolution in container deployment strategies. Unlike CodeDeploy-based blue/green deployments that required separate application and deployment group management, ECS blue/green deployments integrate directly with the ECS service model, providing several compelling advantages.
Key Migration Drivers:
- Operational Simplification: Eliminates the need to manage separate CodeDeploy applications, deployment groups, and complex IAM role configurations
- Enhanced Service Discovery: Support for both Elastic Load Balancing and ECS Service Connect, enabling headless service deployments for queue processing workloads
- Advanced Load Balancer Integration: Flexible ALB listener rule configuration allows multiple services on single listeners with path-based routing and A/B testing capabilities
- Improved AWS CloudFormation Support: No longer requires separate AppSpec files for service revisions and lifecycle hooks
- Extended Lifecycle Hook Duration: ECS hooks support longer execution times compared to CodeDeploy's 1-hour limitation
Current State Assessment
Before initiating migration, organizations must evaluate their existing CodeDeploy implementation. The migration is most straightforward for services using all-at-once deployment configurations, as ECS blue/green deployments currently support only this traffic shifting pattern. Services using canary or linear deployments must first transition to all-at-once CodeDeploy configurations.
Architecture Comparison: CodeDeploy vs. ECS Blue/Green
Load Balancer Configuration Differences
CodeDeploy Approach:
{
"deploymentController": {
"type": "CODE_DEPLOY"
},
"loadBalancers": [
{
"targetGroupArn": "arn:aws:elasticloadbalancing:region:account:targetgroup/primary-tg",
"containerName": "app-container",
"containerPort": 80
}
]
}
ECS Blue/Green Approach:
{
"deploymentController": {
"type": "ECS"
},
"deploymentConfiguration": {
"strategy": "BLUE_GREEN",
"productionTrafficRoute": {
"listenerArn": "arn:aws:elasticloadbalancing:region:account:listener/app/load-balancer/listener-id",
"ruleArn": "arn:aws:elasticloadbalancing:region:account:listener-rule/app/load-balancer/rule-id"
},
"targetGroups": [
{
"name": "primary-target-group",
"weight": 1
},
{
"name": "secondary-target-group",
"weight": 0
}
]
}
}
Service Deployment Differences
CodeDeploy uses TaskSets to manage deployment versions, while ECS blue/green deployments utilize ServiceRevisions. This architectural difference provides better visibility into deployment history and aligns with the broader ECS service deployments API.
CodeDeploy Deployment Process:
- Create deployment via
CreateDeployment()
API - Specify AppSpec file with task definition and configuration
- CodeDeploy creates replacement TaskSet
- Traffic routing through listener rule updates
ECS Blue/Green Deployment Process:
- Update service via
UpdateService()
API - Specify replacement task definition directly
- ECS creates new ServiceRevision
- Traffic routing through target group weight changes
Migration Strategies
Strategy 1: In-Place Update (Recommended for Low-Risk Environments)
This approach updates the existing ECS service to use native blue/green deployments while reusing existing load balancer resources.
Implementation Steps:
- Prepare Load Balancer Configuration:
# Update ALB listener rule to include both target groups
aws elbv2 modify-rule \
--rule-arn arn:aws:elasticloadbalancing:region:account:listener-rule/app/my-alb/listener-id/rule-id \
--actions Type=forward,ForwardConfig='{
"TargetGroups": [
{
"TargetGroupArn": "arn:aws:elasticloadbalancing:region:account:targetgroup/primary-tg",
"Weight": 1
},
{
"TargetGroupArn": "arn:aws:elasticloadbalancing:region:account:targetgroup/secondary-tg",
"Weight": 0
}
]
}'
- Create ECS Blue/Green IAM Role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ecs.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
- Update ECS Service:
aws ecs update-service \
--cluster my-cluster \
--service my-service \
--deployment-controller type=ECS \
--deployment-configuration '{
"strategy": "BLUE_GREEN",
"productionTrafficRoute": {
"listenerArn": "arn:aws:elasticloadbalancing:region:account:listener/app/my-alb/listener-id",
"ruleArn": "arn:aws:elasticloadbalancing:region:account:listener-rule/app/my-alb/rule-id"
},
"targetGroups": [
{
"name": "primary-target-group",
"weight": 1
},
{
"name": "secondary-target-group",
"weight": 0
}
],
"roleArn": "arn:aws:iam::account:role/ECS-BlueGreen-Role"
}'
Strategy 2: New Service with Existing Load Balancer (Recommended for Production)
This approach creates a parallel blue/green setup for testing before switching traffic, providing the safest migration path.
Implementation Steps:
- Create New Target Groups:
aws elbv2 create-target-group \
--name my-service-migration-primary \
--protocol HTTP \
--port 80 \
--vpc-id vpc-12345678 \
--health-check-path /health
aws elbv2 create-target-group \
--name my-service-migration-secondary \
--protocol HTTP \
--port 80 \
--vpc-id vpc-12345678 \
--health-check-path /health
- Create New Listeners on Different Ports:
aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:region:account:loadbalancer/app/my-alb \
--protocol HTTP \
--port 8080 \
--default-actions Type=forward,ForwardConfig='{
"TargetGroups": [
{
"TargetGroupArn": "arn:aws:elasticloadbalancing:region:account:targetgroup/my-service-migration-primary",
"Weight": 1
},
{
"TargetGroupArn": "arn:aws:elasticloadbalancing:region:account:targetgroup/my-service-migration-secondary",
"Weight": 0
}
]
}'
- Create New ECS Service:
aws ecs create-service \
--cluster my-cluster \
--service-name my-service-bluegreen \
--task-definition my-app:latest \
--desired-count 2 \
--deployment-controller type=ECS \
--deployment-configuration '{
"strategy": "BLUE_GREEN",
"productionTrafficRoute": {
"listenerArn": "arn:aws:elasticloadbalancing:region:account:listener/app/my-alb/8080-listener",
"ruleArn": "arn:aws:elasticloadbalancing:region:account:listener-rule/app/my-alb/8080-rule"
},
"targetGroups": [
{
"name": "my-service-migration-primary",
"weight": 1
},
{
"name": "my-service-migration-secondary",
"weight": 0
}
],
"roleArn": "arn:aws:iam::account:role/ECS-BlueGreen-Role"
}'
- Port Switching for Traffic Cutover:
# Change original listener to temporary port
aws elbv2 modify-listener \
--listener-arn arn:aws:elasticloadbalancing:region:account:listener/app/my-alb/original-listener \
--port 8081
# Change new listener to original port
aws elbv2 modify-listener \
--listener-arn arn:aws:elasticloadbalancing:region:account:listener/app/my-alb/8080-listener \
--port 80
Strategy 3: New Service with New Load Balancer (Enterprise/Multi-Region)
This approach is suitable for organizations with existing routing layers (Route 53, API Gateway, CloudFront) that can manage traffic switching at a higher level.
Hands-on Labs
Lab 1: CodeDeploy to ECS Blue/Green Migration with CloudFormation
Objective: Migrate an existing CodeDeploy-enabled ECS service to native ECS blue/green deployments using Infrastructure as Code.
Prerequisites:
- Existing ECS service with CodeDeploy deployment controller
- Application Load Balancer with target groups
- AWS CLI configured with appropriate permissions
Step 1: Create Migration CloudFormation Template
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Migrate ECS service from CodeDeploy to native blue/green deployments'
Parameters:
ClusterName:
Type: String
Default: my-ecs-cluster
ServiceName:
Type: String
Default: my-web-app
VpcId:
Type: AWS::EC2::VPC::Id
SubnetIds:
Type: List<AWS::EC2::Subnet::Id>
LoadBalancerArn:
Type: String
Resources:
# Primary Target Group for Blue/Green
PrimaryTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub '${ServiceName}-primary-tg'
Port: 80
Protocol: HTTP
VpcId: !Ref VpcId
HealthCheckPath: /health
HealthCheckIntervalSeconds: 30
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
UnhealthyThresholdCount: 3
TargetType: ip
# Secondary Target Group for Blue/Green
SecondaryTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub '${ServiceName}-secondary-tg'
Port: 80
Protocol: HTTP
VpcId: !Ref VpcId
HealthCheckPath: /health
HealthCheckIntervalSeconds: 30
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
UnhealthyThresholdCount: 3
TargetType: ip
# ALB Listener with weighted routing
LoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref LoadBalancerArn
Port: 80
Protocol: HTTP
DefaultActions:
- Type: forward
ForwardConfig:
TargetGroups:
- TargetGroupArn: !Ref PrimaryTargetGroup
Weight: 1
- TargetGroupArn: !Ref SecondaryTargetGroup
Weight: 0
# IAM Role for ECS Blue/Green Deployments
ECSBlueGreenRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub '${ServiceName}-bluegreen-role'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ecs.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSServiceRolePolicy
Policies:
- PolicyName: BlueGreenDeploymentPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- elasticloadbalancing:ModifyRule
- elasticloadbalancing:ModifyListener
- elasticloadbalancing:DescribeRules
- elasticloadbalancing:DescribeListeners
Resource: '*'
# Task Definition
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Sub '${ServiceName}-bluegreen'
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Cpu: 256
Memory: 512
ExecutionRoleArn: !Sub 'arn:aws:iam::${AWS::AccountId}:role/ecsTaskExecutionRole'
ContainerDefinitions:
- Name: web-container
Image: nginx:latest
PortMappings:
- ContainerPort: 80
Protocol: tcp
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Sub '/ecs/${ServiceName}'
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: ecs
# CloudWatch Log Group
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub '/ecs/${ServiceName}'
RetentionInDays: 7
# ECS Service with Blue/Green Deployment
ECSService:
Type: AWS::ECS::Service
Properties:
ServiceName: !Sub '${ServiceName}-bluegreen'
Cluster: !Ref ClusterName
TaskDefinition: !Ref TaskDefinition
DesiredCount: 2
LaunchType: FARGATE
NetworkConfiguration:
AwsvpcConfiguration:
SecurityGroups:
- !Ref ServiceSecurityGroup
Subnets: !Ref SubnetIds
AssignPublicIp: ENABLED
DeploymentController:
Type: ECS
DeploymentConfiguration:
Strategy: BLUE_GREEN
ProductionTrafficRoute:
ListenerArn: !Ref LoadBalancerListener
TargetGroups:
- Name: !GetAtt PrimaryTargetGroup.TargetGroupName
Weight: 1
- Name: !GetAtt SecondaryTargetGroup.TargetGroupName
Weight: 0
RoleArn: !GetAtt ECSBlueGreenRole.Arn
BlueGreenUpdatePolicy:
TrafficRoutingPolicy:
TimeBasedCanary:
StepPercentage: 100
BakeTimeMinutes: 5
TerminationPolicy:
MaxTerminationTimeMinutes: 5
# Security Group for ECS Service
ServiceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for ECS service
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !Ref LoadBalancerSecurityGroup
LoadBalancerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security group for ALB
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Outputs:
ServiceArn:
Description: ARN of the ECS service
Value: !Ref ECSService
PrimaryTargetGroupArn:
Description: ARN of primary target group
Value: !Ref PrimaryTargetGroup
SecondaryTargetGroupArn:
Description: ARN of secondary target group
Value: !Ref SecondaryTargetGroup
Step 2: Deploy the Migration Infrastructure
# Deploy the CloudFormation stack
aws cloudformation deploy \
--template-file ecs-bluegreen-migration.yaml \
--stack-name ecs-bluegreen-migration \
--parameter-overrides \
ClusterName=my-ecs-cluster \
ServiceName=my-web-app \
VpcId=vpc-12345678 \
SubnetIds=subnet-12345678,subnet-87654321 \
LoadBalancerArn=arn:aws:elasticloadbalancing:region:account:loadbalancer/app/my-alb \
--capabilities CAPABILITY_NAMED_IAM
Step 3: Verify Migration Success
# Check service status
aws ecs describe-services \
--cluster my-ecs-cluster \
--services my-web-app-bluegreen
# Monitor deployment events
aws ecs describe-services \
--cluster my-ecs-cluster \
--services my-web-app-bluegreen \
--query 'services[^0].events[0:5]'
# Verify target group health
aws elbv2 describe-target-health \
--target-group-arn arn:aws:elasticloadbalancing:region:account:targetgroup/my-web-app-primary-tg
Lab 2: Implementing Lifecycle Hooks for Custom Validation
Objective: Create custom validation logic using ECS blue/green deployment lifecycle hooks to ensure application readiness before traffic shifting.
Step 1: Create Validation Lambda Function
import json
import boto3
import requests
import time
def lambda_handler(event, context):
"""
ECS Blue/Green deployment lifecycle hook for custom validation
"""
# Extract deployment information
deployment_id = event['DeploymentId']
lifecycle_event = event['LifecycleEventHookExecutionId']
task_set_arn = event.get('TaskSetArn')
ecs_client = boto3.client('ecs')
try:
# Perform custom validation logic
if event['LifecycleEventType'] == 'POST_SCALE_UP':
# Validate new tasks are healthy
validation_result = validate_task_health(ecs_client, task_set_arn)
elif event['LifecycleEventType'] == 'TEST_TRAFFIC_SHIFT':
# Run integration tests against test endpoint
validation_result = run_integration_tests(event)
elif event['LifecycleEventType'] == 'PRODUCTION_TRAFFIC_SHIFT':
# Final validation before production traffic
validation_result = final_production_validation(event)
else:
validation_result = {'status': 'SUCCEEDED', 'message': 'No validation required'}
# Return hook response
if validation_result['status'] == 'SUCCEEDED':
return {
'Status': 'SUCCEEDED',
'Message': validation_result['message']
}
elif validation_result['status'] == 'IN_PROGRESS':
return {
'Status': 'IN_PROGRESS',
'Message': validation_result['message'],
'NextInvocationSeconds': 30
}
else:
return {
'Status': 'FAILED',
'Message': validation_result['message']
}
except Exception as e:
print(f"Validation failed with error: {str(e)}")
return {
'Status': 'FAILED',
'Message': f'Validation failed: {str(e)}'
}
def validate_task_health(ecs_client, task_set_arn):
"""Validate that all tasks in the task set are healthy"""
try:
# Get task set details
response = ecs_client.describe_task_sets(
taskSets=[task_set_arn]
)
task_set = response['taskSets'][^0]
running_count = task_set['runningCount']
desired_count = task_set['desiredCount']
if running_count == desired_count and running_count > 0:
return {'status': 'SUCCEEDED', 'message': f'All {running_count} tasks are healthy'}
else:
return {'status': 'IN_PROGRESS', 'message': f'Waiting for tasks: {running_count}/{desired_count} ready'}
except Exception as e:
return {'status': 'FAILED', 'message': f'Task health validation failed: {str(e)}'}
def run_integration_tests(event):
"""Run integration tests against the test endpoint"""
try:
# Extract test endpoint from event
test_endpoint = event.get('TestTrafficEndpoint', 'http://test-endpoint/health')
# Run health check
response = requests.get(test_endpoint, timeout=10)
if response.status_code == 200:
# Run additional integration tests
test_results = {
'health_check': response.status_code == 200,
'response_time': response.elapsed.total_seconds(),
'content_validation': 'healthy' in response.text.lower()
}
if all(test_results.values()) and test_results['response_time'] < 2.0:
return {'status': 'SUCCEEDED', 'message': 'Integration tests passed'}
else:
return {'status': 'FAILED', 'message': f'Integration tests failed: {test_results}'}
else:
return {'status': 'FAILED', 'message': f'Health check failed with status {response.status_code}'}
except Exception as e:
return {'status': 'FAILED', 'message': f'Integration tests failed: {str(e)}'}
def final_production_validation(event):
"""Final validation before production traffic routing"""
try:
# Implement custom business logic validation
# This could include database connectivity, external service health, etc.
validations = {
'database_connectivity': check_database_connection(),
'external_services': check_external_services(),
'configuration_validation': validate_configuration()
}
if all(validations.values()):
return {'status': 'SUCCEEDED', 'message': 'Production validation passed'}
else:
failed_checks = [k for k, v in validations.items() if not v]
return {'status': 'FAILED', 'message': f'Production validation failed: {failed_checks}'}
except Exception as e:
return {'status': 'FAILED', 'message': f'Production validation failed: {str(e)}'}
def check_database_connection():
"""Validate database connectivity"""
# Implement database connection check
return True
def check_external_services():
"""Validate external service dependencies"""
# Implement external service health checks
return True
def validate_configuration():
"""Validate application configuration"""
# Implement configuration validation
return True
Step 2: Deploy Lambda Function with IAM Role
# Create deployment package
zip -r lifecycle-hook-function.zip lambda_function.py
# Create Lambda function
aws lambda create-function \
--function-name ecs-bluegreen-lifecycle-hook \
--runtime python3.9 \
--role arn:aws:iam::account:role/LambdaECSLifecycleRole \
--handler lambda_function.lambda_handler \
--zip-file fileb://lifecycle-hook-function.zip \
--timeout 300 \
--memory-size 256
Step 3: Configure ECS Service with Lifecycle Hooks
aws ecs update-service \
--cluster my-ecs-cluster \
--service my-web-app-bluegreen \
--deployment-configuration '{
"strategy": "BLUE_GREEN",
"productionTrafficRoute": {
"listenerArn": "arn:aws:elasticloadbalancing:region:account:listener/app/my-alb/listener",
"ruleArn": "arn:aws:elasticloadbalancing:region:account:listener-rule/app/my-alb/rule"
},
"targetGroups": [
{
"name": "primary-target-group",
"weight": 1
},
{
"name": "secondary-target-group",
"weight": 0
}
],
"roleArn": "arn:aws:iam::account:role/ECS-BlueGreen-Role",
"blueGreenUpdatePolicy": {
"trafficRoutingPolicy": {
"timeBasedCanary": {
"stepPercentage": 100,
"bakeTimeMinutes": 10
}
},
"terminationPolicy": {
"maxTerminationTimeMinutes": 5
}
},
"deploymentLifecycleHooks": [
{
"lifecycleEventType": "POST_SCALE_UP",
"lambdaFunctionArn": "arn:aws:lambda:region:account:function:ecs-bluegreen-lifecycle-hook",
"roleArn": "arn:aws:iam::account:role/ECS-Lifecycle-Hook-Role"
},
{
"lifecycleEventType": "TEST_TRAFFIC_SHIFT",
"lambdaFunctionArn": "arn:aws:lambda:region:account:function:ecs-bluegreen-lifecycle-hook",
"roleArn": "arn:aws:iam::account:role/ECS-Lifecycle-Hook-Role"
},
{
"lifecycleEventType": "PRODUCTION_TRAFFIC_SHIFT",
"lambdaFunctionArn": "arn:aws:lambda:region:account:function:ecs-bluegreen-lifecycle-hook",
"roleArn": "arn:aws:iam::account:role/ECS-Lifecycle-Hook-Role"
}
]
}'
Lab 3: Multi-Environment Pipeline with ECS Blue/Green Deployments
Objective: Build a complete CI/CD pipeline using AWS CodePipeline that leverages ECS blue/green deployments across development, staging, and production environments.
Step 1: Create CodePipeline with ECS Blue/Green Integration
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Multi-environment CI/CD pipeline with ECS blue/green deployments'
Parameters:
GitHubRepository:
Type: String
Default: 'my-org/my-web-app'
GitHubBranch:
Type: String
Default: 'main'
ECRRepository:
Type: String
Default: 'my-web-app'
Resources:
# CodeBuild Project
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Name: my-web-app-build
ServiceRole: !GetAtt CodeBuildRole.Arn
Artifacts:
Type: CODEPIPELINE
Environment:
Type: LINUX_CONTAINER
ComputeType: BUILD_GENERAL1_MEDIUM
Image: aws/codebuild/amazonlinux2-x86_64-standard:3.0
PrivilegedMode: true
EnvironmentVariables:
- Name: AWS_DEFAULT_REGION
Value: !Ref AWS::Region
- Name: AWS_ACCOUNT_ID
Value: !Ref AWS::AccountId
- Name: IMAGE_REPO_NAME
Value: !Ref ECRRepository
- Name: IMAGE_TAG
Value: latest
Source:
Type: CODEPIPELINE
BuildSpec: |
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
- REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME
- COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
- IMAGE_TAG=${COMMIT_HASH:=latest}
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
- docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker image...
- docker push $REPOSITORY_URI:$IMAGE_TAG
- echo Writing image definitions file...
- printf '[{"name":"web-container","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json
- taskdef-*.json
# CodePipeline
CodePipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
Name: my-web-app-pipeline
RoleArn: !GetAtt CodePipelineRole.Arn
ArtifactStore:
Type: S3
Location: !Ref ArtifactsBucket
Stages:
- Name: Source
Actions:
- Name: SourceAction
ActionTypeId:
Category: Source
Owner: ThirdParty
Provider: GitHub
Version: '1'
Configuration:
Owner: !Select [0, !Split ['/', !Ref GitHubRepository]]
Repo: !Select [1, !Split ['/', !Ref GitHubRepository]]
Branch: !Ref GitHubBranch
OAuthToken: !Ref GitHubToken
PollForSourceChanges: false
OutputArtifacts:
- Name: SourceOutput
- Name: Build
Actions:
- Name: BuildAction
ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: '1'
Configuration:
ProjectName: !Ref CodeBuildProject
InputArtifacts:
- Name: SourceOutput
OutputArtifacts:
- Name: BuildOutput
- Name: DeployDev
Actions:
- Name: DeployToDevAction
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: ECS
Version: '1'
Configuration:
ClusterName: dev-cluster
ServiceName: my-web-app-dev
FileName: imagedefinitions.json
DeploymentTimeout: 15
InputArtifacts:
- Name: BuildOutput
Region: !Ref AWS::Region
- Name: ApproveStaging
Actions:
- Name: ManualApproval
ActionTypeId:
Category: Approval
Owner: AWS
Provider: Manual
Version: '1'
Configuration:
CustomData: 'Please review the application in development and approve for staging deployment'
- Name: DeployStaging
Actions:
- Name: DeployToStagingAction
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: ECS
Version: '1'
Configuration:
ClusterName: staging-cluster
ServiceName: my-web-app-staging
FileName: imagedefinitions.json
DeploymentTimeout: 15
InputArtifacts:
- Name: BuildOutput
Region: !Ref AWS::Region
- Name: ApproveProd
Actions:
- Name: ManualApproval
ActionTypeId:
Category: Approval
Owner: AWS
Provider: Manual
Version: '1'
Configuration:
CustomData: 'Please review the application in staging and approve for production deployment'
- Name: DeployProduction
Actions:
- Name: DeployToProdAction
ActionTypeId:
Category: Deploy
Owner: AWS
Provider: ECS
Version: '1'
Configuration:
ClusterName: production-cluster
ServiceName: my-web-app-prod
FileName: imagedefinitions.json
DeploymentTimeout: 20
InputArtifacts:
- Name: BuildOutput
Region: !Ref AWS::Region
# S3 Bucket for Pipeline Artifacts
ArtifactsBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub 'codepipeline-artifacts-${AWS::AccountId}-${AWS::Region}'
VersioningConfiguration:
Status: Enabled
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
# IAM Roles
CodePipelineRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: CodePipelineExecutionPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:GetBucketVersioning
- s3:GetObject
- s3:GetObjectVersion
- s3:PutObject
Resource:
- !Sub '${ArtifactsBucket}/*'
- !GetAtt ArtifactsBucket.Arn
- Effect: Allow
Action:
- codebuild:BatchGetBuilds
- codebuild:StartBuild
Resource: !GetAtt CodeBuildProject.Arn
- Effect: Allow
Action:
- ecs:DescribeServices
- ecs:DescribeTaskDefinition
- ecs:DescribeTasks
- ecs:ListTasks
- ecs:RegisterTaskDefinition
- ecs:UpdateService
Resource: '*'
- Effect: Allow
Action:
- iam:PassRole
Resource: '*'
CodeBuildRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: CodeBuildExecutionPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/*'
- Effect: Allow
Action:
- ecr:BatchCheckLayerAvailability
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
- ecr:GetAuthorizationToken
- ecr:PutImage
- ecr:InitiateLayerUpload
- ecr:UploadLayerPart
- ecr:CompleteLayerUpload
Resource: '*'
- Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
Resource: !Sub '${ArtifactsBucket}/*'
Parameters:
GitHubToken:
Type: String
NoEcho: true
Description: GitHub OAuth token for repository access
Outputs:
PipelineName:
Description: Name of the CodePipeline
Value: !Ref CodePipeline
ArtifactsBucket:
Description: S3 bucket for pipeline artifacts
Value: !Ref ArtifactsBucket
Real-World Case Study: E-commerce Platform Migration
Background
A major e-commerce platform running on AWS needed to migrate their microservices architecture from CodeDeploy to ECS native blue/green deployments. The platform consisted of 15 microservices handling critical functions including user authentication, product catalog, shopping cart, payment processing, and order management.
Initial Architecture Challenges
CodeDeploy Limitations:
- Complex AppSpec file management across 15 services
- Limited load balancer flexibility preventing path-based routing consolidation
- Manual rollback procedures causing extended downtime during incidents
- Inability to use ECS Service Connect for internal service communication
- High operational overhead managing separate CodeDeploy applications
Business Requirements:
- Zero-downtime deployments during peak shopping periods
- Automated rollback capabilities within 2 minutes
- Support for A/B testing new features
- Cost optimization through resource consolidation
- Improved observability and deployment tracing
Migration Strategy Implementation
Phase 1: Development Environment (Week 1-2)
The team implemented Strategy 2 (new service with existing load balancer) for the development environment, starting with non-critical services:
# Created parallel ECS services for development
aws ecs create-service \
--cluster dev-ecommerce-cluster \
--service-name product-catalog-v2 \
--task-definition product-catalog:15 \
--desired-count 2 \
--deployment-controller type=ECS \
--deployment-configuration '{
"strategy": "BLUE_GREEN",
"productionTrafficRoute": {
"listenerArn": "arn:aws:elasticloadbalancing:us-east-1:account:listener/app/dev-alb/dev-listener",
"ruleArn": "arn:aws:elasticloadbalancing:us-east-1:account:listener-rule/app/dev-alb/catalog-rule"
},
"targetGroups": [
{"name": "product-catalog-primary", "weight": 1},
{"name": "product-catalog-secondary", "weight": 0}
],
"blueGreenUpdatePolicy": {
"trafficRoutingPolicy": {
"timeBasedCanary": {
"stepPercentage": 100,
"bakeTimeMinutes": 3
}
}
}
}'
Phase 2: Staging Environment with Lifecycle Hooks (Week 3-4)
Implemented comprehensive validation logic:
# Custom validation for payment service
def validate_payment_service(event):
validation_checks = {
'payment_gateway_connectivity': test_payment_gateway(),
'database_transactions': test_database_transactions(),
'fraud_detection_service': test_fraud_detection(),
'pci_compliance_check': validate_pci_compliance()
}
failed_checks = [k for k, v in validation_checks.items() if not v]
if not failed_checks:
return {'status': 'SUCCEEDED', 'message': 'Payment service validation passed'}
else:
return {'status': 'FAILED', 'message': f'Failed checks: {failed_checks}'}
Phase 3: Production Migration (Week 5-8)
Used Strategy 1 (in-place update) for production services during low-traffic windows:
Results and Impact
Performance Improvements:
- Deployment Time: Reduced from 45 minutes to 12 minutes per service
- Rollback Time: Improved from 15 minutes to 90 seconds
- Failed Deployment Recovery: 80% reduction in manual intervention
Cost Optimization:
- Infrastructure Costs: 25% reduction through ALB listener consolidation
- Operational Overhead: 60% reduction in deployment pipeline maintenance
- Development Velocity: 40% faster feature delivery
Reliability Enhancements:
- Zero Failed Deployments: Custom lifecycle hooks prevented 12 potential production issues
- Improved Observability: Integrated CloudWatch Insights reduced incident response time by 50%
- Automated Testing: A/B testing capabilities increased feature adoption by 30%
Lessons Learned
Technical Insights:
- Lifecycle Hook Investment: Custom validation logic prevented more issues than anticipated, justifying the initial development investment
- Load Balancer Consolidation: Path-based routing enabled significant cost savings while improving traffic management
- Service Connect Integration: Internal service communication improvements reduced latency by 15%
Operational Insights:
- Phased Migration Approach: Starting with non-critical services allowed the team to refine processes before production migration
- Training Investment: Team training on ECS blue/green concepts was crucial for successful adoption
- Monitoring Enhancement: Enhanced CloudWatch dashboards were essential for confidence during migration
Business Impact:
- Customer Experience: Zero customer-facing downtime during the entire migration period
- Developer Productivity: Simplified deployment model increased development team satisfaction
- Business Agility: Faster deployment cycles enabled more frequent feature releases
Expert Tips & Pitfalls
Pro Tips for Successful Migration
- Gradual Traffic Shifting Strategy: While ECS blue/green currently supports only all-at-once traffic shifting, use lifecycle hooks to implement custom canary deployments by controlling when production traffic shifts occur.
- Target Group Health Check Optimization: Configure aggressive health check settings during migration to ensure faster failure detection and recovery:
aws elbv2 modify-target-group \
--target-group-arn arn:aws:elasticloadbalancing:region:account:targetgroup/my-tg \
--health-check-interval-seconds 10 \
--health-check-timeout-seconds 5 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 2
- Service Connect Integration: Leverage ECS Service Connect for internal service communication, which wasn't possible with CodeDeploy:
{
"serviceConnectConfiguration": {
"enabled": true,
"namespace": "ecommerce-services",
"services": [
{
"portName": "http",
"discoveryName": "product-catalog",
"clientAliases": [
{
"port": 80,
"dnsName": "catalog.local"
}
]
}
]
}
}
- CloudWatch Integration: Use ECS deployment events for comprehensive monitoring:
aws events put-rule \
--name ecs-deployment-events \
--event-pattern '{"source":["aws.ecs"],"detail-type":["ECS Service Action"],"detail":{"eventName":["SERVICE_DEPLOYMENT_STARTED","SERVICE_DEPLOYMENT_COMPLETED","SERVICE_DEPLOYMENT_FAILED"]}' \
--targets Id=1,Arn=arn:aws:sns:region:account:deployment-notifications
- Cost Optimization Through Consolidation: Utilize flexible ALB listener rules to consolidate multiple services behind fewer load balancers:
# Path-based routing for multiple services
aws elbv2 create-rule \
--listener-arn arn:aws:elasticloadbalancing:region:account:listener/app/shared-alb/listener \
--conditions Field=path-pattern,Values="/api/catalog/*" \
--priority 100 \
--actions Type=forward,ForwardConfig='{
"TargetGroups":[
{"TargetGroupArn":"arn:aws:elasticloadbalancing:region:account:targetgroup/catalog-primary","Weight":1},
{"TargetGroupArn":"arn:aws:elasticloadbalancing:region:account:targetgroup/catalog-secondary","Weight":0}
]
}'
Common Pitfalls and Solutions
- Insufficient IAM Permissions: Ensure the ECS deployment controller role has comprehensive permissions for load balancer manipulation:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:ModifyRule",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:DescribeRules",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetHealth"
],
"Resource": "*"
}
]
}
- Target Group Health Check Misalignment: Ensure health check paths and timeouts align between primary and secondary target groups to prevent deployment failures.
-
Lifecycle Hook Timeout Issues: ECS lifecycle hooks have different timeout behavior than CodeDeploy. Use
IN_PROGRESS
status for long-running validations:
# Correct lifecycle hook response for long-running validation
return {
'Status': 'IN_PROGRESS',
'Message': 'Validation in progress, will retry in 60 seconds',
'NextInvocationSeconds': 60
}
- Service Discovery Timing: When migrating services that use service discovery, ensure DNS propagation completes before dependency services attempt connections.
- CloudFormation Stack Dependencies: Be careful with CloudFormation stack dependencies when using Strategy 2 or 3, as circular dependencies can occur between load balancer and service resources.
Advanced Optimization Techniques
- Multi-Target Group Strategy: Utilize ECS's ability to register services with multiple target groups for internal/external separation:
{
"loadBalancers": [
{
"targetGroupArn": "arn:aws:elasticloadbalancing:region:account:targetgroup/external-tg",
"containerName": "web-container",
"containerPort": 80
},
{
"targetGroupArn": "arn:aws:elasticloadbalancing:region:account:targetgroup/internal-tg",
"containerName": "web-container",
"containerPort": 8080
}
]
}
- Circuit Breaker Integration: Combine ECS circuit breaker with blue/green deployments for enhanced failure detection:
{
"deploymentConfiguration": {
"strategy": "BLUE_GREEN",
"deploymentCircuitBreaker": {
"enable": true,
"rollback": true
}
}
}
- Custom Metrics for Validation: Implement custom CloudWatch metrics in lifecycle hooks for deployment decision-making:
import boto3
cloudwatch = boto3.client('cloudwatch')
def publish_deployment_metric(metric_name, value, unit='Count'):
cloudwatch.put_metric_data(
Namespace='ECS/BlueGreen/Deployments',
MetricData=[
{
'MetricName': metric_name,
'Value': value,
'Unit': unit,
'Dimensions': [
{
'Name': 'ServiceName',
'Value': os.environ.get('SERVICE_NAME', 'unknown')
}
]
}
]
)
- A/B Testing Integration: Use listener rule weights for sophisticated A/B testing:
# Gradual traffic increase for A/B testing
aws elbv2 modify-rule \
--rule-arn arn:aws:elasticloadbalancing:region:account:listener-rule/app/alb/rule \
--actions Type=forward,ForwardConfig='{
"TargetGroups":[
{"TargetGroupArn":"arn:aws:elasticloadbalancing:region:account:targetgroup/version-a","Weight":70},
{"TargetGroupArn":"arn:aws:elasticloadbalancing:region:account:targetgroup/version-b","Weight":30}
]
}'
- Deployment Rollback Automation: Implement automated rollback triggers based on CloudWatch alarms:
def setup_automatic_rollback(service_arn, alarm_arn):
"""Setup automatic rollback based on CloudWatch alarms"""
lambda_client = boto3.client('lambda')
# Create Lambda function that monitors alarms and triggers rollback
lambda_client.create_function(
FunctionName='ecs-auto-rollback',
Runtime='python3.9',
Role='arn:aws:iam::account:role/ECS-Auto-Rollback-Role',
Handler='lambda_function.lambda_handler',
Code={'ZipFile': rollback_function_code},
Environment={
'Variables': {
'SERVICE_ARN': service_arn,
'ALARM_ARN': alarm_arn
}
}
)
Latest Updates Section: AWS ECS Blue/Green Deployment Enhancements (2024-2025)
July 2025: Native ECS Blue/Green Deployment Launch
The most significant update came in July 2025 with the launch of native ECS blue/green deployment capabilities, eliminating the dependency on AWS CodeDeploy for blue/green deployments.
Key Features:
- Built-in Deployment Strategy: Direct integration with ECS service model without external dependencies
- Deployment Lifecycle Hooks: Custom validation through Lambda functions with extended timeout support
- Multiple Load Balancer Support: Application Load Balancer, Network Load Balancer, and ECS Service Connect compatibility
- Enhanced CloudFormation Integration: Simplified infrastructure as code without AppSpec file requirements
Impact on Migration Strategy:
{
"deploymentConfiguration": {
"strategy": "BLUE_GREEN",
"blueGreenUpdatePolicy": {
"trafficRoutingPolicy": {
"timeBasedCanary": {
"stepPercentage": 100,
"bakeTimeMinutes": 5
}
},
"terminationPolicy": {
"maxTerminationTimeMinutes": 5
}
}
}
}
September 2024: ECS Service Revisions and Deployment History
Amazon ECS introduced service revisions functionality, providing enhanced visibility into deployment history and enabling better rollback capabilities.
New Capabilities:
- 90-Day Deployment History: Track deployment changes and performance metrics over time
- Service Revision Comparison: Compare configurations between different service versions
-
Enhanced API Support: New
DescribeServiceRevisions
API for programmatic access
Implementation Example:
# View service deployment history
aws ecs describe-service-revisions \
--cluster my-cluster \
--service-name my-service \
--max-results 10
# Compare service revisions
aws ecs describe-service-revisions \
--cluster my-cluster \
--service-name my-service \
--service-revision-arns arn:aws:ecs:region:account:service-revision/cluster/service/revision-1 arn:aws:ecs:region:account:service-revision/cluster/service/revision-2
August 2024: Software Version Consistency
Amazon ECS enhanced container image management by resolving container image tags to specific digests for deployment consistency.
Benefits for Blue/Green Deployments:
- Immutable Deployments: Ensures blue and green environments run identical container versions
- Rollback Reliability: Eliminates image tag drift during rollback scenarios
- Audit Trail: Provides definitive container version tracking across deployments
October 2024: ECS Managed Instances Enhancement
Amazon ECS introduced managed instances pricing model, providing cost-effective alternatives to Fargate for certain workloads.
Cost Implications:
- Management Fee: \$0.01025 per hour per managed instance plus standard EC2 charges
- Blue/Green Considerations: Managed instances support blue/green deployments with per-second billing
- FinOps Impact: Potential cost savings for long-running, predictable workloads migrating from CodeDeploy
Troubleshooting Guide
Issue 1: Service Update Fails with "InvalidParameterException"
Symptoms:
An error occurred (InvalidParameterException) when calling the UpdateService operation:
The deployment controller type cannot be updated for services with active deployments.
Root Cause: Attempting to change deployment controller while a deployment is in progress.
Solution:
# Check for active deployments
aws ecs describe-services \
--cluster my-cluster \
--services my-service \
--query 'services[^0].deployments[?status==`RUNNING`]'
# Wait for deployment completion or stop active deployment
aws ecs update-service \
--cluster my-cluster \
--service my-service \
--force-new-deployment
Prevention: Always verify deployment status before attempting deployment controller migration.
Issue 2: Target Group Health Check Failures During Blue/Green Deployment
Symptoms:
Tasks in secondary target group remain unhealthy, preventing traffic shift completion.
Root Cause: Mismatched health check configuration between primary and secondary target groups.
Solution:
# Synchronize health check settings
PRIMARY_TG_ARN="arn:aws:elasticloadbalancing:region:account:targetgroup/primary-tg"
SECONDARY_TG_ARN="arn:aws:elasticloadbalancing:region:account:targetgroup/secondary-tg"
# Get primary target group health check configuration
aws elbv2 describe-target-groups \
--target-group-arns $PRIMARY_TG_ARN \
--query 'TargetGroups[^0].{HealthCheckPath:HealthCheckPath,HealthCheckIntervalSeconds:HealthCheckIntervalSeconds,HealthCheckTimeoutSeconds:HealthCheckTimeoutSeconds}'
# Apply same configuration to secondary target group
aws elbv2 modify-target-group \
--target-group-arn $SECONDARY_TG_ARN \
--health-check-path /health \
--health-check-interval-seconds 30 \
--health-check-timeout-seconds 5 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 3
Issue 3: Lifecycle Hook Timeout Errors
Symptoms:
Lifecycle hook execution timed out. Hook status: IN_PROGRESS
Root Cause: Lifecycle hook Lambda function not returning proper status or exceeding maximum execution time.
Solution:
import json
import time
def lambda_handler(event, context):
try:
# Implement validation logic with timeout awareness
start_time = time.time()
max_execution_time = 4 * 60 # 4 minutes (leave buffer for Lambda overhead)
while time.time() - start_time < max_execution_time:
validation_result = perform_validation()
if validation_result['complete']:
return {
'Status': 'SUCCEEDED' if validation_result['success'] else 'FAILED',
'Message': validation_result['message']
}
time.sleep(30) # Wait before retry
# If still not complete, return IN_PROGRESS
return {
'Status': 'IN_PROGRESS',
'Message': 'Validation still in progress, will retry',
'NextInvocationSeconds': 60
}
except Exception as e:
return {
'Status': 'FAILED',
'Message': f'Validation failed with error: {str(e)}'
}
def perform_validation():
# Your validation logic here
return {'complete': True, 'success': True, 'message': 'Validation passed'}
Issue 4: ALB Listener Rule Conflicts
Symptoms:
An error occurred (RuleNotFoundException) when calling the ModifyRule operation:
The specified rule does not exist.
Root Cause: Listener rule ARN changed or rule was deleted externally.
Solution:
# List all rules for the listener
aws elbv2 describe-rules \
--listener-arn arn:aws:elasticloadbalancing:region:account:listener/app/my-alb/listener \
--query 'Rules[*].{RuleArn:RuleArn,Priority:Priority,Conditions:Conditions}'
# Identify correct rule ARN and update service
aws ecs update-service \
--cluster my-cluster \
--service my-service \
--deployment-configuration '{
"strategy": "BLUE_GREEN",
"productionTrafficRoute": {
"listenerArn": "arn:aws:elasticloadbalancing:region:account:listener/app/my-alb/listener",
"ruleArn": "arn:aws:elasticloadbalancing:region:account:listener-rule/app/my-alb/correct-rule"
}
}'
Issue 5: Service Connect Configuration Conflicts
Symptoms:
Service fails to start with Service Connect configuration after migration from CodeDeploy.
Root Cause: Service Connect namespace or port configuration conflicts with existing setup.
Solution:
# Check existing Service Connect configuration
aws ecs describe-services \
--cluster my-cluster \
--services my-service \
--query 'services[^0].serviceConnectConfiguration'
# Update service with correct Service Connect configuration
aws ecs update-service \
--cluster my-cluster \
--service my-service \
--service-connect-configuration '{
"enabled": true,
"namespace": "my-app-namespace",
"services": [
{
"portName": "http",
"discoveryName": "my-service",
"clientAliases": [
{
"port": 80,
"dnsName": "my-service.local"
}
]
}
]
}'
Issue 6: IAM Permission Insufficient for ECS Blue/Green
Symptoms:
User: arn:aws:sts::account:assumed-role/ECS-Service-Role is not authorized to perform:
elasticloadbalancing:ModifyRule
Root Cause: ECS deployment controller role lacks necessary permissions.
Solution:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:ModifyRule",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:DescribeRules",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:DeregisterTargets"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecs:CreateTaskSet",
"ecs:DeleteTaskSet",
"ecs:DescribeServices",
"ecs:UpdateServicePrimaryTaskSet"
],
"Resource": "*"
}
]
}
Issue 7: Rollback Failure During Migration
Symptoms: Unable to rollback to CodeDeploy after failed ECS blue/green migration.
Root Cause: Target group or listener configuration changes prevent CodeDeploy compatibility.
Solution:
# Restore CodeDeploy-compatible listener configuration
aws elbv2 modify-rule \
--rule-arn arn:aws:elasticloadbalancing:region:account:listener-rule/app/my-alb/rule \
--actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:region:account:targetgroup/primary-tg
# Revert service to CodeDeploy deployment controller
aws ecs update-service \
--cluster my-cluster \
--service my-service \
--deployment-controller type=CODE_DEPLOY
Further Reading
AWS Official Documentation
- Amazon ECS Blue/Green Deployments Guide: Comprehensive documentation on implementing native ECS blue/green deployments
- ECS Service Deployment Strategies: Detailed comparison of rolling, blue/green, and external deployment strategies
- CodeDeploy to ECS Migration Guide: Official AWS migration documentation with step-by-step instructions
AWS Whitepapers and Best Practices
- AWS Well-Architected Framework - Reliability Pillar: Best practices for designing resilient deployment strategies
- Container Security Best Practices: Security considerations for containerized applications during deployments
- Cost Optimization for Container Workloads: Strategies for optimizing ECS deployment costs
Advanced Topics and Integration Patterns
- ECS Service Connect Deep Dive: Advanced service mesh capabilities for internal service communication
- Multi-Region Blue/Green Deployments: Implementing blue/green deployments across multiple AWS regions
- Observability and Monitoring: CloudWatch integration patterns for deployment monitoring and alerting
Community Resources and Tools
- AWS Samples GitHub Repository: Code examples and templates for ECS blue/green deployments
- AWS Container Blog: Latest updates and best practices from AWS container specialists
- AWS re:Invent Sessions: Annual conference sessions on container deployment strategies and innovations
This comprehensive guide provides organizations with the knowledge and tools necessary to successfully migrate from AWS CodeDeploy to Amazon ECS native blue/green deployments, enabling improved operational efficiency, enhanced deployment capabilities, and better alignment with modern container orchestration practices.
Top comments (0)