Chapter 3

Testing and Deployment

AWS Certified Developer – Associate (DVA-C03) Study GuideDomain 3 · 22% of the examBased on the official DVA-C03 exam objectives

Domain 3 accounts for 22% of the DVA-C03 exam. In the previous version this domain was simply called

"Deployment"; AWS renamed it Testing and Deployment because testing is now a first-class part of the domain, with its own task covering unit and integration testing, mocking, test automation in pipelines, and

AI-assisted test generation. The rest of the domain covers familiar ground: CI/CD pipelines with CodePipeline,

CodeBuild, and CodeDeploy; deploying with AWS SAM and the AWS CDK; deployment strategies such as canary and blue/green; and managing artifacts and per-environment configuration with Amazon ECR and AWS

AppConfig.

Expect scenario-based questions: a pipeline failing at a specific stage, a deployment that must shift traffic gradually with automatic rollback, a team that needs production and test configurations kept apart. Learn each service's mechanics well enough to place the failure or the requirement in the right tool.

CI/CD on AWS

AWS offers three managed services that together form a complete delivery pipeline: AWS CodePipeline orchestrates the workflow, AWS CodeBuild compiles code and runs tests, and AWS CodeDeploy delivers the built artifact to EC2 instances, Lambda functions, or Amazon ECS services. Most exam scenarios describe a pipeline and ask which service or which configuration element is responsible for a behavior, so keep the division of labor clear: CodePipeline moves artifacts between stages, CodeBuild transforms source into artifacts, and

CodeDeploy controls how a new version replaces the old one.

CodePipeline: stages, actions, and artifacts

A pipeline is a sequence of stages, and each stage contains one or more actions. An action has a category -

Source, Build, Test, Deploy, Approval, or Invoke - and a provider that does the work (for example, CodeBuild for a build action or CodeDeploy for a deploy action). Actions within a stage can run in parallel if they do not depend on each other; stages always run in sequence, and every action in a stage must succeed before the pipeline transitions to the next stage.

Key mechanics to know:

artifact store, by default an S3 bucket it manages (you can specify your own bucket, optionally encrypted with a KMS key, which is required for cross-account pipelines). Source actions produce the first artifact - typically a zip of the repository - and each downstream action receives artifacts from the actions before it.

can trigger a pipeline), or third-party Git providers such as GitHub, Bitbucket, and GitLab, which connect through AWS CodeStar Connections. A push trigger depends on the provider: GitHub connections support push triggers with branch and file-path filters; S3 sources trigger on object upload; an EventBridge rule can also start a pipeline on a schedule or in response to repository events.

filters, additional execution modes, and stage rollback (rolling a stage back to a previous successful execution). When a question hinges on one of those features, the answer assumes a V2 pipeline.

optionally sending an SNS notification with a link. Approval actions are the standard human gate before a production deploy stage, and IAM policies determine who may act on them.

not run. You can retry a failed stage or disable a stage transition (with a required reason) to let work continue around a stage - a detail that appears in questions about hotfixes bypassing a blocked stage.

Exam tip

Questions often describe a pipeline that "deploys the old code" or "never triggers." Work through the chain in order - source trigger, artifact store contents, build output artifact, deploy action input. The break is almost always in one link: a source action watching the wrong branch, a build action whose output artifact is not wired to the deploy action, or an artifact store the deploy account cannot read.

CodeBuild: buildspec and environments

CodeBuild runs build jobs inside managed containers. A build project defines the source provider, the environment, and one or more artifacts. The build itself is driven by a buildspec file (buildspec.yml by default, at the root of the source), a YAML file with four phases:

Phaseinstall
pre_buildbuild
post_buildPurpose
Install runtimes and dependencies; declare runtime-versions hereCommands that run before the build, e.g., logging in to ECR, installing packages
The actual compile/test/package commandsCommands that run after the build, e.g., pushing a Docker image, printing status

Each phase holds a list of commands. Phases run in order regardless of failure in an earlier phase (a failing command fails the build overall, but CodeBuild still attempts later phases unless you use on-failure: ABORT in the phase). The buildspec can also declare:

artifacts - files to collect as the build output, with base-directory, discard-paths, and support for

secondary artifacts (multiple named outputs from one build).

cache - paths to cache between builds, stored in S3 or in a local cache, to speed up dependency downloads.

A question about builds being slow because dependencies download every time points here.

Execution modes. By default a pipeline runs in superseded mode: a newer execution supersedes and stops an older one that is still running. Queued mode (V2 only) lets executions wait and run in order;

parallel mode (V2 only) lets multiple executions of the same stage run concurrently.

env - environment variables, including values pulled from Parameter Store (parameter-store) and

Secrets Manager (secrets-manager) so no secrets are hard-coded in the buildspec, plus

exported-variables passed to downstream actions.
reports - test and coverage reports (JUnit XML, Cucumber JSON, and other formats) that CodeBuild

publishes for the project's test actions.

The environment defines the compute (managed images for common runtimes, a custom Docker image, or

Lambda compute for fast-starting builds) and the compute type. Two settings matter frequently on the exam:

privileged mode must be enabled to build Docker images (the build needs access to the Docker daemon), and a project can be placed inside a VPC when the build must reach private resources such as an RDS instance during integration tests - with the corresponding need for the right subnets and security groups. CodeBuild also supports batch builds (build lists, matrices, and fan-out graphs) for monorepos and multi-configuration builds, build timeouts, webhook triggers from Git providers independent of CodePipeline, and build badges.

