Chapter 3

Deployment: Shipping Code Without Breaking Production

AWS Certified Developer – Associate (DVA-C02) Study GuideBased on the official DVA-C02 exam objectives

It is 4:55 on a Friday afternoon, and Priya, a backend developer at an online bookstore, merges the last pull request of the sprint — a "small" checkout change — and clicks Deploy. The pipeline pushes the new code to every production server at the same time. Thirty seconds later the error dashboard turns red. The change carried a bug that only appears under real traffic, and checkout is down. For the next forty minutes, while customers abandon their carts, the team rolls back manually, server by server, because nobody set up an automated rollback. A deploy that was supposed to take five minutes costs the company a Friday evening and a painful slice of revenue. Now picture a different team at a food-delivery startup. They deploy twenty times a day. Every deploy sends the new version to just 10 percent of traffic first, watches the error metrics for ten minutes, and only then ramps up. When a bad change slips through, the system rolls itself back in under five minutes — usually before any human even notices. Same cloud, same building blocks. The difference is not talent. It is deployment engineering: pipelines that build reliably, strategies that limit blast radius, and infrastructure defined as code so every environment is identical. That is what this chapter is about. The DVA-C02 exam devotes 24% of its questions to deployment, and it tests you as a developer who owns releases end to end. You will not be asked to recite console menu paths. You will be given a scenario — a team, a constraint, a failure — and asked which pipeline setup, which deployment strategy, or which infrastructure-as-code feature solves it. This chapter builds those instincts.

The CI/CD Pipeline: From Commit to Production

A CI/CD pipeline automates the boring, error-prone journey from "code merged" to "code serving customers." AWS gives you four managed services that snap together, and the exam expects you to know each one's job and how they connect.

CodeCommit: Where Code Lives

AWS CodeCommit is a managed Git repository service. For the exam, its job is simple: it is the source stage of the pipeline. Developers push code the way they push to any Git remote, and CodeCommit can fire triggers — notifications to Amazon SNS or invocations of AWS Lambda functions — when events happen, such as a push to the main branch. A classic exam scenario: "start the pipeline automatically whenever code is pushed to main." The answer is a CodeCommit trigger kicking off CodePipeline, or simply CodePipeline's source action polling the repository. CodeCommit also supports approval rule templates , which require pull requests to be approved before merging — the exam occasionally tests this as the "require a second pair of eyes" answer. One more exam-relevant fact: AWS closed CodeCommit to new customers on July 25, 2024 — if a team doesn't already use it, they can't start now. Existing customers continue uninterrupted, and the service still appears on the exam as the "managed Git source stage" answer.

Exam tip

CodeCommit is closed to new customers (July 2024) but it is NOT discontinued — existing customers keep using it, and the exam still treats it as a live service. Don't pick "CodeCommit is deprecated" as an answer. If a scenario needs a brand-new Git repository as a pipeline source today, the realistic answer is a third-party host like GitHub wired to CodePipeline's source action.

CodeBuild: Turning Code Into Artifacts

AWS CodeBuild compiles code, runs tests, and produces deployable artifacts (a JAR file, a Docker image, a zipped Lambda package). You control it with a buildspec.yml file, and the exam loves this file's structure. A minimal buildspec.yml shows the structure the exam expects you to recognize:

version: 0.2
phases:
  install:
    commands:
      - pip install -r requirements.txt
  build:
    commands:
      - pytest tests/
      - docker build -t myapp:$CODEBUILD_RESOLVED_SOURCE_VERSION .
  post_build:
    commands:
      - docker push $ECR_REPO:myapp
artifacts:
  files: ['imagedefinitions.json']

A buildspec has four phases that run in order: 1. install — set up the environment (install runtimes, dependencies) 2. pre_build — preparation (log in to Amazon ECR, for example) 3. build — the actual work (compile, run unit tests, build the Docker image) 4. post_ build — finishing touches (push the image to ECR) Then artifacts declares what CodeBuild hands to the next stage (files: lists what to package, discard-paths: yes flattens directories), cache speeds up repeat builds by reusing dependencies, and env injects variables — including secrets pulled from Secrets Manager or Parameter Store at build time, so credentials never sit in the buildspec itself. If a question describes "tests run automatically on every commit and the Docker image is pushed to a registry," that is CodeBuild with a buildspec doing the build and a post_build pushing to ECR.

