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
- AWS CodeCommit
- AWS CodeBuild
- AWS CodeDeploy
- AWS CodePipeline
- AWS Elastic Beanstalk
- AWS CloudFormation
- AWS SAM — Deployment Deep Dive
- Amazon ECS — Elastic Container Service
- Amazon ECR — Elastic Container Registry
- Lambda Deployment — Versions, Aliases & Traffic Shifting
- Deployment Strategies — Master Comparison
- 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_buildphase runs even ifbuildfails — use this for cleanup or notification. Use thefinallyblock 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
ValidateServicehook 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) orOnFailure: 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
ContinueUpdateRollbackAPI.
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:
- Creates a new Lambda version on each
sam deploy. - Creates/updates the alias (
live) to point to the new version. - 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: Retainkeeps 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: 200means: at most 2× desired tasks running, at least 50% always healthy. SettingminimumHealthyPercent: 100+maximumPercent: 200is 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