A common scenario: a build succeeds when run manually but fails in the pipeline. The usual cause is the service role - the pipeline's CodeBuild project runs under its own IAM role, which may lack permissions (for example,

ecr:GetAuthorizationToken or access to a Secrets Manager secret) that a developer's own credentials have.

CodeDeploy: applications, deployment groups, and AppSpec

CodeDeploy automates deployments to three compute targets: EC2/on-premises instances, AWS Lambda, and

Amazon ECS. Every deployment is organized the same way:

function, or an ECS service) and holds the deployment configuration, alarm configuration, and rollback settings.

deployment strategies section).

AppSpec for ECS, or a function version plus AppSpec for Lambda.

The AppSpec file is the contract between CodeDeploy and your application. For EC2 it is appspec.yml at the root of the revision bundle: it maps files to destinations, sets permissions, and defines lifecycle hooks - shell scripts or executables that run at defined points. For Lambda there is no file copying; the AppSpec (YAML or

JSON, supplied directly to CodeDeploy) names the function, the alias, and the current and target versions, plus optional validation hook functions. For ECS the AppSpec (usually embedded in the task definition request) names the new task definition and the production listener's container and port.

For EC2 and on-premises deployments CodeDeploy also distinguishes in-place deployments (the existing instances are updated one batch at a time, with downtime proportional to the configuration) from blue/green deployments (a fresh set of instances is provisioned in a copied Auto Scaling group, traffic is rerouted through the load balancer after validation, and the old instances are terminated after a wait period). Blue/green for EC2 requires an Application Load Balancer or Classic Load Balancer and an Auto Scaling group.

Deployment groups can enable automatic rollback: redeploy the last known good revision when a deployment fails or when a configured CloudWatch alarm enters ALARM state during the deployment. They also support deployment triggers via SNS (for example, notify on deployment success, failure, or stop) and load balancer settings that deregister instances during in-place deployments so they receive no traffic while being updated.

Common trap: CodeDeploy does not build anything, and CodeBuild does not deploy anything. If a scenario says "the pipeline must compile the code and then deploy it to a fleet," you need both services - typically wired together by CodePipeline, which is the only one of the three that orchestrates the others.

Definition

buildspec. The buildspec is a YAML file (buildspec.yml, at the root of the source by default) that tells

CodeBuild what to do: commands grouped into the install, pre_build, build, and post_build phases, plus declarations for artifacts, cache, env, and reports. It matters because nearly every CodeBuild behavior the exam tests - what gets built, what the output artifact contains, where secrets come from - is defined in this one file rather than in console settings.

Core concept

Stages do not pass code to each other directly - artifacts do. Each action consumes the output artifact of an earlier action, so a build can compile perfectly and the deployment can still ship stale code if the output artifact is declared wrong or the deploy action is wired to the wrong input. When a scenario's symptom is "the pipeline ran green but production didn't change," suspect the artifact wiring before you suspect any service's code path.

Infrastructure as Code Deployment: SAM and AWS CDK

Both AWS SAM and the AWS CDK ultimately deploy CloudFormation stacks, but they start from opposite ends.

SAM extends CloudFormation templates with shorthand resource types for serverless applications. The CDK lets you define infrastructure in a programming language, which it synthesizes into a CloudFormation template. The exam expects you to know each tool's workflow commands and what happens during a deployment.

SAM templates and the sam build / sam deploy workflow

A SAM template is a CloudFormation template with the transform Transform: AWS::Serverless-2016-10-31 and serverless resource types: AWS::Serverless::Function, ::Api, ::HttpApi, ::SimpleTable,

::StateMachine, ::LayerVersion, and ::Application (nested apps from the SAM Serverless Application

Repository or local templates). The shorthand matters: a single AWS::Serverless::Function expands into a

Lambda function, an IAM execution role (if you do not supply one), and any event source mappings and permissions implied by its Events property. A Globals section sets properties shared by all resources of a type - runtime, timeout, memory, environment variables - with resource-level properties overriding globals.

The SAM CLI workflow:

1.

sam build compiles the application. It reads the template, builds each function (installing dependencies

per runtime), and writes the result to .aws-sam/build. Use --use-container to build inside

Lambda-like Docker images - needed when dependencies are native or the local runtime differs - and

--cached to reuse unchanged dependency layers between builds.

2.

sam deploy packages and deploys. The first run should use --guided, which prompts for a stack name,

region, parameter values, and whether to allow IAM role creation, then saves the answers to

samconfig.toml. Later deploys read that file; named environments in samconfig.toml (for example
[dev.deploy.parameters] and [prod.deploy.parameters]) are how one template deploys with

different parameters per environment, selected with sam deploy --config-env prod.

3. Capabilities. Because SAM creates IAM resources, deployment usually requires --capabilities

CAPABILITY_IAM (and CAPABILITY_NAMED_IAM for explicitly named roles/policies). Deploying nested

applications adds CAPABILITY_AUTO_EXPAND.

4.

sam sync is the development accelerator: it watches for file changes and pushes code (and, where

possible, infrastructure deltas) directly to the cloud stack without a full CloudFormation deployment - for fast iteration only, not a release mechanism. sam local invoke and sam local start-api run functions and APIs locally in Docker containers for testing before deployment.

5.

sam pipeline init scaffolds a CI/CD pipeline (CodePipeline, GitHub Actions, GitLab CI/CD, and others)

with the IAM roles and artifact bucket a SAM application needs, using staged dev/prod environments by default.

Because SAM deployments are CloudFormation deployments, two CloudFormation behaviors apply directly and are exam favorites. A failed stack update triggers a rollback to the previous good state by default. And before applying an update you can generate a change set - CloudFormation's preview of exactly which resources will

