This is the largest DOP-C02 domain (22%). Most questions describe a release process with a problem — too manual, too risky, too slow, spread over several accounts — and ask for the most automated fix that still lets you stop a bad release.
CI/CD means continuous integration (merge, build and test automatically) and continuous delivery or deployment (release automatically). On AWS: a Git source → CodeBuild builds and tests → CodeDeploy (or CloudFormation, ECS, Beanstalk) deploys → CodePipeline orchestrates the whole thing.
Source control
- Sources can be CodeCommit, S3, ECR, or GitHub, GitLab and Bitbucket through AWS CodeConnections (formerly CodeStar Connections).
- A connection created with the CLI or CloudFormation stays PENDING until someone completes the handshake in the console. A pipeline using it won’t start until it’s AVAILABLE.
- CodeCommit details that still appear:
- Authenticate through IAM: HTTPS Git credentials, SSH keys, or the
git-remote-codecommithelper with roles. - Block pushes to
mainwith an IAM Deny oncodecommit:GitPushwherecodecommit:Referencesisrefs/heads/main. Approval rule templates require N approvals on pull requests. - Repository events (push, pull request created or merged, comments) go to EventBridge. That’s how pipelines start, how pull request builds run (EventBridge → CodeBuild → post the result back as a comment), and how notifications are sent.
- Authenticate through IAM: HTTPS Git credentials, SSH keys, or the
- Pipeline didn’t start after a push? Check that the EventBridge rule for that repository and branch exists. The console creates it; the CLI and IaC must create it themselves.
CodeBuild
Fully managed build servers, billed per minute, nothing to patch — which is why “replace Jenkins on EC2 with CodeBuild” is a common most maintainable answer. Each build runs in a fresh container from an AWS-managed image or your own from ECR.
version: 0.2
env:
variables: { STAGE: prod }
parameter-store: { DB_USER: /app/db/user }
secrets-manager: { DB_PASS: prod/db:password }
phases:
install: { runtime-versions: { python: 3.12 }, commands: [pip install -r req.txt] }
pre_build: { commands: [pytest] }
build: { commands: [docker build -t $REPO:$CODEBUILD_RESOLVED_SOURCE_VERSION .] }
post_build: { commands: [docker push ...] }
reports: { unit: { files: [report.xml] } }
artifacts: { files: [appspec.yml, '**/*'] }
cache: { paths: ['/root/.m2/**/*'] }
- Phases run
install→pre_build→build→post_build. Ifbuildfails,post_buildstill runs, so put cleanup and teardown there. - Secrets: never plaintext environment variables. Use the
parameter-storeandsecrets-managersections and give the CodeBuild service role read access (pluskms:Decrypt). - AWS API access comes from the service role, never from access keys.
- Private resources such as an RDS database: configure the project’s VPC, subnets and security group. Those private subnets then need a NAT gateway or VPC endpoints to reach the internet and AWS APIs.
- Caching: the S3 cache is shared across build hosts (good for dependencies); the local cache (Docker layers, source, custom paths) only helps if the same host is reused.
- Docker builds need privileged mode on the project.
- Test and coverage reports (JUnit, Cucumber, JaCoCo…) show pass/fail trends and can fail the build.
- Logs go to CloudWatch Logs and/or S3. Build state changes emit EventBridge events — alert on
FAILED. - Batch builds run a matrix (several runtimes or targets). Webhooks from GitHub or Bitbucket start builds on pull requests. CodeBuild can also run on Lambda compute for fast, small builds.
CodePipeline
- A pipeline is a series of stages; each stage has actions. Actions with the same
runOrderrun in parallel. Artifacts pass between actions through an S3 artifact store.
| Action category | Providers |
|---|---|
| Source | CodeCommit, S3, ECR, CodeConnections (GitHub, GitLab, Bitbucket) |
| Build / test | CodeBuild, Jenkins |
| Deploy | CodeDeploy, CloudFormation, ECS, Elastic Beanstalk, S3, Service Catalog |
| Approval | Manual approval, optionally notifying an SNS topic |
| Invoke | Lambda, Step Functions |
- Pipeline type V2 adds trigger filters (branches, Git tags, file paths, pull requests), pipeline-level variables, execution modes (SUPERSEDED by default, QUEUED, PARALLEL) and stage rollback on failure.
- Manual approval has a built-in timeout (
timeoutInMinutes, default and maximum 7 days). When it expires the action fails and the pipeline stops — no Lambda or alarm needed. Use approvals where sign-off is a stated requirement, not instead of tests. - CloudFormation deploy action modes: create or update a stack, delete, or create a change set then execute it — put a manual approval between the two to review changes. Use parameter overrides and template configuration files per environment.
- Jenkins: install the CodePipeline plugin and add Jenkins as a custom build or test provider — useful for a gradual migration.
- Notifications: notification rules to SNS or to Amazon Q Developer in chat applications (formerly AWS Chatbot) for Slack and Teams, or EventBridge rules on CodePipeline Pipeline Execution State Change.
Cross-Region and cross-account
- Cross-Region: an action can run in another Region, but the pipeline needs an artifact store in every Region it uses, and packaged Lambda code must sit in a bucket in the target Region.
- Cross-account (tooling account → prod account):
- Encrypt the artifact bucket with a customer managed KMS key. The AWS managed
aws/s3key can’t be used across accounts. - The key policy and bucket policy allow the prod account.
- A cross-account role in prod trusts the tooling account; the pipeline action’s
RoleArnis that role. - A CloudFormation deployment role in prod does the actual deploy.
- Encrypt the artifact bucket with a customer managed KMS key. The AWS managed
- Multi-Region release with gates: one pipeline with sequential stages (approve → Region 1 → approve → Region 2…) using cross-Region actions.
Build once, promote many
Later stages consume the output artifact of earlier stages, so the artifact you tested is the one you ship. Vary only parameters per environment. For ephemeral test environments (create stack → test → delete), there’s no “always run” action flag: tear down in the buildspec’s cleanup step, a V2 stage on-failure condition, or an EventBridge rule on failed executions.
A container pipeline runs: source → build (docker build, tests, scan) → push to ECR → deploy to ECS using imagedefinitions.json (rolling) or imageDetail.json (blue/green).
Artifacts and code quality
- CodeArtifact: private package repositories (npm, PyPI, Maven, NuGet…). A domain groups repositories and can be shared across accounts. An upstream repository with an external connection to the public registry fetches public packages once and caches them. Authenticate with
aws codeartifact login(a 12-hour token). Share CDK constructs and internal libraries here as versioned packages. - Amazon ECR:
- Lifecycle policies delete old or untagged images; tag immutability stops tags being overwritten.
- Replication across Regions and accounts; a repository policy lets other accounts pull.
- Scanning: basic (on push) or enhanced through Amazon Inspector, which re-scans continuously as new CVEs appear.
- Pull-through cache for public registries.
- Quality gates: CodeGuru Reviewer (code review), CodeGuru Profiler (runtime performance), Amazon Q Developer security scans;
cfn-lint,cfn-guard,cfn-nagor Checkov check templates before any deployment (shift-left).
CodeDeploy
| Term | Meaning |
|---|---|
| Application | Container for deployment groups |
| Deployment group | Targets (EC2 tags, an Auto Scaling group, an ECS service, a Lambda function) plus deployment config, alarms, rollback and triggers |
| Revision | The bundle in S3 or GitHub, including appspec.yml |
| Deployment configuration | How fast the rollout goes |
EC2 and on-premises
- The CodeDeploy agent must run on each server (bake it into the AMI or install it with Systems Manager), and the instance profile must be able to read the revision from S3. On-premises servers are registered with an IAM user or role and tags.
appspec.ymllists files (source → destination), permissions, and hooks (a script per lifecycle event, withtimeoutandrunas).- Target the Auto Scaling group, not individual instances, so instances launched later get the latest revision automatically (CodeDeploy adds a lifecycle hook to the group).
- In-place: stop, install, restart on the same servers, batched by
OneAtATime,HalfAtATime,AllAtOnceor a custom minimum-healthy-hosts value. - Blue/green: launch replacement instances (usually by copying the Auto Scaling group), shift the load balancer, terminate the old ones after a wait.
Lifecycle order for in-place EC2 — memorise it:
ApplicationStop— runs the stop script from the previous revisionDownloadBundle(no scripts)BeforeInstall— back up, decrypt, set configurationInstall(no scripts)AfterInstall— configure, set permissionsApplicationStartValidateService— smoke tests; a failure fails the deployment
With a load balancer, BeforeBlockTraffic → BlockTraffic → AfterBlockTraffic come first, and BeforeAllowTraffic → AllowTraffic → AfterAllowTraffic come last.
- Hook scripts get environment variables:
LIFECYCLE_EVENT,DEPLOYMENT_ID,APPLICATION_NAME,DEPLOYMENT_GROUP_NAME,DEPLOYMENT_GROUP_ID. UseDEPLOYMENT_GROUP_NAMEto apply per-environment settings (dev, staging, prod) from a single revision. - A broken
ApplicationStopscript in the last revision fails every new deployment. Redeploy with--ignore-application-stop-failures. - Triggers send SNS notifications on deployment and instance events. Agent logs:
/var/log/aws/codedeploy-agent/; bundles:/opt/codedeploy-agent/deployment-root/.
Lambda and ECS
| Config | Behaviour |
|---|---|
Canary10Percent5Minutes |
10% of traffic for 5 minutes, then the rest |
Linear10PercentEvery1Minute |
+10% every minute |
AllAtOnce |
Everything immediately |
- Lambda: CodeDeploy shifts a function alias between two versions. Hooks
BeforeAllowTrafficandAfterAllowTrafficare Lambda functions that run tests. SAM’sAutoPublishAliasplusDeploymentPreference(type, alarms, hooks) sets all of this up. - ECS blue/green needs an ALB or NLB with a production listener, an optional test listener, and two target groups. The AppSpec names the
TaskDefinition,ContainerNameandContainerPort. Configs:ECSCanary10Percent5Minutes,ECSLinear10PercentEvery1Minutes,ECSAllAtOnce. Hooks:BeforeInstall,AfterInstall,AfterAllowTestTraffic,BeforeAllowTraffic,AfterAllowTraffic.
Rollback
Enable automatic rollback on the deployment group when a deployment fails and/or when CloudWatch alarm thresholds are met. A rollback redeploys the last good revision as a new deployment.
Other deployment targets
ECS rolling updates
minimumHealthyPercent=100andmaximumPercent=200start new tasks before stopping old ones — no disruption.minimumHealthyPercent=0allows a full outage.- The deployment circuit breaker rolls back a failing rolling deployment automatically.
- Blue/green through CodeDeploy, or ECS-native blue/green.
Elastic Beanstalk
You upload code; Beanstalk manages EC2, Auto Scaling, the load balancer and monitoring. Web server or worker tier (reads from SQS; cron.yaml for periodic tasks).
| Policy | How | Capacity | Extra cost | Rollback |
|---|---|---|---|---|
| All at once | Everywhere at once | Downtime | None | Redeploy old version |
| Rolling | Batches of existing instances | Reduced | None | Redeploy |
| Rolling with additional batch | Adds a new batch first | Full | Small | Redeploy |
| Immutable | New instances in a temporary ASG, then swap | Full | Double briefly | Fastest and safest: terminate the new ones |
| Traffic splitting | Canary share of traffic to new instances | Full | Double | Fast; good for A/B tests |
| Blue/green | Separate environment, then swap environment URLs (CNAME) | Full | Two environments | Swap back |
- Customise with
.ebextensions/*.config(option_settings,packages,files,commands,container_commands) or.platform/hookson newer platforms.leader_only: trueincontainer_commandsruns a step on one instance only — use it for database migrations. - Don’t create production RDS inside the Beanstalk environment: it’s deleted with the environment. Create it separately and pass the endpoint as an environment variable.
- Managed platform updates run in a weekly window; enhanced health reporting; logs can stream to CloudWatch.
API Gateway and blue/green elsewhere
- A canary release on an API Gateway stage sends a percentage of traffic to a new deployment; promote it when it’s healthy. Stage variables can point to Lambda aliases.
- Route 53 weighted records shift traffic between stacks gradually but are subject to DNS caching. ALB weighted target groups shift instantly at the load balancer.
Exam checklist
- “Stop a bad release automatically”: CodeDeploy canary or linear with CloudWatch alarm rollback (SAM
DeploymentPreferencefor Lambda). - “Smoke tests after an EC2 deploy”:
ValidateService. “Per-environment config from one revision”:DEPLOYMENT_GROUP_NAME. - “Every deployment fails at ApplicationStop”:
--ignore-application-stop-failures. - “Cross-account pipeline gets Access Denied on artifacts”: customer managed KMS key, key and bucket policies, cross-account role.
- “Pipeline didn’t trigger after a push”: the EventBridge rule is missing, or the connection is still PENDING.
- “Docker build fails in CodeBuild”: enable privileged mode.
- “Beanstalk: full capacity, fastest safe rollback”: immutable. “Full capacity, lowest cost”: rolling with additional batch. “Run a migration once”:
leader_only. - “ECS rolling deploy should roll back on failure”: deployment circuit breaker.
- “Continuous CVE scanning of images, including old ones”: ECR enhanced scanning.