AWSDVA-C02

Domain 3: Deployment

Topic 3 of 4 · Study notes

AWS Certified Developer – Associate (DVA-C02)

Domain 3: Deployment

Exam Code: DVA-C02  |  Level: Associate
Domain Weight: 24%  |  Total Domains: 4  |  Passing Score: 720/1000


Table of Contents

  1. AWS CodeCommit
  2. AWS CodeBuild
  3. AWS CodeDeploy
  4. AWS CodePipeline
  5. AWS Elastic Beanstalk
  6. AWS CloudFormation
  7. AWS SAM — Deployment Deep Dive
  8. Amazon ECS — Elastic Container Service
  9. Amazon ECR — Elastic Container Registry
  10. Lambda Deployment — Versions, Aliases & Traffic Shifting
  11. Deployment Strategies — Master Comparison
  12. Exam Tips & Quick Reference

1. AWS CodeCommit

CodeCommit is AWS's fully managed, private Git repository service. It integrates natively with other AWS developer tools.

1.1 Repository, Branches & Pull Requests

  • Repositories are private Git repos hosted in AWS.
  • Supports Git branching strategies (GitFlow, trunk-based development).
  • Notifications: Configure SNS or Chatbot notifications for repository events (push, PR comments, approvals).
  • Triggers: Execute Lambda or send SNS notifications on specific branch events.
  • Approval Rule Templates: Enforce PR review requirements (minimum approvers, specific groups) across repositories.

1.2 Authentication & Authorization

Auth Method How Use Case
SSH Keys Upload public SSH key to IAM user Developer workstations
HTTPS with Git Credentials Generate service-specific username/password in IAM Git clients, CI/CD tools
HTTPS with AWS CLI Credential Helper Uses AWS CLI + SigV4 Recommended for automation
IAM Roles Federated users assume a role Cross-account access, CI/CD systems

IAM Policies for CodeCommit:

// Allow read-only access to a specific repository
{
  "Effect": "Allow",
  "Action": [
    "codecommit:GitPull",
    "codecommit:GetRepository",
    "codecommit:ListBranches"
  ],
  "Resource": "arn:aws:codecommit:us-east-1:123456789:MyRepo"
}

Exam Note: CodeCommit does NOT support public repositories. All repos are private. There is no concept of a "public fork." For public repos, GitHub or CodeCatalyst is used.


2. AWS CodeBuild

CodeBuild is a fully managed, serverless build service. It compiles source code, runs unit tests, and produces deployment artifacts. No build servers to manage.

2.1 Build Specification — buildspec.yml

The buildspec.yml file instructs CodeBuild what commands to run at each build phase. It must be in the root of the source repository (or specified as a custom location).

version: 0.2

env:
  variables:
    ENV: "production"
  parameter-store:
    DB_PASSWORD: "/myapp/prod/database/password"  # Read from SSM
  secrets-manager:
    API_KEY: "arn:aws:secretsmanager:us-east-1:123:secret:api-key"

phases:
  install:
    runtime-versions:
      nodejs: 18
    commands:
      - echo "Installing dependencies"
      - npm ci

  pre_build:
    commands:
      - echo "Running lint and unit tests"
      - npm run lint
      - npm test
      - echo "Logging in to Amazon ECR"
      - aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY

  build:
    commands:
      - echo "Building the application"
      - npm run build
      - docker build -t $IMAGE_NAME .
      - docker tag $IMAGE_NAME:latest $ECR_REGISTRY/$IMAGE_NAME:$CODEBUILD_RESOLVED_SOURCE_VERSION

  post_build:
    commands:
      - echo "Pushing Docker image to ECR"
      - docker push $ECR_REGISTRY/$IMAGE_NAME:$CODEBUILD_RESOLVED_SOURCE_VERSION
      - echo "Creating imagedefinitions.json for CodeDeploy/ECS"
      - printf '[{"name":"myapp","imageUri":"%s"}]' $ECR_REGISTRY/$IMAGE_NAME:$CODEBUILD_RESOLVED_SOURCE_VERSION > imagedefinitions.json

artifacts:
  files:
    - imagedefinitions.json
    - appspec.yml
    - taskdef.json
  discard-paths: yes

cache:
  paths:
    - node_modules/**/*      # Cache node_modules to speed up future builds
    - /root/.npm/**/*

reports:
  unit-test-results:
    files:
      - "test-results.xml"
    file-format: JUNITXML

Build Phase Execution Order:

SUBMITTED → QUEUED → PROVISIONING → DOWNLOAD_SOURCE → INSTALL
  → PRE_BUILD → BUILD → POST_BUILD → UPLOAD_ARTIFACTS → FINALIZING → COMPLETED

Critical: If any phase fails, the build fails and subsequent phases are skipped. The post_build phase runs even if build fails — use this for cleanup or notification. Use the finally block in phases for guaranteed execution.

2.2 Environment, Caching & VPC

Build Environments:

Environment Type Description Use Case
Managed Image AWS-provided (Amazon Linux, Ubuntu, Windows) Standard builds
Custom Image Your Docker image from ECR/DockerHub Specialized tools or runtimes

Caching Strategies:

Cache Type Stored In Scope Use Case
Local Cache Build host (ephemeral) Single build Fastest; but lost between environments
S3 Cache S3 bucket Across builds Dependencies (node_modules, Maven, pip)

Best Practice: Use S3 caching for package manager dependencies (node_modules, .m2, .gradle). Reduces build time significantly for dependency-heavy projects.

CodeBuild in VPC:
By default, CodeBuild has outbound internet access. Place CodeBuild in your VPC to access private resources (RDS, ElastiCache, private APIs). Same principles as Lambda in VPC — needs NAT Gateway for internet access.

CodeBuild Service Role:
The IAM role CodeBuild assumes during the build. Must allow access to: CodeCommit (pull source), ECR (pull/push images), S3 (artifacts/cache), SSM/Secrets Manager (credentials), CloudWatch Logs (logging).


3. AWS CodeDeploy

CodeDeploy automates application deployments to EC2, on-premises servers, Lambda functions, and ECS services. It is the deployment engine for most CI/CD pipelines on AWS.

3.1 Deployment Targets & AppSpec File

Deployment Targets:

Target Agent Required AppSpec Format
EC2 / On-Premises Yes (CodeDeploy Agent) YAML or JSON
Lambda No YAML or JSON
ECS No YAML or JSON

AppSpec File — EC2/On-Premises:

# appspec.yml for EC2 deployment
version: 0.0
os: linux
files:
  - source: /build/app.jar
    destination: /opt/myapp/
  - source: /scripts/
    destination: /opt/myapp/scripts/
permissions:
  - object: /opt/myapp/app.jar
    mode: "755"
    owner: ec2-user
hooks:
  BeforeInstall:
    - location: scripts/stop_server.sh
      timeout: 60
      runas: root
  AfterInstall:
    - location: scripts/install_dependencies.sh
      timeout: 120
  ApplicationStart:
    - location: scripts/start_server.sh
      timeout: 60
  ValidateService:
    - location: scripts/health_check.sh
      timeout: 30

AppSpec File — Lambda:

# appspec.yml for Lambda deployment
version: 0.0
Resources:
  - MyLambdaFunction:
      Type: AWS::Lambda::Function
      Properties:
        Name: MyFunction
        Alias: live
        CurrentVersion: !Ref PreviousVersion
        TargetVersion: !Ref NewVersion
Hooks:
  BeforeAllowTraffic: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:PreTrafficHook"
  AfterAllowTraffic: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:PostTrafficHook"

3.2 Deployment Strategies

For EC2/On-Premises — Deployment Configurations:

┌──────────────────────────────────────────────────────────────────────────────┐
│                   EC2 CodeDeploy Deployment Strategies                        │
│                                                                                │
│  ┌────────────────┐  ┌────────────────────┐  ┌───────────────────────────┐   │
│  │  AllAtOnce     │  │  HalfAtATime       │  │  OneAtATime               │   │
│  │                │  │                    │  │                           │   │
│  │ Deploy to ALL  │  │ Deploy to 50%      │  │ Deploy one instance       │   │
│  │ instances at   │  │ at a time          │  │ at a time                 │   │
│  │ once           │  │                    │  │                           │   │
│  │                │  │                    │  │                           │   │
│  │ Fastest        │  │ Balanced           │  │ Slowest, safest           │   │
│  │ Downtime risk  │  │ Some availability  │  │ Minimal impact            │   │
│  └────────────────┘  └────────────────────┘  └───────────────────────────┘   │
│                                                                                │
│  Custom: Define minimum healthy hosts (count or percentage)                   │
└──────────────────────────────────────────────────────────────────────────────┘

For Lambda/ECS — Traffic Shifting Configurations:

Configuration Traffic Pattern Use Case
Canary10Percent5Minutes 10% → wait 5 min → 100% Quick validation
Canary10Percent30Minutes 10% → wait 30 min → 100% More observation time
Linear10PercentEvery1Minute +10% every minute Gradual, auto-scale test
Linear10PercentEvery10Minutes +10% every 10 min Conservative gradual
AllAtOnce 0% → 100% instantly Non-production / fast deploys
Custom Your defined percentages Full control

3.3 EC2 Deployment Lifecycle Hooks

┌────────────────────────────────────────────────────────────────────────────┐
│                    EC2 CodeDeploy Lifecycle Event Order                      │
│                                                                              │
│  ApplicationStop         → Stop the currently running application version   │
│  DownloadBundle          → CodeDeploy agent downloads the revision (S3)     │
│  BeforeInstall           → Pre-installation tasks (backup, configure)       │
│  Install                 → Copy files from bundle to destination             │
│  AfterInstall            → Post-install tasks (set permissions, config)     │
│  ApplicationStart        → Start the new application version                │
│  ValidateService         → Health checks; verify the deployment succeeded   │
│                                                                              │
│  (Blue/Green only:)                                                          │
│  BeforeBlockTraffic      → Run before instances removed from load balancer  │
│  BlockTraffic            → Remove instances from ELB                        │
│  AfterBlockTraffic       → Run after ELB deregistration                     │
│  BeforeAllowTraffic      → Run before new instances added to ELB            │
│  AllowTraffic            → Register new instances with ELB                  │
│  AfterAllowTraffic       → Run after ELB registration; final validation     │
└────────────────────────────────────────────────────────────────────────────┘

