[AWS] AWS CodeDeploy

CodeDeploy automates deployments of an application to cloud (EC2, Lambda), or on-premise environments.


Features

  • What to deploy: Revisions
    • A Revision is a bundle (ZIP or TAR) of files to depoly.
    • Scripts: CodeCommit
    • Code: CodeCommit -> CodeBuild
  • How to deploy: Deployment Configuration
    • Specifies the number of instances that remain available at any time during the deployment
    • Deployment type and Rate
    • Success and Failure Condition
      • Recovery Plan
  • Where to deploy: Deployment Group
    • Target Platform
      • EC2 or ASG (Auto Scaling Group)
      • On-premises compute resources
      • ECS (EC2 or Fargate)
      • Lambda
    • You can associate more than one deployment group with a single application.
      • A separate deployment group can be specified to deploy the updates in parallel (the same runOrder) or in sequence (different runOrders).
  • Automated Deployment
    • Minimize downtime, stop and rollback, centralized control

Deployment Steps

  1. Create an application
    • Specify the platform (EC2, ECS, or Lambda)
  2. Create a deployment group (where)
  3. Select the deployment configuration (how)
  4. Create a revision (what)
  5. Deploy
  6. Check results
  7. Redeploy or rollback as needed

Code Deploy AppSpec file

  • An AppSpec file is a configuration file to define parameters that are used during the deployment.
    • Version
    • OS
    • Files: configurations, packages
    • Hooks
  • File Types
    • EC2: YAML
    • Lambda: YAML, JSON
version: 0.0
os: linux
files:
  - source: Config/config.txt
    destination: /webapps/Config
  - source: source
    destination: /webapps/myApp
hooks:
  BeforeInstall:
    - location: Scripts/UnzipResourceBundle.sh
    - location: Scripts/UnzipDataBundle.sh
  AfterInstall:
    - location: Scripts/RunResourceTests.sh
      timeout: 180
  ApplicationStart:
    - location: Scripts/RunFunctionalTests.sh
      timeout: 3600
  ValidateService:
    - location: Scripts/MonitorService.sh
      timeout: 3600
      runas: codedeployuser


CodeDeploy Environment Variables

When you work on the deployment lifecycle hooks, you can customize the deployment dynamically using environment variables.

You can use the following environment values in your hook scripts. For example, you can create multiple deployment groups, such as dev, staging , or prod, and perform the deployment group specific actions based on the value of “DEPLOYMENT_GROUP_NAME”.

  • LIFECYCLE_EVENT: the name of the lifecycle event
  • DEPLOYMENT_ID: the id of the current deployment
  • APPLICATION_NAME: the name of the application being deployed
  • DEPLOYMENT_GROUP_ID: the id of the deployment group of the current deployment
  • DEPLOYMENT_GROUP_NAME: the name of the deployment group of the current deployment

Deploying to EC2 Instances

Features

  • The CodeDeploy agent must be running on target EC2 instances.
  • The EC2 instance must have sufficient permission to access artifacts (deployment bundles).
    • ex) S3 Permissions
  • Deployment Group: EC2 instances via Tags, or ASG
  • With “Load Balancer”, traffic is stopped before instances are updated.

EC2 Deployment Types

In-placeBlue/Green
FeatureUpdate the exiting instances in the deployment group with a new revisionTraffic is shifted from old instances (blue) to new ones (green).

There are two identical environments running differing versions of the application.

It minimizes the deployment downtime but maintaining two environments is expensive.
What to UpdateAuto Scaling Group, EC2 instances, On-premise instancesAuto Scaling Group, EC 2 instances
Update RateCodeDeployDefault.AllAtOnce
CodeDeployDefault.OncAtATime
CodeDeployDefault.HalfAtATime
Custom
CodeDeployDefault.AllAtOnce
CodeDeployDefault.OncAtATime
CodeDeployDefault.HalfAtATime
Custom
DowntimeEach instance will be offline for its updateNone
Service OutrageYes with All at onceNone
Rolling UpdateOne at a time, or Half at at a time One at a time, or Half at at a time
RollbackRedeploy the original revisionEasy to rollback. You can just switch the traffic to the original instances
Use CasesFirst Deployment or Quick Deployment (allowing service outrage)

Additional Settings of Blue/Green Deployments

  • Requirements
    • A new ASG is created and the settings are copied from the old one to the new one.
    • A Load Balancer must be used.
  • Traffic Rerouting
    • Reroute traffic immediately
    • Set the custom wait time
  • Blue Instance Termination Options (BlueInstanceTerminationOption)
    • TERMINATE: Terminate blue (old) instances after the specified wait time (default 1 hour, max 2 days)
    • KEEP_ALIVE: Blue (old) instances keep alive but deregistered from the load balancer.

EC2 Deployment Hooks: In-place Deployment

  1. Phase 1: Deregister an instance from a load balancer
    1. BeforeBlockTraffic
    2. BlockTraffic
    3. AfterBlockTraffic
  2. Phase 2: Application Deployment
    1. ApplicationStop
    2. DownloadBundle
    3. BeforeInstall
    4. Install
    5. AfterInstall
    6. ApplicationStart
    7. ValidateService
  3. Phase 3: Register an instance with a load balancer
    1. BeforeAllowTraffic
    2. AllowTraffic
    3. AfterAllowTraffic

EC2 Deployment Hooks: Blue/Green Deployment

