Infrastructure as Code (IaC) means describing your AWS resources in a file instead of clicking through the console — so environments become versioned, repeatable, and reviewable like any other code. CloudFormation is the underlying provisioning engine for all of AWS IaC; SAM and CDK are two different authoring layers on top of it. Everything a developer does with SAM or CDK eventually becomes a CloudFormation template deployed as a CloudFormation stack — understanding that relationship is the single most important idea in this module.
Transform: AWS::Serverless-2016-10-31, plus a companion CLI. You still write a declarative YAML/JSON template; SAM just gives you compact serverless-focused resource types and a fast local-testing/deploy workflow.synth step compiles that code down into a plain CloudFormation template.AWS::S3::Bucket).NoEcho for masking sensitive values in the console).Fn::ImportValue.Fn::FindInMap.Ref, Fn::GetAtt, Fn::Sub, etc.) — used throughout the template to wire resources together dynamically instead of hardcoding values.Nearly every IaC question on DVA-C02 tests one of three things: (1) can you pick the right tool for a described team/workload (raw CloudFormation vs SAM vs CDK), (2) do you understand a specific safety mechanism — change sets, drift detection, stack policies, DeletionPolicy/UpdateReplacePolicy, rollback — well enough to apply it to a scenario, or (3) can you trace a SAM/CDK CLI command to what it actually does under the hood (build vs package vs deploy; synth vs deploy).
| Domain | Where IaC Shows Up |
|---|---|
| Domain 1 — Development with AWS Services (32%) | Using the SAM CLI and CDK CLI as development tooling; local testing (sam local invoke); AWS SDK/CLI usage that these tools wrap |
| Domain 2 — Security (26%) | Least-privilege CloudFormation service roles; NoEcho parameters vs Secrets Manager/SSM dynamic references; IAM permissions for stack operations |
| Domain 3 — Deployment (24%) | The centerpiece — templates, stacks, change sets, nested stacks, SAM deploy, CDK deploy, deployment configuration across environments |
| Domain 4 — Troubleshooting and Optimization (18%) | Stack rollback behavior, drift detection, stuck rollback recovery (ContinueUpdateRollback), diagnosing failed deployments from stack events |
IaC content is spread across all four domains rather than parked in one — that breadth is exactly why it's worth mastering deeply rather than skimming.
Choose your abstraction: raw CloudFormation YAML/JSON, a SAM template (CloudFormation + Transform), or a CDK app written in a general-purpose language
cdk synth runs your CDK app and emits a plain CloudFormation template into cdk.out. SAM's Transform is expanded server-side by CloudFormation itself at deploy time. A raw template needs no synth step — it already is the CloudFormation template.
sam build compiles/packages function code (in a Docker container matching the Lambda runtime, for compiled dependencies). Local assets — Lambda zips, Docker images — are then uploaded to a staging S3 bucket / ECR repository, and the template is rewritten with the resulting artifact locations.
sam deploy / cdk deploy / aws cloudformation deploy all ultimately call the same CloudFormation CreateStack/UpdateStack API (via a change set under the hood) — CloudFormation is the single control plane underneath all three tools
Resolves intrinsic functions, computes a change set (add/modify/remove, in-place vs replacement), and provisions resources in dependency order
The live, stateful representation of your resources — supports further updates, drift detection, rollback on failure, and deletion as a single unit
cdk synth = produce template only, deploys nothing; cdk deploy = synth + deployTransform: AWS::Serverless-2016-10-31 is what makes a template "SAM"sam local invoke, sam local start-api) and why it matters for developer productivityExam appearance probability: HIGH
The settings, functions, and CLI verbs that show up repeatedly inside scenario questions.
AllowedValues/AllowedPattern constraints, Default, and NoEcho (masks console display only — not encryption)AWS::EC2::KeyPair::KeyName, AWS::SSM::Parameter::Value<String> — validated against real AWS values, and the SSM type resolves a Parameter Store value at deploy timeFn::FindInMapFn::Equals/Fn::And/Fn::Or/Fn::Not) attached to a resource's Condition attribute to decide whether it's created at all — e.g. only create a NAT Gateway when an EnvType parameter equals prodNoEcho hides a value from the console/CLI output — it does not encrypt it or make it a secret. Real secrets belong in Secrets Manager/SSM Parameter Store, referenced dynamically.| Function | What it's for |
|---|---|
Ref | Parameter → returns its input value. Resource → returns that resource's "default" identifier (varies by type, e.g. bucket name for S3, instance ID for EC2) |
Fn::GetAtt | Returns a specific attribute of a resource beyond its default Ref — e.g. !GetAtt Bucket.Arn, !GetAtt MyFunction.Arn |
Fn::Sub | String substitution using ${Placeholder} syntax inline — far more readable than nested Fn::Join |
Fn::Join / Fn::Split / Fn::Select | Build a delimited string / split a string into a list / pick one element from a list |
Fn::FindInMap | Looks up a value from a Mappings table |
Fn::If / Fn::Equals / Fn::And / Fn::Or / Fn::Not | Conditional logic, usually paired with the Conditions section |
Fn::ImportValue | Reads a value another stack Exported in its Outputs — the mechanism behind cross-stack references |
Fn::GetAZs / Fn::Cidr | Return Availability Zones for a Region / carve CIDR blocks from a supplied range — common in networking templates |
Fn::Base64 | Base64-encodes a string — routinely used for EC2 UserData |
"I need the ARN of this S3 bucket" is never answered with plain Ref (that returns the bucket name) — it needs Fn::GetAtt Bucket.Arn. The exam relies on you knowing Ref's return value differs per resource type.
CreateChangeSet → DescribeChangeSet (review) → ExecuteChangeSet (commit) — or discard it, nothing has changed yetIN_SYNC, MODIFIED, DELETED, NOT_CHECKEDNOT_CHECKED, which is different from IN_SYNC and means "unknown," not "fine."AWS::CloudFormation::Stack resource — a child template embedded inside a parent, no independent lifecycle, used for reusable building blocks (e.g. a standard VPC pattern)Exports an Output value; another stack reads it with Fn::ImportValue — for loosely-coupled, independently-lifecycled stacks sharing a handful of valuesDelete (default) / Retain / Snapshot — controls the resource when it's removed from the template or the whole stack is deletedDelete unless set, a classic trap for RDS/EBSCREATE_FAILED/UPDATE_FAILED, CloudFormation automatically rolls back to the last known-good stateContinueUpdateRollback — skips resources that can't roll back cleanly so the stack can reach a stable state againTransform: AWS::Serverless-2016-10-31 at the top of a CloudFormation templateAWS::Serverless::Function, AWS::Serverless::Api, AWS::Serverless::HttpApi, AWS::Serverless::SimpleTable, AWS::Serverless::StateMachine — each expands into the full underlying resources (Lambda function + execution role + permissions, etc.) at deploy timesam initScaffold a new project from a starter templatesam buildInstalls dependencies and packages each function's artifacts (in a Docker container matching the Lambda runtime, for compiled dependencies)sam local invokeRuns a function locally in a Docker container emulating the Lambda runtime, against a supplied test eventsam local start-apiSpins up a local API Gateway emulator in front of your functions for end-to-end local testingsam deploy --guidedInteractive first deploy — uploads artifacts, packages the template, calls CloudFormation, and saves choices to samconfig.tomlsam syncFast iterative dev loop — pushes code changes directly, bypassing a full stack update, for rapid feedbacksam logsTails CloudWatch Logs for a deployed functionCfn*-prefixed, auto-generated, 1:1 mapping to a raw CloudFormation resource — no opinionated defaults, you configure every property yourselfbucket.grantRead(role)) — still synthesizes to the same underlying resources as L1ApplicationLoadBalancedFargateService provisions the service, task definition, and ALB togethercdk synthRuns your app code, emits CloudFormation template(s) + cloud assembly into cdk.out — deploys nothingcdk diffCompares the deployed stack against your current code — a change-set-style preview before deployingcdk deploySynthesizes, uploads assets, then deploys via CloudFormationcdk bootstrapOne-time per account/Region setup — creates the CDK Toolkit stack (S3 staging bucket, ECR repo, IAM deployment roles); required before the first cdk deploycdk destroyDeletes the stackRequirement → Keywords → Expected Answer → why every distractor fails.
Create and review a CloudFormation change set
| Distractor | Why it's wrong |
|---|---|
| Enable drift detection | Detects manual out-of-band changes already made — not a preview of an upcoming update |
Just run update-stack and watch the events | Reactive, not preventive — by the time you see it in events the change may already be happening |
sam local invoke | Tests function code locally — unrelated to previewing infrastructure changes |
CloudFormation drift detection
| Distractor | Why it's wrong |
|---|---|
| Change set | Previews a future update you're about to make — doesn't audit changes that already happened |
| AWS Config | Can track configuration history/compliance generally, but is not the CloudFormation-native mechanism the exam wants here |
| CloudTrail | Logs the API call that made the change, but doesn't compare it against the template's expected state |
AWS CDK
| Distractor | Why it's wrong |
|---|---|
| AWS SAM | Declarative YAML — no real programming constructs for large-scale reuse or unit testing |
| Raw CloudFormation | Would require heavy copy-paste or a hand-built templating layer to achieve what CDK gives natively |
| CloudFormation Macros alone | Can generate template fragments, but is a much heavier, lower-level tool than just using CDK directly |
AWS SAM
| Distractor | Why it's wrong |
|---|---|
| AWS CDK | Viable, but adds a programming-language learning curve this small serverless-only team doesn't need |
| Raw CloudFormation | No sam local invoke/start-api equivalent — local testing has to be built manually |
| Elastic Beanstalk | Manages an application environment, not a fine-grained serverless resource graph |
Nested stack
| Distractor | Why it's wrong |
|---|---|
| Cross-stack export/import | Best for independently-lifecycled stacks sharing a few values — not tight composition |
| StackSets | Solves multi-account/Region replication, not in-account modular reuse |
| Copy-paste the VPC resources into every stack | Works, but violates DRY and is exactly what nested stacks exist to avoid |
DeletionPolicy: Retain on the RDS resource (plus Termination Protection on the stack as a second layer)
| Distractor | Why it's wrong |
|---|---|
| UpdateReplacePolicy: Retain | Only protects the resource during a replacement caused by an update — not a full stack deletion |
| Stack Policy | Restricts update actions only — has no effect on a stack delete operation |
| Enable drift detection | Purely observational, provides zero protection against deletion |
ContinueUpdateRollback (optionally skipping the problem resource)
| Distractor | Why it's wrong |
|---|---|
| Delete and recreate the whole stack | Destructive and unnecessary — loses every other resource's state for one stuck resource |
Retry UpdateStack immediately | Fails again — the stack must leave the rollback-failed state first |
| Disable termination protection | Unrelated to rollback state entirely |
AWS CloudFormation StackSets
| Distractor | Why it's wrong |
|---|---|
| Nested stacks | Scoped to a single stack/account — no cross-account or cross-Region mechanism |
| Manually deploy the same template 150 times (50 accounts × 3 Regions) | Technically possible, operationally unmanageable and error-prone — exactly what StackSets automates |
| A single CDK app with one stack | One stack still deploys to one account/Region per deployment — CDK doesn't remove the need for a multi-account/Region distribution mechanism |
sam build / sam local invoke against the synthesized CDK cloud assembly — the SAM CLI's local-testing tooling isn't exclusive to SAM templates
| Distractor | Why it's wrong |
|---|---|
| Rewrite the entire app in SAM | Unnecessary — throws away working CDK code to gain a capability SAM CLI already supports against CDK output |
| "Impossible — you must pick one tool exclusively" | False; this integration is exactly the scenario being tested |
| Deploy after every change and test in the console | Slow, defeats the point of a fast local feedback loop |
cdk synth/sam build and drive the CloudFormation deploy step automatically on every commitAWS::Serverless::Function, and also powers Custom Resources — a Lambda-backed resource type that lets CloudFormation manage things it doesn't natively support{{resolve:secretsmanager:...}}) pull values into a template at deploy time instead of hardcoding themNoEcho parameters for actual secrets — NoEcho only hides console display, it doesn't encrypt anythingA team builds an order-processing API as a single CDK Stack class (TypeScript), parametrized by environment (dev/test/prod) via CDK context/environment settings. A developer pushes code to the source repository, which triggers CodePipeline. A CodeBuild stage runs cdk synth, producing a CloudFormation template plus a Lambda code asset, which CDK stages to the account's bootstrap S3 bucket (created once via cdk bootstrap). CodePipeline's CloudFormation deploy action then creates a change set against the target environment's stack and executes it — provisioning an HTTP API in Amazon API Gateway, a Lambda function as the backend, and a DynamoDB table for persistence, with a Cognito User Pool authorizer protecting the API and X-Ray tracing enabled end-to-end. If the deployment's CloudWatch Alarms (e.g. Lambda error rate) breach their threshold shortly after go-live, a configured rollback trigger automatically rolls the stack back to the previous known-good state — all without anyone hand-running aws cloudformation update-stack in a terminal.
See 08 — Cross-Service Architectures for this pattern drawn out in full alongside four other realistic architectures, and 09 — Hands-On Lab to build a version of it yourself with sam deploy --guided and cdk deploy.
sam local invoke) matters| Aspect | CloudFormation | SAM | CDK |
|---|---|---|---|
| Authoring style | Declarative JSON/YAML | Declarative YAML/JSON + serverless shorthand | Imperative — real programming language |
| Best for | Simplest/most portable cases, any resource type | Serverless apps (Lambda, API Gateway, DynamoDB, Step Functions) | Any resource type, complex/large-scale infra, heavy reuse |
| Under the hood | Is the CloudFormation template | CloudFormation + Transform macro that expands shorthand resources | Compiles ("synthesizes") to a CloudFormation template |
| Local testing | None built in | sam local invoke, sam local start-api | Via SAM CLI against the synthesized cloud assembly, or CDK's own assertions/unit-test module |
| Learning curve | Low — just YAML/JSON syntax | Low — YAML/JSON plus a handful of SAM concepts | Higher — requires proficiency in the chosen programming language |
| Reuse across stacks | Manual (nested stacks, copy-paste) | Manual, same as CloudFormation | Native — classes, packages, npm/PyPI-published construct libraries |
| Misconception | Reality |
|---|---|
| "SAM and CDK deploy resources directly, bypassing CloudFormation" | Both hand off to CloudFormation, which is the actual provisioning engine in every case |
"cdk synth deploys my stack" | cdk synth only produces the template locally — nothing is deployed until cdk deploy runs |
"NoEcho: true encrypts the parameter value" | It only masks the value in console/CLI output — it is not encryption or a secrets mechanism |
| "Drift detection will fix drifted resources" | It only reports drift (IN_SYNC/MODIFIED/DELETED/NOT_CHECKED) — it never remediates anything |
| "DeletionPolicy protects a resource from being replaced during an update" | That's UpdateReplacePolicy's job specifically — DeletionPolicy governs deletion/removal from the template, not update-driven replacement |
| "A Stack Policy stops someone from deleting the whole stack" | Stack Policies apply only to update actions; Termination Protection is what blocks stack deletion |
| "Nested stacks and cross-stack exports are interchangeable" | Nested stacks are tight composition with no independent lifecycle; cross-stack exports are for loosely-coupled, independently-lifecycled stacks |
| "CDK L1 constructs are always the wrong choice" | L1 is correct whenever a resource/property has no L2 wrapper yet, or you need full raw control — it's not deprecated or discouraged, just lower-level |
cdk synth/cdk deploy.sam build → sam deploy; cdk synth → cdk deploycdk bootstrap = once per account/Region, before the first deployThree short, self-contained exercises that put the concepts from the other tabs under your fingers instead of just in your head — raw CloudFormation, then SAM, then CDK, all deploying to the same underlying engine. All commands target the eu-west-1 (Ireland) Region and use AWS CLI v2. Clean up each exercise's stack when you're done to avoid ongoing charges (the resources used here are all within the AWS Free Tier for light use, but SNS/S3 are not free to leave running indefinitely at scale).
Author a small template by hand, deploy it, preview a modification with a change set, then deliberately break an update so you can watch CloudFormation's automatic rollback happen in front of you.
mkdir cfn-lab && cd cfn-lab
Create template.yaml:
AWSTemplateFormatVersion: '2010-09-09'
Description: DVA-C02 Lab 1 - S3 bucket + SNS topic
Parameters:
BucketNameSuffix:
Type: String
Description: Unique suffix to avoid global S3 name collisions
Resources:
LabBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub "dva-lab-${BucketNameSuffix}"
VersioningConfiguration:
Status: Enabled
LabTopic:
Type: AWS::SNS::Topic
Properties:
TopicName: dva-lab-topic
DisplayName: DVA Lab Notifications
Outputs:
BucketArn:
Description: ARN of the lab bucket
Value: !GetAtt LabBucket.Arn
TopicArn:
Description: ARN of the lab topic
Value: !Ref LabTopic
Export:
Name: dva-lab-topic-arn
aws cloudformation deploy, which internally creates and executes a change set for you:
aws cloudformation deploy \ --region eu-west-1 \ --template-file template.yaml \ --stack-name dva-lab-1 \ --parameter-overrides BucketNameSuffix=$(date +%s) \ --capabilities CAPABILITY_NAMED_IAMStack
dva-lab-1 reaches CREATE_COMPLETE; the CLI prints "Successfully created/updated stack".
aws cloudformation describe-stacks \ --region eu-west-1 \ --stack-name dva-lab-1 \ --query "Stacks[0].Outputs"A JSON array showing
BucketArn and TopicArn with real ARN values.
template.yaml: add a Tags block to LabTopic (e.g. Tags: [{Key: env, Value: lab}]), then create a change set manually instead of deploying directly:
aws cloudformation create-change-set \ --region eu-west-1 \ --stack-name dva-lab-1 \ --change-set-name add-tags-cs \ --template-body file://template.yaml \ --parameters ParameterKey=BucketNameSuffix,UsePreviousValue=trueChange set is created in
CREATE_PENDING then CREATE_COMPLETE status — nothing in the live stack has changed yet.
aws cloudformation describe-change-set \
--region eu-west-1 \
--stack-name dva-lab-1 \
--change-set-name add-tags-cs \
--query "Changes[].ResourceChange.{Action:Action,Resource:LogicalResourceId,Replacement:Replacement}"
Shows Action: Modify on LabTopic with Replacement: False — an in-place update, safe to execute.
aws cloudformation execute-change-set \ --region eu-west-1 \ --stack-name dva-lab-1 \ --change-set-name add-tags-csStack transitions through
UPDATE_IN_PROGRESS to UPDATE_COMPLETE.
template.yaml and set BucketName: !Sub "dva-lab-${BucketNameSuffix}" to a hardcoded name that already exists globally (e.g. reuse a well-known bucket name like aws-cloudtrail-logs-123456789012, which belongs to another account), then deploy directly:
aws cloudformation deploy \ --region eu-west-1 \ --template-file template.yaml \ --stack-name dva-lab-1 \ --parameter-overrides BucketNameSuffix=$(date +%s) \ --capabilities CAPABILITY_NAMED_IAMThe update fails because the bucket name is already taken (a Replacement is required and the new resource can't be created), and the CLI eventually reports the stack rolled back.
aws cloudformation describe-stack-events \
--region eu-west-1 \
--stack-name dva-lab-1 \
--query "StackEvents[?contains(ResourceStatus,'ROLLBACK')].{Status:ResourceStatus,Reason:ResourceStatusReason}" \
--output table
Events show UPDATE_ROLLBACK_IN_PROGRESS then UPDATE_ROLLBACK_COMPLETE — CloudFormation automatically reverted the stack to the last known-good state with no manual intervention required.
aws cloudformation delete-stack --region eu-west-1 --stack-name dva-lab-1Stack and all its resources (bucket, topic) are removed since neither had a
DeletionPolicy: Retain.
Step 6-7 is the single most exam-relevant moment in this lab: it proves CREATE_FAILED/UPDATE_FAILED triggers an automatic rollback with zero human action, and it shows you the actual ResourceStatusReason that scenario questions expect you to diagnose from stack events. It also demonstrates exactly why change sets (steps 3-5) exist — had this failed change been previewed as a change set first, describe-change-set would have flagged the Replacement risk before you ever executed it.
SAM's whole value proposition is the fast local loop before you ever touch CloudFormation. This exercise builds a minimal API Gateway + Lambda app and proves that loop end to end.
sam init --runtime python3.12 --name dva-sam-lab --app-template hello-worldA
dva-sam-lab/ directory is created containing template.yaml, a hello_world/ function directory with app.py, and an events/event.json test event.
template.yaml and identify the shorthand SAM resource types:
Transform: AWS::Serverless-2016-10-31
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello_world/
Handler: app.lambda_handler
Runtime: python3.12
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
You can see the same Transform: AWS::Serverless-2016-10-31 line from the Components tab, and one AWS::Serverless::Function resource whose Events block implicitly creates the underlying AWS::Serverless::Api — this single resource expands into a Lambda function, an execution role, an API Gateway REST API, and the permissions wiring them together.
cd dva-sam-lab sam buildA
.aws-sam/build/ directory appears containing the built artifact and a rewritten template pointing at it — nothing has been uploaded or deployed yet.
sam local invoke HelloWorldFunction --event events/event.jsonDocker starts a container emulating the Lambda runtime, invokes the handler, and prints a response body like
{"message": "hello world"} along with a START/END/REPORT log — confirming the function logic works before any AWS resource exists.
sam deploy --guided --region eu-west-1An interactive prompt asks for a stack name (e.g.
dva-sam-lab), confirms the Region, asks whether to allow SAM CLI IAM role creation, then packages and deploys — on completion it prints the deployed HelloWorldApi endpoint URL and saves all your answers to samconfig.toml for future non-interactive sam deploy runs.
curl $(aws cloudformation describe-stacks \ --region eu-west-1 --stack-name dva-sam-lab \ --query "Stacks[0].Outputs[?OutputKey=='HelloWorldApi'].OutputValue" --output text)Same JSON response as the local invoke — proving
sam local invoke is a genuinely reliable stand-in for the deployed behavior.
sam delete --region eu-west-1 --stack-name dva-sam-lab --no-promptsThe underlying CloudFormation stack, and every resource the
AWS::Serverless::Function expanded into, is deleted.
Step 4 is the exact CLI verb the exam expects you to name whenever a scenario says "test a Lambda function locally before deploying" — and step 6 proves why that's trustworthy: the local container and the deployed Lambda run the identical build artifact. Also notice that sam deploy --guided never called aws cloudformation create-stack directly — under the hood it still packages the template and hands it to CloudFormation, exactly like every other authoring tool in this guide.
This exercise deliberately mirrors Lab 1's simple S3 use case, but authored imperatively in CDK, so you can see with your own eyes that cdk synth produces the same kind of plain CloudFormation template that you hand-wrote in Lab 1.
cdk bootstrap aws://ACCOUNT_ID/eu-west-1A
CDKToolkit CloudFormation stack is created in eu-west-1, containing a staging S3 bucket, an ECR repository, and the IAM roles CDK uses to deploy — required exactly once before any cdk deploy in this account/Region.
mkdir cdk-lab && cd cdk-lab cdk init app --language typescriptA project is generated with
lib/cdk-lab-stack.ts (your Stack class), bin/cdk-lab.ts (the App entry point), and cdk.json pointing at eu-west-1 via your default AWS profile/Region config.
lib/cdk-lab-stack.ts to add one L2 construct — an S3 bucket:
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
export class CdkLabStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new s3.Bucket(this, 'LabBucket', {
versioned: true,
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
});
}
}
Nine lines of imperative TypeScript — compare this to the ~10 lines of declarative YAML the equivalent bucket took in Lab 1's template. versioned: true is the L2 shorthand for the same VersioningConfiguration: {Status: Enabled} property block you wrote by hand earlier.
cdk synthA full CloudFormation template prints to stdout and is written to
cdk.out/CdkLabStack.template.json — no AWS API call to create or update anything has happened yet.
cdk.out/CdkLabStack.template.json and find the bucket resource:
"LabBucket...": {
"Type": "AWS::S3::Bucket",
"Properties": {
"VersioningConfiguration": { "Status": "Enabled" }
},
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
}
A plain AWS::S3::Bucket resource — the exact same resource type you wrote by hand in Lab 1, plus a Custom Resource (Lambda-backed) that CDK auto-generated to implement autoDeleteObjects, since that behavior has no native CloudFormation property.
cdk diffOutput lists the stack's IAM changes and resources to be created, formatted like a change-set preview — this is CDK's analogue to
aws cloudformation describe-change-set from Lab 1.
cdk deploy --region eu-west-1CDK prompts you to approve the IAM/security-related changes, then shows the same kind of
CREATE_IN_PROGRESS → CREATE_COMPLETE stack events Lab 1's raw aws cloudformation deploy produced, because it's calling the identical underlying API.
aws cloudformation describe-stacks --region eu-west-1 \ --stack-name CdkLabStack --query "Stacks[0].StackStatus"
"CREATE_COMPLETE" — indistinguishable from a stack created via raw CloudFormation or SAM, because it is one.
cdk destroy --region eu-west-1The stack and its bucket are deleted (the
DESTROY removal policy + autoDeleteObjects mean the bucket is emptied and removed automatically, rather than blocking deletion the way a non-empty bucket normally would).
Step 5 is the whole point of this lab and of the "Three Tools, One Engine" idea from the Overview tab: when you open the synthesized JSON and see a plain AWS::S3::Bucket resource, you're looking at proof that CDK is not a different deployment mechanism — it's a code generator for the exact same CloudFormation template format Lab 1 used, which is why change sets, drift detection, DeletionPolicy, and rollback behavior all apply to CDK-deployed stacks identically to hand-written ones.
Click card to flip. Mark right or wrong to track score.
DVA-C02 scenario style, Easy → Specialty. Select an answer to reveal the explanation.