☰ All modules Tier 2 · CloudFormation GuideCheat sheet ‹ beanstalksam ›
Contents
  1. How CloudFormation appears on DVA-C02
  2. 1. Stacks and the deployment workflow
  3. 2. Template sections and parameters
  4. 3. Mappings conditions and outputs
  5. 4. Intrinsic functions and pseudo parameters
  6. 5. Exports and nested stacks
  7. 6. Service roles and capabilities
  8. 7. Change sets
  9. 8. Rollbacks and stack failure options
  10. 9. Protecting resources and stacks
  11. 10. Custom resources
  12. 11. Helper scripts and creation policies
  13. 12. StackSets
  14. 13. Drift detection and resource import
  15. 14. Dynamic references
  16. Quick decision rules
  17. Changed vs older material

CloudFormation — DVA-C02 Mastery Guide

  • Sources: course chapter 11 (CloudFormation). The chapter serves as the syllabus only; all wording here is original. The module scope also covers change sets, nested stacks, drift detection, cfn-init/cfn-signal, UpdateReplacePolicy and dynamic references, which the chapter skips or only names.
  • Verified against AWS documentation on 2026-10-12. The marker ⚠️ Changed: <current>. Older material may say <old>. flags a value or behaviour that differs from the course or older practice tests: learn the current value. ⚠️ unverified marks a value that current AWS documentation doesn't confirm: don't rely on it. Every change is listed in Changed vs older material; confirmed rows also go to notes/current-facts.md.
  • Tier 2 (deployment and messaging), bank target 35 questions. Domain: Deployment.
  • How to use it: /explain <topic> teaches from these sections (concept → exam facts → developer angle → traps → 3 check questions); /quiz cloudformation asks bank questions whose source_note links point at the ## N. headings below; /drill cloudformation fires short recall prompts from notes/cloudformation-cheat-sheet.md. Suggested loop: read a section and answer its practice questions before opening the answers → /explain what is still unclear → /quiz cloudformation → /drill cloudformation.

How CloudFormation appears on DVA-C02

DVA-C02 treats CloudFormation as the developer's deployment engine: you write or generate a template, ship it through a pipeline, and must predict what CloudFormation does when something goes wrong. Template trivia rarely appears on its own; it is wrapped in a deployment scenario.

Typical question shapes: a failed deployment and its error to diagnose; "Which TWO actions…" around protection or permissions; "least operational overhead" choices between StackSets, nested stacks, exports and scripts; the exact CLI flag, attribute or pseudo parameter that does the job. Domain map: every topic maps to Deployment (prepare artifacts → §1, §5; automate and test deployments → §6–§8, §11; deploy across accounts → §12); security-flavoured (§6, §14) and troubleshooting-flavoured (§1, §8, §11) questions still count as Deployment in this bank.

Out of scope here: SAM syntax and the sam CLI (see notes/sam-guide.md), CDK (see notes/cdk-guide.md), the CodePipeline CloudFormation action and manual approvals (see notes/cicd-guide.md), Elastic Beanstalk's own stacks (see notes/beanstalk-guide.md), Parameter Store and Secrets Manager internals (see notes/security-encryption-guide.md), iam:PassRole mechanics (see notes/advanced-identity-guide.md), user data and Auto Scaling instance refresh (see notes/ec2-mastery-guide.md §3 and §10). Network design inside templates is out of the exam's scope.

# Topic Why it is on the exam
1 Stacks and the deployment workflow Template size limits, package/deploy, stack states and update behaviours drive most troubleshooting questions
2 Template sections and parameters Which section does what; parameter types that validate input or fetch the latest AMI
3 Mappings conditions and outputs Static lookups vs inputs, environment-specific resources, values other stacks consume
4 Intrinsic functions and pseudo parameters Ref vs Fn::GetAtt return values, Fn::Sub, short-form YAML rules
5 Exports and nested stacks Sharing values between stacks: strong exports, nested stacks for reuse, cross-account outputs
6 Service roles and capabilities Least-privilege deployments, iam:PassRole, InsufficientCapabilities
7 Change sets Preview replacements before they happen; validated and drift-aware deployments
8 Rollbacks and stack failure options Recovering from ROLLBACK_COMPLETE, UPDATE_ROLLBACK_FAILED and DELETE_FAILED
9 Protecting resources and stacks DeletionPolicy, UpdateReplacePolicy, stack policies and termination protection compared
10 Custom resources Lambda- or SNS-backed logic for anything CloudFormation can't do natively
11 Helper scripts and creation policies cfn-init, cfn-signal, cfn-hup, CreationPolicy and wait conditions
12 StackSets One template across many accounts and Regions; permission models and operation preferences
13 Drift detection and resource import Finding out-of-band changes and adopting existing resources
14 Dynamic references Parameter Store and Secrets Manager values in templates without exposing them

1. Stacks and the deployment workflow

Concept

Exam facts

Developer angle

aws cloudformation create-stack --stack-name orders-dev --template-body file://orders.yaml \
  --parameters ParameterKey=Env,ParameterValue=dev --capabilities CAPABILITY_IAM --tags Key=team,Value=orders
aws cloudformation wait stack-create-complete --stack-name orders-dev
aws cloudformation describe-stack-events --stack-name orders-dev --output table \
  --query "StackEvents[?contains(ResourceStatus, 'FAILED')].[LogicalResourceId,ResourceStatusReason]"
# new parameter value, same template
aws cloudformation update-stack --stack-name orders-dev --use-previous-template --capabilities CAPABILITY_IAM \
  --parameters ParameterKey=Env,UsePreviousValue=true ParameterKey=Size,ParameterValue=large
# upload local artifacts, then create or update through a change set in one command
aws cloudformation package --template-file orders.yaml --s3-bucket orders-artifacts-111122223333 \
  --output-template-file packaged.yaml
aws cloudformation deploy --template-file packaged.yaml --stack-name orders-dev \
  --parameter-overrides Env=dev --capabilities CAPABILITY_IAM

Traps

Practice questions

  1. A build job uploads each new version of a Lambda function to s3://orders-artifacts/builds/orders.zip and then runs aws cloudformation update-stack with the unchanged template, whose AWS::Lambda::Function resource points S3Bucket and S3Key at that object. The job reports that there are no updates to perform, and the function keeps running the previous code. Which change fixes the pipeline with the LEAST effort?

    • A. Call update-stack with --use-previous-template instead of uploading the template again.
    • B. Run aws cloudformation package in the job to upload each build under a new checksum-based S3 key.
    • C. Run aws cloudformation detect-stack-drift on the stack before each update-stack call in the job.
    • D. Add a DependsOn attribute from the function to the artifact bucket resource in the template's Resources section.
  2. A developer's first create-stack for a new service failed on a misconfigured resource, and the stack is now in ROLLBACK_COMPLETE. The template has been corrected. The service must be deployed with the corrected template, and the next failed creation must keep the successfully created resources for troubleshooting. Which TWO actions meet these requirements? (Select TWO.)

    • A. Run update-stack on the existing stack with the corrected template.
    • B. Delete the stack and run create-stack again with the corrected template.
    • C. Run continue-update-rollback on the stack, then update it.
    • D. Add --disable-rollback (Preserve successfully provisioned resources) to future create-stack calls.
    • E. Pass --enable-termination-protection on the next create-stack call.
