CodeDeploy Fundamentals
CodeDeploy Fundamentals
AWS CodeDeploy automates code deployments to EC2, on-premises, Lambda, and ECS.
Deployment Types
| Type | EC2 | Lambda | ECS |
|---|---|---|---|
| In-Place | Update existing | - | - |
| Blue/Green | New instances | New version | New task set |
| Canary | - | Traffic shift | Traffic shift |
| Linear | - | Traffic shift | Traffic shift |
Create Application
# Create application
aws codedeploy create-application \
--application-name my-app \
--compute-platform Server
# Create deployment group (EC2)
aws codedeploy create-deployment-group \
--application-name my-app \
--deployment-group-name my-deploy-group \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--ec2-tag-filters Key=Environment,Value=production,Type=KEY_AND_VALUE \
--service-role-arn arn:aws:iam::xxx:role/CodeDeployRole
# Create deployment
aws codedeploy create-deployment \
--application-name my-app \
--deployment-config-name CodeDeployDefault.AllAtOnce \
--deployment-group-name my-deploy-group \
--s3-location bucket=my-deploy-bucket,key=app.zip,bundleType=zip
Compute Platforms
- EC2/On-Premises: Uses IAM roles and tags
- Lambda: Traffic shifting for Lambda functions
- Amazon ECS: Traffic shifting for ECS services
AppSpec Files
AppSpec Files
EC2 AppSpec
# appspec.yml for EC2
version: 0.0
os: linux
files:
- source: /
destination: /var/www/html
overwrite: yes
hooks:
BeforeInstall:
- location: scripts/before_install.sh
timeout: 300
runas: root
AfterInstall:
- location: scripts/after_install.sh
timeout: 300
runas: root
ApplicationStart:
- location: scripts/start_server.sh
timeout: 300
runas: root
ValidateService:
- location: scripts/validate.sh
timeout: 300
runas: root
Lambda AppSpec
# appspec.yml for Lambda
version: 0.0
resources:
- myFunction:
Type: AWS::Lambda::Function
Properties:
Name: my-function
Handler: lambda_function.lambda_handler
Runtime: python3.12
MemorySize: 256
Timeout: 30
hooks:
BeforeInstall: scripts/before_install.py
AfterInstall: scripts/after_install.py
ApplicationStart: scripts/before_allow_traffic.py
AllowTraffic: scripts/after_allow_traffic.py
ECS AppSpec
# appspec.yml for ECS
version: 0.0
resources:
- targetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: "arn:aws:ecs:us-east-1:xxx:task-definition/my-task:1"
LoadBalancerInfo:
ContainerName: my-app
ContainerPort: 8080
hooks:
BeforeInstall: scripts/verify_service.py
AfterInstall: scripts/update_service.py
AllowTraffic: scripts/validate_traffic.py
Deployment Strategies
Deployment Strategies
Blue/Green Deployment
┌─────────────────────────────────────────────────────────────┐
│ Blue/Green Deployment │
├─────────────────────────────────────────────────────────────┤
│ │
│ ALB ──┬──▶ Target Group 1 (Blue) ──▶ EC2 v1 │
│ │ [OLD VERSION] │
│ │ │
│ └──▶ Target Group 2 (Green) ──▶ EC2 v2 │
│ [NEW VERSION] │
│ │
│ Steps: │
│ 1. Deploy to Green environment │
│ 2. Run tests on Green │
│ 3. Switch ALB to Green (instant cutover) │
│ 4. Keep Blue as rollback target │
└─────────────────────────────────────────────────────────────┘
# Blue/Green deployment group
aws codedeploy create-deployment-group \
--application-name my-app \
--deployment-group-name my-bg-group \
--deployment-config-name CodeDeployDefault.BlueGreen \
--blue-green-deployment-configuration '{
"terminationBehavior": "KEEP_ALIVE",
"readyWaitTimeMinutes": 10,
"greenFleetProvisioningOption": {
"action": "DISCOVER_EXISTING"
}
}' \
--auto-rollback-configuration '{
"enabled": true,
"events": ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_REQUEST"]
}'
Canary Deployment (Lambda)
# Canary: 10% traffic for 10 minutes, then 100%
aws codedeploy create-deployment \
--application-name my-lambda-app \
--deployment-group-name my-lambda-group \
--deployment-config-name CodeDeployDefault.LambdaCanary10Percent10Minutes \
--s3-location bucket=my-bucket,key=function.zip
Linear Deployment (Lambda)
# Linear: 10% every 5 minutes
aws codedeploy create-deployment \
--application-name my-lambda-app \
--deployment-group-name my-lambda-group \
--deployment-config-name CodeDeployDefault.LambdaLinear10PercentEvery5Minutes \
--s3-location bucket=my-bucket,key=function.zip
Deployment Configs
| Config | Description |
|---|---|
| AllAtOnce | Deploy to all at once |
| OneAtATime | One instance at a time |
| HalfAtATime | 50% at a time |
| Canary10Percent10Minutes | 10% for 10 min, then 100% |
| Canary10Percent5Minutes | 10% for 5 min, then 100% |
| Linear10PercentEvery1Minute | 10% every 1 min |
| Linear10PercentEvery3Minutes | 10% every 3 min |
Deployment Monitoring and Rollback
Deployment Monitoring and Rollback
Monitor Deployments
# Get deployment status
aws codedeploy get-deployment --deployment-id d-xxx
# Get deployment group info
aws codedeploy get-deployment-group \
--application-name my-app \
--deployment-group-name my-deploy-group
# List deployments
aws codedeploy list-deployments --application-name my-app
# Get deployment instance status
aws codedeploy list-deployment-instances --deployment-id d-xxx
Automatic Rollback
# Configure auto-rollback
aws codedeploy update-deployment-group \
--application-name my-app \
--current-deployment-group-name my-deploy-group \
--auto-rollback-configuration '{
"enabled": true,
"events": ["DEPLOYMENT_FAILURE", "DEPLOYMENT_STOP_ON_REQUEST"]
}'
# Manual stop
aws codedeploy stop-deployment --deployment-id d-xxx
# Manual rollback
aws codedeploy create-deployment \
--application-name my-app \
--deployment-group-name my-deploy-group \
--revision '{
"revisionType": "S3",
"s3Location": {
"bucket": "my-bucket",
"key": "previous-version.zip"
}
}'
CloudWatch Monitoring
# Key metrics
# - DeploymentCount: Number of deployments
# - DeploymentSuccessRate: Success percentage
# - DeploymentDuration: Time taken
aws cloudwatch get-metric-statistics \
--namespace AWS/CodeDeploy \
--metric-name DeploymentSuccessPercent \
--dimensions Name=ApplicationName,Value=my-app \
--start-time $(date -u -d '24 hours ago') \
--end-time $(date -u) \
--period 3600 \
--statistics Average
CodeDeploy Best Practices
CodeDeploy Best Practices
Security
# Use IAM roles for EC2 instances
aws iam attach-role-policy \
--role-name EC2CodeDeployRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforAWSCodeDeploy
# Install CodeDeploy agent on EC2
sudo yum install -y aws-codedeploy-agent
sudo systemctl enable codedeploy-agent
sudo systemctl start codedeploy-agent
# Verify agent
sudo /opt/aws/bin/codedeploy-agent status
Deployment Hooks
# Hook lifecycle events
BeforeInstall → ApplicationStart → AfterInstall → ApplicationStart → ValidateService
# Hook timeout: 3600 seconds (default)
# Hook runas: root or specific user
# Hook location: script path relative to app root
Best Practices
- Test deployments in staging first
- Use deployment configs appropriate for your environment
- Enable auto-rollback on failure
- Implement health checks in ValidateService hooks
- Use IAM roles instead of access keys
- Monitor deployments with CloudWatch
- Keep deployment packages small
- Use blue/green for zero-downtime deployments
- Implement manual approval gates for production
- Version control appspec.yml and deployment scripts