Exam tip

The buildspec phases run strictly in order: install pre_build build post_build. The exam's favorite trap is putting test execution in the wrong phase or asking where the Docker push belongs — it goes in post_build, after the image exists. And remember: CodeBuild produces artifacts; it never deploys them. Deployment is CodeDeploy's job.

CodeDeploy: Putting Bits on Targets

AWS CodeDeploy takes the artifact and installs it on the compute target — EC2 instances, Lambda functions, or ECS services. You steer it with an appspec.yml file, and here is the critical exam fact: the hooks inside appspec.yml are different for each compute platform. For EC2/On-Premises deployments, the AppSpec orchestrates a script lifecycle around your code: BeforeInstall (stop the old version, clean up), AfterInstall (set permissions, configure), ApplicationStart (start the service), and ValidateService (run smoke tests). The full order the exam may probe is ApplicationStop -> DownloadBundle -> BeforeInstall -> AfterInstall -> ApplicationStart -> ValidateService, with traffic hooks (BeforeAllowTraffic/AfterAllowTraffic) when a load balancer is involved. For Lambda deployments, the AppSpec is about traffic shifting, not scripts: it names the function, the alias , the current version and target version , and just two hooks — BeforeAllowTraffic and AfterAllowTraffic — Lambda functions that run validation tests before and after traffic moves. For ECS deployments, the AppSpec points at the replacement task definition and the load balancer's container name and port, with hooks around the blue/green swap. The exam tests whether you can match the hook to the platform. A question about "run a validation Lambda before traffic shifts to the new function version" is BeforeAllowTraffic on a Lambda deployment — not ValidateService, which belongs to EC2.

CodePipeline: The Conductor

AWS CodePipeline ties it all together. A pipeline is a series of stages — typically Source -> Build -> Test -> Deploy — and each stage contains actions . Artifacts flow between stages through an artifact store (an S3 bucket CodePipeline manages). Two details matter for the exam. First, a manual approval action can pause the pipeline between stages ("require a manager's click before production") — the answer whenever a scenario demands human sign-off in an automated pipeline. Second, CodePipeline re-runs the whole pipeline on every source change by default, and you can wire CloudWatch Events/EventBridge rules to trigger pipelines on schedules or events.

Exercise

Exercise 1. A team wants: code pushed to the main branch automatically builds, runs unit tests, builds a Docker image, pushes it to ECR, and then waits for a tech lead's approval before deploying to production. Which services and files do you use? Answer: CodeCommit (source) -> CodePipeline with Source, Build, and Deploy stages -> CodeBuild with a buildspec.yml (tests in the build phase, ECR push in post_build) -> a manual approval action before the Deploy stage -> CodeDeploy to ECS. Why not CodeBuild for the approval? Because CodeBuild only builds; approvals are a CodePipeline action. Why not skip CodePipeline and chain services manually? Because then you lose the artifact handoff, the single execution history, and the approval gate — the pipeline is what makes it one automated release.

Deployment Strategies: Match the Strategy to the Service — and the Fear

