/CI/CD — CodePipeline, CodeBuild, CodeDeploy
Concept
Hard

CI/CD — CodePipeline, CodeBuild, CodeDeploy

12 min read·CodePipelineCodeBuildCodeDeployCI/CDDVA-C02

A comprehensive deep dive into AWS CI/CD services — CodePipeline orchestration, CodeBuild buildspec, CodeDeploy deployment strategies for EC2/Lambda/ECS, appspec.yml, CodeArtifact, and CodeStar Connections for the DVA-C02 exam.


AWS CI/CD Suite — Mental Model

AWS provides four managed services that together cover the full software delivery lifecycle.

Rendering diagram…

Core mental model: CodePipeline is the conductor — it triggers stages in order and passes artifacts between them. CodeBuild is the build worker — it compiles, tests, and packages. CodeDeploy is the deployment engine — it rolls changes out safely to compute resources.


Part 1 — AWS CodePipeline

Pipeline Structure

A pipeline has stages, each stage has actions, and actions consume/produce artifacts stored in S3.

Rendering diagram…
ConceptDetail
StageLogical phase (Source, Build, Test, Deploy)
ActionUnit of work inside a stage — can run in parallel or sequentially
ArtifactFiles passed between stages (stored in S3, encrypted with KMS)
TransitionLink between stages — can be disabled to pause the pipeline
ExecutionOne run of the pipeline triggered by a source change

Source Providers

ProviderTrigger mechanism
AWS CodeCommitCloudWatch Events (push to branch)
GitHub / GitLabCodeStar Connection (OAuth app webhook)
GitHub EnterpriseCodeStar Connection (self-hosted)
Amazon S3S3 event notification on object upload
Amazon ECRCloudWatch Events on image push
BitbucketCodeStar Connection

Manual Approval Action

json
1{
2  "name": "Approve-Production-Deploy",
3  "actionTypeId": {
4    "category": "Approval",
5    "owner": "AWS",
6    "provider": "Manual",
7    "version": "1"
8  },
9  "configuration": {
10    "NotificationArn": "arn:aws:sns:us-east-1:123456789012:pipeline-approvals",
11    "CustomData": "Review staging metrics before approving prod deploy.",
12    "ExternalEntityLink": "https://grafana.internal/d/staging"
13  }
14}

The pipeline pauses. SNS sends an email/Slack notification. An authorized IAM user calls PutApprovalResult (Approved or Rejected) to continue or abort.

Pipeline Events & Notifications

bash
1# CodePipeline emits EventBridge events on state changes
2# Event pattern to catch any pipeline failure:
3aws events put-rule   --name "pipeline-failure-alert"   --event-pattern '{
4    "source": ["aws.codepipeline"],
5    "detail-type": ["CodePipeline Pipeline Execution State Change"],
6    "detail": { "state": ["FAILED"] }
7  }'
8
9# Pipe to SNS → Slack Lambda for team notifications

Pipeline as Code (CloudFormation)

yaml
1MyPipeline:
2  Type: AWS::CodePipeline::Pipeline
3  Properties:
4    RoleArn: !GetAtt PipelineRole.Arn
5    ArtifactStore:
6      Type: S3
7      Location: !Ref ArtifactBucket
8      EncryptionKey:
9        Id: !Ref PipelineKMSKey
10        Type: KMS
11    Stages:
12      - Name: Source
13        Actions:
14          - Name: SourceAction
15            ActionTypeId:
16              Category: Source
17              Owner: AWS
18              Provider: CodeStarSourceConnection
19              Version: '1'
20            Configuration:
21              ConnectionArn: !Ref GitHubConnection
22              FullRepositoryId: myorg/myapp
23              BranchName: main
24            OutputArtifacts:
25              - Name: SourceOutput
26
27      - Name: Build
28        Actions:
29          - Name: BuildAction
30            ActionTypeId:
31              Category: Build
32              Owner: AWS
33              Provider: CodeBuild
34              Version: '1'
35            Configuration:
36              ProjectName: !Ref BuildProject
37            InputArtifacts:
38              - Name: SourceOutput
39            OutputArtifacts:
40              - Name: BuildOutput