Answers
  1. B. package uploads the artifact under a name derived from its checksum and rewrites S3Key, so CloudFormation sees a changed property and deploys the new code. A submits the same template again (still no change); C only reports drift, never redeploys, and doesn't compare Lambda code; D changes ordering, not change detection.
  2. B, D. A stack in ROLLBACK_COMPLETE can only be deleted, so it must be recreated; --disable-rollback keeps successful resources and leaves failed ones for inspection. A is rejected in that state; C applies only to UPDATE_ROLLBACK_FAILED; E protects against stack deletion, not against rollback.

2. Template sections and parameters

Concept

Section Purpose
AWSTemplateFormatVersion Optional; the only valid value is 2010-09-09, a literal (latest assumed when omitted)
Description Literal string, up to 1,024 bytes
Metadata Extra information, e.g. AWS::CloudFormation::Interface (parameter groups and order in the console)
Parameters Inputs supplied at create and update time
Rules Validates parameter values and combinations before any resource changes
Mappings Static two-level lookup tables (§3)
Conditions Booleans that decide which resources, outputs and property values exist (§3)
Transform Macros applied before deployment: AWS::Serverless-2016-10-31 (SAM), AWS::Include, AWS::LanguageExtensions
Resources Required: each resource has a logical ID, a Type of the form Provider::Service::Resource (AWS::EC2::Instance) and Properties
Outputs Values to display, export or reference (§3, §5)

Exam facts

Developer angle

Parameters with validation, an SSM parameter type and a rule:

Parameters:
  Env: {Type: String, AllowedValues: [dev, prod], Default: dev}
  InstanceType: {Type: String, Default: t3.micro, AllowedPattern: "^[a-z0-9]+\\.[a-z0-9]+$",
                 ConstraintDescription: "must look like family.size, for example t3.micro"}
  VpcId: {Type: "AWS::EC2::VPC::Id"}
  SubnetIds: {Type: "List<AWS::EC2::Subnet::Id>"}
  LatestAmiId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64
Rules:
  ProdInstanceSize:
    RuleCondition: !Equals [!Ref Env, prod]
    Assertions:
      # x86_64 types, like the AMI (Graviton types such as m7g need the -arm64 AMI parameter)
      - Assert: {"Fn::Contains": [[m7i.large, m7i.xlarge], !Ref InstanceType]}
        AssertDescription: prod stacks must use m7i.large or m7i.xlarge
Resources:
  WorkerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub "Orders workers (${Env})"
      VpcId: !Ref VpcId
# list-type values: escape the commas
aws cloudformation create-stack --stack-name orders-workers --template-body file://workers.yaml \
  --parameters ParameterKey=VpcId,ParameterValue=vpc-0a1b2c3d4e5f67890 'ParameterKey=SubnetIds,ParameterValue=subnet-0a1b2c3d\,subnet-4e5f6a7b'
aws cloudformation get-template-summary --template-body file://workers.yaml --query Parameters

Traps

Practice questions

  1. A developer maintains a template that launches EC2 instances in several Regions. Every deployment must use the latest Amazon Linux 2023 AMI for its Region, without anyone editing the template or looking up AMI IDs. Which approach meets these requirements with the LEAST operational overhead?

    • A. A Mappings section keyed by Region that lists the current Amazon Linux 2023 AMI ID for every Region the company uses.
    • B. A String parameter with an AllowedPattern of ^ami-[0-9a-f]{17}$ and a ConstraintDescription that explains the format.
    • C. An AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> parameter that defaults to the public AL2023 parameter.
    • D. A parameter of type AWS::EC2::Image::Id whose default value is the AMI ID that is current at the time of each release.
  2. A template takes Env (dev or prod) and InstanceType. CloudFormation must reject a create-stack request before any resource is created when Env is neither value, or when Env is prod and InstanceType isn't m7g.large. Which TWO template features meet these requirements? (Select TWO.)

    • A. AllowedValues on the Env parameter.
    • B. A condition IsProd attached to the instance resource.
    • C. NoEcho on the InstanceType parameter.
    • D. A Rules entry whose RuleCondition checks Env and whose assertion uses Fn::Contains on InstanceType.
    • E. An AWS::CloudFormation::WaitCondition that the instance depends on.
Answers
  1. C. An SSM parameter type resolves the public parameter at every create and update, so each Region gets its latest AMI without edits. A and D need someone to maintain IDs; B only validates the shape of an ID that someone still has to look up.
  2. A, D. AllowedValues rejects any other Env; a rule validates the combination of two parameters before provisioning. B only skips or creates the instance; C masks a value; E waits for signals after resources already exist.

3. Mappings conditions and outputs

Concept

Exam facts

Developer angle

Mapping with a fallback, conditions, a conditional resource, a removable property and outputs:

Parameters:
  Env: {Type: String, AllowedValues: [dev, prod]}
  AlarmEmail: {Type: String, Default: ""}
Mappings:
  EnvSettings:
    dev: {LogRetention: "7"}
    prod: {LogRetention: "365"}
Conditions:
  IsProd: !Equals [!Ref Env, prod]
  ProdWithEmail: !And [!Condition IsProd, !Not [!Equals [!Ref AlarmEmail, ""]]]
Resources:
  AppLogs:
    Type: AWS::Logs::LogGroup
    Properties:
      RetentionInDays: !FindInMap [EnvSettings, !Ref Env, LogRetention, {DefaultValue: "30"}]
  ReportsBucket:
    Type: AWS::S3::Bucket
    Properties:
      VersioningConfiguration: !If [IsProd, {Status: Enabled}, !Ref "AWS::NoValue"]
  AlarmTopic:
    Type: AWS::SNS::Topic
    Condition: ProdWithEmail
    Properties:
      Subscription: [{Protocol: email, Endpoint: !Ref AlarmEmail}]
Outputs:
  BucketName:
    Value: !Ref ReportsBucket
  AlarmTopicArn:
    Condition: ProdWithEmail
    Value: !Ref AlarmTopic
aws cloudformation describe-stacks --stack-name orders-prod \
  --query "Stacks[0].Outputs[?OutputKey=='BucketName'].OutputValue" --output text

Traps