AWS CDK: synth, bootstrap, and deploy

A CDK application is written in TypeScript, Python, Java, C#, or Go using constructs - reusable components that represent one resource (L1 constructs map 1:1 to CloudFormation resources) or a whole pattern (L2 constructs add sensible defaults, helper methods, and IAM grants; L3 constructs, or patterns, combine several resources).

The workflow centers on the CDK CLI:

cdk bootstrap prepares an AWS environment (account + Region) for CDK deployments. It creates the

CDKToolkit CloudFormation stack containing an S3 staging bucket for file assets, an ECR repository for

Docker image assets, and the IAM roles the CLI assumes during deployment. Bootstrapping is required once per environment, and again when a newer bootstrap version is needed.

cdk synth runs the app and emits the synthesized CloudFormation template(s) to cdk.out. Synthesizing

deploys nothing - it is the way to inspect exactly what will be created, and it is what CI systems run to be added, modified, or replaced - review it, and only then execute it. SAM CLI supports the same review: sam

deploy --confirm-changeset displays the change set it creates and waits for approval before executing it.

produce the artifact that a later stage deploys.

cdk diff compares the synthesized template with the deployed stack and reports resource and security

changes (including IAM policy and security group changes) - the CDK equivalent of reviewing a change set before committing to it.

cdk deploy uploads assets, then creates and executes a change set by default ( --method=direct skips

the change set for faster, less auditable deployments). It streams stack events to the terminal and, like

CloudFormation generally, rolls the stack back to its previous state if the update fails.

cdk deploy --hotswap is the developer convenience feature: for changes CloudFormation would handle

slowly - Lambda function code and configuration, ECS task definitions, Step Functions state machines, and a few others - it detects that the change only touches supported properties and applies it directly through the service APIs, bypassing CloudFormation entirely. If a change cannot be hotswapped, the command fails unless you add --hotswap-fallback, which falls back to a full deployment. Hotswap is a development accelerator: it can leave the stack's recorded state inconsistent with what CloudFormation believes, and it is explicitly not recommended for production deployments.

deployment-time values can come from context (cdk.json or the -c flag) - the CDK pattern-parallels SAM's parameter overrides for per-environment configuration.

CDK also has its own pipeline library, CDK Pipelines, a construct that builds a self-mutating CodePipeline: the pipeline first updates itself from the CDK code, then synthesizes and deploys the application's stacks to staged environments with optional manual approvals and test steps.

SAM vs CDK at a glance

AspectInput languageScope
Deployment engineKey commandsPre-deployment review
Fast dev iterationTraffic shifting built-inAWS SAM
YAML/JSON templateServerless-first (Lambda, API Gateway, DynamoDB, Step Functions)CloudFormation
sam build, sam deploy, sam sync, sam localChange sets (under the hood of sam deploy)sam sync, sam local
DeploymentPreference on functions (uses CodeDeploy)AWS CDKTypeScript, Python, Java, C#, Go
All of AWS, any resourceCloudFormation (synthesized templates)cdk bootstrap, cdk synth, cdk diff, cdk deploy
cdk diff; change-set deployment by defaultcdk deploy --hotswap, cdk watchVia CodeDeploy constructs or Lambda alias routing
Definition

SAM template and the serverless transform. A SAM template is a CloudFormation template that declares

Transform: AWS::Serverless-2016-10-31. The transform makes CloudFormation expand SAM's shorthand

serverless resource types (such as AWS::Serverless::Function) into the full set of underlying resources - the function, its execution role, event source mappings, and permissions - at deployment time. It matters because a few lines of SAM shorthand can create far more infrastructure than the template literally lists.

Exam tip

Exam tip. sam sync and cdk deploy --hotswap are development accelerators, not release mechanisms. If a scenario asks how a team should deploy to production, an answer built on either one is wrong no matter how convenient it sounds - production answers go through a real CloudFormation deployment, with the change set reviewed and rollback intact.

Check yourself

1. A SAM deployment fails because the stack requires capabilities to be acknowledged. The template creates an

IAM role with an explicitly chosen name. Which capabilities must be granted?

2. A developer runs cdk synth in CI and expects the stack to update, but nothing changes in the account.

Why?

Deployment Strategies

The deployment strategy determines how a new version replaces the old one and how quickly you can get back if something goes wrong. The exam repeatedly presents a requirement - "shift traffic gradually," "roll back automatically if errors spike," "keep the old version running until the new one is validated" - and asks which strategy or which named configuration satisfies it. Learn the vocabulary first.

StrategyAll-at-onceHow it works
New version replaces the old everywhere immediatelyTraffic/risk profileFastest; highest risk; any rollback is a full redeploy

Answers: 1. CAPABILITY_NAMED_IAM alone - it is required for IAM resources with custom names, and it also covers unnamed IAM resources; CAPABILITY_IAM by itself is not enough for named resources. 2. cdk synth only renders the CloudFormation template into cdk.out and deploys nothing; only cdk deploy creates and executes the change set.

StrategyRolling (in-place)
Blue/greenCanaryLinear
How it worksInstances/containers are replaced in batches while the rest keep serving
A complete new environment (green) is provisioned beside the old (blue); traffic switches only after validationA small percentage of traffic goes to the new version first; the rest follows after a bake period if healthyTraffic shifts in equal increments at fixed intervals (e.g., 10% every 3 minutes)
Traffic/risk profileSome downtime per batch; capacity reduced during deployment
Near-zero downtime; fast rollback by switching back; double infrastructure during the switchLow blast radius; needs traffic-shifting support and monitoringPredictable, gradual; slower than canary's single step