Exam Tip: The ValidateService hook is your health check. If the script exits with a non-zero code, CodeDeploy marks the deployment as FAILED and initiates rollback. Always implement health checks in ValidateService.

Rollback Behavior:

  • Automatic rollback: Configure on deployment failure or when a CloudWatch alarm triggers.
  • When rolling back, CodeDeploy redeployes the last known good revision — it does NOT undo file system changes.

3.4 Lambda & ECS Deployment with CodeDeploy

Lambda Deployment:
CodeDeploy shifts traffic between Lambda aliases using weighted alias routing. It monitors CloudWatch alarms during the shift — any alarm triggers automatic rollback.

Lambda Alias "live" → 100% → $LATEST (v1)

Deployment starts:
Lambda Alias "live" → 90% → v1, 10% → v2   [Canary phase]
Wait 5 minutes... CloudWatch alarms OK?
Lambda Alias "live" → 0% → v1, 100% → v2   [Full shift]

Pre/Post traffic hooks validate before and after traffic shift.

Pre/Post Traffic Hook Functions:
Custom Lambda functions that validate the deployment:

  • BeforeAllowTraffic: Run integration tests before any traffic is shifted.
  • AfterAllowTraffic: Run smoke tests after full traffic shift.

If either hook calls codedeploy.put_lifecycle_event_hook_execution_status(status='Failed'), CodeDeploy rolls back automatically.


4. AWS CodePipeline

CodePipeline orchestrates the CI/CD workflow — connecting source, build, test, and deploy stages into an automated pipeline.

4.1 Pipeline Structure & Stages

┌────────────────────────────────────────────────────────────────────────────┐
│                          CodePipeline Structure                              │
│                                                                              │
│  ┌──────────────┐   ┌──────────────┐   ┌──────────────┐  ┌──────────────┐ │
│  │   SOURCE     │──►│    BUILD     │──►│    TEST      │─►│   DEPLOY     │ │
│  │              │   │              │   │              │  │              │ │
│  │ • CodeCommit │   │ • CodeBuild  │   │ • CodeBuild  │  │ • CodeDeploy │ │
│  │ • GitHub     │   │              │   │   (test spec)│  │ • ECS        │ │
│  │ • S3         │   │              │   │ • Lambda     │  │ • Elastic    │ │
│  │ • ECR        │   │              │   │ • Device Farm│  │   Beanstalk  │ │
│  └──────────────┘   └──────────────┘   └──────────────┘  └──────────────┘ │
│        │                  │                  │                  │           │
│        └──────────────────┴──────────────────┴──────────────────┘           │
│                                  Artifact Store (S3)                         │
└────────────────────────────────────────────────────────────────────────────┘

Pipeline Rules:

  • A pipeline must have at least a Source and one additional stage.
  • Each stage has one or more Actions.
  • Actions within a stage can run in parallel (same runOrder) or sequentially (different runOrder).
  • Between stages, CodePipeline uses an S3 artifact bucket to pass artifacts.

Manual Approval Action:
Add a Manual Approval action between stages. CodePipeline pauses and sends SNS notification. A designated approver must approve or reject in the console (or via CLI) within 7 days.

Stage: Deploy-to-Staging ──► [Manual Approval] ──► Stage: Deploy-to-Production
                                      │
                               Notification via SNS → Email/Slack
                               Approver clicks Approve/Reject in Console

4.2 Artifacts & Integration Points

Artifact Store: An S3 bucket (with optional KMS encryption) where CodePipeline stores artifacts passed between stages. By default, CodePipeline creates this bucket; you can specify your own.

Cross-Account Pipeline:
Deploy to multiple AWS accounts from a single pipeline using cross-account roles. The pipeline account assumes a role in the target account. CodePipeline's artifact S3 bucket must use a customer-managed KMS key accessible by both accounts.

EventBridge Integration:
CodePipeline generates events that EventBridge can capture:

  • Pipeline execution state changes (STARTED, SUCCEEDED, FAILED)
  • Stage and action state changes
    Use these for notifications, automated responses, and downstream triggers.

5. AWS Elastic Beanstalk

Elastic Beanstalk is a PaaS (Platform as a Service) that provisions and manages the infrastructure for web applications. You upload code; Beanstalk handles deployment, scaling, load balancing, and monitoring.

5.1 Supported Platforms & Architecture

Supported Platforms: Node.js, Python, Java (Tomcat), .NET (IIS), PHP, Ruby, Go, Docker (single/multi-container), and custom platforms.

┌──────────────────────────────────────────────────────────────────────────┐
│                      Elastic Beanstalk Architecture                       │
│                                                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐  │
│  │                        Application                                   │  │
│  │  ┌──────────────────┐     ┌───────────────────┐                     │  │
│  │  │  Environment 1    │     │  Environment 2    │                     │  │
│  │  │  (Production)     │     │  (Staging)        │                     │  │
│  │  │                   │     │                   │                     │  │
│  │  │  ┌─────────────┐  │     │  ┌─────────────┐  │                    │  │
│  │  │  │     ALB      │  │     │  │     ALB      │  │                   │  │
│  │  │  └──────┬───────┘  │     │  └──────┬───────┘  │                  │  │
│  │  │         │          │     │         │          │                   │  │
│  │  │  ┌──────▼───────┐  │     │  ┌──────▼───────┐  │                  │  │
│  │  │  │  Auto Scaling │  │     │  │  Auto Scaling │  │                 │  │
│  │  │  │  Group (EC2)  │  │     │  │  Group (EC2)  │  │                 │  │
│  │  │  └──────────────┘  │     │  └──────────────┘  │                  │  │
│  │  └──────────────────┘     └───────────────────┘                     │  │
│  └─────────────────────────────────────────────────────────────────────┘  │
│                                                                            │
│  Application Versions stored in S3 → Deployed to Environments            │
└──────────────────────────────────────────────────────────────────────────┘

