Infrastructure as Code (IaC) on AWS means writing your cloud infrastructure as declarative text that AWS CloudFormation, AWS SAM, or AWS CDK can deploy, update, and tear down repeatedly. For the AWS Certified Developer Associate (DVA-C02) exam, Task Statement 3.1 expects you to read CloudFormation templates fluently, pick the right intrinsic function for a scenario, understand how SAM shorthand macros expand into raw CloudFormation, debug change sets and drift, and reason about multi-account Stack Sets plus Lambda-backed custom resources. This guide walks through every CloudFormation section, every intrinsic function, every resource attribute, and every SAM + CDK workflow that DVA-C02 puts on the table.
What Is CloudFormation and AWS SAM?
AWS CloudFormation is AWS's declarative Infrastructure as Code service. You write a CloudFormation template in YAML or JSON, describe the desired end state of your AWS resources, and CloudFormation provisions, updates, or deletes those resources as a single atomic unit called a stack. AWS SAM (Serverless Application Model) is a CloudFormation extension that ships shorthand resource types for serverless applications — AWS Lambda functions, Amazon API Gateway APIs, Amazon DynamoDB tables, and AWS Step Functions state machines — that expand into raw CloudFormation at deploy time via the Transform: AWS::Serverless-2016-10-31 macro.
The DVA-C02 exam frames Infrastructure as Code around five questions:
- What is the anatomy of a CloudFormation template (Resources, Parameters, Outputs, Mappings, Conditions, Rules, Metadata, Transform)?
- Which intrinsic function do I call to wire two resources together (Ref, Fn::GetAtt, Fn::Sub, Fn::Join, Fn::ImportValue, Fn::If, Fn::FindInMap, Fn::GetAZs, Fn::Transform)?
- How do I control lifecycle behavior on critical resources (DependsOn, DeletionPolicy, UpdateReplacePolicy, CreationPolicy, UpdatePolicy)?
- How do I preview and roll out changes safely (change sets, drift detection, rollback, nested stacks, cross-stack exports, Stack Sets)?
- How does AWS SAM accelerate Lambda + API Gateway + DynamoDB deployments, and when does AWS CDK become a better fit?
This topic answers all five in the depth DVA-C02 demands. Every section keeps the conversation anchored to Task 3.1's verbs: prepare application artifacts, define Infrastructure as Code, deploy application artifacts to AWS.
AWS CloudFormation is an Infrastructure as Code service that lets you model, provision, and manage AWS and third-party resources using declarative templates written in YAML or JSON. A CloudFormation template describes the desired state of a collection of resources; CloudFormation determines the correct order of API calls, handles rollback on failure, and tracks the resulting stack as a single lifecycle unit. AWS SAM extends CloudFormation with serverless-specific shorthand via the AWS::Serverless-2016-10-31 transform. See: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html
白話文解釋 CloudFormation and SAM
要真正掌握 Infrastructure as Code 的 CloudFormation 世界,先用幾個白話類比把核心觀念裝進腦袋。
類比一:蓋房子的藍圖(工地類比) CloudFormation template 就像一張建築藍圖。藍圖上畫的是「三間臥室、兩間浴室、北向採光」——這是宣告式(declarative)描述:你只說「要什麼」,不說「怎麼蓋」。把藍圖交給營造廠(CloudFormation engine),它會算出鋼筋先綁、水電後接的施工順序,幫你把整棟房子蓋起來。CloudFormation 的 stack 就是這棟蓋好的房子;同一張藍圖蓋兩次,兩棟房子完全一樣。這就是 CloudFormation 最核心的保證:每次 deploy 同一份 template,結果都 reproducible。
類比二:開書考試的參考答案區(開書考試類比)
CloudFormation intrinsic functions 就像開書考試允許你翻書抄的那一區。你不用把每個 VPC ID、每個 Security Group ID、每個 Region 名稱死記在 template 裡——你用 Ref、Fn::GetAtt、!Sub ${AWS::Region} 這些函式去「翻書查值」,CloudFormation 在 deploy 當下幫你填空。Pseudo parameters 如 AWS::Region、AWS::AccountId、AWS::StackName 更是 AWS 幫你預先填好的官方答案,直接引用就好,寫死反而扣分。
類比三:瑞士刀 vs 專用刀(瑞士刀類比)
AWS CDK 像瑞士刀——一把工具裡藏著好幾層(L1/L2/L3 constructs),低層(L1)是原始 CloudFormation resource 的一對一映射,中層(L2)幫你補好合理預設(例如 S3 Bucket 預設開啟 SSE-S3),高層(L3)是整套 pattern(例如 API Gateway + Lambda + DynamoDB 一次生成)。AWS SAM 反而像專用削皮刀——只做一件事:把 Lambda、API Gateway、DynamoDB、Step Functions 的樣板寫得極短。SAM 用 AWS::Serverless::Function 一行取代 CloudFormation 裡十幾行 Lambda + IAM Role + Log Group。選工具就看場景:純 serverless 選 SAM,混合型或需要多語言程式邏輯選 CDK,跨服務大型 infra 選純 CloudFormation。
類比四:保險的解約條款(保險類比)
DeletionPolicy 和 UpdateReplacePolicy 就像保險的解約條款。預設是 Delete——stack 刪了,所有 resource 一起消失,包括你的 RDS 資料庫。把 DeletionPolicy 改成 Retain 就等於跟 CloudFormation 簽了「刪 stack 時這個 resource 保留下來」的保單;改成 Snapshot 則是「先拍快照再刪」。考 DVA-C02 時只要看到題目提「production database」「must not lose data」「stack deletion」這些關鍵字,答案幾乎就是 DeletionPolicy: Retain 或 Snapshot。UpdateReplacePolicy 則是另一條保單:當 update 觸發 replacement(例如改了 DB 名稱)時要怎麼處理舊的那顆。
把這四個類比串起來:template 是藍圖、intrinsic functions 是開書抄寫、CDK/SAM 是不同抽象層級的工具、resource attributes 是保單條款。DVA-C02 Task 3.1 的每一題都能拆回這四個軸線其中之一。
CloudFormation Template Anatomy — All Nine Sections
A CloudFormation template is a YAML (or JSON) document with up to nine top-level sections. Only Resources is mandatory. Understanding every section is the foundation of DVA-C02 Task 3.1.
AWSTemplateFormatVersion
AWSTemplateFormatVersion declares the CloudFormation template schema version. The only valid value today is 2010-09-09. CloudFormation is backwards compatible, and omitting this field is legal, but every production CloudFormation template should include it for clarity and future version pinning.
AWSTemplateFormatVersion: "2010-09-09"
Description
Description is a free-form string up to 1024 characters. It surfaces in the AWS Management Console stack list and in aws cloudformation describe-stacks. Good Descriptions in a CloudFormation template save humans in a hurry.
Metadata
Metadata holds structured information about the CloudFormation template that is not consumed by resource provisioning. The most common use is AWS::CloudFormation::Interface to group and order Parameters in the AWS Management Console. SAM also uses Metadata to attach extra attributes to AWS::Serverless::Function resources.
Parameters
Parameters makes a CloudFormation template reusable. You declare inputs (instance type, VPC ID, environment name) and supply them at deploy time via the AWS CLI --parameters flag, CloudFormation console prompts, or CI/CD pipelines. Each parameter has a Type (String, Number, ListAWS::EC2::VPC::Id), optional Default, AllowedValues, AllowedPattern, MinLength/MaxLength, MinValue/MaxValue, NoEcho (to mask secrets), and Description.
Parameters:
EnvName:
Type: String
AllowedValues: [dev, staging, prod]
Default: dev
Description: "Deployment environment"
DBPassword:
Type: String
NoEcho: true
MinLength: 12
Mappings
Mappings is a static lookup table inside the CloudFormation template. The classic use is picking an AMI ID per Region:
Mappings:
RegionAMI:
us-east-1: { AMI: ami-0abcdef1234567890 }
us-west-2: { AMI: ami-0fedcba0987654321 }
Access via !FindInMap [ RegionAMI, !Ref AWS::Region, AMI ]. Mappings make CloudFormation templates portable across Regions without parameterizing every value.
Conditions
Conditions defines named boolean expressions evaluated at deploy time. You typically compare a Parameter value against a constant and then attach the condition to a resource or output with the Condition: attribute.
Conditions:
IsProd: !Equals [ !Ref EnvName, prod ]
Resources:
ProdOnlyBucket:
Type: AWS::S3::Bucket
Condition: IsProd
Resources guarded by a false condition are skipped entirely — CloudFormation does not create them, and Ref/GetAtt against them returns AWS::NoValue.
Transform
Transform declares one or more macros that expand the CloudFormation template before resources are created. The most common Transform is AWS::Serverless-2016-10-31 — the AWS SAM transform — which expands SAM shorthand into raw CloudFormation. AWS::Include is another built-in transform for injecting snippets from S3. Custom macros are Lambda functions registered as CloudFormation macros.
Transform: AWS::Serverless-2016-10-31
Resources (mandatory)
Resources is the only mandatory top-level section in a CloudFormation template. Every entry has a Type (for example AWS::S3::Bucket, AWS::Lambda::Function, AWS::DynamoDB::Table) and a Properties block matching that type's schema. Resource logical IDs (the keys under Resources) must be alphanumeric, unique within the template, and are used when other resources Ref or GetAtt against them.
Outputs
Outputs exposes values from your stack for humans, automation, or other stacks. Each output has a Value (often a Ref or Fn::GetAtt) and optionally an Export name — the key that enables cross-stack references via Fn::ImportValue. Outputs are shown in the AWS Management Console and returned by describe-stacks.
Outputs:
ApiUrl:
Value: !Sub "https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/prod"
Export:
Name: !Sub "${AWS::StackName}-ApiUrl"
Rules
Rules validates parameter combinations at stack creation or update time. A Rule can, for example, require a certain InstanceType only when EnvName is prod. Rules are less common on DVA-C02 but worth recognizing.
A minimal valid CloudFormation template contains just one section: Resources. Every other section (AWSTemplateFormatVersion, Description, Metadata, Parameters, Mappings, Conditions, Transform, Outputs, Rules) is optional. DVA-C02 questions that show a minimal template without AWSTemplateFormatVersion are still valid — do not pick "missing schema version" as the failure cause. The single forced error is a missing Resources section. See: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html
Intrinsic Functions — The CloudFormation Wiring Toolkit
Intrinsic functions are how a CloudFormation template references values it does not know at authoring time. Every DVA-C02 candidate must be fluent in the nine canonical intrinsic functions.
Ref
Ref returns the default identifier of a resource or parameter. For AWS::S3::Bucket, Ref returns the bucket name. For AWS::Lambda::Function, Ref returns the function name. For AWS::EC2::Instance, Ref returns the instance ID. For a Parameter, Ref returns the parameter's value. The shorthand form is !Ref ResourceLogicalId.
Fn::GetAtt
Fn::GetAtt retrieves a specific attribute of a resource — typically an ARN, endpoint, or computed value not returned by Ref. Fn::GetAtt takes two arguments: the resource logical ID and the attribute name. Every resource type documents its GetAtt attributes in the CloudFormation User Guide.
MyFunctionArn: !GetAtt MyFunction.Arn
DbEndpoint: !GetAtt Database.Endpoint.Address
Fn::Sub
Fn::Sub substitutes variables into a string, similar to template literals in JavaScript. It is the most flexible string-building intrinsic function. Fn::Sub automatically resolves ${AWS::Region}, ${AWS::AccountId}, and other pseudo parameters, plus any local Parameter or Resource logical ID.
ApiUrl: !Sub "https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/prod"
LambdaName: !Sub "${AWS::StackName}-handler"
Fn::Join
Fn::Join concatenates a list of strings with a delimiter: !Join [ "-", [ !Ref EnvName, "bucket", !Ref AWS::AccountId ] ]. Fn::Sub is almost always cleaner than Fn::Join, but Fn::Join remains common in older CloudFormation templates and appears on DVA-C02.
Fn::ImportValue
Fn::ImportValue reads an exported output from another stack in the same Region and account. It is the cross-stack reference primitive: one stack Exports, another stack ImportValues. The exporting stack cannot be deleted while an importing stack still references its export — CloudFormation enforces this dependency.
VpcId: !ImportValue NetworkStack-VpcId
Fn::If
Fn::If is a ternary operator keyed on a named condition. It takes three arguments: the condition name, the value to return if true, and the value to return if false. AWS::NoValue is a special value that tells CloudFormation to omit the property entirely.
BucketName: !If [ IsProd, "prod-data", !Ref AWS::NoValue ]
Fn::GetAZs
Fn::GetAZs returns the list of Availability Zones available in a given Region. Pass an empty string to get AZs for the current Region: !GetAZs "". Combine with Fn::Select to pick a specific AZ index.
Fn::FindInMap
Fn::FindInMap looks up a value in the Mappings section by a three-key path: top-level key, second-level key, attribute name. The canonical use is region-to-AMI lookup.
ImageId: !FindInMap [ RegionAMI, !Ref AWS::Region, AMI ]
Fn::Transform
Fn::Transform invokes a macro at a specific location in the CloudFormation template. Unlike the top-level Transform section (which runs once), Fn::Transform can inject processed output inside a Resources block. It is the escape hatch that makes custom macros and AWS::Include usable mid-template.
When building interpolated strings in a CloudFormation template, prefer Fn::Sub (!Sub) over Fn::Join (!Join). !Sub "${MyResource.Arn}" reads exactly like a shell variable; !Join [ "", [ !GetAtt MyResource.Arn ] ] is noisy and error-prone. Fn::Sub also natively resolves pseudo parameters such as ${AWS::Region} and ${AWS::StackName} without any extra ceremony. Reserve Fn::Join for cases where the delimiter genuinely matters (ARN construction with colons, CSV strings). See: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html
Pseudo Parameters — Values AWS Injects for You
Pseudo parameters are values CloudFormation pre-populates and resolves at deploy time. You do not declare them; you just reference them like any other parameter. DVA-C02 tests the following pseudo parameters heavily:
AWS::Region— the Region where the stack is deployed (for exampleus-east-1).AWS::AccountId— the 12-digit AWS account ID hosting the stack.AWS::StackName— the name of the stack being deployed, useful for name-prefixing resources.AWS::StackId— the full ARN of the stack.AWS::Partition— the AWS partition (aws,aws-cn, oraws-us-gov), critical for ARN construction in multi-partition deployments.AWS::URLSuffix— the DNS suffix for the partition (amazonaws.com,amazonaws.com.cn).AWS::NoValue— sentinel that tells CloudFormation to omit a property, most often returned fromFn::Ifbranches.AWS::NotificationARNs— the list of SNS topic ARNs associated with the stack.
Hard-coding a Region string like us-east-1 into a CloudFormation template is a classic DVA-C02 anti-pattern. The correct value is always !Ref AWS::Region or ${AWS::Region} inside Fn::Sub.
Resource Attributes — DependsOn, DeletionPolicy, UpdateReplacePolicy, CreationPolicy, UpdatePolicy
Resource attributes sit alongside Type and Properties on any CloudFormation resource and control lifecycle behavior. They are the most commonly missed DVA-C02 test targets.
DependsOn
DependsOn adds an explicit ordering dependency. CloudFormation already infers most dependencies from Ref and Fn::GetAtt, but some relationships (IAM policy propagation, VPC Gateway attachments, cross-service eventual consistency) need a manual hint. DependsOn accepts a single logical ID or a list.
MyFunction:
Type: AWS::Lambda::Function
DependsOn: [ LoggingPolicy, NetworkInterfaces ]
DeletionPolicy
DeletionPolicy controls what happens to a resource when the containing stack is deleted, or when the resource itself is removed from the template. Three values:
Delete(default) — remove the resource when the stack is deleted.Retain— leave the resource in place; CloudFormation disowns it.Snapshot— take a final snapshot before deletion (supported for RDS DB instances, RDS DB clusters, EBS volumes, ElastiCache clusters, Redshift clusters, and Neptune clusters).
For production CloudFormation templates, DeletionPolicy: Retain on S3 buckets with important data and DeletionPolicy: Snapshot on databases are the go-to defensive defaults.
UpdateReplacePolicy
UpdateReplacePolicy controls what happens to the old resource when a stack update triggers replacement — that is, when a property change forces CloudFormation to delete the current resource and create a new one. The same three values apply: Delete, Retain, Snapshot. DeletionPolicy governs stack deletion; UpdateReplacePolicy governs replacement during updates. Both are typically set together on stateful resources.
Database:
Type: AWS::RDS::DBInstance
DeletionPolicy: Snapshot
UpdateReplacePolicy: Snapshot
Properties: { ... }
CreationPolicy
CreationPolicy forces CloudFormation to wait for an explicit success signal before marking a resource CREATE_COMPLETE. The typical use is waiting for EC2 bootstrap scripts (cfn-init plus cfn-signal) or Auto Scaling group instances to finish boot. CreationPolicy takes ResourceSignal.Count and ResourceSignal.Timeout (ISO 8601 duration).
WebServer:
Type: AWS::EC2::Instance
CreationPolicy:
ResourceSignal:
Count: 1
Timeout: PT15M
UpdatePolicy
UpdatePolicy controls how CloudFormation updates certain resources (Auto Scaling groups, Lambda aliases, ElastiCache replication groups). For AWS::AutoScaling::AutoScalingGroup, two sub-policies dominate DVA-C02:
AutoScalingRollingUpdate— roll instances in batches while keeping minimum in-service count; parameters includeMinInstancesInService,MaxBatchSize,PauseTime,WaitOnResourceSignals.AutoScalingReplacingUpdate— create an entirely new Auto Scaling group, cut over, then delete the old group. Safer rollback but doubles resource count during the update.
AppASG:
Type: AWS::AutoScaling::AutoScalingGroup
UpdatePolicy:
AutoScalingRollingUpdate:
MinInstancesInService: 2
MaxBatchSize: 1
PauseTime: PT5M
WaitOnResourceSignals: true
DVA-C02 commonly tests the distinction: DeletionPolicy fires when the stack itself is deleted (or the resource is removed from the template); UpdateReplacePolicy fires when a stack update triggers a resource replacement. Setting only DeletionPolicy: Retain on an RDS instance still lets an update silently replace and delete the original if you change a forces-replacement property. For genuinely irreplaceable production state, set both: DeletionPolicy: Snapshot AND UpdateReplacePolicy: Snapshot. See: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html
Change Sets — Preview Before You Commit
A CloudFormation change set is a preview of what CloudFormation will do when you next update the stack. You generate a change set with aws cloudformation create-change-set --stack-name ... --template-body file://template.yaml --change-set-name preview1. CloudFormation computes the diff between current stack state and the new template, producing a list of Add, Modify, or Remove actions. For each Modify it classifies the replacement behavior as True (resource will be replaced), False (in-place update), or Conditional (depends on other properties). You then review the change set and either aws cloudformation execute-change-set or delete it.
Change sets are the DVA-C02-favored safety mechanism for production CloudFormation updates. They expose hidden replacements (like the classic RDS DBInstanceIdentifier change) before you click execute. SAM deploys use change sets under the hood by default — sam deploy runs create-change-set then execute-change-set.
Drift Detection — Catching Out-of-Band Changes
Drift detection compares a stack's expected state (what CloudFormation believes based on the last deploy) against the actual current state in AWS. You trigger drift detection via aws cloudformation detect-stack-drift or the AWS Management Console. Each resource is classified as IN_SYNC, MODIFIED, DELETED, or NOT_CHECKED.
Drift happens when operators bypass CloudFormation — editing a Security Group in the AWS Management Console, deleting an S3 bucket with the AWS CLI, or tweaking an IAM policy outside the template. The DVA-C02 exam wants you to know:
- Drift detection is read-only. It does not fix drift.
- Not all resource types are drift-supported. Unsupported types report
NOT_CHECKED. - Remediating drift typically means either updating the template to match actual state, or re-deploying the stack to overwrite the out-of-band changes.
Nested Stacks vs Cross-Stack References
CloudFormation gives you two modularization patterns: nested stacks and cross-stack references. Both appear on DVA-C02.
Nested Stacks
A nested stack is a CloudFormation stack created as a resource inside another stack using AWS::CloudFormation::Stack. The parent stack's Properties.TemplateURL points to an S3 URL holding the child template. Nested stacks are owned by the parent — deleting the parent cascades to all nested children. They are ideal for packaging reusable components (a standard VPC module, a standard logging module) that you instantiate from many parent stacks.
NetworkStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/my-bucket/network.yaml
Parameters:
VpcCidr: 10.0.0.0/16
Cross-Stack References with Export + Fn::ImportValue
Cross-stack references decouple stacks. Stack A Exports an output; Stack B Fn::ImportValues it. The two stacks have independent lifecycles — but once imported, the exporting stack cannot be deleted or modified in a way that removes the export while the importing stack still consumes it. Export names must be unique per Region per account.
# Stack A (network)
Outputs:
VpcId:
Value: !Ref Vpc
Export: { Name: NetworkStack-VpcId }
# Stack B (app)
Resources:
AppSG:
Properties:
VpcId: !ImportValue NetworkStack-VpcId
Nested Stacks vs Cross-Stack References — Decision Matrix
| Axis | Nested Stacks | Cross-Stack References |
|---|---|---|
| Coupling | Tight (parent owns children) | Loose (independent stacks) |
| Lifecycle | Deleted together with parent | Independent; delete blocked while importer exists |
| Passing data | Via Parameters to nested stack | Via Export/ImportValue |
| Best for | Reusable module instantiated per parent | Shared infrastructure consumed by many apps |
| DVA-C02 signal | "Reusable template fragment" | "Separate stacks sharing a VPC ID" |
AWS SAM — Serverless Shorthand for CloudFormation
AWS SAM (Serverless Application Model) is a CloudFormation Transform plus a CLI. The Transform: AWS::Serverless-2016-10-31 declaration at the top of a SAM template tells CloudFormation to expand SAM resource types into full CloudFormation before deployment.
SAM Resource Types
The SAM-specific resource types DVA-C02 expects you to know:
- AWS::Serverless::Function — expands into
AWS::Lambda::Function,AWS::IAM::Role,AWS::Lambda::Permission, CloudWatch Logs group, and event-source mappings. Properties likeEventsauto-generate API Gateway routes, EventBridge rules, SQS triggers, and S3 notifications. - AWS::Serverless::Api — expands into
AWS::ApiGateway::RestApi,AWS::ApiGateway::Stage,AWS::ApiGateway::Deployment. SAM can also generate an HTTP API viaAWS::Serverless::HttpApi. - AWS::Serverless::StateMachine — expands into
AWS::StepFunctions::StateMachineplus its IAM role. - AWS::Serverless::SimpleTable — expands into
AWS::DynamoDB::Tablewith a simple primary key schema. - AWS::Serverless::LayerVersion — expands into
AWS::Lambda::LayerVersion. - AWS::Serverless::Application — nested SAM applications pulled from the Serverless Application Repository or S3.
SAM Globals
Globals is a SAM-specific section where you set defaults applied across every function or API in the template. Common globals include Function.Runtime, Function.Timeout, Function.Environment.Variables, Function.Tracing, and Api.Cors. Globals dramatically shorten templates with many similar Lambda functions.
Globals:
Function:
Runtime: python3.12
Timeout: 30
Tracing: Active
Environment:
Variables:
TABLE_NAME: !Ref DataTable
SAM CLI — sam build, sam deploy, sam local invoke, sam local start-api
The SAM CLI is the local companion to SAM templates. The commands DVA-C02 expects you to recognize:
- sam init — scaffolds a new SAM project from a template (zip or container, runtime, hello-world starter).
- sam build — compiles source code and dependencies into a deployment-ready artifact under
.aws-sam/build/. Uses the runtime's build tooling (pip, npm, mvn, go mod). - sam deploy — uploads artifacts to S3, generates a CloudFormation change set, and optionally executes it.
--guidedwalks you through parameters interactively. - sam local invoke — runs a specific Lambda function locally in a Docker container that mirrors the AWS Lambda runtime. Takes an event JSON payload via
--event event.json. Perfect for unit-test-style single-function debugging. - sam local start-api — spins up a local HTTP server emulating Amazon API Gateway, routing requests to your Lambda functions in local Docker containers. Test the full API surface without deploying.
- sam local start-lambda — starts a local Lambda endpoint that mirrors the AWS Lambda Invoke API, so SDK clients pointed at
http://127.0.0.1:3001will hit local functions. - sam logs — tails CloudWatch Logs for a deployed function;
--tailstreams live. - sam sync — rapid inner-loop deploys that skip the full CloudFormation change set for code-only changes.
- sam validate — lints the SAM template.
- sam delete — deletes the CloudFormation stack created by
sam deploy.
SAM Pipelines
sam pipeline init scaffolds a CI/CD pipeline (CodePipeline, GitHub Actions, GitLab CI, Jenkins, or Bitbucket Pipelines) that deploys a SAM application across multiple stages and AWS accounts. It generates IAM roles with least-privilege permissions for each stage and a pipeline configuration file. SAM Pipelines is the quickest path from "I have a SAM template" to "I have multi-environment CI/CD" for DVA-C02 scenarios asking "how do I automate serverless deployments?"
The two SAM local commands most frequently tested on DVA-C02 are:
- sam local invoke — run a single Lambda locally in Docker with an event JSON. Use when testing one function with crafted input.
- sam local start-api — start a local API Gateway + Lambda Docker environment. Use when testing the full HTTP surface end to end.
If a question says "test one Lambda with a specific event payload," the answer is sam local invoke. If a question says "test the REST API locally with curl or Postman," the answer is sam local start-api. See: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html
AWS CDK — Infrastructure in Real Programming Languages
AWS CDK (Cloud Development Kit) v2 lets you define CloudFormation stacks in TypeScript, JavaScript, Python, Java, C#, and Go. CDK code synths (synthesizes) into a CloudFormation template and uses CloudFormation as its deployment engine. CDK's value proposition over raw CloudFormation: loops, conditionals, classes, unit testing, and a rich library of pre-built constructs with sensible defaults.
Construct Levels — L1, L2, L3
CDK organizes building blocks into three levels:
- L1 constructs (Cfn classes)* — one-to-one mappings of CloudFormation resource types.
CfnBucketmaps toAWS::S3::Bucketwith exactly the same properties. Use when you need the escape hatch to raw CloudFormation. - L2 constructs — curated, opinionated wrappers with sensible defaults and helper methods.
s3.BucketaddsgrantRead,grantWrite, automatic encryption, and versioning flags — all producing the right CloudFormation under the hood. L2 is the idiomatic layer for most CDK code. - L3 constructs (patterns) — multi-resource compositions.
aws_ecs_patterns.ApplicationLoadBalancedFargateServiceprovisions an ECS Fargate service plus an Application Load Balancer plus autoscaling plus CloudWatch alarms in one call. L3 constructs dramatically reduce template size for common architectures.
CDK CLI Commands
- cdk init — bootstrap a new CDK project.
- cdk synth — synthesize the CloudFormation template from CDK code. Output lives under
cdk.out/. - cdk diff — compare the synthesized template against the currently deployed stack; reports
[+],[-],[~]changes. - cdk deploy — synth plus CloudFormation deploy, creating or updating the stack.
- cdk destroy — tear down the stack.
- cdk bootstrap — create the staging resources (S3 bucket, IAM role) CDK needs in a target account and Region before first deploy.
CDK Context and Aspects
- Context — a CDK mechanism for passing runtime configuration via
cdk.jsonor-c key=valueon the CLI. Context values are cached after first lookup for reproducibility. Common use: environment-specific feature flags. - Aspects — cross-cutting visitors that walk the construct tree and apply changes uniformly. Typical uses: enforce tagging policies, require encryption on every S3 bucket, add removal policies to every stateful resource. Aspects are CDK's answer to "apply this rule to every resource in the app."
SAM vs CDK vs Raw CloudFormation
| Dimension | Raw CloudFormation | AWS SAM | AWS CDK |
|---|---|---|---|
| Language | YAML / JSON | YAML / JSON with Transform | TypeScript, Python, Java, C#, Go |
| Best for | Any AWS resource, large orgs with YAML review culture | Lambda + API Gateway + DynamoDB serverless stacks | Multi-service apps with programmatic composition |
| Loops and conditionals | Mappings + Conditions only | Inherits CloudFormation + Globals | Native language |
| Local test | No native | sam local invoke + sam local start-api | Unit tests + cdk synth |
| Output | Direct CloudFormation | Expanded CloudFormation | Synthesized CloudFormation |
| DVA-C02 emphasis | Template anatomy + intrinsic functions | Transform + SAM CLI + serverless resources | Construct levels + cdk commands |
Parameter Overrides, Change Sets, and Deploy-Time Controls
aws cloudformation deploy --parameter-overrides and sam deploy --parameter-overrides let you pass Parameter values without editing the CloudFormation template. Combined with --capabilities CAPABILITY_IAM or CAPABILITY_NAMED_IAM (required when the template creates or names IAM resources) and --no-execute-changeset (generate but do not execute), parameter overrides are the glue between a single reusable template and multiple environments in a CI/CD pipeline.
Stack Sets — Multi-Account, Multi-Region Deployment
AWS CloudFormation StackSets lets a single administrator account deploy the same CloudFormation template across many target accounts and Regions in one operation. Two permission models matter on DVA-C02:
- Self-managed permissions — you manually create trust IAM roles (
AWSCloudFormationStackSetAdministrationRolein the admin account,AWSCloudFormationStackSetExecutionRolein each target account). Gives the most control; required when target accounts are not part of an AWS Organization. - Service-managed permissions — StackSets automatically manages IAM trust across an AWS Organization. Enables auto-deployment to new accounts as they join an OU. Simplest for organizations already on AWS Organizations.
StackSet operation parameters like MaxConcurrentCount, FailureToleranceCount, and RegionConcurrencyType control blast radius during rollouts. Use StackSets when a DVA-C02 scenario says "deploy the same template to many accounts" or "roll out a baseline stack across the organization."
cfn-init and cfn-signal — EC2 Bootstrap from Templates
For EC2-based workloads, CloudFormation ships helper scripts pre-installed on Amazon Linux AMIs:
- cfn-init — reads the
AWS::CloudFormation::Initmetadata on an EC2 instance resource and applies it: install packages, create files, start services, run commands. This is CloudFormation's answer to configuration management inside the instance boot. - cfn-signal — sends a signal to CloudFormation saying "I am ready" (or "I failed"). Paired with
CreationPolicy.ResourceSignal, it makes CloudFormation wait for the instance to finish bootstrap before marking the resourceCREATE_COMPLETE. - cfn-get-metadata — fetch metadata at runtime.
- cfn-hup — a daemon that re-runs cfn-init when the stack's metadata changes, enabling in-place reconfiguration.
A canonical EC2 bootstrap in a CloudFormation template:
WebServer:
Type: AWS::EC2::Instance
CreationPolicy:
ResourceSignal: { Count: 1, Timeout: PT10M }
Metadata:
AWS::CloudFormation::Init:
config:
packages: { yum: { httpd: [] } }
services: { sysvinit: { httpd: { enabled: true, ensureRunning: true } } }
Properties:
UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
yum update -y aws-cfn-bootstrap
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServer --region ${AWS::Region}
/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServer --region ${AWS::Region}
Custom Resources — Extending CloudFormation with Lambda
Custom resources let you execute arbitrary logic during CloudFormation stack operations. You declare AWS::CloudFormation::CustomResource or the shorter Custom::<Name> with a ServiceToken pointing to a Lambda function (or SNS topic). CloudFormation invokes the Lambda with a RequestType of Create, Update, or Delete and waits for the function to send a signed response to a pre-signed S3 URL.
Use cases tested on DVA-C02:
- Generating random values (random S3 bucket suffixes) at deploy time.
- Calling third-party APIs (create an Auth0 tenant during stack deploy).
- Configuring AWS services that have no native CloudFormation resource type yet.
- Post-deploy initialization (seed a DynamoDB table with default rows).
Custom resources must always respond to CloudFormation within the timeout or the stack hangs in CREATE_IN_PROGRESS until it eventually fails. Best practice: the Lambda handler must wrap all logic in try/except and always send a response — SUCCESS or FAILED — even when logic fails.
DVA-C02 commonly tests the failure mode where a custom resource Lambda throws an unhandled exception and never sends a response to the pre-signed S3 URL. CloudFormation has no way to know the Lambda failed — it waits up to 1 hour before giving up, trapping the stack in CREATE_IN_PROGRESS or DELETE_IN_PROGRESS. The fix: always wrap custom resource handlers in try/except/finally and always POST to event.ResponseURL with { "Status": "SUCCESS" | "FAILED", ...}. Many SDK helpers (cfnresponse for Python, aws-cdk-lib/custom-resources for CDK) implement this pattern correctly. See: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html
CloudFormation Rollback and Stack Failure Behaviors
When a CloudFormation stack operation fails, CloudFormation automatically rolls back by default. Key behaviors DVA-C02 tests:
- CREATE_FAILED → ROLLBACK_IN_PROGRESS → ROLLBACK_COMPLETE — failed create rolls back; the stack ends in
ROLLBACK_COMPLETE. A stack inROLLBACK_COMPLETEcannot be updated — you must delete and recreate it. - UPDATE_FAILED → UPDATE_ROLLBACK_IN_PROGRESS → UPDATE_ROLLBACK_COMPLETE — failed update rolls back to the last-known-good state.
- DisableRollback — pass
--disable-rollbackoncreate-stackorupdate-stackto skip automatic rollback. Useful for debugging: resources stay in whatever state they reached. - ContinueUpdateRollback — resume a rollback that got stuck because a resource could not be rolled back (for example, an S3 bucket was manually deleted after partial success).
Common DVA-C02 Exam Traps
Trap 1: Ref vs Fn::GetAtt
Ref returns the default identifier (bucket name, function name, instance ID). Fn::GetAtt returns a specific attribute (ARN, endpoint, hosted zone ID). When a question asks for "the ARN of this Lambda," the answer is !GetAtt MyFunction.Arn, not !Ref MyFunction.
Trap 2: Fn::ImportValue vs Nested Stack Parameters
Fn::ImportValue crosses stack boundaries via Export. Nested stacks pass data via Parameters on AWS::CloudFormation::Stack. If the question shows two independent stacks sharing a VPC ID, the answer is Export + Fn::ImportValue. If the question shows one parent template instantiating a reusable child, the answer is nested stack parameters.
Trap 3: DeletionPolicy Does Not Protect Against Updates
Setting DeletionPolicy: Retain protects against stack deletion, not against in-place replacement during updates. For that, add UpdateReplacePolicy: Retain.
Trap 4: SAM Transform Must Be at the Top
A SAM template without Transform: AWS::Serverless-2016-10-31 is just a broken CloudFormation template. CloudFormation will reject AWS::Serverless::Function as an unknown resource type. The Transform line is mandatory for SAM.
Trap 5: CDK Requires Bootstrap Before First Deploy
Running cdk deploy in a new account/Region without first running cdk bootstrap fails with a missing CDKToolkit stack error. Bootstrap creates the S3 bucket and IAM roles CDK needs to stage assets.
Trap 6: sam local invoke Requires Docker
sam local invoke and sam local start-api spin up Lambda runtime emulators in Docker containers. Without Docker installed and running, both commands fail. Linux, macOS, and Windows all need the Docker daemon.
Trap 7: Change Sets Do Not Apply Themselves
Creating a change set is preview-only. Until you call execute-change-set, nothing deploys. Forgetting the execute step is a common DVA-C02 distractor.
Trap 8: StackSets Self-Managed vs Service-Managed Permissions
Service-managed permissions require AWS Organizations. Self-managed permissions work across arbitrary accounts but require manual IAM role setup in each target. Pick service-managed when the scenario says "all accounts in the organization"; pick self-managed when the scenario says "these specific accounts" or explicitly rules out Organizations.
Trap 9: Drift Detection Is Read-Only
Drift detection reports differences but does not fix them. Remediating drift means re-deploying the stack to overwrite the out-of-band changes or updating the template to reflect actual state.
Trap 10: Custom Resource Silent Hang
Custom resource Lambdas that fail silently trap stacks in IN_PROGRESS for up to an hour. Always send a response in a finally block.
Key Numbers and Must-Memorize Facts
DVA-C02 asks exact numbers less often than CLF-C02, but a few CloudFormation and SAM limits surface in scenarios:
- CloudFormation template size: 1 MB for direct upload, 1 MB for S3-hosted templates (unchanged since launch).
- Resources per stack: 500 (soft limit; adjustable).
- Parameters per template: 200.
- Outputs per template: 200.
- Mappings per template: 200.
- Stack Set operations: default 10 concurrent accounts, configurable via
MaxConcurrentCount. - Custom resource Lambda timeout response window: up to 1 hour before CloudFormation times out.
- CreationPolicy timeout: ISO 8601 duration, typically
PT15Mfor EC2 bootstrap, configurable per resource. - SAM Transform version:
AWS::Serverless-2016-10-31(yes, the date is the version — do not change it). - CDK v2 supported languages: TypeScript, JavaScript, Python, Java, C#, Go.
- CDK bootstrap stack name:
CDKToolkit. - CloudFormation helper scripts: cfn-init, cfn-signal, cfn-get-metadata, cfn-hup.
Infrastructure as Code Decision Tree for DVA-C02
When a DVA-C02 question asks "which tool?" walk this decision tree:
- Is the workload purely serverless (Lambda + API Gateway + DynamoDB + Step Functions)? → AWS SAM.
- Is the team comfortable writing TypeScript, Python, Java, C#, or Go and wants loops, unit tests, and patterns? → AWS CDK.
- Is the team operating at enterprise scale with a YAML-centric review process and wants raw control? → Raw AWS CloudFormation.
- Need to deploy the same stack across many accounts or Regions? → CloudFormation StackSets on top of any of the above.
- Need to inject deploy-time logic CloudFormation cannot express natively? → Custom Resource backed by Lambda.
- Need fast local iteration on a Lambda function? → sam local invoke or sam local start-api.
- Need to preview the blast radius of a stack update? → Change set via
create-change-set. - Suspect someone clicked past your CloudFormation template? → Drift detection.
FAQ — IaC with SAM and CloudFormation
Q1: What is the difference between AWS CloudFormation, AWS SAM, and AWS CDK?
A: AWS CloudFormation is the underlying declarative Infrastructure as Code engine using YAML or JSON. AWS SAM is a CloudFormation Transform plus CLI that shortens serverless templates — AWS::Serverless::Function expands into the full Lambda + IAM Role + Log Group + event sources during deploy. AWS CDK lets you write CloudFormation stacks in TypeScript, Python, Java, C#, or Go; it synthesizes CloudFormation templates and deploys them. All three end up calling CloudFormation — they differ in authoring ergonomics.
Q2: When should I use Fn::ImportValue vs nested stack Parameters?
A: Use Fn::ImportValue when two stacks have independent lifecycles and share a long-lived resource ID (like a VPC ID or shared KMS key ARN). Use nested stack Parameters when one parent template owns and instantiates reusable child templates — the children exist only as part of the parent stack and die with it. ImportValue enforces a strong coupling: the exporting stack cannot delete the export while any stack imports it.
Q3: What does DeletionPolicy: Retain do and how is it different from UpdateReplacePolicy: Retain?
A: DeletionPolicy: Retain tells CloudFormation to leave the resource in place when the stack itself is deleted (or when the resource is removed from the template). UpdateReplacePolicy: Retain tells CloudFormation to leave the old resource in place when a stack update triggers replacement (for example, renaming an RDS instance). Both are needed together for irreplaceable production state. Supported values for both: Delete, Retain, Snapshot (the last only for stateful resources like RDS, EBS, ElastiCache, Redshift, Neptune).
Q4: When do I use sam local invoke vs sam local start-api?
A: Use sam local invoke to test a single Lambda function with a specific event JSON — perfect for unit-test-style runs where you craft inputs. Use sam local start-api to launch a local HTTP server that emulates API Gateway and routes incoming requests to your Lambdas — perfect for end-to-end REST API testing with curl, Postman, or a browser. Both require Docker.
Q5: What are CDK L1, L2, and L3 constructs and when do I pick each level?
A: L1 constructs (Cfn* classes) are one-to-one mappings of raw CloudFormation resource types — use them as an escape hatch when an L2 construct does not expose a property. L2 constructs are curated wrappers with sensible defaults, helper methods (grantRead, grantWrite), and sane security defaults — the idiomatic layer for most CDK code. L3 constructs (patterns) are multi-resource blueprints like ApplicationLoadBalancedFargateService — use them when the pattern matches your architecture and you want minimal code.
Q6: How do change sets differ from direct stack updates?
A: A change set is a preview. aws cloudformation create-change-set computes the diff between current stack state and the new template, lists every Add, Modify, or Remove action, and classifies replacements. Nothing changes in your account until you run execute-change-set. Direct update-stack applies the changes immediately without a preview. For production, change sets are the DVA-C02 recommended safety net — they expose hidden replacements (like RDS identifier renames) before execution. sam deploy uses change sets under the hood by default.
Q7: What is drift detection and can it fix drift?
A: Drift detection compares a CloudFormation stack's expected state (from the last deploy) against actual state in AWS. It classifies each resource as IN_SYNC, MODIFIED, DELETED, or NOT_CHECKED. Drift detection is read-only — it reports but does not fix drift. Remediation is manual: either update the template to match actual state, or re-deploy the stack to overwrite out-of-band changes. Not all resource types support drift detection; unsupported types report NOT_CHECKED.
Q8: When are Stack Sets with service-managed permissions the right choice? A: Choose service-managed permissions when your target accounts are part of an AWS Organization and you want StackSets to handle IAM trust automatically, including auto-deploy to new accounts that join a specified OU. Choose self-managed permissions when targets are not in an Organization, or when you need fine-grained manual control over the administration and execution IAM roles. DVA-C02 scenarios mentioning "AWS Organizations" or "all accounts in an OU" usually point to service-managed.
Q9: Why would a custom resource Lambda trap a stack in CREATE_IN_PROGRESS?
A: Custom resources require the Lambda to POST a response (SUCCESS or FAILED) to a pre-signed S3 URL in the event. If the Lambda throws an unhandled exception and exits without responding, CloudFormation waits up to 1 hour before giving up — trapping the stack in CREATE_IN_PROGRESS or DELETE_IN_PROGRESS. The fix: wrap all custom resource handler logic in try/except/finally and always send a response, even on failure. Libraries like cfnresponse (Python) and aws-cdk-lib/custom-resources implement this pattern correctly.
Q10: What do cfn-init and cfn-signal do on an EC2 instance?
A: cfn-init reads the AWS::CloudFormation::Init metadata on an EC2 resource and applies it — install packages, create files, start services, run commands. cfn-signal sends a success or failure signal to CloudFormation from inside the instance. Paired with CreationPolicy.ResourceSignal, CloudFormation waits for cfn-signal before marking the resource CREATE_COMPLETE. This pattern is how you guarantee the stack does not advance until an EC2 instance finishes bootstrap — the EC2-native answer for deploy-time configuration that CloudFormation itself cannot perform.
Further Reading — Official AWS Documentation
- AWS CloudFormation User Guide: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html
- CloudFormation Template Anatomy: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html
- Intrinsic Function Reference: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html
- Pseudo Parameters: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html
- DeletionPolicy Attribute: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html
- UpdateReplacePolicy Attribute: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html
- CreationPolicy Attribute: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-creationpolicy.html
- UpdatePolicy Attribute: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html
- Change Sets: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-changesets.html
- Drift Detection: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-drift.html
- StackSets Concepts: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-concepts.html
- Custom Resources: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html
- Helper Scripts (cfn-init, cfn-signal): https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-helper-scripts-reference.html
- AWS SAM Developer Guide: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html
- sam local invoke: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html
- sam local start-api: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-start-api.html
- SAM Pipelines: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-pipelines.html
- AWS CDK v2 Developer Guide: https://docs.aws.amazon.com/cdk/v2/guide/home.html
- CDK Constructs (L1/L2/L3): https://docs.aws.amazon.com/cdk/v2/guide/constructs.html
Mastering Infrastructure as Code is the fastest way to raise your DVA-C02 Domain 3 score. Internalize the nine CloudFormation template sections, the nine intrinsic functions, the three pseudo parameters you reuse everywhere (AWS::Region, AWS::AccountId, AWS::StackName), the five resource attributes (DependsOn, DeletionPolicy, UpdateReplacePolicy, CreationPolicy, UpdatePolicy), the change set and drift detection workflows, the SAM Transform plus the sam local invoke / sam local start-api pair, and the CDK L1/L2/L3 construct hierarchy. Every DVA-C02 Task 3.1 question reduces to choosing the right CloudFormation primitive, the right SAM shorthand, or the right CDK construct from these lists.