This chapter covers AWS CloudFormation for developers, focusing on how to define, deploy, and manage infrastructure as code using templates. CloudFormation is a core topic in the DVA-C02 exam, appearing in roughly 10-15% of questions, particularly in the Deployment domain (Objective 3.2). You will learn template structure, resource creation, change sets, stack updates, and troubleshooting — all essential for automating deployments and ensuring reproducible environments.
Jump to a section
Imagine you are building a house. Instead of manually pouring concrete, framing walls, and installing wiring, you hand a detailed blueprint to a general contractor. The blueprint specifies every component: foundation dimensions (12x20 meters), wall stud spacing (16 inches on center), wire gauge (12 AWG), and the exact model of each light fixture. The contractor reads the blueprint, procures materials, and builds the house step by step. If you need a second identical house, you reuse the same blueprint. If you need to modify the house, you update the blueprint and the contractor tears down and rebuilds only the changed parts. The contractor also tracks the state of each component—whether it's built, in progress, or failed—and rolls back if something goes wrong. You never touch a hammer. In AWS CloudFormation, the blueprint is a JSON or YAML template, the contractor is the CloudFormation service, and the house is your entire infrastructure—EC2 instances, security groups, S3 buckets, and more. The template declaratively defines the desired state, and CloudFormation orchestrates the creation, update, or deletion of resources in the correct order, handling dependencies and rollbacks automatically. Just as a blueprint eliminates manual construction errors, a CloudFormation template eliminates manual infrastructure mistakes.
What is AWS CloudFormation?
AWS CloudFormation is an Infrastructure as Code (IaC) service that allows you to model and provision AWS resources using declarative templates. Instead of manually creating resources via the AWS Management Console or scripting API calls, you define the entire infrastructure in a JSON or YAML file, and CloudFormation handles the provisioning, updating, and deletion of those resources in an orderly and predictable manner. The exam tests your ability to read and write templates, understand resource dependencies, and manage stack operations.
How CloudFormation Works Internally
When you submit a template to CloudFormation, it creates a stack — a collection of AWS resources that are managed as a single unit. The service parses the template, validates the resource definitions, and then initiates the creation of resources in the correct order based on depends-on relationships. CloudFormation uses a state machine to track the status of each resource (e.g., CREATE_IN_PROGRESS, CREATE_COMPLETE, CREATE_FAILED). If a resource creation fails, CloudFormation can automatically roll back the entire stack, deleting any resources that were successfully created, unless you specify a custom DeletionPolicy.
Template Structure
A CloudFormation template consists of several top-level sections:
AWSTemplateFormatVersion: (optional) The version of the template format. Current value is 2010-09-09.
Description: A string describing the template. Must follow the format version if included.
Metadata: Additional information about the template, like template author or dependencies.
Parameters: Input values that are passed to the template when creating or updating the stack. Useful for making templates reusable (e.g., instance type, environment name).
Mappings: A static lookup table (e.g., mapping AWS regions to AMI IDs).
Conditions: Conditions that control whether certain resources are created or properties are set, based on parameter values.
Transform: For referencing AWS Serverless Application Model (SAM) or other macros.
Resources: (Required) The core of the template — the AWS resources you want to create. Each resource has a logical ID, a type (e.g., AWS::EC2::Instance), and properties.
Outputs: Values that are returned after the stack is created, such as the DNS name of a load balancer.
Resource Dependencies
CloudFormation automatically determines the order of resource creation based on property references. For example, if an EC2 instance references a security group by its logical ID, CloudFormation knows to create the security group first. You can also explicitly declare dependencies using the DependsOn attribute:
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
DependsOn:
- MySecurityGroup
Properties:
...Intrinsic Functions
CloudFormation provides intrinsic functions to transform values at runtime:
Ref: Returns the physical ID of a resource or the value of a parameter.
Fn::GetAtt: Returns an attribute value from a resource (e.g., the public IP of an EC2 instance).
Fn::Join: Joins strings with a delimiter.
Fn::Sub: Substitutes variables in a string, e.g., !Sub "${AWS::Region}".
Fn::Select: Selects an element from a list.
Fn::FindInMap: Returns a value from a mapping.
Fn::If: Returns one value if a condition is true, another if false.
Fn::Equals, Fn::Not, Fn::And, Fn::Or: Condition functions.
Stack Update and Change Sets
When you update a stack, CloudFormation compares the new template with the existing stack and determines what changes to make. It creates a change set that lists all proposed changes (additions, modifications, deletions) before you apply them. This is a key exam topic: change sets allow you to preview changes and avoid unintended modifications. For example, you can see if a change will cause resource replacement (e.g., changing an EC2 instance type requires replacement) or in-place update (e.g., updating a security group rule).
Rollback and Deletion Policies
If a stack creation or update fails, CloudFormation by default rolls back to the last known good state. You can disable rollback during creation by setting DisableRollback to true. For updates, you can set RollbackConfiguration to specify a trigger (e.g., a CloudWatch alarm). The DeletionPolicy attribute on a resource controls what happens when the stack is deleted:
Delete: (default) Deletes the resource.
Retain: Preserves the resource (e.g., to keep an S3 bucket with data).
Snapshot: Creates a snapshot before deletion (supported for RDS, ElastiCache, Redshift, etc.).
Stack Sets and Nested Stacks
StackSets allow you to deploy stacks across multiple accounts and regions from a single template. Nested stacks let you compose a stack from other stacks, promoting reuse. The parent stack references a nested stack template URL (in S3) and passes parameters. This is useful for breaking down large templates into manageable modules.
Verification Commands
The primary CLI commands for CloudFormation are:
# Create a stack
aws cloudformation create-stack --stack-name my-stack --template-body file://template.yaml
# Create a change set
aws cloudformation create-change-set --stack-name my-stack --template-body file://new-template.yaml --change-set-name my-change-set
# Execute a change set
aws cloudformation execute-change-set --change-set-name my-change-set --stack-name my-stack
# Delete a stack
aws cloudformation delete-stack --stack-name my-stack
# Describe stack events
aws cloudformation describe-stack-events --stack-name my-stackInteraction with Other Services
CloudFormation integrates with many AWS services:
AWS SAM: An extension of CloudFormation for serverless applications. SAM templates are transformed into CloudFormation via the Transform section.
AWS CodePipeline: Can deploy CloudFormation stacks using the CreateStack action.
AWS Config: Can track changes to CloudFormation stacks.
CloudTrail: Logs all CloudFormation API calls.
Best Practices for Developers
Use parameters for environment-specific values (e.g., environment name, instance type).
Use mappings for region-specific values (e.g., AMI IDs).
Use conditions to create resources only in certain environments (e.g., skip a development database).
Always use change sets before updating production stacks.
Set DeletionPolicy: Retain on critical data stores (S3 buckets, RDS databases).
Validate templates using aws cloudformation validate-template.
Common Exam Scenarios
The exam often tests:
Recognizing the correct intrinsic function to use (e.g., Fn::GetAtt vs Ref).
Understanding when a resource will be replaced vs updated.
Interpreting change set output.
Knowing the default rollback behavior.
Identifying the correct DeletionPolicy for a given scenario.
Troubleshooting stack creation failures (e.g., insufficient IAM permissions, dependency issues).
Create a CloudFormation Template
Write a YAML or JSON template that defines the desired AWS resources. Start with the `AWSTemplateFormatVersion` (optional) and a `Description`. Define `Parameters` for inputs like instance type or environment name. Use `Resources` to declare each resource with a logical ID, type, and properties. For example, an EC2 instance resource (`AWS::EC2::Instance`) requires an `ImageId` and `InstanceType`. Use `Mappings` for region-specific AMI IDs. Add `Outputs` to return useful information after stack creation, like the public IP of the instance. Validate the template syntax using the AWS CLI command `aws cloudformation validate-template --template-body file://template.yaml`.
Create a Stack from the Template
Use the AWS Management Console, CLI, or SDK to create a stack. In the CLI, run `aws cloudformation create-stack --stack-name my-stack --template-body file://template.yaml --parameters ParameterKey=InstanceType,ParameterValue=t2.micro`. CloudFormation parses the template, validates resource definitions, and starts provisioning resources in the correct order based on dependencies. It creates a stack object and assigns a unique stack ID. The stack status transitions from `CREATE_IN_PROGRESS` to `CREATE_COMPLETE` or `CREATE_FAILED`. You can monitor progress via the console or by polling `describe-stack-events`.
Monitor Stack Creation Events
Track the progress of stack creation by viewing stack events. Each event corresponds to a resource creation step, showing the logical ID, resource type, status, and status reason. For example, a security group creation event might show `CREATE_COMPLETE` with no status reason. If a resource fails, the status reason explains the error (e.g., 'You do not have permission to create the resource'). CloudFormation automatically rolls back on failure unless `DisableRollback` is set. Use `aws cloudformation describe-stack-events --stack-name my-stack` to retrieve events.
Update the Stack Using Change Sets
When you need to modify the stack, first create a change set to preview changes. Run `aws cloudformation create-change-set --stack-name my-stack --template-body file://new-template.yaml --change-set-name my-change-set`. The change set lists all proposed changes, including whether each resource will be added, modified, or deleted, and whether the modification requires replacement (e.g., changing an EC2 instance type) or is an in-place update (e.g., adding a security group rule). Review the change set using `describe-change-set`. If satisfied, execute it with `execute-change-set`. This minimizes risk by allowing you to abort before applying changes.
Delete the Stack and Handle Deletion Policies
To delete the stack and all its resources, run `aws cloudformation delete-stack --stack-name my-stack`. CloudFormation deletes resources in reverse order of creation. Resources with `DeletionPolicy: Retain` are preserved (e.g., S3 buckets with data). Resources with `DeletionPolicy: Snapshot` are snapshotted before deletion (e.g., RDS databases). If a resource fails to delete (e.g., an S3 bucket that is not empty), the stack deletion fails and the stack remains in `DELETE_FAILED` state. You can then manually delete the resource and retry deletion.
Scenario 1: Multi-Environment Deployment
A company runs three environments: development, staging, and production. They use a single CloudFormation template with parameters for environment name, instance type, and database size. Conditions in the template control resource creation: for development, they skip creating a load balancer and use smaller instances. They deploy using separate stacks per environment: app-dev, app-staging, app-prod. Updates are rolled out first to staging, then production, using change sets. This ensures consistency and reduces manual errors. Common issue: forgetting to update the parameter values when promoting a stack, leading to mismatched configurations. They use AWS CodePipeline to automate deployments, with approval gates before production.
Scenario 2: Disaster Recovery with Cross-Region Replication
A financial services firm needs to replicate infrastructure to a secondary region for disaster recovery. They use StackSets to deploy the same template to us-east-1 and us-west-2 simultaneously. The template includes an S3 bucket with DeletionPolicy: Retain and versioning enabled. They synchronize data using S3 cross-region replication. During a disaster, they promote the secondary stack by updating Route 53 DNS records. The challenge is handling stateful resources like RDS; they use snapshot-based replication and a separate CloudFormation template to restore from snapshot. Misconfiguration of StackSets permissions (lack of necessary IAM roles in target accounts) is a common pitfall.
Scenario 3: Serverless Application with SAM
A startup builds a serverless application using AWS Lambda, API Gateway, and DynamoDB. They use the AWS Serverless Application Model (SAM), which extends CloudFormation. The SAM template defines a Lambda function with AWS::Serverless::Function, an API with AWS::Serverless::Api, and a DynamoDB table. The Transform section includes AWS::Serverless-2016-10-31. They use sam build and sam deploy to create the CloudFormation stack. A common issue is exceeding the CloudFormation template size limit (51,200 bytes) for large applications; they mitigate by using nested stacks. The exam tests knowledge of SAM transforms and how they map to CloudFormation resources.
What DVA-C02 Tests on CloudFormation
The DVA-C02 exam focuses on Objective 3.2: Deploying and managing infrastructure with CloudFormation. Key subtopics include:
- Template structure: Recognizing sections like Parameters, Resources, Outputs, Conditions, and Mappings.
- Intrinsic functions: Knowing when to use Ref vs Fn::GetAtt, Fn::Sub, Fn::Select, and Fn::FindInMap.
- Change sets: Understanding that change sets allow you to preview changes before applying them. A common question: 'How can you safely update a production stack?' Answer: Create a change set, review it, then execute.
- Rollback behavior: Default is to roll back on failure. The exam tests DisableRollback and RollbackConfiguration with CloudWatch alarms.
- Deletion policies: Retain for preserving resources, Snapshot for databases. Trap: candidates think Delete is the default for all resources, but for some resources like S3 buckets, the default is to delete only if empty.
- StackSets: For multi-account/region deployments. Know that StackSets require a trusted IAM role.
- Nested stacks: For modular templates. The parent stack references a template URL in S3.
- Troubleshooting: Common errors include insufficient IAM permissions, circular dependencies, and template size limits (51,200 bytes for template body, 460,800 bytes for template URL).
Common Wrong Answers and Why
Using `Ref` to get an attribute like public IP: Ref returns the physical ID (e.g., instance ID), not attributes. Use Fn::GetAtt for attributes.
Thinking `DeletionPolicy: Snapshot` works for EC2: It only works for resources that support snapshots (RDS, ElastiCache, Redshift, Neptune). For EC2, you must use Retain or automate snapshotting separately.
Assuming update always replaces resource: Some updates are in-place (e.g., security group rule addition), others require replacement (e.g., changing EC2 instance type). The exam tests which properties cause replacement.
Believing change sets are mandatory: They are optional but recommended. You can update a stack directly, but change sets provide a safety net.
Specific Numbers and Terms
Template size limit: 51,200 bytes for template body, 460,800 bytes for template URL (S3).
Maximum number of resources per stack: 500 (default, can be increased).
Maximum number of parameters: 200.
Maximum number of outputs: 200.
Stack name length: 1-128 characters, alphanumeric and hyphens.
AWSTemplateFormatVersion: 2010-09-09 (the only valid version).
Edge Cases
Stack deletion failure: If an S3 bucket is not empty, deletion fails. Use DeletionPolicy: Retain or empty the bucket first.
Circular dependency: If resource A depends on B and B depends on A, CloudFormation fails. Use DependsOn carefully.
Stack import: You can import existing resources into a CloudFormation stack using resource import. The exam may test this as a way to bring existing infrastructure under management.
How to Eliminate Wrong Answers
If the question asks for a resource's attribute, eliminate any answer that uses Ref — Ref gives the ID, not attributes.
If the question involves cross-account deployment, eliminate answers that don't mention StackSets or IAM roles.
If the question is about safe updates, eliminate answers that skip change sets.
If the question involves preserving a resource on stack deletion, eliminate answers that don't mention DeletionPolicy: Retain.
CloudFormation is a declarative IaC service for provisioning AWS resources via templates.
Templates consist of sections: AWSTemplateFormatVersion, Description, Parameters, Mappings, Conditions, Transform, Resources, Outputs.
Resources are the only required section; each resource has a logical ID, type, and properties.
Use `Ref` to get the primary identifier of a resource; use `Fn::GetAtt` to get specific attributes.
Change sets allow you to preview changes before applying them to a stack.
Default rollback on failure can be disabled with `DisableRollback: true`.
DeletionPolicy options: Delete (default), Retain, Snapshot (for supported resources).
StackSets deploy stacks across multiple accounts and regions.
Nested stacks allow modular templates; parent references a template URL in S3.
Template body limit: 51,200 bytes; template URL limit: 460,800 bytes.
Maximum resources per stack: 500 (default).
Valid `AWSTemplateFormatVersion` is `2010-09-09`.
These come up on the exam all the time. Here's how to tell them apart.
CloudFormation
AWS-native, tightly integrated with IAM and other services.
Declarative templates in YAML or JSON.
Managed state stored in CloudFormation service (no backend configuration needed).
Supports change sets for previewing updates.
Free to use (pay only for resources created).
Terraform
Cloud-agnostic, supports multiple providers (AWS, Azure, GCP).
Uses HashiCorp Configuration Language (HCL).
State stored in a backend (S3, Terraform Cloud) that you must configure.
Offers `terraform plan` for preview, but no native change set concept.
Open-source, but Terraform Cloud/Enterprise has costs.
Mistake
CloudFormation templates must be written in JSON.
Correct
CloudFormation supports both JSON and YAML. YAML is more readable and commonly used. The exam tests both formats, but you can choose either.
Mistake
The `Ref` function returns the physical resource ID for all resources.
Correct
`Ref` typically returns the primary identifier (e.g., EC2 instance ID, security group ID), but for some resources like S3 buckets, it returns the bucket name. `Fn::GetAtt` returns specific attributes.
Mistake
`DeletionPolicy: Snapshot` works for any resource.
Correct
`Snapshot` is only supported for resources that support snapshots: RDS DB instances, ElastiCache clusters, Redshift clusters, and Neptune DB clusters. For other resources, use `Retain` or `Delete`.
Mistake
CloudFormation always rolls back on failure.
Correct
By default, yes, but you can disable rollback during stack creation by setting `DisableRollback: true`. For updates, you can configure `RollbackConfiguration` with CloudWatch alarms.
Mistake
You cannot update a stack without using a change set.
Correct
You can update a stack directly using `update-stack` without a change set. Change sets are optional but recommended for previewing changes before applying them.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
Parameters are defined in the `Parameters` section of the template. When creating or updating a stack, you provide parameter values via the CLI, console, or SDK. For example, using the CLI: `aws cloudformation create-stack --stack-name my-stack --template-body file://template.yaml --parameters ParameterKey=InstanceType,ParameterValue=t2.micro`. You can also use `ParameterKey=KeyName,ParameterValue=my-key`. Parameter values can be referenced in the template using `!Ref ParameterName` or `Fn::Sub`.
`Ref` returns the physical ID of a resource (e.g., EC2 instance ID, security group ID). For some resources, it returns a different identifier (e.g., S3 bucket name). `Fn::GetAtt` returns a specific attribute of a resource, such as the public IP address of an EC2 instance or the ARN of a Lambda function. Use `Ref` when you need the resource's primary identifier; use `Fn::GetAtt` when you need a specific attribute. For example, `!GetAtt MyEC2Instance.PublicIp`.
Set the `DeletionPolicy` attribute to `Retain` on the S3 bucket resource. For example: `MyS3Bucket: Type: AWS::S3::Bucket, DeletionPolicy: Retain, Properties: ...`. This ensures the bucket is preserved when the stack is deleted. If you want to create a snapshot before deletion (for supported resources like RDS), use `DeletionPolicy: Snapshot`.
Yes, you can update a stack directly using the `update-stack` command or the console. However, it is recommended to use a change set first to preview the changes, especially for production stacks. A change set shows exactly what resources will be added, modified, or deleted, and whether modifications will cause replacement. This helps avoid unintended disruptions.
By default, CloudFormation rolls back the stack, deleting any resources that were successfully created. You can disable this behavior by setting `DisableRollback: true` during stack creation. The stack then remains in `CREATE_FAILED` state, and you can troubleshoot the failure. For updates, you can configure `RollbackConfiguration` with CloudWatch alarms to trigger a rollback.
Use the `Fn::ImportValue` intrinsic function to import an output value from another stack. The exporting stack must have an `Output` with an `Export` name. For example, in the exporting stack: `Outputs: VpcId: Value: !Ref MyVPC, Export: Name: MyVpcId`. In the importing stack: `!ImportValue MyVpcId`. This works across stacks in the same region and account.
The template body (inline) has a maximum size of 51,200 bytes. If you upload the template to an S3 bucket and reference it via URL, the maximum size is 460,800 bytes. The template URL must point to an S3 bucket that the CloudFormation service can access.
You've just covered CloudFormation for Developers — now see how well it sticks with free DVA-C02 practice questions. Full explanations included, no account needed.
Done with this chapter?