Skip to content
intermediate Phase 5 · AWS DevOps Tools

CodeDeploy

Automate deployments to EC2, Lambda, and on-premises with CodeDeploy.

1h
0 problems
Topic Progress 0%

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

  1. Test deployments in staging first
  2. Use deployment configs appropriate for your environment
  3. Enable auto-rollback on failure
  4. Implement health checks in ValidateService hooks
  5. Use IAM roles instead of access keys
  6. Monitor deployments with CloudWatch
  7. Keep deployment packages small
  8. Use blue/green for zero-downtime deployments
  9. Implement manual approval gates for production
  10. Version control appspec.yml and deployment scripts