Part 2 — AWS CodeBuild

How CodeBuild Works

Rendering diagram…

buildspec.yml — Full Structure

yaml
1version: 0.2
2
3env:
4  variables:
5    NODE_ENV: production
6  parameter-store:
7    DB_PASSWORD: /myapp/prod/db-password   # pulled from SSM at build start
8  secrets-manager:
9    NPM_TOKEN: myapp/npm-token:token       # pulled from Secrets Manager
10  exported-variables:
11    - IMAGE_TAG                            # export for later pipeline stages
12
13phases:
14  install:
15    runtime-versions:
16      nodejs: 20
17    commands:
18      - npm ci --prefer-offline
19
20  pre_build:
21    commands:
22      - echo "Running pre-build checks..."
23      - aws ecr get-login-password --region $AWS_DEFAULT_REGION |
24          docker login --username AWS --password-stdin $ECR_REGISTRY
25      - export IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c1-7)
26
27  build:
28    commands:
29      - npm run test:ci
30      - npm run build
31      - docker build -t $ECR_REGISTRY/$ECR_REPO:$IMAGE_TAG .
32      - docker push $ECR_REGISTRY/$ECR_REPO:$IMAGE_TAG
33
34  post_build:
35    commands:
36      - echo "Writing image definition for CodeDeploy..."
37      - printf '[{"name":"app","imageUri":"%s"}]' "$ECR_REGISTRY/$ECR_REPO:$IMAGE_TAG" > imagedefinitions.json
38
39artifacts:
40  files:
41    - imagedefinitions.json
42    - appspec.yml
43    - taskdef.json
44  discard-paths: no
45
46cache:
47  paths:
48    - node_modules/**/*    # cache node_modules between builds
49    - /root/.npm/**/*
50
51reports:
52  unit-test-results:
53    files:
54      - 'test-results/**/*.xml'
55    file-format: JUNITXML

Build Environment

bash
1# Key environment variables automatically available in every build:
2# CODEBUILD_BUILD_ID         — unique build ID
3# CODEBUILD_BUILD_NUMBER     — numeric build counter
4# CODEBUILD_RESOLVED_SOURCE_VERSION — full git commit SHA
5# CODEBUILD_SRC_DIR          — path to checked-out source
6# AWS_DEFAULT_REGION         — region where build runs
7# AWS_ACCOUNT_ID             — your account ID
8# CODEBUILD_BUILD_SUCCEEDING — 1 if succeeding, 0 if failing (post_build only)
Build EnvironmentDescription
Managed imageAWS-provided (Amazon Linux 2, Ubuntu) — easiest
Custom Docker imageYour own ECR/Docker Hub image — full control
ARM buildBUILD_GENERAL1_SMALL on ARM for multi-arch

VPC Access

CodeBuild runs in AWS-managed infrastructure by default. To access resources in your VPC (RDS, ElastiCache, internal APIs):

yaml
1# CloudFormation — VPC config for CodeBuild project
2MyBuildProject:
3  Type: AWS::CodeBuild::Project
4  Properties:
5    VpcConfig:
6      VpcId: !Ref MyVpc
7      Subnets:
8        - !Ref PrivateSubnet1
9        - !Ref PrivateSubnet2
10      SecurityGroupIds:
11        - !Ref BuildSecurityGroup

Caveat: When CodeBuild runs inside a VPC, it cannot reach the public internet unless your VPC has a NAT Gateway. S3 and other AWS services can be reached via VPC endpoints.

Local Build with CodeBuild Agent

bash
1# Run a build locally — same environment as CodeBuild
2docker pull public.ecr.aws/codebuild/amazonlinux2-x86_64-standard:5.0
3
4# Run the local agent
5docker run -it   -v /var/run/docker.sock:/var/run/docker.sock   -e IMAGE_NAME=public.ecr.aws/codebuild/amazonlinux2-x86_64-standard:5.0   -e ARTIFACTS=/tmp/artifacts   -e SOURCE=/path/to/your/project   public.ecr.aws/codebuild/local-builds:latest