Deploying is not just copying files — it is deciding how much of your fleet changes at once and what happens when things go wrong . The exam's favorite trap is that similar-sounding strategies belong to different services . Learn every strategy together with its service, then match the scenario's fear to the right pair. CodeDeploy for EC2: in-place deployments. CodeDeploy updates your existing instances according to a deployment configuration . AllAtOnce pushes to every instance simultaneously — fastest, and the most dangerous: during the deploy some instances serve old code while others serve new, and if the new version is broken, everything breaks at once. Priya's Friday disaster was AllAtOnce. HalfAtATime updates half the fleet, then the other half; OneAtATime updates a single instance before moving on — slowest, safest of the three. Batching keeps the site up, but capacity dips while instances update, and a bad version still reaches some customers before you notice. Elastic Beanstalk: deployment policies. Beanstalk has its own set with confusingly similar names. All at once is the same idea — fast, downtime possible. Rolling updates in batches with reduced capacity during the deploy. Rolling with additional batch fixes the capacity dip: Beanstalk launches extra instances first, then rolls through the fleet, so capacity never drops below 100% — you pay for the extra batch during the deploy. Immutable goes further: an entirely new fleet launches, traffic shifts only after every new instance passes health checks, and the old fleet terminates. Nothing is ever half-updated, rollback is a traffic flip, and you briefly pay double capacity. (Beanstalk blue/green is separate again: clone the environment, swap the CNAMEs.) Lambda: traffic shifting, not instance updating. There are no servers, so strategies shift request traffic: AllAtOnce , Canary (10% -> 50% -> 100% in steps, pausing between to watch metrics — that first 10% is a tripwire), and Linear (an even ramp, 10% every few minutes — gentler). You configure them through SAM's Deployment Preference or CodeDeploy's Lambda deployment configs, with CloudWatch alarms triggering automatic rollback. ECS: blue/green. CodeDeploy replaces ECS tasks behind an Application Load Balancer that has two target groups : the production listener keeps serving the current (blue) tasks while the test listener validates the new (green) ones, then traffic flips. Rollback flips it back.

Exam tip

Answer in two steps: which SERVICE, then which fear. "Rolling with additional batch" and "Immutable" are Elastic Beanstalk policies — never choose them for a CodeDeploy EC2 question, where the configurations are AllAtOnce, HalfAtATime, and OneAtATime. Fear of downtime during a Beanstalk deploy rolling with additional batch or immutable. Fear of a bad version reaching everyone on Lambda canary or linear. The exam almost always describes the fear; your job is to name the service first, then the strategy.

Exercise

Exercise 2. A payment service on Elastic Beanstalk cannot tolerate any capacity drop during deploys, and a bad release must be reversible in under a minute. The team accepts paying for extra instances during deployments. Which deployment policy, and why not the others? Answer: Immutable — a brand-new fleet passes health checks before any traffic moves, capacity never dips, and rollback is a traffic flip that takes seconds. Why not rolling? Because instances leave service during updates, so capacity drops. Why not rolling with additional batch? It also protects capacity and is cheaper, but instances are still updated in place — a bad AMI poisons the fleet and rollback means another full rolling deploy, not a one-minute flip. Why not all at once? Because a bad version hits 100% of traffic instantly — the opposite of the requirement.

Lambda Releases: Versions, Aliases, and Weighted Traffic

Lambda deployments work differently from EC2 because there are no servers to update — there are only versions and aliases , and the exam tests the distinction relentlessly. A Lambda version is an immutable snapshot of a function's code plus its configuration. Publish version 7 and it is frozen forever: you cannot edit it, and its ARN ends in :7. $LATEST is the special mutable pointer to your current working draft — the only version you can change. The exam's trap: "the team edited the function and production broke" usually means they pointed production at $LATEST instead of a published version. An alias is a named pointer to a version — like a Git tag. prod might point to version 7 today and version 8 tomorrow. Aliases do two jobs. First, they give clients a stable ARN (function:prod) that never changes even as versions roll forward. Second, they enable weighted traffic shifting : an alias can send 90% of invocations to version 7 and 10% to version 8. That is Lambda's canary deployment — no CodeDeploy required, just alias weights. Rollback is moving the alias back, which takes seconds. AWS SAM automates this with the DeploymentPreference property. In template.yml you write something like DeploymentPreference: { Type: Canary10Percent10Minutes, Alarms: [my-alarm], Hooks: { PreTraffic: my-validation-function } } and SAM (via CodeDeploy, behind the scenes) shifts 10% of traffic, waits ten minutes while CloudWatch alarms watch, then completes the rollout — rolling back automatically if an alarm fires. The PreTraffic and PostTraffic hooks run your validation Lambda before and after the shift. The predefined types the exam names are AllAtOnce , Canary10PercentXMinutes , and Linear10PercentEveryXMinutes — learn to read them as "how much traffic, how fast."