CodeDeploy deployment configurations

CodeDeploy names these strategies per compute platform. The predefined names are testable facts - questions quote them directly.

EC2/on-premises (in-place only): CodeDeployDefault.AllAtOnce, CodeDeployDefault.HalfAtATime,

CodeDeployDefault.OneAtATime. The batch size determines how many instances are offline at once. A

minimum healthy hosts setting (a count or a percentage of the fleet) stops the deployment if too many instances fail, protecting capacity.

Amazon ECS: CodeDeployDefault.ECSAllAtOnce, ECSCanary10Percent5Minutes,

ECSCanary10Percent15Minutes, ECSLinear10PercentEvery1Minute, ECSLinear10PercentEvery3Minutes.

Lambda traffic shifting: aliases and deployment preferences

Lambda versions are immutable; aliases are named pointers to versions, and an alias can point at two versions with weights - the routing configuration. That is the mechanism underneath every Lambda canary: CodeDeploy

(or SAM on top of it) publishes a new version, points the alias mostly at the old version with a small weight on the new one, waits, and then moves the weight to 100% on the new version.

With SAM you rarely configure CodeDeploy by hand. Instead, a function declares a DeploymentPreference:

Lambda: CodeDeployDefault.LambdaAllAtOnce, LambdaCanary10Percent5Minutes,

LambdaCanary10Percent10Minutes, LambdaCanary10Percent15Minutes, LambdaCanary10Percent30Minutes

, LambdaLinear10PercentEvery1Minute, LambdaLinear10PercentEvery2Minutes,

LambdaLinear10PercentEvery3Minutes, LambdaLinear10PercentEvery10Minutes. The names encode the

strategy and the interval; custom configurations can define other percentages and intervals.

AutoPublishAlias: live
DeploymentPreference:
Type: Linear10PercentEvery1Minute
Alarms:
- !Ref AlarmLogicalId
Hooks:
PreTraffic: !Ref PreTrafficHookFunction
PostTraffic: !Ref PostTrafficHookFunction

SAM generates the CodeDeploy application and deployment group for you. Three elements of this block are worth memorizing: AutoPublishAlias (SAM publishes a new version on each deploy and points the alias at it),

Alarms (a CloudWatch alarm in ALARM state during the shift makes CodeDeploy roll back automatically to the previous version), and Hooks (PreTraffic and PostTraffic Lambda functions that validate the new version - running smoke tests, for instance - and can fail the deployment before any production traffic moves).

API Gateway has its own canary mechanism for API deployments: a canary release on a stage routes a configurable percentage of requests to the new deployment, can override stage variables for canary requests, and is either promoted (the canary becomes the production deployment) or removed. Questions distinguish this from Lambda alias weighting - the API Gateway canary acts on the API deployment, not on function versions.

ECS deployments: rolling updates vs blue/green

An ECS service can be deployed in two controller styles. With the ECS rolling update controller, the service scheduler replaces tasks gradually, governed by minimumHealthyPercent and maximumPercent on the service's deployment configuration: for example, maximumPercent 200 with minimumHealthyPercent 100 lets the scheduler start new tasks before stopping old ones, avoiding any capacity dip. ECS also offers a deployment circuit breaker: if new tasks keep failing to stabilize, ECS automatically rolls the service back to the last completed deployment - the simplest automatic-rollback answer for rolling ECS deployments.

With the CodeDeploy blue/green controller, CodeDeploy creates a replacement task set (green) beside the original (blue). It uses two target groups and two listeners on an Application Load Balancer: a production listener and a test listener. The deployment sequence is testable in detail:

1. Green tasks start and register with the green target group.

2. The test listener lets you (or a validation hook) exercise the green tasks before any production traffic moves.

3. After the bake/approval window, production traffic shifts from blue to green according to the deployment configuration (all at once, canary, or linear).

4. Blue tasks remain running for a termination wait time, so a rollback during that window is just a traffic switch back. After the wait, CodeDeploy terminates the blue task set.

Lifecycle hooks compared

Hooks are where each platform runs validation logic. The platforms differ - EC2 hooks are scripts on the instance, Lambda and ECS hooks are Lambda functions invoked by CodeDeploy - and the exam exploits that difference.

PlatformEC2 in-placeEC2 blue/gree n
LambdaECS blue/gree nHook style
Scripts in the AppSpec hooks section, run by the CodeDeploy agentSame scripts, plus traffic-blocking hooks around deregistrationLambda validation functions named in the AppSpec
Lambda validation functions named in the AppSpecKey hooks (in order)ApplicationStop -> DownloadBundle -> BeforeInstall -> Install -> AfterInstall -> ApplicationStart -> ValidateService
Adds BeforeBlockTraffic / BlockTraffic / AfterBlockTraffic and AllowTraffic steps around the in-place sequenceBeforeAllowTraffic -> (traffic shifts per configuration) -> AfterAllowTrafficBeforeInstall -> Install -> AfterInstall -> AllowTestTraffic -> BeforeAllowTraffic -> AllowTraffic -> AfterAllowTraffic

A hook function that returns failure (or times out) fails the deployment and triggers rollback if automatic rollback is enabled - that is how a failing smoke test prevents a release without any human watching.

Rollback triggers and automatic rollback

Consolidate the rollback mechanisms, because questions blur them:

when a monitored CloudWatch alarm fires. It redeploys the last known good revision (EC2/ECS) or shifts the alias fully back to the previous version (Lambda).