Elastic Beanstalk Tiers:

Tier Purpose Behind
Web Server Tier Serves HTTP requests ALB + EC2 Auto Scaling Group
Worker Tier Processes background jobs SQS Queue + EC2 Auto Scaling Group

Environment Types:

Type Load Balancer Use Case
Single Instance No (Elastic IP) Development; cost-optimized
Load Balanced ALB/CLB/NLB Production; high availability

5.2 Deployment Policies

Policy Downtime Speed Uses All Capacity Rollback
All at Once Yes (brief) Fastest Yes Manual redeploy
Rolling No Medium No (reduced during deploy) Manual redeploy
Rolling with Additional Batch No Medium Yes (new batch added first) Manual redeploy
Immutable No Slow Yes Terminate new instances
Traffic Splitting No Slow Yes Reroute traffic instantly
Blue/Green No Slow Yes Swap URLs instantly
┌─────────────────────────────────────────────────────────────────────────────┐
│                  Elastic Beanstalk Deployment Policy Deep Dive               │
│                                                                               │
│  ALL AT ONCE:                                                                 │
│  v1[A] v1[B] v1[C] ──► v2[A] v2[B] v2[C]   (all down, then all up)         │
│                                                                               │
│  ROLLING:                                                                     │
│  v1[A] v1[B] v1[C]                                                           │
│  ──► v2[A] v1[B] v1[C]   (A updated, B+C still v1)                          │
│  ──► v2[A] v2[B] v1[C]   (B updated)                                        │
│  ──► v2[A] v2[B] v2[C]   (C updated, done)                                  │
│                                                                               │
│  ROLLING WITH ADDITIONAL BATCH:                                               │
│  v1[A] v1[B] v1[C]                                                           │
│  ──► v1[A] v1[B] v1[C] + v2[D]   (new batch added)                          │
│  ──► v2[A] v1[B] v1[C] (v2[D] terminated after v2[A] live)                  │
│  ──► v2[A] v2[B] v1[C] ...                                                  │
│  → Full capacity maintained throughout                                        │
│                                                                               │
│  IMMUTABLE:                                                                   │
│  v1[A] v1[B] + New ASG: v2[new1]   (start 1 to test)                        │
│  ──► v2[new1] healthy → scale new ASG to full v2 fleet                      │
│  ──► Swap ASGs → Terminate old v1 ASG                                        │
│  → New instances; no modification of existing. Safest for production.        │
│                                                                               │
│  BLUE/GREEN:                                                                  │
│  Blue Env (v1) ──► Route 53/CNAME swap ──► Green Env (v2)                   │
│  → Completely separate environments; instant rollback by URL swap            │
└─────────────────────────────────────────────────────────────────────────────┘

Exam Decision Guide:

  • Need zero downtime AND safe rollback for production? → Immutable or Blue/Green
  • Need zero downtime AND maintain full capacity throughout? → Rolling with Additional Batch
  • Development environment; fastest deploy, downtime OK? → All at Once
  • Blue/Green distinction: Blue/Green uses separate environments (separate DNS). Immutable uses a new ASG within the same environment.

5.3 .ebextensions & Platform Hooks

.ebextensions/ is a folder in your application source bundle that contains YAML/JSON configuration files. Beanstalk processes them in alphabetical order during deployment.

# .ebextensions/01_packages.config — install OS packages
packages:
  yum:
    git: []
    htop: []

# .ebextensions/02_env.config — set environment properties
option_settings:
  aws:elasticbeanstalk:application:environment:
    NODE_ENV: production

# .ebextensions/03_container.config — customize EC2 instance
container_commands:
  01_run_migrations:
    command: "python manage.py migrate"
    leader_only: true   # Only runs on one instance (the leader) — critical!
  02_collectstatic:
    command: "python manage.py collectstatic --noinput"

leader_only: true is critical for database migrations — you only want one instance running the migration, not all instances simultaneously.

Platform Hooks (hooks/ directory):
Platform-specific hooks directory for newer Amazon Linux 2 platforms (replaces some .ebextensions use cases):

Directory When Executed
hooks/prebuild/ Before build phase
hooks/build/ During build phase
hooks/predeploy/ Before deploy phase
hooks/postdeploy/ After deploy phase

5.4 Environment Variables & Configuration

# Set via .ebextensions
option_settings:
  aws:elasticbeanstalk:application:environment:
    DB_HOST: mydb.cluster.us-east-1.rds.amazonaws.com
    LOG_LEVEL: INFO