Exam tip

If a question says "gradually shift Lambda traffic and roll back automatically on errors," the answer is an alias with weighted routing driven by SAM's DeploymentPreference (or CodeDeploy directly). If it says "the team edited $LATEST and broke production," the fix is publishing immutable versions and pointing the alias at a version. Versions are snapshots; aliases are pointers; weights are canaries.

Exercise

Exercise 3. A Lambda-backed API needs canary releases: 10% of traffic to the new version for 10 minutes, automatic rollback if the error alarm fires, and a validation function run before any traffic shifts. The team uses SAM. What do you configure? Answer: Publish a new version, keep the prod alias, and set DeploymentPreference to Canary10Percent10Minutes with the error alarm in Alarms and the validation function as the PreTraffic hook. W hy not just move the alias manually? Because manual moves have no automatic rollback on alarms and no built-in waiting periods. Why not AllAtOnce? Because it shifts 100% immediately — the opposite of a canary. Why not CodeDeploy EC2 configs like OneAtATime? Because those apply to instances, not Lambda traffic weights.

Infrastructure as Code: SAM and CloudFormation

Clicking through the console does not scale, and it definitely does not reproduce. Infrastructure as code means your environments are defined in files, versioned in Git, and deployed identically every time. The exam treats this as a professional non-negotiable.

SAM: CloudFormation for Serverless

AWS SAM (Serverless Application Model) is a simplified layer over CloudFormation for serverless apps. A SAM template is dramatically shorter than raw CloudFormation for the same app:

Transform: AWS::Serverless-2016-10-31
Resources:
  CheckoutFunction:
    Type: AWS::Serverless::Function
    Properties:
      Runtime: python3.12
      Handler: app.lambda_handler
      Events:
        CheckoutApi:
          Type: Api
          Properties: { Path: /checkout, Method: post }

You write a template.yml starting with Transform: AWS::Serverless-2016-10-31, then declare AWS::Serverless::Function, AWS::Serverless::Api, and AWS::Serverless::Table resources in a fraction of the lines raw CloudFormation needs. The CLI workflow is sam build (compile), sam package (upload artifacts to S3), and sam deploy (create/update the stack, with --guided the first time to save parameters). sam local lets you test functions and APIs on your laptop before deploying. When a scenario says "a developer wants to define a Lambda function, its API Gateway endpoint, and its DynamoDB table in one short template and deploy from the CLI," that is SAM.

CloudFormation: The Full Power Tool

AWS CloudFormation provisions any AWS resources from templates (JSON or YAML) organized into stacks . Four features carry most exam questions: Parameters make templates reusable: instead of hardcoding an instance type, you declare a parameter and pass the value at deploy time (sam deploy --parameter-overrides). Combined with Mappings (lookup tables, e.g., AMI IDs per region) and Conditions (deploy this resource only in production), one template serves every environment. Intrinsic functions compute values inside the template. The exam's shortlist: Ref (returns a parameter's value or a resource's physical ID), Fn::GetAtt (returns a resource attribute, like a bucket's DNS name), Fn::Sub (string substitution, "${AWS::StackName}-logs"), Fn::Join (concatenate with a delimiter), and Fn::ImportValue (pull an exported value from another stack — the cross-stack reference answer). Change sets answer "what will this update actually do?" You create a change set against a live stack, CloudFormation shows you exactly which resources will be added, modified, or replaced — and then you choose to execute it or walk away. Any scenario with "preview the impact before applying" is a change set. Skipping this step is how production databases get accidentally replaced. Drift detection answers the opposite question: "did anyone change something behind CloudFormation's back?" If an operator tweaks a security group in the console, the stack's actual state no longer matches its template — it has drifted . Drift detection scans the stack and reports which resources and properties differ, so you can reconcile them. The exam pairs these two constantly: change sets look forward (what will change), drift detection looks backward (what changed without permission).