updates you can configure rollback triggers (alarms watched during a monitoring window) through the console/CLI update flow, and --rollback-configuration on APIs. In SAM/CDK terms this is the safety net when the infrastructure change itself fails, distinct from CodeDeploy's application-level rollback.

tasks failing to reach steady state.

artifacts and configuration section below).

Exam tip

Read rollback questions literally. "Roll back the deployment" -> CodeDeploy automatic rollback or the ECS circuit breaker. "Roll back the stack" -> CloudFormation behavior. "Roll back the configuration" -> AppConfig. The noun in the question tells you the service.

Approvals: human gates and AI-assisted review

Gradual traffic shifting handles runtime risk; approvals handle change risk - a human decision before production is touched. The mechanisms:

console, CLI, or an SNS-delivered link. Place it between a staging deploy/test stage and the production deploy stage.

green and validation hooks pass.

on AWS this means Amazon Q Developer and similar assistants are used around the approval step:

summarizing what a change set or cdk diff will modify, flagging high-risk changes (IAM policy widenings, resource replacements, security group changes) in a proposed deployment, and drafting the risk summary a human approver reads. The governance rule the exam tests is unchanged: AI assistance informs the approval; it does not replace the accountable human gate in regulated or production paths, and pipelines still express the gate as a manual approval action. Treat any option that has an AI autonomously approving its own generated change to production as the wrong answer, and options that use AI output to make the human review faster and better informed as the right pattern.

Definition

canary deployment. A canary deployment shifts a small percentage of traffic (commonly 10%) to the new version for a bake period while the rest stays on the old version; if monitoring stays healthy, the remainder of the traffic follows. It matters because it limits the blast radius of a bad release to a small slice of users and makes rollback a quick traffic shift back rather than a redeploy.

Definition

deployment configuration. In CodeDeploy, a deployment configuration is the named rule set that controls how quickly a new version replaces the old one - all at once, in instance batches for EC2, or by traffic percentage and interval for Lambda and ECS canary and linear shifts - including the minimum healthy hosts setting that protects EC2 fleet capacity. It matters because exam questions quote the predefined configuration names directly and expect you to decode the strategy from the name.

Definition

alias routing. Alias routing is Lambda's traffic-shifting mechanism: an alias is a named pointer to a function version, and its routing configuration can split invocations between two versions by weight (for example, 90% to the old version and 10% to the new one). It matters because it is the mechanism CodeDeploy and SAM actually adjust to execute canary and linear deployments - and rolling back means returning the weight fully to the previous version.

Check yourself

1. A Lambda deployment must send 10% of traffic to the new version for 10 minutes, then shift the rest. Which predefined CodeDeploy configuration does this describe?

2. During an ECS blue/green deployment, a smoke test against the green task set fails before any production traffic has shifted. What is production traffic running on, and why is recovery straightforward at this point?

Answers: 1. CodeDeployDefault.LambdaCanary10Percent10Minutes - the name encodes the platform, the canary shape, the percentage, and the bake duration. 2. Production traffic is still served entirely by the blue task set, because the test listener exists precisely so green can be validated before the production listener shifts; the failed green set can simply be terminated with no rollback of live traffic required.

Testing Applications

The renamed domain makes testing a core skill: writing unit and integration tests for AWS-backed code, mocking AWS services so tests run fast and free, wiring test automation into pipelines, and using AI assistants to generate and maintain tests.

Unit testing and mocking AWS services

A unit test exercises one function or module in isolation. Code that calls AWS services creates a problem: a real call to DynamoDB or SQS in every test run is slow, costs money, needs credentials, and makes tests depend on shared state. The standard solution is to mock or stub the AWS SDK client so the test controls the service's responses:

real client and returns queued responses (and can assert the request parameters); in JavaScript,

aws-sdk-client-mock mocks v3 SDK clients; in Java, Mockito mocks SDK interfaces.

in-process, so code runs against a fake DynamoDB table or S3 bucket. This blurs into lightweight integration testing.

local stand-ins with real service semantics, useful for integration tests that do not justify a cloud deployment.

Design rules that show up in scenarios: inject the SDK client as a dependency (or construct it outside the handler) so tests can substitute a mock; keep the Lambda handler thin and the business logic in plain functions that need no AWS calls at all; and assert on behavior for the paths that matter - success, throttling/error responses from the stub, and malformed input.

Integration testing in the pipeline

Integration tests verify components together: the function against a real DynamoDB table, the API against its authorizer, the pipeline of services end to end. They run against real AWS resources - usually in a dedicated test account or a temporary stack deployed from the same SAM/CDK template - so they are slower and are placed deliberately in the delivery flow:

1. Build stage runs unit tests (CodeBuild test actions can emit JUnit/Cucumber reports that CodeBuild and the pipeline surface; a failed report fails the stage).

2. Deploy to a test environment - a separate stack/stage with its own resources.

3. Test stage runs integration and end-to-end tests against that environment (CodeBuild running a test suite, or an Invoke action calling a test-runner Lambda; AWS Device Farm fills this role for mobile apps).

4. Approval and promotion - passing tests gate the manual approval or automatic promotion to production.

Two practices distinguish good answers here. Ephemeral environments: create the test stack per pipeline run and tear it down afterward, so tests are isolated and cost is bounded. And test data hygiene: seed known data, use unique identifiers per run, and never run integration tests against production data. A scenario where "tests pass individually but fail when the pipeline runs them in parallel" points at shared test state - the fix is isolation, not retries.

AI-assisted test generation and regression testing