Part 3 — AWS CodeDeploy

Deployment Targets

ComputeAgent requiredNotes
EC2 / On-Premises✅ CodeDeploy agentInstalls on instance at boot
AWS LambdaNative integration via aliases + traffic shifting
Amazon ECSIntegrates with ALB listener rules

CodeDeploy for EC2 / On-Premises

Deployment Configurations

StrategyHow it worksDowntimeSpeed
CodeDeployDefault.AllAtOnceDeploy to all instances simultaneouslyYesFastest
CodeDeployDefault.HalfAtATimeDeploy to 50% at a timeNoMedium
CodeDeployDefault.OneAtATimeDeploy to one instance at a timeNoSlowest
Blue/GreenNew ASG fleet; shift ALB traffic; terminate oldNoFast

appspec.yml — EC2

yaml
1version: 0.0
2os: linux
3
4files:
5  - source: /build/dist
6    destination: /var/www/app
7
8permissions:
9  - object: /var/www/app
10    owner: ec2-user
11    group: ec2-user
12    mode: 755
13    type:
14      - directory
15      - file
16
17hooks:
18  ApplicationStop:
19    - location: scripts/stop_server.sh
20      timeout: 30
21      runas: root
22
23  BeforeInstall:
24    - location: scripts/install_dependencies.sh
25      timeout: 60
26      runas: root
27
28  AfterInstall:
29    - location: scripts/change_permissions.sh
30      timeout: 30
31      runas: root
32
33  ApplicationStart:
34    - location: scripts/start_server.sh
35      timeout: 60
36      runas: root
37
38  ValidateService:
39    - location: scripts/validate_service.sh
40      timeout: 30
41      runas: ec2-user

EC2 Deployment Lifecycle Hook Order

Rendering diagram…

For Blue/Green deployments, additional hooks run on the new (green) instances:
BeforeAllowTraffic → traffic shifted → AfterAllowTraffic

CodeDeploy for Lambda

Lambda deployments shift traffic between two alias weights pointing to different function versions.

Rendering diagram…

Lambda Deployment Configurations

ConfigDescription
LambdaAllAtOnceShift 100% immediately
LambdaCanary10Percent5Minutes10% for 5 min, then 90%
LambdaCanary10Percent30Minutes10% for 30 min, then 90%
LambdaLinear10PercentEvery1Minute+10% every 1 min (10 min total)
LambdaLinear10PercentEvery2Minutes+10% every 2 min (20 min total)
LambdaLinear10PercentEvery3Minutes+10% every 3 min (30 min total)
LambdaLinear10PercentEvery10Minutes+10% every 10 min (100 min total)
CustomYour own percentage + interval

appspec.yml — Lambda

yaml
1version: 0.0
2Resources:
3  - MyFunction:
4      Type: AWS::Lambda::Function
5      Properties:
6        Name: MyLambdaFunction
7        Alias: prod
8        CurrentVersion: !Ref CurrentVersion
9        TargetVersion: !Ref NewVersion
10
11Hooks:
12  - BeforeAllowTraffic: MyValidationFunction   # runs before shifting traffic
13  - AfterAllowTraffic: MyMonitorFunction       # runs after full shift
javascript
1// BeforeAllowTraffic / AfterAllowTraffic hook Lambda
2import { CodeDeployClient, PutLifecycleEventHookExecutionStatusCommand } from '@aws-sdk/client-codedeploy';
3
4const codedeploy = new CodeDeployClient({});
5
6export async function handler(event) {
7  const { DeploymentId, LifecycleEventHookExecutionId } = event;
8
9  try {
10    // Run your validation (smoke test, canary check, etc.)
11    await runSmokeTest();
12
13    await codedeploy.send(new PutLifecycleEventHookExecutionStatusCommand({
14      deploymentId: DeploymentId,
15      lifecycleEventHookExecutionId: LifecycleEventHookExecutionId,
16      status: 'Succeeded',
17    }));
18  } catch (err) {
19    await codedeploy.send(new PutLifecycleEventHookExecutionStatusCommand({
20      deploymentId: DeploymentId,
21      lifecycleEventHookExecutionId: LifecycleEventHookExecutionId,
22      status: 'Failed',   // triggers automatic rollback
23    }));
24  }
25}

CodeDeploy for ECS

ECS deployments replace the current task set with a new one and shift ALB listener traffic.

yaml
1# appspec.yml — ECS
2version: 0.0
3Resources:
4  - TargetService:
5      Type: AWS::ECS::Service
6      Properties:
7        TaskDefinition: <TASK_DEFINITION>
8        LoadBalancerInfo:
9          ContainerName: app
10          ContainerPort: 8080
11        PlatformVersion: LATEST
12
13Hooks:
14  - BeforeInstall: BeforeInstallHookLambda
15  - AfterInstall: AfterInstallHookLambda
16  - AfterAllowTestTraffic: TestTrafficHookLambda
17  - BeforeAllowTraffic: BeforeAllowTrafficHookLambda
18  - AfterAllowTraffic: AfterAllowTrafficHookLambda

ECS Blue/Green uses two target groups on the ALB. The new task set receives test traffic first (via a test listener on a separate port), then production traffic shifts over.

Rollback Behavior

TriggerBehavior
Deployment failureRolls back to last successful deployment revision
CloudWatch Alarm breachAutomatic rollback if alarm configured on deployment group
Manual rollbackVia console or aws deploy create-deployment with previous revision

Important: Rollback in CodeDeploy is not an undo — it creates a new deployment of the previous revision. The deployment history always shows both the failed deployment and the rollback deployment.


Part 4 — AWS CodeArtifact

CodeArtifact is a managed artifact repository compatible with npm, PyPI, Maven, Gradle, NuGet, and Swift.

Rendering diagram…
bash
1# Authenticate npm to CodeArtifact (token valid for 12 hours)
2aws codeartifact login   --tool npm   --domain my-domain   --domain-owner 123456789012   --repository my-repo
3
4# Now npm install reads from CodeArtifact (with upstream fallback to npmjs.com)
5npm install lodash   # served from CodeArtifact cache or proxied from npm
6
7# Publish a private package
8npm publish          # goes to CodeArtifact repo
9
10# Python — authenticate pip
11aws codeartifact login --tool pip --domain my-domain --repository my-repo
12pip install boto3
ConceptDetail
DomainContainer for repositories; enables cross-repo policies
RepositoryPackage store for a specific tool (npm, PyPI, etc.)
UpstreamPull-through cache for public registries
AssetIndividual package file (tarball, wheel, etc.)
Authorization token12-hour token from GetAuthorizationToken API

Part 5 — CodeStar Connections

CodeStar Connections provides OAuth-based integration between CodePipeline/CodeBuild and third-party Git providers.

ProviderConnection type
GitHub.comCodeStar Connection (OAuth app)
GitHub Enterprise ServerCodeStar Connection (self-hosted)
GitLab.comCodeStar Connection
GitLab Self-ManagedCodeStar Connection
Bitbucket CloudCodeStar Connection

Connections must be manually activated in the console once (OAuth handshake), then they can be referenced in CloudFormation/CDK pipelines without any secrets.


Full Pipeline Example (GitHub → Build → Lambda Deploy)

Rendering diagram…
bash
1# Trigger a manual pipeline execution
2aws codepipeline start-pipeline-execution --name my-pipeline
3
4# Get pipeline status
5aws codepipeline get-pipeline-state --name my-pipeline
6
7# Approve a manual approval action
8aws codepipeline put-approval-result   --pipeline-name my-pipeline   --stage-name Approve-Prod   --action-name ManualApproval   --result actionStatus=Approved,summary="Metrics look good"   --token <token-from-get-pipeline-state>
9
10# Get CodeDeploy deployment status
11aws deploy get-deployment --deployment-id d-ABCDEF123
12
13# Stop a deployment (with optional rollback)
14aws deploy stop-deployment   --deployment-id d-ABCDEF123   --auto-rollback-enabled