Exam tip

Change sets and drift detection are the exam's favorite pair — and its favorite confusion. Change set = "show me what my template update WILL do before I run it." Drift = "show me what someone ALREADY changed outside the template." One prevents surprises; the other finds them.

Exercise

Exercise 4. A team manages 30 microservices with CloudFormation. Two requirements: (a) developers must see exactly which resources an update will replace before it runs, and (b) the platform team must detect when anyone modifies stack resources directly in the console. Which features? Answer: (a) Change sets — create, review the add/modify/replace plan, then execute. (b) Drift detection — scheduled scans reporting resources whose live state differs from the template. Why not just update the stack directly for (a)? Because a direct update executes blindly; a change set is the only way to preview replacements (like a database being replaced instead of updated). Why not CloudTrail for (b)? Because CloudTrail logs API calls but does not compare live state against the template — drift detection is purpose-built for exactly that comparison.

AWS CDK: Infrastructure as Real Code

AWS CDK (Cloud Development Kit) lets you define infrastructure in a real programming language — TypeScript, Python, Java, C#, or Go — instead of YAML. You write constructs , reusable building blocks: an L1 construct maps one-to-one to a CloudFormation resource, an L2 adds sane defaults, and an L3 bundles whole patterns (a Lambda behind an API with a DynamoDB table) into a few lines. The CDK then synthesizes your code into a standard CloudFormation template. The workflow is cdk synth (generate the template — great for review), cdk diff (preview changes, the CDK equivalent of a change set), and cdk deploy (deploy the stack). Because it is real code, you get loops, conditionals, and unit tests for your infrastructure — things YAML cannot do. When a scenario says "the team wants to define infrastructure in TypeScript with reusable components and test it before deploying," that is CDK. The exam's key distinction: CDK always produces CloudFormation underneath — it is a friendlier authoring layer, not a separate provisioning engine.

Exam tip

Writing infrastructure in Python/TypeScript, reusable constructs, cdk deploy — the answer is CDK. If the question asks what CDK generates, the answer is a CloudFormation template: CDK never provisions directly.

Elastic Beanstalk: The Managed Middle Ground

AWS Elastic Beanstalk is for teams who want to deploy code without managing the underlying infrastructure. You upload your application, pick a platform (Java, Node.js, Python, Docker, etc.), and Beanstalk provisions the EC2 instances, load balancer, Auto Scaling group, and monitoring. Two exam areas matter. Deployment policies control how new application versions roll out — and they mirror the strategies from earlier in this chapter: All at once (fastest, downtime possible), Rolling (batches, reduced capacity during deploy), Rolling with additional batch (extra capacity first, no dip), and Immutable (brand-new instances, traffic shifts only after health checks pass). Blue/green on Beanstalk is done differently: you clone the environment and swap the CNAMEs (environment URLs), giving you a fully tested standby environment and instant rollback. If a question asks for the safest Beanstalk deploy, the answer is Immutable (or blue/green via CNAME swap for full environment isolation). .ebextensions are how you customize what Beanstalk does not cover. You drop .config files (YAML or JSON) into a .ebextensions/ folder in your application bundle, and Beanstalk executes them during deployment. The keys the exam tests: option_settings (override Beanstalk settings, like environment variables), packages (install system packages via yum/apt), commands (run shell commands before the app is set up), container_co mmands (run after the app is extracted but before deployment — with leader_only: true for tasks that must run once, like database migrations), and files (write files to the instance, like config files). The classic scenario: "run database migrations exactly once per deployment" — that is a container_commands entry with leader_only: true.

AppConfig: Deploying Configuration Like Code

