AWS for DevOps — CodeDeploy

2 minute read

6.2 — CodeDeploy

AWS CodeDeploy automates application deployments to EC2, on-premises servers, Lambda functions, and ECS services. It eliminates manual SSH-and-copy workflows and supports advanced strategies like blue/green deployments.

  Build artefact (S3 / GitHub)
       │
       ▼
  CodeDeploy reads appspec.yml
       │
       ▼
  Runs lifecycle hooks on each target
       │
       ▼
  ApplicationStop → BeforeInstall → Install
       → AfterInstall → ApplicationStart
       → ValidateService
       │
       ▼
  Deployment succeeds or rolls back

Deployment Components

Component What It Is
Application Logical name grouping your deployments
Deployment Group Set of target instances (tagged EC2s, ASG, ECS service)
Deployment Configuration Rules — how many instances at a time, failure thresholds
Revision The application code + appspec.yml stored in S3 or GitHub
appspec.yml Deployment descriptor — tells CodeDeploy what to do

appspec.yml — EC2/On-Premises

version: 0.0
os: linux
files:
  - source: /
    destination: /opt/my-app
    overwrite: true

permissions:
  - object: /opt/my-app
    owner: ec2-user
    group: ec2-user
    mode: "755"

hooks:
  ApplicationStop:
    - location: scripts/stop-server.sh
      timeout: 60
      runas: ec2-user

  BeforeInstall:
    - location: scripts/cleanup.sh
      timeout: 120
      runas: root

  AfterInstall:
    - location: scripts/install-deps.sh
      timeout: 300
      runas: ec2-user

  ApplicationStart:
    - location: scripts/start-server.sh
      timeout: 60
      runas: ec2-user

  ValidateService:
    - location: scripts/health-check.sh
      timeout: 60
      runas: ec2-user

Lifecycle Event Order (EC2/On-Premises)

  ApplicationStop
       │
  DownloadBundle  (CodeDeploy internal — no hook)
       │
  BeforeInstall
       │
  Install         (CodeDeploy internal — copies files)
       │
  AfterInstall
       │
  ApplicationStart
       │
  ValidateService

appspec.yml — ECS (Blue/Green)

version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws:ecs:ap-south-1:123456789012:task-definition/my-app:3"
        LoadBalancerInfo:
          ContainerName: "my-app"
          ContainerPort: 8080

Hooks:
  - BeforeInstall: "LambdaFunctionToValidateBeforeTrafficShift"
  - AfterInstall: "LambdaFunctionToValidateAfterTrafficShift"
  - AfterAllowTestTraffic: "LambdaFunctionToRunTests"
  - BeforeAllowTraffic: "LambdaFunctionToCheckHealth"
  - AfterAllowTraffic: "LambdaFunctionToRunSmokeTests"

CodeDeploy Agent

EC2 instances need the CodeDeploy Agent installed:

# Install on Amazon Linux 2
$ sudo yum install -y ruby wget
$ cd /home/ec2-user
$ wget https://aws-codedeploy-ap-south-1.s3.ap-south-1.amazonaws.com/latest/install
$ chmod +x ./install
$ sudo ./install auto

# Verify agent is running
$ sudo service codedeploy-agent status
The AWS CodeDeploy agent is running as PID 12345

# Check agent logs
$ tail -f /var/log/aws/codedeploy-agent/codedeploy-agent.log

Creating a Deployment (CLI)

# 1. Create an application
$ aws deploy create-application \
    --application-name my-app \
    --compute-platform Server

# 2. Create a deployment group
$ aws deploy create-deployment-group \
    --application-name my-app \
    --deployment-group-name production \
    --service-role-arn arn:aws:iam::123456789012:role/CodeDeployRole \
    --ec2-tag-filters Key=Environment,Value=Production,Type=KEY_AND_VALUE \
    --deployment-config-name CodeDeployDefault.OneAtATime \
    --auto-rollback-configuration enabled=true,events=DEPLOYMENT_FAILURE

# 3. Create a deployment
$ aws deploy create-deployment \
    --application-name my-app \
    --deployment-group-name production \
    --s3-location bucket=my-artefacts,bundleType=zip,key=my-app/latest.zip
{
    "deploymentId": "d-ABC123DEF"
}

Deployment Configurations

Configuration Behaviour
CodeDeployDefault.OneAtATime One instance at a time — safest, slowest
CodeDeployDefault.HalfAtATime 50% at a time — balanced
CodeDeployDefault.AllAtOnce All instances simultaneously — fastest, riskiest
Custom Define minimumHealthyHosts as count or percentage

Rollback Settings

$ aws deploy update-deployment-group \
    --application-name my-app \
    --current-deployment-group-name production \
    --auto-rollback-configuration \
        enabled=true,events=DEPLOYMENT_FAILURE,events=DEPLOYMENT_STOP_ON_ALARM \
    --alarm-configuration \
        enabled=true,alarms=[{name=HighCPU},{name=HighError5xx}]

This triggers automatic rollback when:

  • A deployment fails (any lifecycle hook returns non-zero)
  • A CloudWatch alarm fires during deployment

IAM Roles for CodeDeploy

Role Trust Key Permissions
CodeDeploy Service Role codedeploy.amazonaws.com Read S3, describe instances, manage ELB
EC2 Instance Profile ec2.amazonaws.com Read S3 (download artefact), write CloudWatch Logs

Common Mistakes

Mistake Why It Hurts Fix
Agent not installed Deployment hangs forever Install and start the CodeDeploy agent
Wrong IAM instance profile EC2 can’t download artefact from S3 Attach S3 read + CodeDeploy permissions
Scripts not executable Hook fails with permission denied chmod +x scripts/*.sh before bundling
No ValidateService hook Broken deploy goes undetected Always validate with a health check

Quick Reference

Task Command
Create application aws deploy create-application --application-name NAME
Create deployment group aws deploy create-deployment-group --application-name NAME --deployment-group-name DG
Deploy aws deploy create-deployment --application-name NAME --deployment-group-name DG --s3-location ...
Check status aws deploy get-deployment --deployment-id ID
List deployments aws deploy list-deployments --application-name NAME

Next → CodePipeline

Updated: