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 Elastic Beanstalk
- AWS CodeCommit
- AWS CodeBuild
- AWS CodeDeploy
- AWS CodePipeline
- AWS CloudFormation
- AWS SAM — Serverless Application Model
- Lambda Deployment Patterns
- ECS & EC2 Deployment Patterns
- AWS CodeArtifact
- Deployment Strategy Comparison
- Exam Tips & Quick Reference
1. AWS Elastic Beanstalk
Elastic Beanstalk is a Platform-as-a-Service (PaaS) that lets you deploy and manage applications without managing the underlying infrastructure. You upload code; Elastic Beanstalk automatically handles capacity provisioning, load balancing, auto-scaling, and health monitoring. The service itself is free — you pay only for the EC2, RDS, and other AWS resources it creates.
1.1 Architecture & Environment Tiers
┌─────────────────────────────────────────────────────────────────────┐
│ Elastic Beanstalk Architecture │
│ │
│ Application (top-level container) │
│ └── Application Versions (ZIP files stored in S3) │
│ └── Environments (one version running at a time) │
│ ├── Web Server Tier │
│ │ ELB → Auto Scaling Group → EC2 Instances │
│ │ URL: myapp.us-east-1.elasticbeanstalk.com │
│ │ │
│ └── Worker Tier │
│ SQS Queue → EC2 Instances (daemon pulls messages) │
│ Scales based on SQS ApproximateNumberOfMessages metric │
└─────────────────────────────────────────────────────────────────────┘
Supported Platforms: Go, Java SE, Java/Tomcat, .NET Core (Linux), .NET (Windows), Node.js, PHP, Python, Ruby, Single/Multi-container Docker, Packer.
Environment Tiers:
- Web Server Tier: Handles HTTP/HTTPS traffic via an ELB in front of an Auto Scaling Group.
- Worker Tier: Processes background jobs by pulling messages from an SQS queue. No ELB. Scales on queue depth.
- A web tier can decouple long-running tasks by pushing messages to a Worker tier SQS queue.
1.2 Deployment Policies
The deployment policy controls how Elastic Beanstalk rolls out new application versions to EC2 instances.
| Policy | Downtime | Maintains Full Capacity | Rollback Speed | Cost Impact | Uses Existing Instances |
|---|---|---|---|---|---|
| All at once | Yes | No — all instances update simultaneously | Slow — full redeploy required | Lowest | Yes |
| Rolling | No | No — a batch is out of service while updating | Slow — redeploy to restored instances | Low | Yes |
| Rolling with additional batch | No | Yes — extra batch launched before old ones update | Slow — redeploy required | Slightly higher | Yes + temporary new |
| Immutable | No | Yes — fresh instances alongside old ones | Fast — terminate the new ASG | High — double instances temporarily | No — all new |
| Blue/Green | No | Yes — entirely separate environment | Fast — swap CNAME back | High — two full environments | No — separate env |
| Traffic Splitting (Canary) | No | Yes | Fast — shift traffic back | Medium | Partial |
Choosing the right policy:
- "Dev environment, fastest deploy, downtime acceptable" → All at once
- "Maintain full capacity, use existing instances, minimize cost" → Rolling with additional batch
- "Zero downtime, fastest rollback, no tolerance for deployment failure" → Immutable
- "Incompatible old/new versions must not run simultaneously, easy rollback" → Blue/Green
- "Gradually shift traffic to validate a new version" → Traffic Splitting
Critical: Blue/Green is not a native Elastic Beanstalk deployment type. It is implemented manually by creating a second Elastic Beanstalk environment with the new version and then swapping the environment CNAMEs (or updating Route 53) to redirect traffic.
1.3 Configuration & ebextensions
Package format: Elastic Beanstalk requires deployment packages as .zip files only. .tar and .tar.gz formats are not supported.
ebextensions:
Configuration files that customize the Elastic Beanstalk environment. They run during deployment before the application starts.
myapp.zip
├── application code (src/, requirements.txt, etc.)
└── .ebextensions/
├── options.config ← environment variables
├── packages.config ← install OS packages
└── healthcheck.config ← health check URL
Rules for .ebextensions:
- The directory must be named exactly
.ebextensions/in the root of the ZIP. - Files must have the
.configextension (e.g.,options.config). - Files are YAML or JSON format.
# .ebextensions/environment.config
option_settings:
aws:elasticbeanstalk:application:environment:
DB_HOST: "mydb.example.com"
LOG_LEVEL: "INFO"
aws:elasticbeanstalk:environment:process:default:
HealthCheckPath: /health
Critical Exam Trap: A
.configfile in.ebextensions/that is not being processed is almost always because: (1) the file extension is wrong (e.g.,.yamlinstead of.config), or (2) the directory is not at the root of the ZIP archive.
Resources created via .ebextensions are deleted when the environment is deleted. For persistent resources like production databases, create them outside Elastic Beanstalk.
Load Balancer Migration:
It is not possible to change the load balancer type on an existing Elastic Beanstalk environment (e.g., from CLB to ALB). To change the LB type, you must create a new environment, deploy the same application version, and then swap CNAMEs to redirect traffic.
1.4 RDS Integration & Lifecycle Management
RDS inside vs outside Elastic Beanstalk:
| Approach | When to Use | Critical Risk |
|---|---|---|
| RDS inside EB | Development and testing only | The RDS instance is deleted when the environment is terminated |
| RDS outside EB | Production | DB lifecycle is completely independent of the application environment |
Decoupling an existing internal RDS (production migration steps):
- Take a snapshot of the RDS database.
- Enable Deletion Protection on the RDS instance.
- Create a new Elastic Beanstalk environment pointing to the same RDS endpoint.
- Swap CNAMEs to the new environment.
- Terminate the old environment — Deletion Protection prevents RDS from being deleted.
Application Version Lifecycle Policy:
- Elastic Beanstalk stores application versions as ZIP files in S3.
- Maximum: 1,000 application versions per application.
- Set a lifecycle policy to automatically delete old versions by age or by count.
- Set "Retain source bundle in S3" to preserve ZIP files in S3 even after deleting the application version record.
2. AWS CodeCommit
CodeCommit is a fully managed, private Git repository service hosted on AWS. All data is encrypted at rest using KMS and in transit via HTTPS/SSH.
2.1 Authentication & Triggers
Authentication methods:
| Method | How |
|---|---|
| HTTPS | Generate Git credentials (username/password) in the IAM console — specific to CodeCommit |
| SSH | Upload an SSH public key to the IAM user; use the associated key ID as the SSH username |
| Cross-account | Use an IAM Role + STS AssumeRole — never share SSH keys or HTTPS credentials across accounts |
IAM policies control repository-level permissions (clone, push, create branches, etc.).
Triggering pipelines:
- CodePipeline can detect commits on a specific branch and start automatically.
- The pipeline only triggers for commits on the configured source branch. Commits to other branches are ignored.
Note: AWS deprecated CodeCommit for new customers in mid-2024. GitHub, GitLab, and Bitbucket are all valid CodePipeline source providers and may appear in exam questions.
3. AWS CodeBuild
CodeBuild is a fully managed continuous integration service. It compiles source code, runs tests, and produces deployment artifacts. There are no servers to provision or manage. You pay per build minute.
3.1 buildspec.yml Anatomy
buildspec.yml is CodeBuild's build specification file. It must be located at the root of the source code repository (or a custom path specified in the CodeBuild project settings).
version: 0.2
env:
variables:
# Plaintext only — do not store secrets here
ENVIRONMENT: "staging"
parameter-store:
# Fetched from SSM Parameter Store at build start
DB_HOST: /myapp/staging/db-host
secrets-manager:
# Fetched from Secrets Manager at build start
API_KEY: "arn:aws:secretsmanager:us-east-1:123:secret:myapp-api-key"
phases:
install:
runtime-versions:
nodejs: 18
commands:
- echo Installing dependencies
- npm install
pre_build:
commands:
- echo Logging in to Amazon ECR
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ECR_REGISTRY
build:
commands:
- echo Build started at $(date)
- npm run build
- docker build -t $IMAGE_NAME:$CODEBUILD_RESOLVED_SOURCE_VERSION .
post_build:
commands:
- docker push $ECR_REGISTRY/$IMAGE_NAME:$CODEBUILD_RESOLVED_SOURCE_VERSION
- echo Build complete
artifacts:
files:
- '**/*'
base-directory: dist
cache:
paths:
- node_modules/**/* # Cached in S3 between builds for faster execution
buildspec.yml sections:
| Section | Purpose |
|---|---|
env.variables |
Plaintext environment variables — never store secrets here |
env.parameter-store |
Fetches values from SSM Parameter Store at build start |
env.secrets-manager |
Fetches values from Secrets Manager at build start |
phases.install |
Install required runtimes and tools |
phases.pre_build |
Setup before the main build (authentication, validation) |
phases.build |
Compile code, run tests, build container images |
phases.post_build |
Package artifacts, push images, notifications |
artifacts |
Files to upload to S3 as the build output |
cache |
Files to cache in S3 between builds (speeds up dependency installation) |
3.2 Security, VPC & Troubleshooting
Security:
- CodeBuild uses an IAM service role that must have permissions for CodeCommit, S3, ECR, SSM Parameter Store, and Secrets Manager as needed.
- Build environment variables are available to all build commands — never inject secrets via
env.variables.
VPC Access:
By default, CodeBuild runs in a managed network that cannot reach your VPC resources (RDS, ElastiCache). To access VPC resources from a build, configure the CodeBuild project with VPC settings: specify the VPC ID, subnets, and security groups.
Troubleshooting build failures:
- Check the build history logs in the CodeBuild console. Each build shows a phase-by-phase log with the exact command output and exit codes.
- If environment variable character limits are exceeded: move variables to SSM Parameter Store and reference them in the
parameter-storesection. - Use the CodeBuild local agent (Docker-based) to run and debug buildspec.yml locally before committing.
4. AWS CodeDeploy
CodeDeploy automates application deployments to EC2 instances, on-premises servers, AWS Lambda functions, and Amazon ECS services. It is the only AWS CI/CD service that supports on-premises servers.
4.1 Deployment Platforms & appspec.yml
Supported platforms:
| Platform | Deployment Types Available | Agent Required |
|---|---|---|
| EC2 / On-Premises | In-place, Blue/Green | Yes — must be installed and running |
| AWS Lambda | Blue/Green (traffic shifting) | No |
| Amazon ECS | Blue/Green only | No |
The appspec.yml file is CodeDeploy's deployment specification. It must be at the root of the deployment bundle (not in a subdirectory).
EC2/On-Premises appspec.yml:
version: 0.0
os: linux
files:
- source: / # copy everything from the bundle root
destination: /var/www/myapp
permissions:
- object: /var/www/myapp
pattern: "**"
owner: nginx
group: nginx
mode: "644"
hooks:
BeforeInstall:
- location: scripts/stop_server.sh
timeout: 300
runas: root
AfterInstall:
- location: scripts/set_permissions.sh
timeout: 60
ApplicationStart:
- location: scripts/start_server.sh
timeout: 300
ValidateService:
- location: scripts/validate_health.sh
timeout: 120
Lambda appspec.yml:
version: 0.0
Resources:
- MyLambdaFunction:
Type: AWS::Lambda::Function
Properties:
Name: my-function
Alias: live
CurrentVersion: "3"
TargetVersion: "4"
Hooks:
- BeforeAllowTraffic: pre-traffic-validation-function
- AfterAllowTraffic: post-traffic-validation-function
Critical: The Lambda appspec.yml requires four specific fields under
Properties:Name,Alias,CurrentVersion, andTargetVersion. Missing any of these causes the deployment to fail.
4.2 EC2 Lifecycle Hooks
CodeDeploy executes lifecycle event hooks in a fixed order. Understanding this order is heavily tested.
┌────────────────────────────────────────────────────────────────────┐
│ CodeDeploy EC2 In-Place Deployment │
│ Lifecycle Event Hook Order │
│ │
│ ApplicationStop ← Stop the current running application │
│ │ │
│ DownloadBundle ← RESERVED — CodeDeploy downloads bundle │
│ │ (cannot run custom scripts here) │
│ BeforeInstall ← Pre-install tasks (decrypt files, backups) │
│ │ Files do NOT exist yet at this point │
│ Install ← RESERVED — CodeDeploy copies files │
│ │ (cannot run custom scripts here) │
│ AfterInstall ← Post-install configuration │
│ │ Files EXIST. Change permissions here. │
│ ApplicationStart ← Start the new application version │
│ │ │
│ ValidateService ← Health check — verify deployment succeeded │
│ LAST hook. Failure here = rollback. │
└────────────────────────────────────────────────────────────────────┘
Hook decision guide:
| Task | Correct Hook |
|---|---|
| Stop the currently running application | ApplicationStop |
| Decrypt files or create backup before overwrite | BeforeInstall |
| Change file permissions on deployed files | AfterInstall (files exist, app not started) |
| Start the new application version | ApplicationStart |
| Run smoke tests or health checks | ValidateService (last hook — failure triggers rollback) |
Critical:
DownloadBundleandInstallare reserved hooks — CodeDeploy uses them internally to download and copy files. You cannot run custom scripts during these phases.
EC2 in-place deployment configurations:
AllAtOnce— all instances at once. Fastest. Causes downtime.HalfAtATime— half the instances updated at a time.OneAtATime— one instance at a time. Slowest. Zero downtime.- Custom — define your own minimum healthy percentage.
Rollback behavior:
- Rollback creates a new deployment using the last known good revision.
- It is NOT an undo or restore operation — the previous application files are redeployed fresh.
- Automatic rollback triggers: deployment failure, or a CloudWatch Alarm threshold breach.
4.3 Lambda & ECS Traffic Shifting
Lambda traffic shifting strategies:
| Strategy | Behavior |
|---|---|
LambdaLinear10PercentEvery1Minute |
Shift 10% of traffic every 1 minute until 100% |
LambdaLinear10PercentEvery3Minutes |
Shift 10% every 3 minutes until 100% |
LambdaCanary10Percent5Minutes |
10% for 5 minutes, then shift 100% |
LambdaCanary10Percent30Minutes |
10% for 30 minutes, then shift 100% |
LambdaAllAtOnce |
Shift 100% immediately |
ECS Blue/Green deployment:
- Blue/Green only — in-place deployments are not supported for ECS.
- Requires an ALB with two target groups: one for the Blue (current) version and one for the Green (new) version.
- The same Linear and Canary strategies apply (prefix
ECSCanaryorECSLinearinstead ofLambdaCanary/LambdaLinear).
Critical: ECS CodeDeploy deployments are Blue/Green only and require an ALB. There is no in-place deployment option for ECS through CodeDeploy.
5. AWS CodePipeline
CodePipeline is a fully managed continuous delivery service that orchestrates all stages of a release pipeline — from source code to production deployment.
5.1 Stages, Artifacts & Triggering
┌─────────────────────────────────────────────────────────────────────┐
│ CodePipeline Flow │
│ │
│ Source Stage Build Stage Test Stage Deploy Stage │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │CodeCommit│──S3──► │CodeBuild │─S3─►│CodeBuild │─S3►│CodeDeploy│ │
│ │ GitHub │artifact│ │artif│ Device │artif│ EB │ │
│ │ S3 │ │ Jenkins │ │ Farm │ │ ECS │ │
│ │ ECR │ └──────────┘ └──────────┘ └──────────┘ │
│ └──────────┘ │
│ ↑ │
│ Trigger: commit to │
│ configured branch Artifacts passed between stages via S3 │
└─────────────────────────────────────────────────────────────────────┘
Stage providers by type:
| Stage Type | Providers |
|---|---|
| Source | CodeCommit, GitHub, Bitbucket, ECR (image push), S3 (object upload) |
| Build | CodeBuild, Jenkins |
| Test | CodeBuild, AWS Device Farm, 3rd-party test services |
| Deploy | CodeDeploy, Elastic Beanstalk, CloudFormation, ECS (standard), S3 |
| Invoke | Lambda, Step Functions |
| Approval | Manual approval action |
Artifacts:
Every stage produces an output artifact that is stored in an S3 bucket. The next stage receives this artifact as its input. This S3 bucket is created automatically by CodePipeline and should not be modified manually.
Triggering:
- CodeCommit source: Triggers via an EventBridge rule when a commit is pushed to the configured branch.
- S3 source: Triggers via EventBridge when an object is uploaded to the configured bucket/key.
- ECR source: Triggers via EventBridge when a new image is pushed.
Critical Exam Trap: A CodePipeline configured with a CodeCommit source will only trigger when a commit is made to the specific branch configured as the source. Commits to other branches are ignored. This is the most common reason a pipeline does not trigger after a code push.
5.2 Manual Approval & Notifications
Manual Approval Action:
Adds a human gate to the pipeline. Execution pauses at the approval step and an SNS notification is sent. A designated approver can approve or reject in the console or via the CLI.
Pipeline pauses at Approval step
→ SNS notification sent to approvers (email, Lambda, etc.)
→ Approver reviews the change (deployment package, test results)
→ Approver clicks Approve or Reject in the console
→ Pipeline continues (Approve) or stops (Reject)
Failure Notifications:
Pipeline stage fails
→ EventBridge catches the pipeline state change event
→ SNS topic → email/Slack notification to development team
→ Lambda → automated incident response
Auditing:
- CloudTrail logs all CodePipeline API calls, including who approved or rejected manual approval actions.
- EventBridge detects real-time state changes (stage started, succeeded, failed).
6. AWS CloudFormation
CloudFormation provides Infrastructure as Code (IaC) for AWS. You declare the desired state of your infrastructure in a template file (YAML or JSON), and CloudFormation creates, updates, and deletes resources to match that state. The service is free — you pay only for the resources it creates.
6.1 Template Structure & Sections
AWSTemplateFormatVersion: "2010-09-09" # Always this exact value
Description: "Production VPC and Application Stack"
Parameters: # User-supplied inputs at deploy time
Mappings: # Static lookup tables (hardcoded values)
Conditions: # Logic to conditionally create resources
Resources: # MANDATORY — the AWS resources to create
Outputs: # Values to export or display after deployment
Critical:
Resourcesis the only mandatory section in a CloudFormation template. All other sections are optional.AWSTemplateFormatVersionmust always be"2010-09-09"— no other value is valid.
Parameters — dynamic inputs:
Parameters:
EnvironmentType:
Type: String
Default: dev
AllowedValues: [dev, staging, prod]
Description: "Deployment target environment"
DatabasePassword:
Type: String
NoEcho: true # value masked in console output and CloudFormation events
MinLength: 12
ConstraintDescription: "Must be at least 12 characters"
Mappings — static lookup tables:
Mappings:
RegionToAMI:
us-east-1:
AmazonLinux2: ami-0abcdef1234567890
us-west-2:
AmazonLinux2: ami-0fedcba9876543210
Resources:
WebServer:
Type: AWS::EC2::Instance
Properties:
# FindInMap[MapName, TopLevelKey, SecondLevelKey]
ImageId: !FindInMap [RegionToAMI, !Ref "AWS::Region", AmazonLinux2]
Best Practice: Use Mappings for values that differ by region or environment but are known in advance. Use Parameters for values that need to be supplied by the user at deploy time.
Conditions — conditional resource creation:
Conditions:
IsProduction: !Equals [!Ref EnvironmentType, prod]
IsNotProduction: !Not [!Condition IsProduction]
Resources:
ProductionDatabase:
Type: AWS::RDS::DBInstance
Condition: IsProduction # only created in production
Properties: ...
DevDatabase:
Type: AWS::RDS::DBInstance
Condition: IsNotProduction # only created in non-production
Properties: ...
6.2 Intrinsic Functions & Pseudo Parameters
Commonly used intrinsic functions:
| Function | YAML Shorthand | What It Returns |
|---|---|---|
Fn::Ref |
!Ref |
For a parameter: its value. For a resource: its physical ID (e.g., EC2 instance ID, S3 bucket name). |
Fn::GetAtt |
!GetAtt |
A specific attribute of a resource (e.g., !GetAtt MyBucket.Arn, !GetAtt MyDB.Endpoint.Address) |
Fn::FindInMap |
!FindInMap |
A value from a Mappings table by key path |
Fn::ImportValue |
!ImportValue |
An exported Output value from another CloudFormation stack |
Fn::Sub |
!Sub |
String interpolation — substitutes ${VarName} with values |
Fn::Join |
!Join |
Concatenates values with a delimiter |
Fn::Base64 |
!Base64 |
Base64-encodes a string — required for EC2 UserData |
Fn::If |
!If |
Returns one of two values based on a Condition |
Pseudo parameters (always available, no declaration needed):
| Parameter | Returns |
|---|---|
AWS::AccountId |
The AWS account ID: 123456789012 |
AWS::Region |
The current region: us-east-1 |
AWS::StackName |
The name of the current CloudFormation stack |
AWS::StackId |
The full ARN of the current stack |
AWS::NoValue |
Removes the property when used in a Condition — acts as null |
Cross-stack references (Outputs + ImportValue):
# Stack 1 — Network stack exports the VPC ID
Outputs:
VPCId:
Value: !Ref MyVPC
Export:
Name: !Sub "${AWS::StackName}-VPC-ID" # must be unique in the region
# Stack 2 — Application stack imports the VPC ID
Resources:
AppSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !ImportValue "NetworkStack-VPC-ID"
Critical: You cannot delete a stack whose Outputs are currently imported by another stack. The consuming stack must be deleted or updated first.
6.3 Change Sets, DeletionPolicy & Rollbacks
Change Sets — safe preview before deployment:
# Step 1: Create the change set (shows what will change — does not execute)
aws cloudformation create-change-set \
--stack-name MyProductionStack \
--change-set-name v2-changes \
--template-body file://template.yaml
# Step 2: Review the change set in the console or via CLI
# Step 3: Execute when ready
aws cloudformation execute-change-set \
--stack-name MyProductionStack \
--change-set-name v2-changes
DeletionPolicy — protect resources from accidental deletion:
| Policy | Behavior | Default? |
|---|---|---|
Delete |
Resource is deleted when the stack or resource is removed from the template | Yes — this is the default |
Retain |
Resource is kept; CloudFormation removes only the stack reference | No |
Snapshot |
A final snapshot is taken before deletion | No — only for supported services |
Snapshot is supported for: EBS volumes, RDS DB instances, RDS DB clusters, ElastiCache clusters, Redshift clusters, Neptune clusters, DocumentDB clusters.
Critical: Deleting a CloudFormation stack that contains an S3 bucket will fail if the bucket is not empty (DeletionPolicy
Deleteon a non-empty bucket). Use a Custom Resource backed by a Lambda function to empty the bucket before the stack deletion proceeds.
Rollback behavior:
- Stack creation failure: By default, CloudFormation rolls back and deletes all resources created so far.
- Stack update failure: CloudFormation rolls back to the last known stable state.
- Stuck rollback: If a rollback itself gets stuck (e.g., due to a manual resource change), use
ContinueUpdateRollbackto retry.
aws cloudformation continue-update-rollback --stack-name MyStack
Capabilities — required for IAM resource creation:
| Capability | When Required |
|---|---|
CAPABILITY_IAM |
Template creates unnamed IAM resources |
CAPABILITY_NAMED_IAM |
Template creates named IAM resources (e.g., an IAM Role with a specific name) |
CAPABILITY_AUTO_EXPAND |
Template uses CloudFormation Macros or includes nested stacks |
Without the required capability: InsufficientCapabilitiesException.
6.4 StackSets, Custom Resources & Dynamic References
StackSets — multi-account, multi-region deployment:
Administrator Account
└── Creates StackSet with template
└── Deploys Stack Instances to:
├── Account A / us-east-1
├── Account A / eu-west-1
├── Account B / us-east-1
└── Account C / ap-southeast-1
- Only the Administrator account (or a Delegated Admin) can create and manage StackSets.
- Updates to the StackSet propagate to all Stack Instances automatically.
- Common use: deploy a security baseline, logging configuration, or IAM roles across an entire AWS Organization.
Custom Resources — extend CloudFormation beyond native resources:
Resources:
EmptyBucketBeforeDelete:
Type: Custom::S3BucketEmptier
Properties:
ServiceToken: !GetAtt BucketEmptierLambda.Arn # same region as stack
BucketName: !Ref MyS3Bucket
Common custom resource use cases:
- Empty an S3 bucket before stack deletion (native Delete on non-empty bucket fails).
- Provision third-party or on-premises resources not supported by CloudFormation.
- Run custom validation during create/update/delete operations.
Dynamic References — resolve external values at deployment time:
Resources:
MyRDSInstance:
Type: AWS::RDS::DBInstance
Properties:
# Resolve from SSM Parameter Store (plaintext)
DBInstanceClass: "{{resolve:ssm:/myapp/db-instance-class:1}}"
# Resolve from SSM Parameter Store (SecureString — encrypted)
MasterUsername: "{{resolve:ssm-secure:/myapp/db-username:1}}"
# Resolve from Secrets Manager
MasterUserPassword: "{{resolve:secretsmanager:myapp-db-secret:SecretString:password}}"
7. AWS SAM — Serverless Application Model
SAM is an open-source framework that extends CloudFormation with simplified syntax specifically for serverless applications. A SAM template is a CloudFormation template with additional shorthand resource types. During deployment, the SAM Transform macro expands these into standard CloudFormation resources.
7.1 SAM Template Anatomy
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31 # Mandatory — signals the SAM macro
Description: My Serverless API
Globals:
Function:
Runtime: python3.12
Timeout: 30
MemorySize: 512
Environment:
Variables:
TABLE_NAME: !Ref OrdersTable
Resources:
OrdersApi:
Type: AWS::Serverless::Api
Properties:
StageName: prod
Auth:
DefaultAuthorizer: MyCognitoAuthorizer
Authorizers:
MyCognitoAuthorizer:
UserPoolArn: !GetAtt UserPool.Arn
CreateOrderFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/create_order.handler
CodeUri: src/
Events:
ApiEvent:
Type: Api
Properties:
RestApiId: !Ref OrdersApi
Path: /orders
Method: POST
SQSEvent:
Type: SQS
Properties:
Queue: !GetAtt OrderQueue.Arn
BatchSize: 5
OrdersTable:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: orderId
Type: String
SAM resource shorthand:
| SAM Resource Type | Expands To (CloudFormation) |
|---|---|
AWS::Serverless::Function |
Lambda Function + IAM Execution Role + all Event Source Mappings |
AWS::Serverless::Api |
API Gateway REST API + Deployment + Stage |
AWS::Serverless::HttpApi |
API Gateway HTTP API + Stage |
AWS::Serverless::SimpleTable |
DynamoDB Table with on-demand capacity |
AWS::Serverless::StateMachine |
Step Functions State Machine + IAM Role |
AWS::Serverless::LayerVersion |
Lambda Layer Version |
AWS::Serverless::Application |
A reference to a Serverless Application Repository app |
Critical:
Transform: AWS::Serverless-2016-10-31is mandatory. Without it, CloudFormation does not invoke the SAM macro and will fail to recognize SAM resource types, returningINVALID_CHANGE_SET_STATUS.
7.2 SAM CLI Commands
| Command | Purpose |
|---|---|
sam init |
Scaffold a new project from an AWS-provided or custom template |
sam build |
Compile code and install dependencies into the .aws-sam/ build directory |
sam local invoke "FunctionName" |
Invoke a Lambda function once locally using Docker |
sam local invoke -e event.json "FunctionName" |
Invoke with a specific JSON event payload |
sam local start-api |
Start a local HTTP server simulating API Gateway + Lambda |
sam local start-lambda |
Start a local Lambda endpoint (for SDK-based testing) |
sam local generate-event s3 put |
Generate a sample S3 PutObject event payload for testing |
sam validate |
Validate the SAM template syntax |
sam package |
Zip Lambda code and upload to S3; output a transformed CloudFormation template |
sam deploy |
Deploy using CloudFormation (creates or updates the stack) |
sam deploy --guided |
Interactive wizard; saves settings to samconfig.toml |
sam logs -n FunctionName --tail |
Stream CloudWatch Logs in real time |
sam sync --code |
Hot-swap code changes directly to Lambda — bypasses CloudFormation, completes in seconds |
sam sync --watch |
Watch for file changes and automatically sync code |
Key Concept:
sam deploy --guidedcreates asamconfig.tomlfile storing deployment settings. Subsequentsam deploycommands without--guideduse this file automatically.
Key Concept:
sam sync --codeis a critical time-saver during development. It updates Lambda function code directly without running through a full CloudFormation stack update. Use it for iterative code changes.
7.3 SAM + CodeDeploy Traffic Shifting
SAM can automatically configure CodeDeploy for gradual Lambda traffic shifting:
CreateOrderFunction:
Type: AWS::Serverless::Function
Properties:
AutoPublishAlias: live # automatically creates and updates a "live" alias
DeploymentPreference:
Type: Canary10Percent10Minutes # shift 10% of traffic; full shift after 10 min
Alarms:
- !Ref FunctionErrorAlarm # auto-rollback if this alarm fires
Hooks:
PreTraffic: !Ref PreTrafficHook # Lambda runs BEFORE traffic shifts
PostTraffic: !Ref PostTrafficHook # Lambda runs AFTER traffic shifts
Available DeploymentPreference types:
Canary10Percent5Minutes,Canary10Percent10Minutes,Canary10Percent15Minutes,Canary10Percent30MinutesLinear10PercentEvery1Minute,Linear10PercentEvery2Minutes,Linear10PercentEvery3Minutes,Linear10PercentEvery10MinutesAllAtOnce
8. Lambda Deployment Patterns
8.1 Versions, Aliases & Package Limits
Versions:
$LATESTis the mutable working copy. All code and configuration changes take effect immediately on$LATEST.- Publishing creates an immutable snapshot (
1,2,3, etc.). Code and configuration are frozen and cannot change. - Each version has a unique ARN:
arn:aws:lambda:us-east-1:123:function:MyFunc:3
Aliases:
- A named pointer to a specific version. The alias ARN does not change even when the pointer is updated.
- Cannot point to another alias — only to numbered versions or
$LATEST. - Supports weighted traffic routing for gradual canary rollouts.
PROD alias → 95% V4 + 5% V5 (canary rollout in progress)
STAGING alias → V5 (full testing in staging)
DEV alias → $LATEST (latest uncommitted changes)
API Gateway stage variable: ${stageVariables.lambdaAlias}
→ No API Gateway changes needed when Lambda version is updated
Updating Lambda code via CLI:
# Upload new code (Lambda does NOT auto-detect S3 changes)
aws lambda update-function-code \
--function-name my-function \
--s3-bucket my-artifacts-bucket \
--s3-key my-function.zip
# Publish an immutable version from $LATEST
aws lambda publish-version --function-name my-function
# Update the PROD alias to point to the new version
aws lambda update-alias \
--function-name my-function \
--name PROD \
--function-version 5
Critical: If you upload a new ZIP to the same S3 key and trigger a CloudFormation stack update, Lambda will NOT pick up the new code unless the
S3KeyorS3ObjectVersionin the CloudFormation template has also changed. Update one of these values to force a redeployment.
Package size limits:
- Compressed ZIP: 50 MB (direct upload) or 250 MB from S3.
- Unzipped: 250 MB hard limit — AWS Support cannot increase this.
- Fix for > 250 MB: split into smaller functions, use Lambda Layers for shared libraries, or deploy as a container image (up to 10 GB from ECR).
9. ECS & EC2 Deployment Patterns
ECS Rolling Update:
- Controlled via
minimumHealthyPercentandmaximumPercentin the ECS service configuration. - Example:
minimumHealthyPercent=100,maximumPercent=200— launch new tasks before stopping old ones. - Example:
minimumHealthyPercent=50,maximumPercent=100— stop half first, then start new tasks.
ECS Blue/Green via CodeDeploy:
- Requires an ALB with two target groups.
- CodeDeploy shifts traffic between target groups using the chosen strategy.
- On deployment, new tasks are registered to the green target group and traffic is shifted over.
EC2 ASG Instance Refresh:
Rolls out a new AMI or Launch Template configuration across an Auto Scaling Group without manual intervention.
aws autoscaling start-instance-refresh \
--auto-scaling-group-name MyASG \
--preferences MinHealthyPercentage=80,InstanceWarmup=300
Lifecycle Hooks for zero-downtime deployments:
Scale-Out Event:
1. New instance launches → state: Pending:Wait
2. Custom script runs (install monitoring agent, register with load balancer)
3. CompleteLifecycleAction CONTINUE → instance enters InService
Scale-In Event:
1. Instance selected for termination → state: Terminating:Wait
2. Custom script runs (deregister, drain connections, backup logs)
3. CompleteLifecycleAction CONTINUE → instance terminated
10. AWS CodeArtifact
CodeArtifact is a fully managed artifact repository that works with standard package managers (npm, pip, Maven, NuGet, Gradle, Swift).
Key capabilities:
- Proxies public repositories (npmjs.com, PyPI, Maven Central) — packages are cached on first download.
- Your organization can approve or block specific package versions for governance.
- Teams across VPCs and accounts can share internal packages.
- EventBridge integration: trigger pipelines when package versions are published, modified, or deleted.
# Configure npm to use CodeArtifact
aws codeartifact login --tool npm --domain my-domain --repository my-repo
# Configure pip to use CodeArtifact
aws codeartifact login --tool pip --domain my-domain --repository my-repo
11. Deployment Strategy Comparison
| Strategy | Downtime | Cost Overhead | Rollback Speed | Risk Level |
|---|---|---|---|---|
| All at Once | Yes | None | Slow — full redeploy | High |
| Rolling | No — partial capacity reduction | None | Slow — redeploy to instances | Medium |
| Rolling + Additional Batch | No — full capacity maintained | Low — temporary extra instances | Slow — redeploy required | Low–Medium |
| Immutable | No | High — double instances during deploy | Fast — terminate new ASG | Low |
| Blue/Green | No | High — two full environments | Fast — swap DNS/CNAME back | Very Low |
| Canary / Linear | No | Medium | Fast — abort traffic shift | Very Low |
Which service uses which patterns:
| Service | Deployment Options | Notes |
|---|---|---|
| Elastic Beanstalk | All at once, Rolling, Rolling+batch, Immutable, Blue/Green | Blue/Green requires manual CNAME swap |
| CodeDeploy (EC2) | AllAtOnce, HalfAtATime, OneAtATime, Custom | In-place only |
| CodeDeploy (Lambda) | AllAtOnce, Canary, Linear | Traffic shifting via alias |
| CodeDeploy (ECS) | AllAtOnce, Canary, Linear | Blue/Green only — requires ALB |
| ECS Service Update | Rolling (MinHealthy/MaxPercent) | Built-in, no CodeDeploy needed |
12. Exam Tips & Quick Reference
Scenario-to-Answer Mapping
| Scenario Keyword / Requirement | Correct Answer |
|---|---|
| "Deploy without managing infrastructure" | AWS Elastic Beanstalk |
| "Deploy to EC2 and on-premises servers" | AWS CodeDeploy (only CI/CD service with on-prem support) |
| "EB: fastest deploy, downtime OK, dev environment" | Elastic Beanstalk All at once |
| "EB: full capacity maintained, use existing instances" | Rolling with additional batch |
| "EB: zero downtime, fastest rollback" | Immutable deployment |
| "EB: incompatible versions cannot run together" | Blue/Green (new environment + CNAME swap) |
| "EB config file not being processed" | File must have .config extension in .ebextensions/ directory |
| "EB package deployment fails" | Must be a .zip file — .tar is not supported |
| "RDS deleted when EB environment terminated" | RDS was created inside the EB environment — create it separately for production |
| "buildspec.yml not found by CodeBuild" | Must be at root of source code repository |
| "Secrets in buildspec.yml" | Use env.parameter-store or env.secrets-manager — never env.variables |
| "CodeBuild cannot access private RDS" | Configure VPC settings in the CodeBuild project |
| "CodeDeploy: change file permissions after deployment" | AfterInstall lifecycle hook |
| "CodeDeploy: health check after app starts" | ValidateService lifecycle hook (last hook — failure triggers rollback) |
| "CodeDeploy rollback mechanism" | New deployment with previous revision — not an undo |
| "ECS deployment type via CodeDeploy" | Blue/Green only — requires ALB |
| "Lambda CodeDeploy deployment" | Alias traffic shifting (CurrentVersion + TargetVersion in appspec.yml) |
| "Manual gate before production deployment" | CodePipeline Manual Approval action |
| "Pipeline failure notification" | EventBridge → SNS topic |
| "Pipeline not triggered after code push" | Commit was not on the configured source branch |
| "SAM deploy order" | sam build → sam package → sam deploy |
| "Iterate Lambda code changes fast without CloudFormation" | sam sync --code |
| "Lambda not picking up new S3 code upload" | Update S3Key or S3ObjectVersion in CloudFormation template |
| "CF: only mandatory section" | Resources |
| "CF: AMI ID per region" | Use Mappings with !FindInMap and AWS::Region pseudo parameter |
| "CF: preview what will change before deploying" | Create a Change Set, review it, then execute |
| "CF: protect RDS from stack deletion" | DeletionPolicy: Snapshot or DeletionPolicy: Retain |
| "CF: S3 bucket delete fails" | Bucket is not empty — use Custom Resource (Lambda) to empty first |
| "CF: IAM named resources require" | CAPABILITY_NAMED_IAM |
| "CF: share value between stacks" | Output with Export + !ImportValue in consuming stack |
| "CF: deploy to 50 accounts and 5 regions" | CloudFormation StackSets |
| "SAM Transform header" | Transform: AWS::Serverless-2016-10-31 — mandatory |
Common Traps
- EB Blue/Green is not a native deployment type: It is implemented by creating a second environment and swapping CNAMEs. You cannot select Blue/Green in the EB deployment policy dropdown — it requires manual environment management.
- appspec.yml vs buildspec.yml:
buildspec.ymlis for CodeBuild (build instructions).appspec.ymlis for CodeDeploy (deployment instructions). Both must be at the root of their respective bundles. - CodeDeploy rollback is a new deployment: Rolling back does not restore files to their previous state — CodeDeploy creates a brand new deployment using the last known good application revision.
- ECS CodeDeploy is Blue/Green only: ECS does not support in-place deployments via CodeDeploy. Blue/Green requires an ALB with two target groups.
- Lambda does not auto-detect S3 changes: Uploading a new ZIP to the same S3 key does not trigger a Lambda update. You must call
update-function-codeor update the CloudFormation template with a newS3Key/S3ObjectVersion. - CloudFormation does not recognize SAM types without Transform: If
Transform: AWS::Serverless-2016-10-31is missing, CloudFormation returns an error stating the resource type is unknown. - Pipeline source branch matters: CodePipeline only triggers on commits to the branch explicitly configured in the source stage. A commit to
feature-branchwill not trigger a pipeline configured to watchmain. - DeletionPolicy default is Delete: Unless you explicitly set
RetainorSnapshot, CloudFormation deletes all resources when the stack is deleted — including production databases.
Key Terms — Domain 3
| Term | One-Line Definition |
|---|---|
| Elastic Beanstalk | PaaS that deploys and manages applications without infrastructure management |
| buildspec.yml | CodeBuild's build specification file — defines phases, env vars, artifacts, and cache |
| appspec.yml | CodeDeploy's deployment specification — defines file placements and lifecycle hook scripts |
| Lifecycle Hook (CodeDeploy) | A named event in the EC2 deployment sequence where custom scripts can run |
| ValidateService | The final CodeDeploy lifecycle hook — used to confirm deployment health; failure triggers rollback |
| Blue/Green Deployment | Running two identical environments and switching traffic between them for zero-downtime deploys |
| Canary Deployment | Gradually shifting traffic to a new version (e.g., 10% → 100%) to validate before full rollout |
| CloudFormation Change Set | A preview of proposed stack changes before they are executed — shows additions, modifications, deletions |
| DeletionPolicy | CloudFormation resource attribute controlling what happens to a resource when the stack is deleted |
| StackSet | CloudFormation feature for deploying a single template across multiple accounts and regions |
| SAM Transform | CloudFormation macro (AWS::Serverless-2016-10-31) that expands SAM shorthand into full resources |
| sam sync --code | SAM CLI command that hot-swaps Lambda code directly, bypassing CloudFormation for speed |
| CodeArtifact | Managed artifact repository — proxies and caches packages from public repositories |
| Instance Refresh | ASG feature that rolls out a new Launch Template configuration across the fleet |
| Event Source Mapping | Lambda configuration connecting a polling source (SQS, Kinesis, DynamoDB Streams) to a function |
End of Domain 3: Deployment. Continue to Domain 4: Troubleshooting and Optimization →
Ready to test yourself?
Practice questions for this topic