# Or fetch from SSM at startup via container command
container_commands:
  fetch_secrets:
    command: "aws ssm get-parameter --name /myapp/prod/dbpassword --with-decryption --query Parameter.Value --output text > /opt/myapp/.dbpassword"

Saved Configurations: Named snapshots of environment configuration (option settings, EC2 instance type, scaling settings). Stored in Elastic Beanstalk (backed by S3). Apply to new or existing environments. Useful for promoting staging config to production.


6. AWS CloudFormation

CloudFormation is AWS's Infrastructure as Code (IaC) service that provisions and manages AWS resources via declarative JSON or YAML templates.

6.1 Template Anatomy

AWSTemplateFormatVersion: "2010-09-09"
Description: "Production application stack"

# Parameters — inputs to the template
Parameters:
  EnvironmentName:
    Type: String
    AllowedValues: [dev, staging, prod]
    Default: dev
    Description: Deployment environment name

  DBPassword:
    Type: AWS::SSM::Parameter::Value<SecureString>  # Fetch from SSM at deploy time
    Default: /myapp/db/password

# Mappings — conditional values by key
Mappings:
  InstanceByEnvironment:
    dev:
      InstanceType: t3.micro
    prod:
      InstanceType: m5.large

# Conditions — control resource creation
Conditions:
  IsProd: !Equals [!Ref EnvironmentName, prod]
  IsNotProd: !Not [!Condition IsProd]

# Resources — the actual AWS resources (REQUIRED)
Resources:
  MyBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain          # Don't delete bucket on stack deletion
    UpdateReplacePolicy: Snapshot   # Take snapshot before replacing
    Properties:
      BucketName: !Sub "myapp-${EnvironmentName}-${AWS::AccountId}"
      VersioningConfiguration:
        Status: !If [IsProd, Enabled, Suspended]

  MyDB:
    Type: AWS::RDS::DBInstance
    Condition: IsProd              # Only create in production
    Properties:
      DBInstanceClass: !FindInMap [InstanceByEnvironment, !Ref EnvironmentName, InstanceType]

# Outputs — return values from the stack
Outputs:
  BucketArn:
    Value: !GetAtt MyBucket.Arn
    Export:
      Name: !Sub "${AWS::StackName}-BucketArn"   # Cross-stack export

6.2 Intrinsic Functions

Function Syntax Purpose
Ref !Ref ResourceId Returns resource's primary identifier (or parameter value)
Fn::GetAtt !GetAtt Resource.Attribute Returns a specific attribute of a resource
Fn::Sub !Sub "string with ${var}" String substitution with resource refs or variables
Fn::Join !Join [delimiter, [values]] Concatenates values with a delimiter
Fn::Select !Select [index, list] Returns one value from a list by index
Fn::If !If [Condition, TrueValue, FalseValue] Conditional value selection
Fn::Equals !Equals [v1, v2] Returns true if both values are equal
Fn::FindInMap !FindInMap [Map, Key1, Key2] Retrieves value from Mappings section
Fn::ImportValue !ImportValue ExportName Imports output from another stack
Fn::Split !Split [delimiter, string] Splits a string into a list
Fn::Base64 !Base64 "string" Base64 encodes a string (for EC2 UserData)
Fn::Cidr !Cidr [ipBlock, count, mask] Generates CIDR IP ranges
# Common pattern: EC2 UserData with Sub
UserData:
  Fn::Base64: !Sub |
    #!/bin/bash
    yum update -y
    echo "Environment: ${EnvironmentName}" >> /etc/profile
    aws s3 cp s3://${MyBucket}/config.yml /opt/myapp/config.yml

6.3 Rollbacks, Change Sets & Stack Policies

Rollback Behavior on Create:

  • If any resource fails during stack creation, CloudFormation rolls back and deletes ALL successfully created resources.
  • Use --disable-rollback (CLI) or OnFailure: DO_NOTHING (console) to keep partial resources for debugging.

Rollback Behavior on Update:

  • On failure, CloudFormation automatically rolls back to the last stable state.
  • "UPDATE_ROLLBACK_FAILED" — stack is stuck. Fix the underlying issue, then use ContinueUpdateRollback API.

Change Sets:
Preview the impact of a stack update BEFORE applying it. Shows which resources will be added, modified, or replaced.

# Create a change set
aws cloudformation create-change-set \
  --stack-name MyStack \
  --template-body file://template.yml \
  --change-set-name MyChangeSet

# Review the change set
aws cloudformation describe-change-set \
  --stack-name MyStack \
  --change-set-name MyChangeSet

# Execute if satisfied
aws cloudformation execute-change-set \
  --stack-name MyStack \
  --change-set-name MyChangeSet

Exam Tip: Change Sets are the safe way to update production stacks. Always create and review a Change Set before updating a production CloudFormation stack. Replacement operations (shown as "Replacement: True") will cause downtime.

Stack Policies:
A JSON document that controls which resources can be updated or replaced during stack updates. Prevents accidental changes to critical resources.

// Protect RDS instance from replacement
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "Update:*",
      "Principal": "*",
      "Resource": "*"
    },
    {
      "Effect": "Deny",
      "Action": ["Update:Replace", "Update:Delete"],
      "Principal": "*",
      "Resource": "LogicalResourceId/MyProductionDB"
    }
  ]
}