AI-assisted development applies to testing as directly as to writing features, and the exam now names it:

tests for existing code - generating cases for boundary conditions, error paths, and SDK mock setups that developers commonly skip. Generated tests are a starting point: they must be reviewed, because an assistant will happily assert whatever the current code does, including its bugs.

working behavior still works. AI assistance helps by identifying which existing tests a change affects, proposing new tests for changed paths, and triaging failures (grouping failures by likely root cause, summarizing a stack trace against the diff). In the pipeline, regression suites typically run in the build or test stage on every commit for fast feedback, with the full suite gating promotion.

decisions. The exam's pattern, here as elsewhere in the AI content, is that AI speeds up authoring and analysis while humans remain responsible for correctness and for what the pipeline enforces.

Common trap: "Use an AI assistant to generate tests" and "skip testing because the code was AI-generated"

are opposite answers. AI-generated application code increases, not decreases, the need for a real suite - and generated tests that merely mirror current behavior do not satisfy a requirement to verify specified behavior.

Core concept

A stubbed unit test proves your code reacts correctly to the responses you told the stub to return - it cannot prove the real service behaves that way, that your IAM permissions allow the call, or that the request is valid against the live API. That gap is exactly why integration tests against real resources still exist: stubs buy speed, isolation, and determinism, while integration tests buy truth about how the pieces behave together.

Artifacts and Configuration

A deployment needs two things besides code: the built artifact to run (an image, a zip, a package) and the configuration that tells it which environment it is in. Domain 3 tests both: ECR as the image registry in the delivery flow, environment-specific configuration without rebuilding artifacts, and AWS AppConfig for deploying configuration itself safely.

ECR image workflows

Amazon Elastic Container Registry (ECR) is the registry that feeds ECS, EKS, and Lambda container-image deployments, and it sits in the middle of the CI/CD flow:

1. CodeBuild builds and pushes. A build project with privileged mode runs docker build, authenticates with aws ecr get-login-password piped to docker login, tags the image (a common convention: the

Git commit hash or build ID, plus latest only as a convenience), and pushes to the repository. In

CodePipeline, an ECR source action can then trigger a downstream pipeline on each push, or the push itself is the last step of a build stage whose output feeds an ECS deploy action.

3. Repository hygiene is examinable. Image scanning (basic scanning on push, or enhanced scanning through Amazon Inspector) flags OS and library vulnerabilities in pushed images - a pipeline can gate on findings. Lifecycle policies automatically expire images by age or count (e.g., keep the last 30 tagged images, delete untagged images after 7 days), controlling storage cost. Tag immutability prevents a pushed tag from being overwritten, which guarantees that the image a digest refers to cannot silently change - pair it with commit-hash tags. Replication copies images to other Regions or accounts for multi-Region deployments, and pull-through cache rules mirror public registries for dependencies.

2. Deploy actions consume the image. An ECS deploy action (CodePipeline's ECS provider, or CodeDeploy for blue/green) needs to know which image to run; the pipeline passes an imagedefinitions.json artifact mapping container names to image URIs (with digest or tag) produced by the build.

Lambda functions packaged as container images follow the same path - the image must be in ECR in the same account as the function, and each deployment publishes a new version pointing at the new image. SAM (

PackageType: Image with a Dockerfile) and the CDK (Docker image assets, which it stages to a bootstrap ECR

repository automatically) both front this workflow.

For completeness: ZIP-based Lambda deployments and EC2 bundles travel through S3 instead (CodeDeploy revisions, SAM's packaging bucket), and language package artifacts (npm, PyPI, Maven) are the territory of AWS

CodeArtifact, which can also proxy public repositories - if a question is about a private npm/PyPI repository for the build, CodeArtifact is the answer, not ECR.

Per-environment configuration

The discipline the exam enforces: build once, configure per environment. The same immutable artifact is promoted from dev to staging to production; what changes is configuration supplied at deploy time or read at runtime. The mechanisms, from most to least static:

CDK context values and per-stack env; CloudFormation parameters and mappings generally. Use these for values that shape infrastructure (table names, VPC IDs, instance sizes).

(for example, a build) publish values consumed later, avoiding hard-coded values per stage.

environment variables for simple values, SSM Parameter Store for hierarchical configuration (

/myapp/prod/db-endpoint vs /myapp/dev/db-endpoint, with IAM scoping per path) and Secrets

Manager for credentials that must rotate. Runtime reads keep a redeploy from being necessary when only a value changes, and Lambda extensions/caching patterns keep the read cost negligible.

deployment groups (or SAM stacks, or ECS services) per environment, each with its own strategy and alarms, so a canary in production and an all-at-once in dev are independent choices.

Common trap: Hard-coding a production endpoint in the build, then rebuilding a "prod artifact," contradicts build-once-promote-everywhere and is the wrong answer whenever a parameter, variable, or runtime lookup achieves the same result. Conversely, putting secrets in plain environment variables or in the buildspec - rather than Secrets Manager/Parameter Store references that CodeBuild resolves at build time - is the insecure option the question is fishing for.

AWS AppConfig: feature flags and configuration deployment

AWS AppConfig (part of AWS Systems Manager) deploys configuration data to applications with the same care

CodeDeploy brings to code: gradually, validated, monitored, and reversible. It applies to feature flags, operational thresholds, allow/deny lists, and any freeform JSON/YAML configuration an application reads at runtime.

The AppConfig model has five pieces:

ConceptApplication
EnvironmentConfiguration profile
Deployment strategyValidator
What it isA logical container for a system's configuration
A deployment target grouping (dev, prod, a Region, a fleet segment) - not an AWS account constructOne configuration: either a feature flag profile or a freeform profile, stored in AppConfig's hosted store, S3, Parameter Store, Secrets Manager, or CodeCommit
How a change rolls out: growth type (linear or exponential), growth factor/percentage steps, deployment duration, and a final bake time during which alarms are watched before the deployment completesA check run before deployment starts: a JSON Schema validator for structure, or a Lambda validator for custom rules

A deployment applies a new version of a profile to an environment using a strategy - for example, linear growth of 25% of targets every 15 minutes with a 30-minute bake. During rollout, applications retrieve values through the AppConfig Data API (StartConfigurationSession, then GetLatestConfiguration with the session token, polling at the interval AppConfig returns) or, more efficiently, through the AWS AppConfig Lambda extension or the AppConfig agent on EC2/ECS/on-premises, which poll and cache configuration locally so application reads are local and fast.

The safety features mirror CodeDeploy and are tested the same way:

during the rollout or bake time, AppConfig stops the deployment and rolls back to the previous configuration version.

rules; the application checks the flag's evaluated value for its context (user ID, account, percentage rollout is handled by flag rules/variants in the flag configuration). The deployment discipline is identical - a flag change that breaks production is a configuration deployment and can be rolled back by redeploying the prior version, or the flag itself can be flipped off as the fastest mitigation. Toggling a flag changes behavior without a code deployment - the answer to scenarios about enabling a feature for 5% of users, running a kill switch, or decoupling release from deployment.

a schema/Lambda validator rejects it at deployment start - distinct from alarms, which catch bad effects during rollout.

Exam tip

AppConfig vs Parameter Store is a favorite distinction. Parameter Store is a place applications read values from. AppConfig is a deployment system for configuration - versioned rollouts, strategies, validators, and alarm-driven rollback - even when the underlying configuration happens to be stored in Parameter Store. If the scenario includes gradual rollout or rollback of the configuration itself, the answer is AppConfig.

Core concept

Configuration changes are deployments, with the same risk profile as code changes - a bad threshold or flag value can break production as surely as a bad binary. That is why AppConfig treats configuration the way

CodeDeploy treats code: versioned, validated before rollout, shifted gradually, and rolled back automatically when alarms fire. "Just update the parameter" skips all of that machinery.

Exam tip

Exam tip. Registry questions hinge on what is being stored. Container images point to ECR; language packages such as private npm, PyPI, or Maven artifacts point to CodeArtifact. If a scenario mentions a private package repository feeding the build, ECR is the distractor.

Check yourself

1. A team wants to roll a new feature-flag value out to 25% of targets every 15 minutes, with automatic rollback if an error alarm fires - and no code redeploy. Which service and features deliver this?

2. An ECS deployment ran an older image than expected even though the same tag was rebuilt and pushed again. Which ECR repository setting prevents a pushed tag from being silently overwritten?

Answers: 1. AWS AppConfig - a feature flag configuration profile deployed with a linear deployment strategy, with CloudWatch alarms attached so the configuration deployment rolls back automatically. 2. Tag immutability - with it enabled, a pushed tag cannot be overwritten, so pair it with commit-hash tags (or deploy by digest) to guarantee the image you tested is the image that runs.

Supplement: Test environments and AI-assisted CI/CD

Two Domain 3 examples deserve names, because the official exam guide lists them explicitly - and the in-scope topics the chapters touch only lightly are collected on this page with them. Registration for DVA-C03 opens on

December 1, 2026; the last day to take DVA-C02 is November 30, 2026.

Test environments: Amplify branches and Copilot environments. Amplify Hosting connects to a Git repository and creates a deployment for each connected branch, each with its own URL - so a pull request's frontend can be previewed live and removed when the branch is deleted. AWS Copilot environments provision an isolated set of resources (VPC, cluster, services) per environment, so the same application code deploys into a per-branch environment that reviewers can exercise and then delete. Both sit alongside the Lambda aliases and container image tags covered in Chapter 3: the pattern is the same - one isolated, disposable environment per change - only the tooling differs.

AI-assisted CI/CD. Amazon Q Developer and Kiro can summarize a pending change set for a human approver

(see Chapter 3, check question 6), generate environment-provisioning code for review, and analyze post-deployment validation results - canary metric comparisons, Synthetics canary failures, and test reports - to suggest whether to promote or roll back. The approval action itself stays human: AI informs the decision; it does not replace the approver of record. The same discipline as AI-assisted testing applies: generated artifacts are reviewed, never trusted blindly.

Also in scope - the short list. The exam guide's in-scope AI list names Amazon Bedrock, Amazon Bedrock

AgentCore, Amazon Quick, and Kiro - Quick is Amazon's agentic AI assistant for work: chat, research, and automation across company data. Elastic Beanstalk is in-scope Compute: upload code, choose a platform, and

Beanstalk provisions and manages the infrastructure; know its deployment policies (all at once, rolling, rolling with additional batch, immutable, and traffic splitting) and its health reporting. Serialization (Skill 1.1.7):

Lambda handlers receive JSON events and must return JSON-serializable values, so know your language's JSON mapping. Test events (Skill 3.2.3): saved Lambda test events and API Gateway method tests send sample JSON payloads without deploying anything, and mock integrations (Chapter 1) fake a backend the same way. Health checks and probes (Skill 4.2.5): ALB and Route 53 health checks gate traffic, while container platforms use liveness probes to restart a stuck container and readiness probes to withhold traffic until it is ready. CloudFront signed URLs (Skill 2.1.4) protect content at the edge the way S3 presigned URLs protect a bucket. AWS Private

CA (Skill 2.2.2) issues private certificates for internal services. And a Lambda function in a VPC (Skill 1.2.1) attaches to private subnets and reaches AWS services through the VPC endpoints of Chapter 2 or a NAT gateway.

End-of-Chapter Test

1. A CodeBuild project builds a Docker image and pushes it to Amazon ECR. The build fails at the docker build step with an error that the Docker daemon is not running. What is the most likely fix?

  1. Add a cache section to the buildspec
  2. Enable privileged mode on the build project
  3. Move the docker build command to the post_build phase
  4. Store the ECR credentials in the buildspec env section

2. A team uses SAM to deploy a Lambda function with AutoPublishAlias: live. They want 10% of traffic on the new version for 5 minutes, then the remainder, with the deployment reversing automatically if an error alarm fires. Which DeploymentPreference type and supporting element meet this requirement?

  1. AllAtOnce, with a PostTraffic hook
  2. Linear10PercentEvery1Minute, with a PreTraffic hook
  3. Canary10Percent5Minutes, with the alarm listed in the preference's Alarms
  4. Canary10Percent10Minutes, with a separate CodePipeline approval action

3. An ECS service uses the CodeDeploy blue/green deployment controller. What is the purpose of the test listener on the load balancer?

  1. It balances production traffic between the blue and green task sets during the shift
  2. It lets the green task set receive validation traffic before production traffic is shifted to it
  3. It health-checks the blue task set while the green tasks terminate
  4. It routes rollback traffic back to the blue task set after the bake period ends

4. A Python Lambda function's unit tests are slow and flaky because they call a real DynamoDB table in a shared account. What is the best change to make the unit tests fast and isolated?

  1. Run the tests inside the deployed Lambda function instead of locally
  2. Point the tests at DynamoDB Local and accept the network dependency
  3. Stub the DynamoDB client with botocore's Stubber (or an equivalent mock) so responses are canned
  4. Wrap every test in retries until it passes

5. Developers keep deploying a CDK app and waiting several minutes for CloudFormation even when only Lambda function code changed. For their development environment only, which option speeds this up, and what is the caveat?

  1. cdk deploy --method=direct; it skips the change set but still deploys everything
  2. cdk deploy --hotswap; it bypasses CloudFormation for supported changes but must not be used for production
  3. cdk synth followed by sam deploy; the tools are interchangeable for Lambda code
  4. cdk bootstrap before every deploy; it refreshes the deployment assets

6. A pipeline must not reach the production deployment stage until a release manager reviews the change. An AI assistant already summarizes the change set for reviewers. Which pipeline element enforces the gate?

  1. A CodeBuild test action that fails when changes are unreviewed
  2. A CodeDeploy deployment group with automatic rollback enabled
  3. A CodePipeline manual approval action placed before the production deploy stage
  4. An SNS topic subscribed to by the release manager

7. A team wants to enable a new checkout flow for 5% of users initially, expand gradually, and disable it instantly if payment errors increase - all without redeploying code. Which AppConfig capability combination fits?

  1. A freeform configuration profile redeployed with AllAtOnce, plus a JSON Schema validator
  2. A feature flag profile deployed with a linear growth strategy, with CloudWatch alarms attached for automatic rollback
  3. A Parameter Store parameter updated manually as usage grows
  4. A Secrets Manager secret with automatic rotation enabled

8. CodeDeploy is deploying to a Lambda alias. The deployment configuration shifts traffic in equal 10% increments once per minute until the new version serves all traffic. Which predefined configuration is this?

  1. CodeDeployDefault.LambdaCanary10Percent5Minutes
  2. CodeDeployDefault.LambdaAllAtOnce
  3. CodeDeployDefault.LambdaLinear10PercentEvery1Minute
  4. CodeDeployDefault.ECSLinear10PercentEvery1Minute Answer key 1. B - Building Docker images requires access to the Docker daemon, which CodeBuild only provides when the project runs in privileged mode. A buildspec cache speeds dependency downloads but does not start a daemon; phase placement does not matter if the daemon is unavailable; and credentials belong in neither the buildspec nor plain environment settings (the build role's permissions and get-login-password handle ECR auth). 2. C - The SAM deployment preference name encodes the shape: canary, 10%, 5-minute bake. Rollback on errors comes from listing the CloudWatch alarm in Alarms; CodeDeploy monitors it during the shift and reverses the alias weights if it fires. Linear shifts 10% per interval (a different shape), and hooks validate but do not themselves watch alarms. 3. B - The test listener fronts the green target group so validation (manual checks or hook functions) can exercise the replacement task set before the production listener shifts any real traffic. Production traffic moves on the production listener, health checks are target-group functions rather than the listener's purpose, and rollback is a traffic decision by CodeDeploy, not something the test listener routes. 4. C - Unit tests should not touch real infrastructure at all; stubbing/mocking the SDK client makes them fast, free, deterministic, and isolated. DynamoDB Local is a reasonable integration-test tool but still a network dependency for a unit test, running tests in the deployed function couples tests to shared state, and retries hide flakiness instead of removing its cause. 5. B - Hotswap detects changes limited to supported resources (Lambda code/configuration, ECS task

Answer key

1.

2.

3.

4.

5.

6.

7.

8.

Want the full AWS Developer – Associate (DVA-C03) package?

This guide is free to read. Get the downloadable PDF guidebook plus the full DVA-C03 practice exam with 3 months of online access.

Get DVA-C03 Full Access — $10