Exam Guide: Developer – Associate
ποΈ Domain 3: Deployment
π Task 4: Deploy Code By Using AWS Continuous Integration And Continuous Delivery (CI/CD) Services
This task tests your ability to build and manage CI/CD pipelines using AWS developer tools. You need to understand how CodeCommit, CodeBuild, CodeDeploy, and CodePipeline work together, how to write buildspec and appspec files, how deployment strategies differ, and how to configure automatic rollbacks. Deployment strategies for Lambda and EC2, SAM deployment preferences, and pipeline orchestration.
π Concepts
AWS CI/CD Pipeline Overview
The four AWS developer tools form a complete CI/CD pipeline:
Service Role Input Output CodeCommit Source control Git push Source artifact CodeBuild Build and test Source artifact Build artifact CodeDeploy Deploy Build artifact Running application CodePipeline Orchestration Trigger (push, schedule) Coordinated pipeline executionHow they connect:
CodeCommit (source) β CodeBuild (build/test) β CodeDeploy (deploy)
β |
βββββββββ CodePipeline (orchestrates all) ββββββ
Enter fullscreen mode Exit fullscreen mode
π‘CodePipeline is the orchestrator. It doesn’t build or deploy anything itself. It connects stages (source, build, test, deploy) and manages transitions between them. Each stage can use different providers (GitHub instead of CodeCommit, Jenkins instead of CodeBuild, etc.).
CodeCommit Fundamentals
Feature Details What It Is Managed Git repository hosted in AWS Authentication HTTPS (Git credentials or credential helper) or SSH (SSH keys) Encryption Encrypted at rest (AWS managed keys) and in transit (HTTPS/SSH) Triggers SNS notifications or Lambda functions on repository events Cross-account Use IAM roles withAssumeRole for cross-account access
Branching
Standard Git branching: main, develop, feature branches
π‘CodeCommit supports triggers for push events that can invoke Lambda functions or send SNS notifications. This is different from CodePipeline’s source stage: triggers are repository-level events, while CodePipeline polls or uses CloudWatch Events to detect changes.
CodeBuild buildspec.yml Structure
The buildspec file tells CodeBuild what to do. It has four phases:
version: 0.2
env:
variables:
ENV_NAME: "production"
parameter-store:
DB_PASSWORD: "/myapp/db-password"
secrets-manager:
API_KEY: "myapp/api-key:API_KEY"
phases:
install:
runtime-versions:
python: 3.13
commands:
- pip install -r requirements.txt
pre_build:
commands:
- echo "Running tests..."
- python -m pytest tests/ -v
build:
commands:
- echo "Building..."
- sam build
post_build:
commands:
- echo "Packaging..."
- sam package --s3-bucket my-bucket --output-template-file packaged.yaml
artifacts:
files:
- packaged.yaml
- appspec.yml
discard-paths: yes
cache:
paths:
- '/root/.cache/pip/**/*'
reports:
test-reports:
files:
- "**/*.xml"
base-directory: test-results
Enter fullscreen mode Exit fullscreen mode
Phase
When It Runs
Typical Use
install
First
Install dependencies, runtime versions
pre_build
Before build
Run tests, log in to ECR, lint code
build
Main phase
Compile code, run SAM build, create artifacts
post_build
After build
Package artifacts, push images, notifications
Section
Purpose
env.variables
Plain text environment variables
env.parameter-store
Values pulled from SSM Parameter Store at build time
env.secrets-manager
Values pulled from Secrets Manager at build time
artifacts
Files to pass to the next pipeline stage
cache
Paths to cache between builds (speeds up installs)
reports
Test report files for CodeBuild report groups
π‘The
buildspecfile must be namedbuildspec.ymland placed in the root of your source directory (unless you override the name in the CodeBuild project settings).The
envsection can pull secrets from Parameter Store and Secrets Manager. This is the secure way to use credentials in builds. Never hardcode secrets in the buildspec.
CodeDeploy appspec.yml Structure
The appspec file tells CodeDeploy how to deploy your application. The structure differs by compute platform:
For Lambda:
version: 0.0
Resources:
- MyFunction:
Type: AWS::Lambda::Function
Properties:
Name: my-function
Alias: prod
CurrentVersion: 1
TargetVersion: 2
Hooks:
- BeforeAllowTraffic: PreTrafficCheckFunction
- AfterAllowTraffic: PostTrafficCheckFunction
Enter fullscreen mode Exit fullscreen mode
For EC2/On-Premises:
version: 0.0
os: linux
files:
- source: /
destination: /var/www/html
permissions:
- object: /var/www/html
owner: www-data
group: www-data
mode: "755"
hooks:
BeforeInstall:
- location: scripts/before_install.sh
timeout: 300
AfterInstall:
- location: scripts/after_install.sh
timeout: 300
ApplicationStart:
- location: scripts/start_server.sh
timeout: 300
ValidateService:
- location: scripts/validate.sh
timeout: 300
Enter fullscreen mode Exit fullscreen mode
CodeDeploy Lifecycle Hooks
Lambda Deployment Hooks:
Hook
When It Runs
Purpose
BeforeAllowTraffic
Before traffic shifts to new version
Run validation tests against the new version
AfterAllowTraffic
After traffic shifts to new version
Run integration tests, verify health
EC2 Deployment Hooks (in order):
Hook
When It Runs
Purpose
BeforeInstall
Before files are copied
Clean up old files, stop services
AfterInstall
After files are copied
Configure app, set permissions
ApplicationStart
After AfterInstall
Start services, warm up
ValidateService
After ApplicationStart
Health checks, smoke tests
BeforeBlockTraffic
Before deregistering from ELB
Graceful connection draining
AfterBlockTraffic
After deregistering from ELB
Run tasks while instance is out of service
BeforeAllowTraffic
Before registering with ELB
Final checks before receiving traffic
AfterAllowTraffic
After registering with ELB
Verify instance is healthy in ELB
π‘ For Lambda deployments, the hooks are Lambda functions themselves: they run your validation code and must return
SucceededorFailedto CodeDeploy.For EC2, hooks are shell scripts that run on the instance.
If a hook fails (the deployment rolls back).
Deployment Strategies Comparison
Know each strategy of by heart:
Strategy
How It Works
Downtime
Rollback Speed
Risk
Best For
AllAtOnce
Deploy to all instances simultaneously
Brief
Redeploy previous version
High: all instances affected
Dev/test environments
Rolling
Deploy in batches (one batch at a time)
None (if batch size < total)
Redeploy previous version
Medium: one batch at a time
EC2 fleets with ELB
Rolling with additional batch
Adds new instances before removing old ones
None
Redeploy previous version
Low: maintains full capacity
Production EC2 fleets
Blue/Green
Create entirely new environment, switch traffic
None
Switch back to blue
Low
Production with zero downtime
Canary
Shift X% traffic, wait, then shift 100%
None
Shift back to 0%
Low: limited blast radius
Lambda, API Gateway
Linear
Shift X% every N minutes
None
Shift back to 0%
Low: gradual exposure
Lambda, API Gateway
SAM DeploymentPreference Types
SAM automates Lambda deployment strategies through CodeDeploy:
Type
Traffic Shift Pattern
Example
AllAtOnce
100% immediately
Instant cutover
Canary10Percent5Minutes
10% for 5 min, then 100%
Quick canary validation
Canary10Percent10Minutes
10% for 10 min, then 100%
Longer canary validation
Canary10Percent15Minutes
10% for 15 min, then 100%
Extended canary validation
Canary10Percent30Minutes
10% for 30 min, then 100%
Conservative canary
Linear10PercentEvery1Minute
+10% every minute (10 min total)
Fast linear rollout
Linear10PercentEvery2Minutes
+10% every 2 min (20 min total)
Moderate linear rollout
Linear10PercentEvery3Minutes
+10% every 3 min (30 min total)
Slow linear rollout
Linear10PercentEvery10Minutes
+10% every 10 min (100 min total)
Very conservative rollout
SAM Template Example:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: python3.13
AutoPublishAlias: live
DeploymentPreference:
Type: Canary10Percent5Minutes
Alarms:
- !Ref MyFunctionErrorAlarm
Hooks:
PreTraffic: !Ref PreTrafficHookFunction
PostTraffic: !Ref PostTrafficHookFunction
Enter fullscreen mode Exit fullscreen mode
π‘
AutoPublishAliasis required forDeploymentPreferenceto work. SAM automatically publishes a new version on each deploy and updates the alias. TheAlarmssection triggers automatic rollback if any alarm enters ALARM state during deployment. Canary shifts traffic in two steps (X% then 100%), while Linear shifts in equal increments.
API Gateway Stages and Custom Domains
Concept What It Is Use Case Stage A named reference to a deployment (dev, staging, prod) Environment separation Stage Variables Key-value pairs available in the stage Point to different Lambda aliases per stage Canary Release Split traffic between current and canary deployment Test new API version with real traffic Custom Domain Map your domain to API Gatewayapi.example.com instead of xyz.execute-api.region.amazonaws.com
Base Path Mapping
Map URL paths to different APIs
/v1 β API v1, /v2 β API v2
Stage Variables For Lambda Integration:
Stage: prod β stageVariables.lambdaAlias = "prod"
Stage: dev β stageVariables.lambdaAlias = "dev"
Lambda ARN: arn:aws:lambda:region:account:function:name:${stageVariables.lambdaAlias}
Enter fullscreen mode Exit fullscreen mode
API Gateway Canary Settings:
Setting Description Canary Percentage % of traffic routed to canary deployment (0-100) Stage Variable Overrides Different stage variables for canary traffic Promote Canary Move canary deployment to production Delete Canary Remove canary and keep current productionπ‘API Gateway stages are not the same as Lambda aliases, but they work together. Use stage variables to point each stage to the corresponding Lambda alias.
A common pattern: API Gateway prod stage β stage variable lambdaAlias=prod β Lambda function prod alias β version 5.
Rollback Strategies
Rollback Type How It Works When It Triggers Automatic (alarm-based) CodeDeploy monitors CloudWatch alarms during deployment Alarm enters ALARM state Automatic (hook failure) CodeDeploy rolls back if a lifecycle hook fails Hook returnsFailed
Manual
You stop the deployment and roll back
You detect an issue
SAM Automatic
SAM configures CodeDeploy with alarms from DeploymentPreference
Configured alarm triggers
CloudWatch Alarm For Automatic Rollback:
Metric
Threshold
Purpose
Errors
> 0 for 1 minute
Catch any Lambda errors
Duration
> timeout * 0.8 for 5 minutes
Catch performance degradation
Throttles
> 0 for 1 minute
Catch concurrency issues
5XXError (API GW)
> 1% for 5 minutes
Catch server errors
π‘Automatic rollback with CloudWatch alarms is the recommended approach for production deployments.
SAM makes this easy: just add the
Alarmslist toDeploymentPreference.CodeDeploy monitors the alarms during the deployment window. If any alarm fires, it automatically shifts all traffic back to the previous version. The rollback is fast because it just updates the alias pointer.
Pre/Post Traffic Hooks
Traffic hooks are Lambda functions that validate your deployment:
PreTraffic Hook Pattern:
import boto3
import json
codedeploy = boto3.client('codedeploy')
def handler(event, context):
deployment_id = event['DeploymentId']
lifecycle_event_hook_execution_id = event['LifecycleEventHookExecutionId']
# Run your validation tests here
try:
# Example: invoke the new version and check the response
lambda_client = boto3.client('lambda')
response = lambda_client.invoke(
FunctionName='my-function:live', # the alias
Payload=json.dumps({'test': True})
)
result = json.loads(response['Payload'].read())
if result.get('statusCode') == 200:
status = 'Succeeded'
else:
status = 'Failed'
except Exception:
status = 'Failed'
# Report back to CodeDeploy
codedeploy.put_lifecycle_event_hook_execution_status(
deploymentId=deployment_id,
lifecycleEventHookExecutionId=lifecycle_event_hook_execution_id,
status=status
)
Enter fullscreen mode Exit fullscreen mode
π‘ The PreTraffic hook runs before any traffic shifts to the new version: use it for smoke tests and validation.
The PostTraffic hook runs after all traffic has shifted: use it for integration tests.
Both hooks must call
put_lifecycle_event_hook_execution_statusto tell CodeDeploy whether to proceed or roll back.If a hook times out (default 1 hour), the deployment fails.
CodePipeline Concepts
Concept Description Pipeline The overall workflow definition Stage A logical group of actions (Source, Build, Deploy) Action A task within a stage (CodeBuild action, CodeDeploy action) Artifact Files passed between stages (stored in S3) Transition The link between stages (can be disabled to pause the pipeline) Approval action Manual approval gate before proceeding Pipeline Feature Details Trigger CloudWatch Events (push to CodeCommit), webhook (GitHub), S3 upload Cross-region Actions can deploy to different regions Cross-account Use IAM roles for cross-account deployments Parallel Actions Multiple actions in the same stage run in parallel Sequential stages Stages run in order. A stage must complete before the next startsπ‘ CodePipeline stores artifacts in an S3 bucket (created automatically or specified by you).
Each action produces output artifacts and consumes input artifacts.
If you need a manual approval before deploying to production, add an Approval action between the staging deploy and production deploy stages.
ποΈ Build A Complete CI/CD Pipeline
Build a Complete CI/CD Pipeline from scratch using the AWS Console.
- A CodeCommit repository with application code
- A CodeBuild project that runs tests and packages the application
- A CodePipeline that orchestrates source β build β deploy
- A Lambda function with canary deployment configured through SAM
- CloudWatch alarms for automatic rollback
- A working pipeline that triggers on code push
Prerequisites
Part I
Create A Github Repository And Add Code
π‘ Why GitHub instead of CodeCommit? AWS closed CodeCommit to new customers in July 2024. Even accounts that can create a CodeCommit repo often find it’s not offered as a CodePipeline source provider. GitHub via CodeConnections is the reliable, current, real-world source integration. And it’s fully supported by CodePipeline. CodeCommit, CodeBuild, CodeDeploy, and CodePipeline (If your account does offer CodeCommit and you’d rather use it, use it)
Step 01: Create the GitHub Repository
Go to GitHub β New β Repository name: cicd-demo-app β Choose Private (or Public)
β οΈ Don’t initialize with a README (we’ll push our own files)
Click Create repository
π‘ Prefer CodeCommit? If your account offers CodeCommit and it appears as a CodePipeline source provider, you can use it instead: create the repo in the CodeCommit console, generate Git credentials in IAM (Security credentials β API keys β Generate API key β AWS CodeCommit), attach the
AWSCodeCommitPowerUserpolicy to your user, then clone the HTTPS URL and push. HTTPS uses Git credentials. SSH uses an uploaded SSH key. Everything downstream (CodeBuild, CodePipeline, CodeDeploy) is identical. only the source provider changes.Step By Step Guide For Setting Up CodeCommit
Step 1: Open the CodeCommit console β Create repository
- Repository name:
cicd-demo-app- Description – optional:
Demo application for CI/CD pipelineClick Create
Step 2: Configure Git Credentials
π‘ CodeCommit HTTPS access uses Git credentials tied to your IAM user (a generated username/password, separate from your AWS access keys).
Step 3: Open the IAM console β IAM users β select your IAM userStep 4: Click the Security credentials tab
Step 5: In the API keys section, click Generate API key
Step 6: Service βΌ:
AWS CodeCommitClick Generate API key
Step 7: Retrieve API key
β οΈ Copy or download the username and password now: This is the only time the password is shown. If you lose it, you must reset it.Click Close
π‘ Git Credentials vs Access Keys. CodeCommit HTTPS uses a dedicated username/password (Git credentials), not your
AWS_ACCESS_KEY_ID. These are IAM-managed and require a CodeCommit policy likeAWSCodeCommitPowerUseron your user. HTTPS = Git credentials or the credential helper. SSH = an uploaded SSH public key.Step 8: Now attach a CodeCommit permissions policy to the same IAM user so it can actually use the repository.
Step 9: Still on the user’s page, go to the Permissions tab β Add permissions βΌ β Attach policies directly β search for and select
AWSCodeCommitPowerUserβ Next β Add permissions.Step 10: Clone And Add Application Code
git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/cicd-demo-app cd cicd-demo-app
python
Step 02: Add the Application Code Locally
mkdir cicd-demo-app
cd cicd-demo-app
git init
git branch -M main
Enter fullscreen mode Exit fullscreen mode
Step 03: Create the Lambda function code app.py
import json
VERSION = "1.0.0"
def lambda_handler(event, context):
"""Order API handler with version tracking."""
return {
'statusCode': 200,
'headers': {'Content-Type': 'application/json'},
'body': json.dumps({
'message': 'Order API is running',
'version': VERSION,
'functionVersion': context.function_version
})
}
Enter fullscreen mode Exit fullscreen mode
Step 04: Create the SAM template template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: CI/CD Demo Application
Globals:
Function:
Timeout: 10
Runtime: python3.13
Resources:
OrderFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.lambda_handler
CodeUri: .
AutoPublishAlias: live
DeploymentPreference:
Type: Canary10Percent5Minutes
Alarms:
- !Ref OrderFunctionErrorAlarm
OrderFunctionErrorAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Errors on OrderFunction
Namespace: AWS/Lambda
MetricName: Errors
Dimensions:
- Name: FunctionName
Value: !Ref OrderFunction
Statistic: Sum
Period: 60
EvaluationPeriods: 1
Threshold: 1
ComparisonOperator: GreaterThanOrEqualToThreshold
TreatMissingData: notBreaching
Enter fullscreen mode Exit fullscreen mode
Step 05: Create the buildspec buildspec.yml
version: 0.2
phases:
install:
runtime-versions:
python: 3.13
commands:
- pip install aws-sam-cli
build:
commands:
- sam build
post_build:
commands:
- sam package --s3-bucket ${ARTIFACT_BUCKET} --output-template-file packaged.yaml
artifacts:
files:
- packaged.yaml
Enter fullscreen mode Exit fullscreen mode
Step 06: Push the code
git add .
git commit -m "Initial application code"
Enter fullscreen mode Exit fullscreen mode
Step 07: Push to Github
git remote add origin `https://github.com/YOUR_USERNAME/cicd-demo-app.git`
git push -u origin main
Enter fullscreen mode Exit fullscreen mode
Part II
Set Up a CodeBuild Project
Step 01: Create an S3 Bucket for Artifacts
Open the S3 console β Create bucket β Account Regional namespace (recommended) β Bucket name: cicd-demo-artifacts
Keep defaults β Create bucket
Step 02: Create the CodeBuild Project
Open the CodeBuild console β Create project
Project configuration:
-
Project name:
cicd-demo-build -
Project type:
Default project
βΌ Source:
-
Source provider βΌ:
GitHub -
Repository:
Repository in my GitHub account -
Repository:
cicd-demo-app
β οΈ If you used CodeCommit instead of GitHub: Set Source provider to CodeCommit
βΌ Environment:
-
Provisioning model:
On-demand -
Environment image:
Managed image -
Compute:
EC2 -
Running mode:
Container -
Operating system:
Amazon Linux -
Runtime(s):
Standard -
Image:
aws/codebuild/amazonlinux-x86_64-standard:5.0 -
Image version:
Always use the latest image for this runtime version -
Service role:
New service role
βΆ Additional Configuration: β Environment variables:
-
Name:
ARTIFACT_BUCKETβ Value:your S3 bucket name
βΌ Buildspec:
-
Build specifications:
Use a buildspec file -
Buildspec name – optional:
buildspec.yml
βΌ Artifacts:
-
Type:
Amazon S3 -
Bucket name:
cicd-demo-artifacts-... -
Name:
build-output
Click Create build project
β οΈ Grant the CodeBuild role access to your artifact bucket.
The auto-created CodeBuild service role can write to CodeBuild’s default locations, but sam package uploads to your custom ARTIFACT_BUCKET, and the role won’t have permission by default.
If the build fails at post_build with an AccessDenied on S3:
Step 1: Go to IAM β Roles β the
codebuild-cicd-demo-build-service-role
Step 2: Add permissions β Attach policies β attachAmazonS3FullAccess(or a scoped inline policy allowings3:PutObject,s3:GetObject,s3:GetBucketLocationon your bucket)π‘ Also confirm your S3 bucket and CodeBuild project are in the same region
Step 03: Run a Test Build
Click Start build
β οΈ Watch the build logs in real time
Verify each phase completes: INSTALL β PRE_BUILD β BUILD β POST_BUILD
Check the S3 bucket for the packaged.yaml artifact
π‘ CodeBuild charges by the minute. Build environments are ephemeral. They’re created fresh for each build. Use the
cachesection in buildspec.yml to cache dependencies between builds and speed up subsequent builds. CodeBuild can also pull secrets from Parameter Store and Secrets Manager using theenvsection.
Part III
Create a CodePipeline
Step 01: Build the Pipeline
Step 01.1: Open the CodePipeline console β Create pipeline
Step 01.2: Choose creation option
-
Category:
Build custom pipeline
Click Next
Step 01.3: Choose Pipeline settings
-
Pipeline name:
cicd-demo-pipeline -
Execution mode:
queued - Service role: New service role
Click Next
Step 01.4: Add a source stage
-
Source provider βΌ:
GitHub (via GitHub App) - Connection: click Connect to GitHub β authorize the CodeConnections connection (reuse the one from CodeBuild if you already made it)
-
Repository name:
YOUR_USERNAME/cicd-demo-app -
Default branch:
main -
Output artifact format:
CodePipeline default
Click Next
π‘ CodeConnections. A connection is a reusable, managed OAuth link between AWS and GitHub (or Bitbucket/GitLab). CodePipeline uses it to detect pushes and pull source. No Git credentials or webhooks to manage yourself. The same connection works across CodePipeline and CodeBuild.
Step 01.5: Add build stage – optional
-
Build provider:
Other build providers -
βΌ
AWS CodeBuild -
Project name:
cicd-demo-build
Click Next
Step 01.6: Add test stage – optional
Click Next
Step 01.7: Add deploy stage
-
Deploy provider βΌ:
AWS CloudFormation -
Region:
United States (North Virginia) -
Input artifacts:
BuildArtifact -
Action mode:
Create or update a stack -
Stack name:
cicd-demo-app -
Artifact name:
BuildArtifact -
File name:
packaged.yaml -
Capabilities:
CAPABILITY_IAMCAPABILITY_AUTO_EXPAND - Role name: create/select a CloudFormation deployment role (see the warning below)
Click Next β Create pipeline
Step 02: Watch the Pipeline Execute
The pipeline starts automatically after creation
β οΈ Watch each stage transition: Source β Build β Deploy
Click on each stage to see details and logs
The deploy stage creates a CloudFormation stack with your Lambda function
Step 03: Add a Manual Approval Stage
Step 03.1: Click Edit on the pipeline
Step 03.2: Click Add stage between Build and Deploy
Step 03.3 Stage name: Approval
Click Add stage
Step 03.4: Click Add action group:
-
Action name:
ManualApproval -
Action provider:
Manual approval -
Click:
Done
Click Save
π‘Now the pipeline pauses at the Approval stage and waits for someone to approve before deploying.
Part IV
Configure Canary Deployment with Alarms
Step 01: Verify the Deployment Configuration
Open the CodeDeploy console β Applications
π‘ You should see a deployment group created by SAM (named something like
cicd-demo-app-ServerlessDeploymentApplication-*)
Click on it to see the deployment configuration: CodeDeployDefault.LambdaCanary10Percent5Minutes
Step 02: View the CloudWatch Alarm
Open the CloudWatch console β Alarms
π‘ Find the
OrderFunctionErrorAlarmcreated by the SAM template
It should be in OK state (no errors yet)
Step 03: Trigger a Deployment
Step 03.1: Update app.py locally
import json
VERSION = "2.0.0"
def lambda_handler(event, context):
"""Order API handler v2 β added health check."""
action = event.get('action', 'default')
if action == 'health':
return {
'statusCode': 200,
'body': json.dumps({'status': 'healthy', 'version': VERSION})
}
return {
'statusCode': 200,
'headers': {'Content-Type': 'application/json'},
'body': json.dumps({
'message': 'Order API is running',
'version': VERSION,
'functionVersion': context.function_version,
'improvement': 'Added health check endpoint'
})
}
Enter fullscreen mode Exit fullscreen mode
Step 03.2: Push the change
git add .
git commit -m "v2.0.0 - Add health check"
git push origin main
Enter fullscreen mode Exit fullscreen mode
π‘ The pipeline triggers automatically
Step 03.3: After the deploy stage, go to CodeDeploy β watch the canary deployment:
- 10% of traffic shifts to version 2
- CodeDeploy waits 5 minutes while monitoring the alarm
- If no alarm fires, 100% shifts to version 2
Step 04: Test Automatic Rollback
Push a broken version that throws errors
import json
VERSION = "3.0.0-broken"
def lambda_handler(event, context):
"""Intentionally broken to test rollback."""
raise Exception("Something went wrong!")
Enter fullscreen mode Exit fullscreen mode
Push and let the pipeline deploy
π‘ During the canary phase, the 10% of traffic hitting the new version generates errors
The CloudWatch alarm triggers β CodeDeploy automatically rolls back
All traffic returns to the previous working version
Part V
Set Up Automatic Rollback with CloudWatch Alarms
Step 01: Create Additional Alarms
Step 01.1: Open the CloudWatch console β Alarms β Create alarm
Step 01.2: Select metric: Lambda β By Function Name β OrderFunction β Duration
Step 01.3: Configure
-
Statistic:
Average -
Period:
60 seconds -
Threshold:
Greater than 5000(5 seconds) -
Evaluation periods:
2 of 3 -
Alarm name:
OrderFunction-HighDuration
Click Create alarm
Step 01.4: Create another alarm for throttles
-
Metric:
ThrottlesforOrderFunction -
Threshold:
Greater than 0 -
Period:
60 seconds -
Alarm name:
OrderFunction-Throttles
Step 02: Update the SAM Template template.yaml with Multiple
DeploymentPreference:
Type: Canary10Percent5Minutes
Alarms:
- !Ref OrderFunctionErrorAlarm
- !Ref OrderFunctionDurationAlarm
- !Ref OrderFunctionThrottleAlarm
Enter fullscreen mode Exit fullscreen mode
Push the change to trigger a pipeline run with the updated alarm configuration.
π‘ You can attach multiple CloudWatch alarms to a deployment preference. If any single alarm fires during the deployment window, CodeDeploy rolls back.
This gives you defense in depth: catch errors, latency spikes, and throttling issues. The alarms are only monitored during the active deployment window, not permanently.
ποΈ What You Built | π Exam Concepts Recap
What You Built Exam Concept Connected a GitHub repo via CodeConnections Source stage, managed source integrations Built a CodeBuild project withbuildspec.yml
Build phases, environment variables, artifacts
Created a CodePipeline (source β build β deploy)
Pipeline orchestration and artifact flow
Added a manual approval stage
Human gates before production deployment
Configured Canary10Percent5Minutes in SAM
Gradual traffic shifting with DeploymentPreference
Attached CloudWatch alarms to the deployment
Automatic rollback on alarm breach
Pushed a broken version and watched it roll back
Defense-in-depth deployment safety
Used AutoPublishAlias: live
Required for SAM safe deployments
β οΈ Clean Up Protocol
-
CodePipeline β Delete
cicd-demo-pipeline -
CodeBuild β Delete
cicd-demo-buildproject -
CloudFormation β Delete the
cicd-demo-appstack (removes Lambda, alarms, CodeDeploy resources) - Developer Tools β Settings β Connections β delete the GitHub CodeConnections connection (and optionally delete/keep the GitHub repo yourself)
- S3 β Empty and delete the artifacts bucket
- IAM β Delete the service roles created for CodeBuild, CodePipeline, and the CloudFormation deploy role
- CloudWatch β Delete any remaining log groups and alarms
Key Takeaways
- CodePipeline orchestrates the pipeline but doesn’t build or deploy: it connects CodeCommit (source), CodeBuild (build), and CodeDeploy (deploy) stages.
-
buildspec.yml has four phases:
install,pre_build,build,post_build. - Use the
envsection to pull secrets from Parameter Store and Secrets Manager securely. - appspec.yml structure differs between Lambda (Resources + Hooks) and EC2 (files + permissions + hooks).
- Canary shifts traffic in two steps (X% then 100%).
- Linear shifts in equal increments.
- Blue/Green creates a new environment and switches all traffic at once.
-
SAM DeploymentPreference requires
AutoPublishAlias. It automatically creates CodeDeploy deployments with traffic shifting and alarm monitoring. -
PreTraffic hooks run before traffic shifts: use for smoke tests. 10. PostTraffic hooks run after: use for integration tests. Both must call
put_lifecycle_event_hook_execution_status. - Automatic rollback triggers when a CloudWatch alarm fires during deployment or when a lifecycle hook fails. This is the recommended approach for production.
-
API Gateway stage variables let you point different stages to different Lambda aliases:
prodstage βprodalias,devstage βdevalias. - CodePipeline artifacts are stored in S3. Each action consumes input artifacts and produces output artifacts that flow to the next stage.
- Manual approval actions in CodePipeline create gates between stages: useful for requiring human sign-off before production deployments.
Additional Resources
- Setup for HTTPS users using Git credentials
- What is AWS CodePipeline?
- Build specification reference for CodeBuild
- CodeDeploy AppSpec file reference
- Deploying serverless applications gradually with AWS SAM
- Set up an API Gateway canary release deployments
- Working with deployment configurations in CodeDeploy
β οΈ The Future of AWS CodeCommit β οΈ
ποΈ
λ΅κΈ λ¨κΈ°κΈ°