Practice questions

  1. A developer uses one template for dev and prod stacks. Only prod stacks must contain an Amazon SQS dead-letter queue; dev stacks must not create it. Which approach meets this requirement with the LEAST template duplication?

    • A. Add a condition based on the Env parameter and set it as the queue's Condition attribute.
    • B. Maintain separate dev.yaml and prod.yaml templates and have the pipeline select the right one for each environment.
    • C. Put the queue's properties in a Mappings entry for prod and leave the dev entry empty.
    • D. Set DeletionPolicy: Delete on the queue and delete it by hand after each dev deployment.
  2. In a shared template, an AWS::RDS::DBInstance named ReportsDb is created only when the IsProd condition is true. An output ReportsEndpoint returns !GetAtt ReportsDb.Endpoint.Address. Creating a dev stack from the template fails. Which TWO changes would each let the same template deploy in both environments? (Select TWO.)

    • A. Add DependsOn: ReportsDb to the ReportsEndpoint output.
    • B. Move the ReportsDb definition into a Mappings entry for prod.
    • C. Add Condition: IsProd to the ReportsEndpoint output.
    • D. Replace Fn::GetAtt with Fn::ImportValue in the output.
    • E. Change the output value to !If [IsProd, !GetAtt ReportsDb.Endpoint.Address, "not-deployed"].