Not everything that changes is code. Feature flags , throttling limits, and tuning parameters change constantly, and redeploying the whole application just to flip a flag is slow and risky. AWS AppConfig deploys configuration separately from code, with the same safety machinery as code deployments. You store configuration — a JSON/YAML document or a feature flag — in AppConfig, then roll it out with a depl oyment strategy : all-at-once , linear (for example, 50% of targets every 30 seconds), or canary (a small percentage first, then the rest). During the rollout, AppConfig watches validators (a Lambda function that checks the new configuration is sane) and CloudWatch alarms — if validation fails or an alarm fires, it automatically rolls back to the previous configuration. Your application fetches the current configuration at runtime through the AppConfig agent or API, so a flag flip reaches production in seconds with zero redeploys. When a scenario says "gradually roll out a feature flag to 10% of users with automatic rollback on errors — without redeploying," that is AppConfig, not CodeDeploy. CodeDeploy ships code artifacts; AppConfig ships configuration data.

Exam tip

Feature flags + gradual rollout + automatic rollback + no redeploy = AppConfig. The exam loves contrasting it with CodeDeploy: CodeDeploy deploys application revisions (code, task definitions); AppConfig deploys configuration. If the thing being rolled out is a JSON flag rather than a build artifact, it is AppConfig.

Containers: ECR and ECS Basics

Amazon ECR (Elastic Container Registry) is the managed Docker registry: private repositories for your images, with image scanning on push (vulnerability scanning, enhanced by Inspector), lifecycle policies (automatically expire old or untagged images so the registry does not grow forever — "keep the last 20 tagged images, delete untagged after 14 days"), tag immutability (prevent overwriting a release tag), and cross-account/cross-region replication. Amazon ECS (Elastic Container Service) runs those containers. The exam's vocabulary: a task definition is the blueprint (container image, CPU/memory, port mappings, environment variables); a task is a running copy of it; a service keeps the desired number of tasks running and replaces failed ones; a cluster is the logical grouping. Two launch types : EC2 (you manage the instances) and Fargate (serverless — no instances to manage). The critical distinction the exam hammers: the execution role lets ECS itself pull your image from ECR and write logs to CloudWatch, while the task role grants permissions to your application code (read from S3, write to DynamoDB). Mix them up and you get the exam's favorite "the task starts but the app gets AccessDenied" scenario. For blue/green ECS deployments, CodeDeploy needs an ALB with two target groups — the production listener serves blue while the test listener validates green.

Exam tip

Execution role = "ECS the platform needs this to run my task" (pull image, push logs). Task role = "my code needs this to do its job" (call AWS APIs). If containers fail to start or cannot pull the image, suspect the execution role. If the app runs but AWS calls fail, suspect the task role.

End-of-Chapter Test

1. A developer's buildspec.yml runs unit tests in the build phase and pushes the Docker image to ECR in the post_build phase. The team wants builds to reuse downloaded dependencies instead of fetching them every time. Which buildspec section should they configure? A) artifacts B) env C) phases D) cache

2. A CodeDeploy deployment to EC2 instances must run database migration scripts before the new application revision starts on each instance, then verify the application responds correctly after startup. Which AppSpec hooks should the scripts use? A) BeforeInstall for migrations, ValidateService for verification B) BeforeAllowTraffic for migrations, AfterAllowTraffic for verification C) ApplicationStop for migrations, DownloadBundle for verification D) AfterInstall for migrations, BeforeInstall for verification

3. A production service runs on Elastic Beanstalk across 20 EC2 instances. The company requires that capacity never drops below 100% during deployments and will pay for extra instances to achieve it. Rollback speed is not critical. Which deployment policy should they choose? A) All at once B) Rolling C) Rolling with additional batch D) Immutable

4. A Lambda function serves a checkout API through the prod alias. The team wants 10% of traffic on the new version for 10 minutes, automatic rollback if the error-rate alarm fires, and a validation function executed before any traffic shifts. They use SAM. Which configuration meets all requirements? A) DeploymentPreference: AllAtOnce with the alarm in Alarms B) DeploymentPreference: Canary10Percent10Minutes with Alarms and a PreTraffic hook C) Manually update the alias weights to 90/10 and watch the dashboard D) CodeDeployDefault.LambdaLinear10PercentEvery1Minute on the function