DeletionPolicy and UpdateReplacePolicy:

Policy DeletionPolicy UpdateReplacePolicy
Delete Delete resource (default) Delete old resource
Retain Keep resource after stack deletion Keep old resource
Snapshot Take snapshot before deleting (RDS, EBS, ElastiCache) Take snapshot before replacing

6.4 Nested Stacks & Cross-Stack References

Nested Stacks: Break large templates into smaller, manageable units. A parent stack creates child stacks using AWS::CloudFormation::Stack resources.

# Parent stack referencing a nested stack
Resources:
  NetworkStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/mybucket/network.yml
      Parameters:
        VpcCidr: "10.0.0.0/16"

  AppStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/mybucket/app.yml
      Parameters:
        VpcId: !GetAtt NetworkStack.Outputs.VpcId
        SubnetId: !GetAtt NetworkStack.Outputs.PrivateSubnetId

Cross-Stack References:
Export outputs from one standalone stack and import them in another. Decouples stacks at the export/import level.

# Stack A — exports VPC ID
Outputs:
  VpcId:
    Value: !Ref MyVPC
    Export:
      Name: SharedVPC-VpcId   # Must be unique within the region

# Stack B — imports VPC ID
Resources:
  MySubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !ImportValue SharedVPC-VpcId

Critical: You CANNOT delete a stack that has exported values being imported by another stack. You must update or delete the importing stack first.

Nested Stacks vs Cross-Stack References:

Nested Stacks Cross-Stack References
Relationship Parent manages child lifecycle Stacks are independent
Update Parent re-deploys children Stacks updated independently
Best for Tightly coupled infrastructure Shared/reusable resources (VPC, security groups)

6.5 CloudFormation StackSets

StackSets deploy CloudFormation stacks to multiple AWS accounts and regions from a single template. Managed from an administrator account.

Deployment Model Description
Self-Managed Manually create IAM roles in each target account
Service-Managed (AWS Organizations) Automatically creates IAM roles; can auto-deploy to new accounts in an OU
Administrator Account
        │
        ▼
   StackSet Template
        │
   ┌────┼────┐
   ▼    ▼    ▼
Acc A Acc B Acc C   (Stack instances — one per account/region combination)
 us-east-1  eu-west-1  ap-southeast-1

6.6 CloudFormation Drift Detection

Drift occurs when resources are manually modified outside of CloudFormation. Drift Detection identifies which resources have drifted (been changed) from the template state.

  • Detects: MODIFIED (resource exists but differs), DELETED (resource no longer exists).
  • Does NOT auto-remediate — you must update the stack or re-import the resource.

7. AWS SAM — Deployment Deep Dive

7.1 Traffic Shifting with SAM

SAM simplifies Lambda traffic shifting by abstracting CodeDeploy configuration into the DeploymentPreference property.

Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: python3.12
      AutoPublishAlias: live          # Auto-create alias and version on each deploy

      DeploymentPreference:
        Type: Canary10Percent5Minutes  # CodeDeploy deployment configuration
        Alarms:
          - !Ref MyFunctionErrorAlarm  # Roll back if this alarm fires
        Hooks:
          PreTraffic: !Ref PreTrafficHookFunction
          PostTraffic: !Ref PostTrafficHookFunction
        TriggerConfigurations:
          - TriggerEvents: [DeploymentFailure]
            TriggerName: DeploymentFailureNotification
            TriggerTargetArn: !Ref MySNSTopic

  # Alarm that triggers automatic rollback
  MyFunctionErrorAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: MyFunctionErrors
      MetricName: Errors
      Namespace: AWS/Lambda
      Statistic: Sum
      Period: 60
      EvaluationPeriods: 2
      Threshold: 5
      ComparisonOperator: GreaterThanThreshold
      Dimensions:
        - Name: FunctionName
          Value: !Ref MyFunction

What AutoPublishAlias does automatically:

  1. Creates a new Lambda version on each sam deploy.
  2. Creates/updates the alias (live) to point to the new version.
  3. Wires up CodeDeploy to gradually shift traffic to the new version.

8. Amazon ECS — Elastic Container Service

ECS is AWS's fully managed container orchestration service for running Docker containers.

8.1 Task Definitions & Services

Task Definition: A JSON blueprint for your container. Defines the Docker image, CPU/memory, port mappings, environment variables, IAM role, logging, and volume mounts.