Answers
  1. A. A condition attached to the resource creates it only when IsProd is true, in a single template. B duplicates the template; C is impossible because mappings hold values, not resources; D creates the queue anyway and adds manual work.
  2. C, E. Either give the output the same condition or make its value conditional with Fn::If. A isn't a valid output attribute and wouldn't help; B is impossible (mappings can't hold resources); D reads another stack's export, unrelated to the missing resource.

4. Intrinsic functions and pseudo parameters

Concept

Exam facts

Function Returns Short-form example
Ref Parameter value; for a resource, its identifier (type-specific) !Ref OrdersTable
Fn::GetAtt A named attribute of a resource !GetAtt OrdersTable.Arn
Fn::Sub String with ${Param}, ${Resource}, ${Resource.Attr}, ${AWS::Region} substituted !Sub "arn:${AWS::Partition}:s3:::${Bucket}/*"
Fn::Join Items joined with a delimiter !Join [",", [a, b]]
Fn::Select, Fn::Split Item by index; list from a string !Select [0, !GetAZs ""]
Fn::FindInMap Mapping value (§3) !FindInMap [Map, Key, Name]
Fn::ImportValue, Fn::GetStackOutput Another stack's export or output (§5) Fn::ImportValue: !Sub "${Net}-VpcId"
Fn::Base64 Base64 of a string, for EC2 UserData Fn::Base64: !Sub |
Fn::GetAZs Availability Zones of a Region, alphabetical (only those with a default subnet when any exist); "" = current Region !GetAZs ""
Fn::Cidr, Fn::Transform CIDR blocks; run a macro on a snippet
Fn::ForEach, Fn::Length, Fn::ToJsonString Loops, list length, JSON string; require Transform: AWS::LanguageExtensions full form only

Developer angle

Parameters:
  LatestAmiId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64
Resources:
  ReportsBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub "reports-${AWS::AccountId}-${AWS::Region}"
  WorkerInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: t3.micro
      AvailabilityZone: !Select [0, !GetAZs ""]
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          echo "STACK=${AWS::StackName} BUCKET=${ReportsBucket}" > /etc/worker.env
          echo 'Literal kept for the shell: ${!HOME}' >> /etc/worker.env
Outputs:
  DailyReportsArn:
    Value: !Sub "${ReportsBucket.Arn}/daily/*"
# physical ID behind a logical ID (what Ref returned)
aws cloudformation describe-stack-resource --stack-name reports --logical-resource-id ReportsBucket \
  --query StackResourceDetail.PhysicalResourceId --output text

Traps

Practice questions

  1. A template creates an AWS::SQS::Queue with the logical ID JobsQueue and an inline IAM policy that must allow sqs:SendMessage on that queue. With Resource: !Ref JobsQueue, the stack fails because IAM rejects the policy document. Which value should the Resource element use?

    • A. !Sub "arn:aws:sqs:::${JobsQueue}"
    • B. !Ref JobsQueue.Arn
    • C. !GetAtt JobsQueue.QueueUrl
    • D. !GetAtt JobsQueue.Arn
  2. A developer writes UserData: !Base64 !Sub | followed by a script that uses ${AWS::StackName} and ${AWS::Region}, and CloudFormation rejects the template. The script must keep its substitutions. Which TWO rewrites are valid? (Select TWO.)

    • A. UserData: !Base64 !Join followed by a list that rebuilds the script line by line.
    • B. UserData: followed by an indented Fn::Base64: !Sub | block.
    • C. UserData: !Sub !Base64 | followed by the script.
    • D. UserData: !Sub | followed by the script, because CloudFormation base64-encodes UserData automatically.
    • E. UserData: !Base64 followed by an indented "Fn::Sub": | block.
Answers
  1. D. Ref on a queue returns its URL; the policy needs the ARN, which Fn::GetAtt provides. A builds an invalid ARN without Region and account; B isn't valid syntax for Ref; C returns the URL again.
  2. B, E. Either the outer or the inner function must use its full name. A and C still chain two short forms; D fails because AWS::EC2::Instance expects base64 text in UserData.

5. Exports and nested stacks

Concept

Exam facts

Developer angle

Producer exports; the consumer imports, nests a component and reads a cross-account output:

# network.yaml (producer)
Resources:
  Vpc:
    Type: AWS::EC2::VPC
    Properties: {CidrBlock: 10.0.0.0/16}
Outputs:
  VpcId:
    Value: !Ref Vpc
    Export:
      Name: !Sub "${AWS::StackName}-VpcId"
# app.yaml (consumer)
Parameters:
  NetworkStackName: {Type: String, Default: network-prod}
Resources:
  AppSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: App tier
      VpcId:
        Fn::ImportValue: !Sub "${NetworkStackName}-VpcId"
  ArtifactBucketStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: ./templates/hardened-bucket.yaml  # package rewrites this to an S3 URL
      Parameters: {RetentionDays: "30"}
  ReportsQueue:
    Type: AWS::SQS::Queue
    Properties:
      KmsMasterKeyId:
        Fn::GetStackOutput:
          StackName: shared-keys
          OutputName: QueueKeyArn
          Region: eu-west-1
          RoleArn: arn:aws:iam::111111111111:role/ReadSharedOutputs
Outputs:
  ArtifactBucketName:
    Value: !GetAtt ArtifactBucketStack.Outputs.BucketName
aws cloudformation list-exports --query "Exports[].[Name,Value]" --output table
aws cloudformation list-imports --export-name network-prod-VpcId

Traps

Practice questions

  1. A platform team owns a VPC stack. Twelve application teams deploy their own stacks on their own schedules and need the VPC ID and private subnet IDs. The platform team must be prevented from accidentally deleting or changing those values while any application uses them. Which approach meets these requirements?

    • A. Nest each application stack inside the VPC stack as an AWS::CloudFormation::Stack resource.
    • B. Export the IDs as VPC stack outputs and use Fn::ImportValue in each application template.
    • C. Copy the IDs into each application template as String parameter defaults and update them when the network changes.
    • D. Read the IDs in each application template with Fn::GetStackOutput, which needs no export declaration.
  2. A developer wants to delete an old shared-network stack, but CloudFormation blocks the deletion because another stack imports one of its exports. The network stack must be deleted without leaving the consuming stacks broken. Which TWO actions should the developer take? (Select TWO.)

    • A. Run aws cloudformation list-imports --export-name with the export's name to find the importing stacks.
    • B. Run delete-stack with --retain-resources, listing the logical IDs of the outputs that other stacks import.
    • C. Update each importing stack to stop using that export, then delete the network stack.
    • D. Disable termination protection on the network stack.
    • E. Rename the export in the network stack's Outputs section and update the network stack.
Answers
  1. B. Exports with Fn::ImportValue give independent stacks a strong reference: the producer can't delete or change an export in use. A merges independent lifecycles into one unit; C copies values that silently go stale; D creates only a weak reference that doesn't block deletion.
  2. A, C. Find the consumers, migrate them off the export, then delete. B applies to resources in DELETE_FAILED, not to outputs; D isn't the blocker; E changes an exported value in use, which CloudFormation refuses.

6. Service roles and capabilities

Concept

Exam facts

Developer angle

Trust policy of the service role, then a developer policy that only allows stacks deployed through that role:

{"Version": "2012-10-17",
 "Statement": [{"Effect": "Allow",
                "Principal": {"Service": "cloudformation.amazonaws.com"},
                "Action": "sts:AssumeRole"}]}
{
  "Version": "2012-10-17",
  "Statement": [
    {"Effect": "Allow",
     "Action": ["cloudformation:CreateStack", "cloudformation:UpdateStack", "cloudformation:CreateChangeSet"],
     "Resource": "arn:aws:cloudformation:eu-west-1:111122223333:stack/orders-*/*",
     "Condition": {"StringEquals": {"cloudformation:RoleARN": "arn:aws:iam::111122223333:role/cfn-orders-deployer"}}},
    {"Effect": "Allow",
     "Action": ["cloudformation:ExecuteChangeSet", "cloudformation:DescribeStacks", "cloudformation:DescribeStackEvents"],
     "Resource": "arn:aws:cloudformation:eu-west-1:111122223333:stack/orders-*/*"},
    {"Effect": "Allow",
     "Action": "iam:PassRole",
     "Resource": "arn:aws:iam::111122223333:role/cfn-orders-deployer",
     "Condition": {"StringEquals": {"iam:PassedToService": "cloudformation.amazonaws.com"}}}
  ]
}
aws cloudformation validate-template --template-body file://orders.yaml --query "[Capabilities,CapabilitiesReason]"
aws cloudformation create-stack --stack-name orders-prod \
  --template-url https://orders-templates-111122223333.s3.eu-west-1.amazonaws.com/orders.yaml \
  --role-arn arn:aws:iam::111122223333:role/cfn-orders-deployer --capabilities CAPABILITY_NAMED_IAM

Traps

Practice questions

  1. A company wants developers to deploy approved templates that create S3 buckets and Lambda functions. Developers must not hold permissions to create those resources directly. Which solution meets the requirement and follows least privilege?

    • A. Create a service role with the S3 and Lambda permissions, and let developers pass only that role to CloudFormation.
    • B. Attach AmazonS3FullAccess and AWSLambda_FullAccess to the developers' IAM role for the duration of each deployment window.
    • C. Have developers deploy with access keys of a shared IAM user that holds the S3 and Lambda permissions.
    • D. Add CAPABILITY_NAMED_IAM to every deployment that creates the S3 buckets and Lambda functions.
  2. A pipeline runs aws cloudformation create-stack on a template that declares Transform: AWS::Serverless-2016-10-31 and an AWS::IAM::Role with RoleName: orders-worker. The call fails with InsufficientCapabilitiesException. Which TWO changes allow the stack creation to succeed? (Select TWO.)

    • A. Add CAPABILITY_IAM to --capabilities.
    • B. Add CAPABILITY_NAMED_IAM to --capabilities.
    • C. Add --role-arn with a service role that allows iam:CreateRole.
    • D. Add CAPABILITY_AUTO_EXPAND to --capabilities.
    • E. Add --enable-termination-protection to the call.
Answers
  1. A. CloudFormation performs the work with the service role's permissions; developers only operate stacks and pass that one role. B and C hand developers (or everyone with the keys) the underlying permissions; D is an acknowledgement for IAM resources, not a permission.
  2. B, D. The named role requires CAPABILITY_NAMED_IAM, and creating a stack directly from a template with a transform requires CAPABILITY_AUTO_EXPAND. A doesn't cover named IAM resources; C supplies permissions, not the acknowledgements; E is unrelated.

7. Change sets

Concept

Exam facts

Developer angle

aws cloudformation create-change-set --stack-name orders-prod --change-set-name add-gsi-2026-10-12 \
  --template-body file://orders.yaml --parameters ParameterKey=Env,UsePreviousValue=true --capabilities CAPABILITY_IAM
aws cloudformation wait change-set-create-complete --stack-name orders-prod --change-set-name add-gsi-2026-10-12
aws cloudformation describe-change-set --stack-name orders-prod --change-set-name add-gsi-2026-10-12 --output table \
  --query "Changes[].ResourceChange.[Action,LogicalResourceId,ResourceType,Replacement]"
aws cloudformation execute-change-set --stack-name orders-prod --change-set-name add-gsi-2026-10-12
# overwrite console edits back to the template values
aws cloudformation create-change-set --stack-name orders-prod --change-set-name revert-console-edits \
  --use-previous-template --deployment-mode REVERT_DRIFT

A pipeline gate that stops when a change set would replace anything:

import boto3

cfn = boto3.client("cloudformation")
changes = cfn.describe_change_set(StackName="orders-prod", ChangeSetName="add-gsi-2026-10-12")["Changes"]
replaced = [c["ResourceChange"]["LogicalResourceId"] for c in changes
            if c["Type"] == "Resource" and c["ResourceChange"].get("Replacement") in ("True", "Conditional")]
if replaced:
    raise SystemExit(f"Change set replaces resources: {replaced}")

Traps

Practice questions

  1. Before updating a production stack, a developer must see which resources would be replaced without changing anything, and a reviewer must approve before the changes apply. What should the developer do?

    • A. Run update-stack with --disable-rollback, inspect the stack events, and roll back manually if needed.
    • B. Run detect-stack-drift on the stack and review the drift results with the reviewer before updating.
    • C. Create a change set, review its Replacement values, and execute it after approval.
    • D. Run validate-template on the new template and share the returned capabilities with the reviewer.
  2. A root stack contains two nested stacks. A developer runs aws cloudformation create-change-set on the root stack with an updated child template and sees only an AWS::CloudFormation::Stack modification, with no detail about the child's resources. Which TWO statements are correct? (Select TWO.)

    • A. The developer must create a separate change set on each nested stack and execute them one by one.
    • B. Adding --include-nested-stacks creates nested change sets that show the child resources' changes.
    • C. The nested change sets are executed by executing the root change set.
    • D. Change sets don't support stacks that contain nested stacks.
    • E. Running execute-change-set on a nested change set applies only that child's changes.
Answers
  1. C. A change set lists every change, including Replacement, and applies nothing until it is executed. A changes the stack immediately; B compares resources with the current template, not with the new one; D checks syntax only.
  2. B, C. The CLI creates nested change sets only with --include-nested-stacks, and the hierarchy is executed from the root. A and E describe operations started from children, which CloudFormation runs from the root change set instead; D is false.

8. Rollbacks and stack failure options

Concept

Exam facts

Developer angle

# keep what worked, fix the template, retry in place (or give up with rollback-stack)
aws cloudformation create-stack --stack-name orders-dev --template-body file://orders.yaml --capabilities CAPABILITY_IAM --disable-rollback
aws cloudformation update-stack --stack-name orders-dev --template-body file://orders-fixed.yaml --capabilities CAPABILITY_IAM --disable-rollback
aws cloudformation rollback-stack --stack-name orders-dev
# a stack stuck in UPDATE_ROLLBACK_FAILED
aws cloudformation continue-update-rollback --stack-name orders-prod \
  --resources-to-skip LegacyQueue orders-prod-Storage-1A2B3C4D5E6F.ReportsDb
aws cloudformation continue-update-rollback --stack-name orders-prod --force-rollback
# roll back if the 5xx alarm fires during the update or the next 15 minutes
aws cloudformation update-stack --stack-name orders-prod --use-previous-template \
  --parameters ParameterKey=Env,UsePreviousValue=true --capabilities CAPABILITY_IAM \
  --rollback-configuration "RollbackTriggers=[{Arn=arn:aws:cloudwatch:eu-west-1:111122223333:alarm:orders-5xx,Type=AWS::CloudWatch::Alarm}],MonitoringTimeInMinutes=15"
# a stack stuck in DELETE_FAILED
aws cloudformation delete-stack --stack-name orders-dev --retain-resources UploadsBucket
aws cloudformation delete-stack --stack-name orders-dev --deletion-mode FORCE_DELETE_STACK

Traps

Practice questions

  1. A stack update failed and the stack is now in UPDATE_ROLLBACK_FAILED, because an operator deleted an SQS queue that CloudFormation is trying to roll back to. The queue can't be recreated with its original identity. What should the developer do to return the stack to a usable state?

    • A. Run update-stack with the original template and the original parameter values.
    • B. Run rollback-stack on the stack to return it to its last known stable state.
    • C. Run delete-stack with --retain-resources for the queue, then create the stack again.
    • D. Run continue-update-rollback and skip the queue with --resources-to-skip.
  2. While iterating on a template, a developer sees an EC2 instance fail during creation, and every rollback deletes the instance before its logs can be read. The developer wants to keep the successfully created resources, read /var/log/cfn-init.log, and then continue with the same stack after fixing the template. Which TWO actions meet these requirements? (Select TWO.)

    • A. Create the stack with --disable-rollback (Preserve successfully provisioned resources).
    • B. Create the stack with --on-failure DELETE and a longer --timeout-in-minutes value.
    • C. Add DeletionPolicy: Retain to the instance resource and to its security group resource.
    • D. Pass --enable-termination-protection when creating the stack again.
    • E. After fixing the template, run update-stack on the stack in CREATE_FAILED with failure preservation still selected.
Answers
  1. D. continue-update-rollback with skipped resources (or a forced rollback) returns the stack to UPDATE_ROLLBACK_COMPLETE. A isn't allowed in UPDATE_ROLLBACK_FAILED; B works only for CREATE_FAILED and UPDATE_FAILED; C deletes the stack instead of recovering it.
  2. A, E. Preservation keeps the instance and the stack in CREATE_FAILED, and an update with preservation retries from that point. B deletes everything; C may keep the instance, but outside a stack that still ends in ROLLBACK_COMPLETE, so it can't be continued; D only blocks deletes.

9. Protecting resources and stacks

Concept

Four separate safety nets, each for a different event:

Mechanism Protects against Set where
DeletionPolicy A resource being deleted because the stack is deleted, the resource is removed from the template or its condition turns false Resource attribute in the template
UpdateReplacePolicy The old physical resource being deleted after a replacement during an update Resource attribute in the template
Stack policy Unintended update actions (modify, replace, delete) on chosen resources during stack updates JSON document on the stack
Termination protection The whole stack being deleted Flag on the stack

Exam facts

Developer angle

Resources:
  OrdersDb:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Snapshot
    UpdateReplacePolicy: Snapshot
    Properties: {Engine: postgres, DBInstanceClass: db.t4g.medium, AllocatedStorage: "50",
                 MasterUsername: orders_admin, ManageMasterUserPassword: true}
  UploadsBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain

Stack policy that blocks replacement or removal of the database and allows everything else:

{
  "Statement": [
    {"Effect": "Deny", "Action": ["Update:Replace", "Update:Delete"], "Principal": "*",
     "Resource": "LogicalResourceId/OrdersDb"},
    {"Effect": "Allow", "Action": "Update:*", "Principal": "*", "Resource": "*"}
  ]
}
aws cloudformation set-stack-policy --stack-name orders-prod --stack-policy-body file://stack-policy.json
aws cloudformation update-stack --stack-name orders-prod --template-body file://orders.yaml --capabilities CAPABILITY_IAM \
  --stack-policy-during-update-body file://allow-db-replace.json
aws cloudformation update-termination-protection --stack-name orders-prod --enable-termination-protection
aws cloudformation describe-stacks --stack-name orders-prod --query "Stacks[0].EnableTerminationProtection"

Traps

Practice questions

  1. A production stack contains an AWS::RDS::DBInstance. If a future template change forces CloudFormation to replace the instance, the old instance's data must be kept as a snapshot. Which attribute meets this requirement?

    • A. DeletionPolicy: Snapshot
    • B. UpdateReplacePolicy: Snapshot
    • C. A stack policy that denies Update:Modify on the instance
    • D. Termination protection on the stack
  2. A team must guarantee that nobody can delete the production stack by accident, and that stack updates can never replace or remove the OrdersTable resource while every other resource stays updatable. Which TWO actions meet these requirements? (Select TWO.)

    • A. Add DeletionPolicy: Retain to every resource in the template.
    • B. Set UpdateReplacePolicy: Retain on OrdersTable.
    • C. Enable termination protection on the stack.
    • D. Apply a stack policy that denies Update:Replace and Update:Delete on LogicalResourceId/OrdersTable and allows Update:* on everything else.
    • E. Attach an IAM policy that denies cloudformation:UpdateStack to all users.
Answers
  1. B. UpdateReplacePolicy decides what happens to the old physical resource after a replacement. A applies to deletes, not replacements; C blocks a different action and doesn't snapshot anything; D only prevents deleting the stack.
  2. C, D. Termination protection blocks deleting the stack; the stack policy blocks replacing or removing the table during updates while allowing other changes. A keeps resources after a delete but doesn't stop the stack deletion; B keeps the old table but still allows replacement; E blocks every update.

10. Custom resources

Concept

Exam facts

Developer angle

Empty a bucket before CloudFormation deletes it (the custom resource references the bucket, so it is deleted first):

Resources:
  ArtifactBucket:
    Type: AWS::S3::Bucket
  EmptyBucketRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - {Effect: Allow, Principal: {Service: lambda.amazonaws.com}, Action: "sts:AssumeRole"}
      ManagedPolicyArns: ["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]
      Policies:
        - PolicyName: empty-artifact-bucket
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - {Effect: Allow, Action: ["s3:ListBucket", "s3:ListBucketVersions"], Resource: !GetAtt ArtifactBucket.Arn}
              - {Effect: Allow, Action: ["s3:DeleteObject", "s3:DeleteObjectVersion"], Resource: !Sub "${ArtifactBucket.Arn}/*"}
  EmptyBucketFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: python3.13
      Handler: index.handler
      Timeout: 300
      Role: !GetAtt EmptyBucketRole.Arn
      Code:
        ZipFile: |
          import boto3
          import cfnresponse

          def handler(event, context):
              bucket = event["ResourceProperties"]["BucketName"]
              physical_id = event.get("PhysicalResourceId", f"empty-{bucket}")
              try:
                  if event["RequestType"] == "Delete":
                      boto3.resource("s3").Bucket(bucket).object_versions.delete()
                  cfnresponse.send(event, context, cfnresponse.SUCCESS, {}, physical_id)
              except Exception as exc:
                  cfnresponse.send(event, context, cfnresponse.FAILED, {}, physical_id, reason=str(exc))
  EmptyArtifactBucket:
    Type: Custom::EmptyBucket
    Properties:
      ServiceToken: !GetAtt EmptyBucketFunction.Arn
      ServiceTimeout: 360  # a little above the function's 300-second timeout
      BucketName: !Ref ArtifactBucket

Traps

Practice questions

  1. A stack creates an S3 bucket that collects build logs. Deleting the stack fails with DELETE_FAILED because the bucket isn't empty, and the bucket must be deleted together with the stack. Which solution meets this requirement with the LEAST manual effort?

    • A. Set DeletionPolicy: Retain on the bucket and delete the bucket by hand later.
    • B. Add an S3 Lifecycle rule that expires objects after one day, and retry the deletion the next day.
    • C. Add a Lambda-backed custom resource that empties the bucket on Delete requests.
    • D. Run delete-stack with --deletion-mode FORCE_DELETE_STACK whenever the first deletion attempt fails.
  2. A Lambda-backed custom resource sometimes leaves a stack in CREATE_IN_PROGRESS for about an hour before it fails. Logs show that the function times out while calling an external API. Which TWO changes make such failures surface quickly? (Select TWO.)

    • A. Wrap the handler logic in try/except and send a FAILED response with a Reason before the function times out.
    • B. Set ServiceTimeout on the custom resource to a value slightly above the function's timeout.
    • C. Increase the function's memory to 10,240 MB.
    • D. Add a CreationPolicy with a ResourceSignal Timeout of PT5M to the custom resource.
    • E. Change the ServiceToken to the ARN of an SNS topic that the function subscribes to.
Answers
  1. C. The custom resource depends on the bucket, so CloudFormation deletes it first and its Delete handler empties the bucket before the bucket is removed. A and D leave the bucket behind; B is slow and unreliable for a stack deletion.
  2. A, B. An explicit FAILED response ends the wait at once, and ServiceTimeout caps the wait when no response arrives. C doesn't fix a hanging external call; D isn't supported on custom resources; E only changes the transport, and CloudFormation still waits for the response.

11. Helper scripts and creation policies

Concept

Exam facts

Developer angle

An Auto Scaling group that waits for two healthy instances at creation and for each new instance during rolling updates; the cfn-hup files let running instances reapply metadata changes (SubnetIds and LatestAmiId are parameters as in §2):

Resources:
  AppLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Metadata:
      AWS::CloudFormation::Init:
        config:
          packages: {yum: {nginx: []}}
          files:
            /etc/cfn/cfn-hup.conf:
              content: !Sub |
                [main]
                stack=${AWS::StackId}
                region=${AWS::Region}
                interval=5
            /etc/cfn/hooks.d/cfn-auto-reloader.conf:
              content: !Sub |
                [cfn-auto-reloader-hook]
                triggers=post.update
                path=Resources.AppLaunchTemplate.Metadata.AWS::CloudFormation::Init
                action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource AppLaunchTemplate --region ${AWS::Region}
                runas=root
          services:
            sysvinit:
              nginx: {enabled: "true", ensureRunning: "true"}
              cfn-hup: {enabled: "true", ensureRunning: "true", files: [/etc/cfn/cfn-hup.conf, /etc/cfn/hooks.d/cfn-auto-reloader.conf]}
    Properties:
      LaunchTemplateData:
        ImageId: !Ref LatestAmiId
        InstanceType: t3.micro
        UserData:
          Fn::Base64: !Sub |
            #!/bin/bash
            yum install -y aws-cfn-bootstrap
            /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource AppLaunchTemplate --region ${AWS::Region}
            /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource AppGroup --region ${AWS::Region}
  AppGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    CreationPolicy:
      ResourceSignal: {Count: 2, Timeout: PT15M}
    UpdatePolicy:
      AutoScalingRollingUpdate: {MaxBatchSize: 1, MinInstancesInService: 1, WaitOnResourceSignals: true, PauseTime: PT15M}
    Properties:
      MinSize: "2"
      MaxSize: "4"
      VPCZoneIdentifier: !Ref SubnetIds
      LaunchTemplate: {LaunchTemplateId: !Ref AppLaunchTemplate, Version: !GetAtt AppLaunchTemplate.LatestVersionNumber}

Traps

Practice questions

  1. A stack launches an EC2 instance whose user data installs an application. The instance reaches CREATE_COMPLETE before the installation finishes, and a dependent resource then fails its health checks. Which solution makes CloudFormation wait until the application is installed?

    • A. Add a CreationPolicy to the instance and call cfn-signal -e $? after cfn-init.
    • B. Add a DependsOn attribute from the dependent resource to the instance resource.
    • C. Pass --timeout-in-minutes 30 to the create-stack call that launches the instance.
    • D. Add a rollback trigger on the instance's StatusCheckFailed alarm with a 15-minute monitoring time.
  2. A developer adds a configuration file to the AWS::CloudFormation::Init metadata of a launch template and updates the stack. Instances that are already running don't receive the file. Which TWO changes make running instances apply future metadata changes? (Select TWO.)

    • A. Add UpdateReplacePolicy: Retain to the launch template.
    • B. Configure and start the cfn-hup daemon on the instances through /etc/cfn/cfn-hup.conf.
    • C. Run aws cloudformation signal-resource for every instance after each stack update completes.
    • D. Add a cfn-hup hook file that runs cfn-init on post.update for the launch template's metadata path.
    • E. Increase ResourceSignal.Count in the creation policy.
Answers
  1. A. The creation policy holds the instance in CREATE_IN_PROGRESS until cfn-signal reports cfn-init's result. B orders creation but still treats a running instance as complete; C only bounds the total time; D reacts to infrastructure health, not to the installation.
  2. B, D. cfn-hup polls the stack metadata, and its hook reruns cfn-init when the metadata changes. A only matters when the resource is replaced; C sends signals and doesn't apply configuration; E changes how many signals creation waits for.

12. StackSets

Concept

Exam facts

Developer angle

# service-managed StackSet for one OU, two Regions in parallel
aws cloudformation create-stack-set --stack-set-name baseline-logging --permission-model SERVICE_MANAGED \
  --template-url https://templates-111122223333.s3.eu-west-1.amazonaws.com/logging.yaml \
  --auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false --capabilities CAPABILITY_NAMED_IAM
aws cloudformation create-stack-instances --stack-set-name baseline-logging \
  --deployment-targets OrganizationalUnitIds=ou-ab12-34cd5678 --regions eu-west-1 eu-central-1 \
  --operation-preferences RegionConcurrencyType=PARALLEL,MaxConcurrentPercentage=25,FailureTolerancePercentage=10
aws cloudformation describe-stack-set-operation --stack-set-name baseline-logging \
  --operation-id 11111111-2222-3333-4444-555555555555
# self-managed StackSet with a per-instance parameter override
aws cloudformation create-stack-set --stack-set-name app-alarms --template-body file://alarms.yaml --permission-model SELF_MANAGED
aws cloudformation create-stack-instances --stack-set-name app-alarms --accounts 222233334444 555566667777 \
  --regions us-east-1 --parameter-overrides ParameterKey=Threshold,ParameterValue=80

Traps

Practice questions

  1. A company uses AWS Organizations. The same logging resources must be deployed to every existing account and to every account added in the future. Which solution meets these requirements with the LEAST operational overhead?

    • A. A CodePipeline pipeline in each account that runs aws cloudformation deploy whenever the template changes.
    • B. A StackSet with self-managed permissions and execution roles created in each account.
    • C. A nested stack in the management account that declares one child stack for every member account.
    • D. A service-managed StackSet that targets the organization root with automatic deployment.
  2. A developer creates a StackSet with self-managed permissions in account 111122223333 to deploy into accounts 222233334444 and 555566667777. Stack instance creation fails because the StackSet can't assume a role in the target accounts. Which TWO configurations are required? (Select TWO.)

    • A. Activate trusted access with AWS Organizations from the organization's management account.
    • B. Register account 111122223333 as a delegated administrator for StackSets with aws organizations register-delegated-administrator.
    • C. Create AWSCloudFormationStackSetExecutionRole in each target account with a trust policy that allows account 111122223333.
    • D. Pass --operation-preferences FailureToleranceCount=2 to create-stack-instances.
    • E. Create AWSCloudFormationStackSetAdministrationRole in account 111122223333 with permission to assume the execution role in the target accounts.
Answers
  1. D. Service-managed StackSets create their own roles and, with automatic deployment, add stack instances when accounts join. A and B need per-account setup and manual follow-up for new accounts; C deploys only into the management account.
  2. C, E. Self-managed StackSets need the administration role in the administrator account and the execution role, trusting that account, in every target. A and B belong to the service-managed model; D only changes how many failures the operation tolerates.

13. Drift detection and resource import

Concept

Exam facts

Developer angle

DRIFT_ID=$(aws cloudformation detect-stack-drift --stack-name orders-prod --query StackDriftDetectionId --output text)
aws cloudformation describe-stack-drift-detection-status --stack-drift-detection-id "$DRIFT_ID" \
  --query "[DetectionStatus,StackDriftStatus,DriftedStackResourceCount]"
aws cloudformation describe-stack-resource-drifts --stack-name orders-prod --stack-resource-drift-status-filters MODIFIED DELETED \
  --query "StackResourceDrifts[].[LogicalResourceId,StackResourceDriftStatus]"

Import a hand-made bucket (import.json, then a template that adds LegacyUploads with a DeletionPolicy):

[{"ResourceType": "AWS::S3::Bucket", "LogicalResourceId": "LegacyUploads",
  "ResourceIdentifier": {"BucketName": "orders-legacy-uploads"}}]
aws cloudformation create-change-set --stack-name orders-prod --change-set-name import-legacy-uploads \
  --change-set-type IMPORT --resources-to-import file://import.json --template-body file://orders-with-legacy-bucket.yaml
aws cloudformation execute-change-set --stack-name orders-prod --change-set-name import-legacy-uploads

Traps

Practice questions

  1. An operator changed the visibility timeout of an SQS queue in the console. The queue belongs to a stack whose template sets VisibilityTimeout: 60. The developer must find which resources in the stack differ from the template, without changing any resource. What should the developer do?

    • A. Create a change set from the template that is currently deployed and review the changes it lists.
    • B. Run detect-stack-drift and review describe-stack-resource-drifts.
    • C. Run update-stack --use-previous-template and read the stack events for the modified resources.
    • D. Run validate-template against the deployed template retrieved with get-template.
  2. A team created an S3 bucket named orders-legacy-uploads and a DynamoDB table by hand, and now wants an existing stack to manage them without recreating them. Which TWO steps are required? (Select TWO.)

    • A. Add both resources to the stack's template, each with a DeletionPolicy attribute.
    • B. Delete the resources and let CloudFormation recreate them with the same names.
    • C. Run detect-stack-drift on the stack with the resource identifiers of both resources.
    • D. Create a change set of type IMPORT whose --resources-to-import lists each resource's identifier, then execute it.
    • E. Add the resources to the template and point their properties at the existing ARNs with Fn::ImportValue.
Answers
  1. B. Drift detection compares actual property values with the template and changes nothing. A standard change set (A) compares templates only, so it shows no differences; C changes nothing when nothing differs and isn't a drift report; D checks syntax only.
  2. A, D. Import needs a template that declares the resources with a DeletionPolicy, and an IMPORT change set with their identifiers. B destroys data; C only reports drift for resources already in the stack; E reads exports from other stacks.

14. Dynamic references

Concept

Exam facts

Developer angle

Resources:
  OrdersDb:
    Type: AWS::RDS::DBInstance
    DeletionPolicy: Snapshot
    UpdateReplacePolicy: Snapshot
    Properties:
      Engine: mysql
      DBInstanceClass: db.t4g.micro
      AllocatedStorage: "20"
      MasterUsername: "{{resolve:secretsmanager:orders/db:SecretString:username}}"
      MasterUserPassword: "{{resolve:secretsmanager:orders/db:SecretString:password}}"
  WorkerTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateData:
        ImageId: "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64}}"
        InstanceType: t3.micro
  SupportUser:
    Type: AWS::IAM::User
    Properties:
      LoginProfile:
        Password: "{{resolve:ssm-secure:/orders/support-initial-password:3}}"
        PasswordResetRequired: true

Read permissions for the stack's service role:

{"Version": "2012-10-17",
 "Statement": [
   {"Effect": "Allow", "Action": "ssm:GetParameters",
    "Resource": "arn:aws:ssm:eu-west-1:111122223333:parameter/orders/*"},
   {"Effect": "Allow", "Action": "secretsmanager:GetSecretValue",
    "Resource": "arn:aws:secretsmanager:eu-west-1:111122223333:secret:orders/db-*"}]}

Traps

Practice questions

  1. A developer is writing a template for an Amazon RDS for MySQL instance. The master password is stored in AWS Secrets Manager as JSON with username and password keys. The password must not appear in the template, its parameters or the stack outputs. Which value should the MasterUserPassword property use?

    • A. !Ref DbPassword, where DbPassword is a NoEcho parameter.
    • B. {{resolve:ssm:/orders/db-password}}, where the parameter is a SecureString.
    • C. {{resolve:secretsmanager:orders/db:SecretString:password}}
    • D. A Mappings entry that holds the password, read with !FindInMap.
  2. A stack sets an RDS MasterUserPassword to {{resolve:secretsmanager:orders/db:SecretString:password}}. A security engineer changed the secret's value in Secrets Manager, but the database still accepts the old password. Which TWO statements are correct? (Select TWO.)

    • A. CloudFormation re-resolves dynamic references every 15 minutes and updates the database password.
    • B. CloudFormation resolves the reference only when it creates or updates the resource that contains it.
    • C. Running detect-stack-drift will report the password as drifted.
    • D. Changing the reference to {{resolve:ssm-secure:/orders/db-password}} makes CloudFormation refresh the value automatically.
    • E. Configuring Secrets Manager rotation for the secret keeps the database password and the secret in sync without stack updates.
Answers
  1. C. A Secrets Manager dynamic reference keeps the password out of the template, parameters and outputs. A still passes the password as a parameter value; B fails because ssm references can't read SecureString parameters; D stores the password in the template.
  2. B, E. Dynamic references are read only during create or update of the resource; rotation changes the database and the secret together. A confuses this with the cfn-hup polling interval; C is wrong because dynamic references and write-only passwords aren't drift-checked; D behaves the same way as the Secrets Manager reference.

Quick decision rules

Changed vs older material

Learn the Current column; older practice material may still show the Older material may say value. After confirmation, the same rows (with verification dates) go to notes/current-facts.md.

Topic Older material may say Current (verified 2026-10-12) Source
§1 · Where templates must live Every template must first be uploaded to S3 Inline TemplateBody up to 51,200 bytes; larger templates up to 1 MB via an S3 TemplateURL; the console uploads local files to a managed bucket AWS docs
§1 · Template quotas 200 resources, 60 parameters, 60 outputs, 100 mappings, 450 KB S3 template 500 resources, 200 parameters, 200 outputs, 200 mappings, 1 MB S3 template (since 2020-10-22) What's New
§1 · Visual template editor Design templates in Infrastructure Composer (or CloudFormation Designer) Template studio in the CloudFormation console; the standalone Infrastructure Composer console ends support on 2026-12-07 (full experience in the AWS Toolkit for VS Code) AWS docs
§1 · Waiting for resources Every stack operation waits for each resource to stabilize Express mode (--deployment-config '{"mode": "EXPRESS"}') completes once configuration is applied; rollback off by default; not for StackSets AWS docs
§3 · Fn::FindInMap DefaultValue Needs the AWS::LanguageExtensions transform Works in any template AWS docs
§4 · Name of the reference function Fn::Ref Ref (JSON {"Ref": "Name"}, YAML !Ref Name); there is no Fn:: prefix AWS docs
§5 · Sharing outputs across accounts and Regions Outputs can be shared only within one account and Region (exports) Fn::GetStackOutput reads outputs from other Regions and accounts (RoleArn) without exports, as a weak reference AWS docs
§6 · CAPABILITY_AUTO_EXPAND Required for templates with macros or nested stacks Required for direct create or update from templates with macros or transforms (including macros combined with nested stacks); nested stacks alone don't need it AWS docs
§7 · Validation before deployment Change sets only diff templates; errors appear during execution Pre-deployment validation on create-stack, update-stack and create-change-set: property syntax and name conflicts fail early; change sets also warn about quotas, non-empty buckets, Config recorders and ECR repositories; skip with --disable-validation AWS docs
§7 · Change sets and drift Change sets compare only the new and previous templates Drift-aware change sets (--deployment-mode REVERT_DRIFT) compare against actual state and revert drift AWS docs
§8 · Rollback of newly created resources Only rollback on or off and OnFailure --retain-except-on-create deletes newly created resources on rollback even with DeletionPolicy: Retain AWS docs
§8 · Leaving UPDATE_ROLLBACK_FAILED List every resource in --resources-to-skip continue-update-rollback --force-rollback skips all resources that failed to roll back, nested stacks included AWS docs
§8 · Leaving DELETE_FAILED Only delete-stack --retain-resources Also --deletion-mode FORCE_DELETE_STACK (since 2024-05-22) AWS docs
§9 · Default DeletionPolicy Delete for every resource Delete, except Snapshot for AWS::RDS::DBCluster and for AWS::RDS::DBInstance without DBClusterIdentifier AWS docs
§9 · DeletionPolicy values Delete, Retain, Snapshot Also RetainExceptOnCreate AWS docs
§10 · Custom resource wait time A stuck custom resource always blocks the stack for one hour ServiceTimeout 1–3,600 seconds (default 3,600) AWS docs
§10 · Inline Lambda code (ZipFile) Limited to 4,096 characters Zipped by CloudFormation into a package of up to 4 MB AWS docs
§12 · StackSets concurrency Maximum concurrent accounts can never exceed failure tolerance + 1 ConcurrencyMode SOFT_FAILURE_TOLERANCE keeps the configured concurrency; the default STRICT_FAILURE_TOLERANCE still caps it at tolerance + 1 AWS docs