5. A CloudFormation template deploys a production database. Before applying an update, the team must see whether the update will replace (rather than modify) the database. After deployment, they must detect whether anyone changed the database's security group directly in the console. Which two features address these needs? A) Change sets for the preview; drift detection for the console changes B) Stack policies for the preview; change sets for the console changes C) Drift detection for the preview; CloudTrail for the console changes D) Nested stacks for the preview; StackSets for the console changes

6. An Elastic Beanstalk application needs environment-specific database connection strings and a schema migration that runs exactly once per deployment. How should the developer configure this? A) commands for the connection strings; files for the migration B) packages for the connection strings; services for the migration C) option_settings for the connection strings; container_commands with leader_only for the migration D) Hardcode the connection strings; run the migration manually after each deploy

7. An ECS task starts successfully and pulls its image, but the application code inside the container gets AccessDenied when writing to DynamoDB. What is the most likely cause? A) The task execution role is missing dynamodb:PutItem B) The task role is missing dynamodb:PutItem C) The container image was not scanned on push D) The task definition has the wrong launch type

8. A team defines a Lambda function, a REST API, and a DynamoDB table for a new microservice. They want the shortest possible template and CLI-based deployment with local testing before pushing. Which approach fits best? A) Raw CloudFormation with three AWS::Lambda::Function, AWS::ApiGateway::RestApi, and AWS::DynamoDB::Table resources B) Elastic Beanstalk with a Docker platform C) CodePipeline with manual approval actions D) AWS SAM with AWS::Serverless::Function, AWS::Serverless::Api, and AWS::Serverless::SimpleTable, deployed with sam build and sam deploy, tested with sam local

9. A team deploys a web application to EC2 with CodeDeploy. They want the fastest possible deployment and accept that all instances update simultaneously with brief downtime. Which deployment configuration should they choose? A) OneAtATime B) HalfAtATime C) AllAtOnce D) Rolling with additional batch

10. A team needs to roll out a new feature flag to 10% of users first, automatically roll back if error rates spike, and avoid redeploying the application. Which service should they use? A) CodeDeploy with a canary deployment configuration B) AWS AppConfig with a canary deployment strategy and CloudWatch alarms C) Elastic Beanstalk with an immutable deployment policy D) CloudFormation with a change set

11. A CloudFormation template needs to reference the DNS name of an Application Load Balancer created in the same stack, and also pull a database endpoint exported from a different stack. Which intrinsic functions should the developer use? A) Ref for the ALB DNS name; Fn::ImportValue for the cross-stack database endpoint B) Fn::GetAtt for the ALB DNS name; Fn::ImportValue for the cross-stack database endpoint C) Fn::Sub for both values D) Fn::Join for the ALB DNS name; Ref for the cross-stack database endpoint

Answer Key