{
  "family": "myapp",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "executionRoleArn": "arn:aws:iam::...:role/ecsTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::...:role/ecsTaskRole",
  "containerDefinitions": [
    {
      "name": "myapp",
      "image": "123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:latest",
      "portMappings": [{"containerPort": 8080, "protocol": "tcp"}],
      "environment": [{"name": "NODE_ENV", "value": "production"}],
      "secrets": [
        {"name": "DB_PASSWORD", "valueFrom": "arn:aws:secretsmanager:...:secret:dbpassword"}
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/myapp",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ]
}

Two IAM Roles in ECS:

Role Purpose Examples
Task Execution Role ECS agent pulls Docker image, sends logs Pull from ECR, write to CloudWatch Logs, fetch Secrets Manager values
Task Role Container application calls AWS services DynamoDB, S3, SQS, SNS, STS

Critical: Do NOT confuse these. The Task Execution Role is for ECS infrastructure. The Task Role is for your application code.

ECS Service:
Maintains a specified number of running task instances. Integrates with ALB for load balancing and Auto Scaling for elastic capacity.

8.2 Launch Types — EC2 vs Fargate

Feature EC2 Launch Type Fargate Launch Type
Infrastructure You manage EC2 instances AWS manages all infrastructure
Container agent Required on each EC2 Not needed
Pricing Pay for EC2 instances Pay per task (vCPU + memory per second)
Isolation Shared host kernel Task-level isolation
Control Full OS access No OS access
Spot integration Yes (Spot instances) Yes (Fargate Spot)
Use case Consistent heavy workloads Variable workloads, simplicity

ECS Anywhere: Run ECS tasks on on-premises servers or VMs using the ECS agent. Register external instances to an ECS cluster.

8.3 ECS Deployment Strategies

Strategy How Use Case
Rolling Update Replace old tasks with new tasks incrementally. Configure minimumHealthyPercent and maximumPercent. Default; no extra cost
Blue/Green (CodeDeploy) New task set stands up alongside old. Traffic shifts (canary/linear/all at once). Old task set terminated after. Zero-downtime; instant rollback
External Deployment Use your own deployment controller Custom deployment logic
Blue/Green ECS Deployment:
1. CodeDeploy creates new task set (Green) alongside existing (Blue)
2. ALB Target Group 1 → Blue (100%)
3. Shift begins: ALB TG1 → Blue (90%) + Green (10%)  [Canary]
4. All clear → ALB TG1 → Green (100%)
5. Blue task set terminated after stability period

9. Amazon ECR — Elastic Container Registry

ECR is a fully managed Docker container registry for storing, managing, and deploying Docker container images.

9.1 Repository, Image Scanning & Lifecycle Policies

Authentication to ECR:

# Authenticate Docker to ECR (valid for 12 hours)
aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin \
  123456789.dkr.ecr.us-east-1.amazonaws.com

# Push image
docker tag myapp:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:latest
docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:latest

Image Scanning:

Scan Type When What It Finds
Basic Scanning On push (or manual) OS-level CVEs using Clair
Enhanced Scanning Continuous OS + language-level CVEs using Amazon Inspector

Lifecycle Policies:
Automatically expire and delete old or untagged images to manage storage costs.

{
  "rules": [
    {
      "rulePriority": 1,
      "description": "Remove untagged images older than 14 days",
      "selection": {
        "tagStatus": "untagged",
        "countType": "sinceImagePushed",
        "countUnit": "days",
        "countNumber": 14
      },
      "action": {"type": "expire"}
    },
    {
      "rulePriority": 2,
      "description": "Keep only last 10 tagged images",
      "selection": {
        "tagStatus": "tagged",
        "tagPrefixList": ["v"],
        "countType": "imageCountMoreThan",
        "countNumber": 10
      },
      "action": {"type": "expire"}
    }
  ]
}

ECR Cross-Account Access:
Add a repository policy (resource-based policy) allowing another account to pull images. Used for sharing base images or allowing multi-account CI/CD pipelines.


10. Lambda Deployment — Versions, Aliases & Traffic Shifting

10.1 Versions

Every time you publish a Lambda function, a new version is created. Versions are immutable — once published, the code and configuration cannot be changed.

Attribute $LATEST Published Version (e.g., v3)
Mutable Yes No
ARN function:MyFunc:$LATEST function:MyFunc:3
Use in production Not recommended Yes
# Publish a new version
aws lambda publish-version --function-name MyFunction

# Returns: { "Version": "5", "FunctionArn": "...function:MyFunction:5" }

10.2 Aliases & Traffic Shifting (Canary/Linear)

A Lambda alias is a pointer to a specific function version. Aliases have their own ARN and are mutable — you update the alias to point to a new version without changing client code.

# Create alias "live" pointing to version 3
aws lambda create-alias \
  --function-name MyFunction \
  --name live \
  --function-version 3

# Update alias to version 4 with traffic splitting (Canary)
aws lambda update-alias \
  --function-name MyFunction \
  --name live \
  --function-version 4 \
  --routing-config '{"AdditionalVersionWeights": {"3": 0.9}}'
  # 90% → v3, 10% → v4

Common Alias Patterns:

API Gateway → Lambda:MyFunction:live (alias)
                                    │
                              alias "live"
                              ├── 90% → Version 5 (stable)
                              └── 10% → Version 6 (new release)

Stage Variables in API Gateway:
  dev stage → alias: dev
  prod stage → alias: live

Exam Trap: Aliases can point to weighted versions (traffic shifting). However, an alias CANNOT point to another alias — only to specific versions or $LATEST.


11. Deployment Strategies — Master Comparison

┌─────────────────────────────────────────────────────────────────────────────────┐
│                    Deployment Strategy Comparison Matrix                         │
│                                                                                   │
│  Strategy          │ Downtime │ Rollback Speed │ Cost    │ Risk Level             │
│  ────────────────────────────────────────────────────────────────────────────    │
│  All At Once       │   YES    │   Slow (redeploy)│  Low   │   HIGH                │
│  Rolling           │   No     │   Slow           │  Low   │   Medium              │
│  Rolling+Batch     │   No     │   Slow           │ Medium │   Medium              │
│  Immutable         │   No     │   Fast (term new) │ High  │   LOW                 │
│  Blue/Green        │   No     │   Instant (swap)  │ High  │   LOWEST              │
│  Canary            │   No     │   Instant         │ Medium│   LOW (phased)        │
│  Linear            │   No     │   Instant         │ Medium│   LOW (gradual)       │
└─────────────────────────────────────────────────────────────────────────────────┘

Where Each Strategy Is Used:

Strategy Elastic Beanstalk ECS Lambda EC2 + CodeDeploy
All At Once
Rolling
Rolling + Batch
Immutable
Blue/Green
Canary
Linear

12. Exam Tips & Quick Reference

Scenario-to-Answer Mapping

Scenario Keyword / Requirement Correct Answer
"Deploy to EC2 with zero downtime; instant rollback" Elastic Beanstalk Blue/Green or CodeDeploy Blue/Green
"Deploy Lambda; route 10% traffic to new version, monitor, then full release" Lambda Alias with Canary traffic shifting (CodeDeploy or SAM)
"Provision the same stack in 50 AWS accounts" CloudFormation StackSets
"Preview impact of CloudFormation update before applying" Change Set
"Run database migrations only once during EB deployment" .ebextensions with leader_only: true
"Run CodeBuild in private subnet to access internal APIs" CodeBuild in VPC
"Build phase completes; artifacts passed to CodeDeploy" CodePipeline Artifact Store (S3)
"Protect RDS from accidental replacement in CloudFormation" Stack Policy + DeletionPolicy: Snapshot
"Hook before CodeDeploy sends traffic to new Lambda" AppSpec BeforeAllowTraffic hook
"Automatically expire Docker images older than 30 days" ECR Lifecycle Policy
"Container needs to call DynamoDB; which IAM role?" ECS Task Role (not Task Execution Role)
"Pull Docker image from ECR; write logs to CloudWatch" ECS Task Execution Role
"Same CloudFormation template, different config per env" Parameters + Mappings + Conditions
"Cross-stack output dependency blocks stack deletion" Delete or update importing stack first
"CodeDeploy rolls back automatically" CloudWatch Alarm in DeploymentPreference or Beanstalk rollback on failure

Common Traps

  • Elastic Beanstalk Rolling vs Immutable: Rolling modifies existing instances in place. Immutable creates entirely new instances. Immutable is safer and easier to roll back (terminate new ASG).
  • leader_only: true: Without this, container commands (like DB migrations) run on ALL instances simultaneously — causing race conditions or duplicate work.
  • Lambda alias → alias: An alias CANNOT point to another alias. Aliases can only point to specific version numbers or $LATEST.
  • CloudFormation Retain policy: DeletionPolicy: Retain keeps the resource when the stack is deleted, but it becomes unmanaged — CloudFormation no longer tracks it. You must manage or manually delete it.
  • CodeDeploy rollback: CodeDeploy "rollback" is actually a new deployment of the previous revision — it does not undo file system changes. Hooks run again during rollback.
  • Change Set vs Stack Policy: A Change Set previews changes before execution. A Stack Policy prevents certain changes from being executed at all. Use both for critical stacks.
  • ECS Rolling Update percentages: minimumHealthyPercent: 50 + maximumPercent: 200 means: at most 2× desired tasks running, at least 50% always healthy. Setting minimumHealthyPercent: 100 + maximumPercent: 200 is a Blue/Green-like rolling update with no capacity reduction.
  • CloudFormation cross-stack delete: You CANNOT delete a stack that exports values being used by another stack. Error: "Export ... cannot be deleted as it is in use."

Key Terms — Domain 3

Term One-Line Definition
buildspec.yml The YAML file that defines CodeBuild phases, commands, artifacts, and caching
appspec.yml The YAML file CodeDeploy reads to know where to copy files and which hooks to run
Lifecycle Hook A script CodeDeploy runs at a specific point in the deployment process
Lambda Version An immutable snapshot of a Lambda function's code and configuration
Lambda Alias A mutable pointer to a specific Lambda version; supports weighted traffic splitting
Change Set A CloudFormation preview of which resources will be added, changed, or replaced
Stack Policy A JSON document that restricts which CloudFormation resources can be updated
DeletionPolicy Controls what happens to a resource when its CloudFormation stack is deleted
Nested Stack A CloudFormation stack created and managed by a parent stack
StackSet A CloudFormation feature to deploy stacks across multiple accounts and regions
Canary Deployment Deploy to a small percentage of traffic first; shift to 100% after validation
Linear Deployment Gradually increase traffic to new version in equal increments over time
Blue/Green Maintain two identical environments; instantly switch traffic from old to new
Immutable Deployment EB strategy that creates entirely new instances instead of updating existing ones
Task Execution Role IAM role used by the ECS agent to pull images and write logs
Task Role IAM role used by the application running inside the container to call AWS services
leader_only .ebextensions flag to run a container command on only one EB instance

End of Domain 3. Continue to Domain 4: Troubleshooting and Optimization →

Ready to test yourself?

Practice questions for this topic

Start Practicing →

DVA-C02 Topics

Topic 3 of 4