In the Blue/Green deployment,

  1. The Phase 2 & 3 are done first in the Green (new) instances.
  2. And then Phase 1 is done in the Blue (old) instances.

Deploying to ECS

Features

  • Blue/Green deployments only
    • Requires the Application Load Balancer
  • The ECS Task Definition and Container Images must be created before the ECS deployment. -> appspec.yml
  • ALB is required to do the blue/green deployment.
  • CodeDeploy Agent is NOT required.

Deployment Steps (CodePipleline)

  1. CodeCommit
    • Code is pushed
  2. CodeBuild
    1. Create a new Docker image
    2. Push the image to ECR
    3. Create a new ECS Task Definition file
      • A new Docker image is referenced.
      • A new ECS revison is created
    4. Create appspec.yml in S3
      • TaskDefinition
      • LoadBalancerInfo
  3. CodeDeploy
    1. A new task set is created.
    2. Traffic is rerouted to the new task set. (Traffic Shift)
    3. The old task set is terminated.

Deployment Configuration

TypeBlue/Green
Lineargrow traffic every N minutes until 100%CodeDeployDefault.ECSLinear10PercentEvery1Minutes
CodeDeployDefault.ECSLinear10PercentEvery3Minutes
Canarytry X percent for N minutes, then 100%CodeDeployDefault.ECSCanary10Percent5Minutes
CodeDeployDefault.ECSCanary10Percent15Minutes
All at onceimmediately 100%CodeDeployDefault.ECSAllAtOnce
# appspec.yml

version: 0.0
resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "arn:aws:ecs:<region>:<account>:task-definition/<name>:<revision>"
        LoadBalancerInfo:
          ContainerName: "<name>"
          ContainerPort: <port> 

ECS Deployment Hooks

  1. Phase 1
    1. BeforeInstall
    2. Install
    3. AfterInstall
  2. Phase 2
    1. AllowTestTraffic
    2. AfterAllowTestTraffic
      • You can perform health checks and trigger a rollback if the health checks fail.
  3. Phase 3
    1. BeforeAllowTraffic
    2. AllowTraffic
    3. AfterAllowTraffic

Deploying Lambda Functions

You can deploy lambda functions and shift traffic between aliases using CodeDeploy.

Features

  • Integrated with SAM
  • The version info is specified in the appspec.yml file
  • Blue/Green deployments only
    • Traffic shifting with alias
  • CodeDeploy agent is NOT required
  • Easy and automatic rollback using CloudWatch alarms

Deployment Configuration

TypeBlue/Green
Lineargrow traffic every N minutes until 100%CodeDeployDefault.LambdaLinear10PercentEvery1Minutes
CodeDeployDefault.LambdaLinear10PercentEvery2Minutes
CodeDeployDefault.LambdaLinear10PercentEvery3Minutes
CodeDeployDefault.LambdaLinear10PercentEvery10Minutes
Canarytry X percent for N minutes, then 100%CodeDeployDefault.LambdaCanary10Percent5Minutes
CodeDeployDefault.LambdaCanary10Percent10Minutes
CodeDeployDefault.LambdaCanary10Percent15Minutes
CodeDeployDefault.LambdaCanary10Percent30Minutes
All at onceimmediately 100%CodeDeployDefault.LambdaAllAtOnce

In the appspec.yaml, you need to specify the name, the alias, the current version and the target (new) version.

# appspec.yml

version: 0.0
resources:
  - <lambdaFunctionName>:
      Type: AWS::Lambda::Function
      Properties:
        Name: <lambdaFunctionName>
        Alias: <alias>
        CurrentVersion: 1
        TargetVersion: 2 

Lambda Deployment Hooks

  1. BeforeAllowTraffic
  2. AllowTraffic
  3. AfterAllowTraffic

Rollbacks

  • Deployments can be rolled back:
    • Automatic:
      • When a deployment fails
      • or When a CloudWatch Alarm thresholds are met
    • Manual
  • You can disable rollback.
  • When a rollback happens, CodeDeploy redeploys the last known good revision as a new deployment.
    • It does not restore old instances.

Troubleshooting

Troubleshooting CodeDeploy – AWS CodeDeploy (amazon.com)

<Case 1>

InvalidSignatureException – Signature expired:

  • CodeDeploy requires accurate time reference.
  • Check the data & time of an EC2 instance.

<Case 2>

HEALTH_CONSTRAINTS

  • When all lifecycle events are skipped, you will get
    • “The overall deployment failed because too many instances failed deployment.”
    • “Too few healthy instances are available for deployment”
    • “Some instances in your deployment group are experiencing problems.”

The reasons can be

  • A CodeDeploy agent is not installed, not running, or not reachable.
    • Check whether an agent can reach to the CodeDeploy endpoint via Internet or NAT Gateway
  • The CodeDeploy Service Role does not have proper permissions.
  • The target EC2 instances do not have a proper instance profile attached.
  • If you are using HTTP proxy, configure CodeDeploy agent with :proxy_uri parameter.

<Case 3>

Failed AllowTraffic lifecycle event in Blue/Green deployment.

  • Most likely the ELB health check configured incorrectly.
  • Review and correct any errors in ELB health checks

<Case 4>

When the deployment occurs to ASG and a scale-out event occurs during the deployment,

  • The new instance created by ASG will be updated with revision of the most recently deployed
    • Note that it is not the target revision.
  • ASG will have instances hosting different versions.
  • CodeDeploy automatically starts a deployment to update any outdated instances.

Leave a Comment