1. D — The cache section (with paths:) tells CodeBuild to persist directories like dependency folders between builds. Why not A? artifacts declares what the build produces for the next stage, not what it reuses. Why not B? env injects variables and secrets; it stores nothing between runs. Why not C? phases defines the ordered steps (install/pre_build/build/post_build) — caching is a separate top-level section. 2. A — On EC2, BeforeInstall runs after the old version stops but before new files land (the right moment for migrations), and ValidateService runs after ApplicationStart specifically to verify the service works. Note that CodeDeploy hooks execute on every target instance — there is no built-in "run once" semantic. (For a migration that must run exactly once per deployment on Beanstalk, you'd use container_commands with leader_only — see Q6.) Why not B? BeforeAllowTraffic/AfterAllowTraffic are Lambda and ECS hooks for traffic shifting — EC2 AppSpecs use the install/start/validate lifecycle. Why not C? ApplicationStop halts the old version and DownloadBundle fetches the revision; neither is the migration or verification point. Why not D? AfterInstall runs after files are copied but the app has not started — migrations there are possible but the ordering is wrong relative to startup, and BeforeInstall cannot verify a service that is not running. 3. C — On Elastic Beanstalk, rolling with additional batch launches extra instances before updating the fleet, so capacity never drops below 100% during the deploy. Why not A? All at once risks downtime while instances restart — the opposite of the requirement. Why not B? Rolling updates in batches with reduced capacity during the deploy window. Why not D? Immutable also protects capacity and rolls back faster, but it briefly runs a full second fleet — overkill when the scenario says rollback speed is not critical and the team only agreed to pay for an extra batch. 4. B — Canary10Percent10Minutes shifts 10% for ten minutes, Alarms triggers automatic rollback, and the PreTraffic hook runs validation before any shift. Why not A? AllAtOnce moves 100% immediately — no canary at all. Why not C? Manual alias moves have no automatic rollback and no enforced waiting period; a distracted engineer is the rollback plan. Why not D? Linear10PercentEvery1Minute ramps 10% per minute (full shift in ~10 minutes with no bake time at 10%) — it does not match "10% for 10 minutes then proceed," and it names a CodeDeploy config rather than the SAM DeploymentPreference the team uses. 5. A — A change set previews exactly which resources will be added, modified, or replaced before execution; drift detection compares live resource state against the template to catch out-of-band console changes. Why not B? Stack policies guard against updates to protected resources but do not preview anything; change sets do not monitor live state. Why not C? Drift detection looks backward at existing changes, not forward at planned ones; CloudTrail logs API calls but never compares live state to the template. Why not D? Nested stacks organize large templates and StackSets deploy across accounts/regions — neither previews replacements nor detects drift. 6. C — option_settings sets Beanstalk environment properties (the standard place for connection strings per environment), and container_commands with leader_only: true runs the migration once on a single instance after the app is extracted but before deployment completes. Why not A? commands run before the application is set up (too early for app-aware migrations) and files just writes files to disk. Why not B? packages installs OS packages and services manages daemons — neither sets config values nor runs one-time migrations. Why not D? Hardcoding secrets is never acceptable, and manual migrations defeat the purpose of automated deployments. 7. B — The task started and pulled its image, so the execution role works; the application's own AWS calls use the task role, which evidently lacks the DynamoDB permission. Why not A? The execution role is for ECS platform actions (pull image, write logs) — the image pulled fine, so it is healthy. Why not C? Image scanning is a security control; unscanned images still run. Why not D? The wrong launch type would prevent the task from starting at all, not cause in-container AccessDenied errors. 8. D — SAM's serverless resource types compress the template dramatically, sam build/sam deploy handle packaging and deployment from the CLI, and sam local emulates Lambda and API Gateway locally for pre-push testing. Why not A? Raw CloudFormation works but needs far more lines (explicit roles, permissions, API resources/methods) and has no local emulation. Why not B? Beanstalk is for long-running app servers, not a Lambda+API+DynamoDB serverless design. Why not C? CodePipeline orchestrates releases; it does not define infrastructure or offer local testing. 9. C — AllAtOnce pushes to every instance simultaneously — fastest, with the tradeoff of simultaneous downtime if the release is bad. Why not A? OneAtATime updates a single instance before moving on — slowest, safest. Why not B? HalfAtATime is the middle ground, not the fastest. Why not D? Rolling with additional batch is an Elastic Beanstalk policy, not a CodeDeploy EC2 configuration — the exam tests whether you match the strategy to the service. 10. B — AppConfig deploys configuration (feature flags) separately from code, with canary/linear strategies, validators, and automatic rollback on alarms — no redeploy needed. Why not A? CodeDeploy ships code artifacts and task definitions, not feature-flag configuration. Why not C? Beanstalk immutable deploys full application versions — overkill for a flag flip and still a redeploy. Why not D? Change sets preview infrastructure changes; they do not roll out runtime configuration with gradual traffic shifting. 11. B — Fn::GetAtt returns a resource's attributes (like DNSName); Fn::ImportValue pulls an exported value from another stack. Why not A? Ref returns a resource's physical ID (for an ALB, its name — not the DNS name). Why not C? Fn::Sub does string substitution; it cannot fetch resource attributes or cross-stack exports. Why not D? Fn::Join concatenates strings — it does not retrieve anything.

Answer key