DVA-C02 Quick Reference

TopicKey Fact
CodePipeline artifact storageS3 bucket (encrypted with KMS)
CodePipeline trigger for CodeCommitCloudWatch Events (not polling)
CodePipeline trigger for GitHubCodeStar Connection (webhook)
Manual approval notificationSNS topic
CodeBuild phases orderinstall → pre_build → build → post_build
buildspec.yml default locationRoot of source repository
CodeBuild VPC caveatNeeds NAT Gateway to reach internet from VPC
CodeBuild env var from SSMparameter-store section in buildspec env block
CodeBuild env var from Secrets Managersecrets-manager section in buildspec env block
CodeDeploy EC2 requiresCodeDeploy agent installed on instances
CodeDeploy Lambda requiresNo agent — uses alias traffic shifting
CodeDeploy ECS requiresNo agent — uses ALB listener rules + two target groups
appspec.yml EC2 hook orderApplicationStop → BeforeInstall → Install → AfterInstall → ApplicationStart → ValidateService
CodeDeploy rollback mechanismNew deployment of previous revision (not an undo)
Lambda canary deploymentSmall % first (e.g., 10%), then rest after interval
Lambda linear deploymentEqual % increments on a fixed schedule
CodeDeploy alarm rollbackCloudWatch Alarm triggers automatic rollback
CodeArtifact token validity12 hours
CodeArtifact upstreamPull-through cache for public package registries
Cross-account pipelineCodePipeline assumes role in target account for deploy actions
Pipeline notification eventsEventBridge (CodePipeline emits state change events)

Practice Questions9

easy

Q1. A development team uses AWS CodePipeline. After a code push to CodeCommit, the pipeline triggers CodeBuild. CodeBuild compiles the code but the unit tests fail. What happens to the pipeline?


Select one answer before revealing.

medium

Q2. A developer wants to run unit tests and integration tests in parallel during a CodePipeline Build stage to reduce total build time. Which CodeBuild feature supports running multiple build groups in parallel?


Select one answer before revealing.

medium

Q3. A team uses AWS CodeDeploy to deploy to EC2 instances. They want to gradually shift traffic from the old version to the new version — starting with 10% and shifting 100% after 10 minutes if no alarms trigger. Which deployment configuration should be used?


Select one answer before revealing.

easy

Q4. A developer writes a buildspec.yml for CodeBuild. The build has 4 phases. Which of the following represents the correct order of phases in a CodeBuild build?


Select one answer before revealing.

easy

Q5. A developer uses AWS SAM to define a Lambda function and API Gateway. After running `sam deploy`, the developer needs to test the Lambda function locally before the next deployment. Which command should be used?


Select one answer before revealing.

medium

Q6. A developer needs to create a CodePipeline that builds a Docker image, pushes it to ECR, and updates an ECS service. The pipeline must pass the ECR image URI from the Build stage to the Deploy stage. How is data passed between CodePipeline stages?


Select one answer before revealing.

medium

Q7. A team wants to enforce a manual approval before production deployments in their CodePipeline. A Slack notification must be sent to the ops team when approval is required. Which CodePipeline action type should be added?


Select one answer before revealing.

hard

Q8. A developer uses CodeDeploy to deploy a new version of a Lambda function. They want to automatically roll back if the p99 latency CloudWatch alarm triggers within 10 minutes of deployment. Which CodeDeploy feature enables this?


Select one answer before revealing.

medium

Q9. A developer uses AWS CloudFormation to deploy infrastructure. After updating a stack, the deployment fails. CloudFormation shows ROLLBACK_IN_PROGRESS. What does this mean and what is the developer's next step?


Select one answer before revealing.