Quick-reference tmux cheatsheet: sessions, windows, panes, copy mode, synchronize-panes, .tmux.conf …
AWS CloudFormation Cheatsheet AWS CloudFormation Cheatsheet

Summary
CloudFormation is still my default for AWS-native infrastructure. No state file to babysit, and rollbacks come free. This is the reference I wish I had when I started: template anatomy, the intrinsic functions I actually use, and the CLI commands for the full stack lifecycle. For imperative AWS scripting I reach for boto3 instead, and config management after provisioning goes to Ansible.
Template Anatomy
AWSTemplateFormatVersion: '2010-09-09' # only valid value
Description: App network layer
Parameters: # runtime inputs
EnvName:
Type: String
Default: dev
AllowedValues: [dev, staging, prod]
VpcCidr:
Type: String
Default: 10.0.0.0/16
AllowedPattern: ^\d+\.\d+\.\d+\.\d+/\d+$
Mappings: # static lookup tables
RegionAmi:
us-east-1: { Ami: ami-0abc1234 }
ca-central-1: { Ami: ami-0def5678 }
Conditions: # booleans evaluated at deploy time
IsProd: !Equals [!Ref EnvName, prod]
Resources: # the only REQUIRED section
MyVpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidr
Outputs: # values to display/export
VpcId:
Value: !Ref MyVpc
Export:
Name: !Sub '${EnvName}-vpc-id'
Other top-level sections: Metadata, Rules (parameter validation), Transform (AWS::Serverless-2016-10-31 for SAM, AWS::LanguageExtensions for Fn::ForEach).
Expand your knowledge with Ansible Cheatsheet
Intrinsic Functions
Docs: Intrinsic function reference, CloudFormation User Guide
| Function | Short form | What it does |
|---|---|---|
Ref | !Ref | Parameter value or resource’s default ID (e.g. VPC ID, bucket name) |
Fn::GetAtt | !GetAtt Res.Attr | Named attribute of a resource (!GetAtt Db.Endpoint.Address) |
Fn::Sub | !Sub '${Var}-x' | String interpolation of params, resources, pseudo params |
Fn::Join | !Join [':', [a, b]] | Join list with delimiter |
Fn::If | !If [Cond, valTrue, valFalse] | Conditional value (condition from Conditions) |
Fn::ImportValue | !ImportValue name | Read another stack’s export |
Fn::Select | !Select [0, !GetAZs ''] | Pick item from a list (!GetAZs = region’s AZs) |
Fn::Split | !Split [',', !Ref Csv] | String to list |
Fn::FindInMap | !FindInMap [Map, Key, SubKey] | Lookup in Mappings |
!Sub beats !Join for readability in almost every case:
Deepen your understanding in Ansible Cheatsheet
BucketArn: !Sub 'arn:${AWS::Partition}:s3:::${MyBucket}/*'
Sample Template: S3 + IAM
Docs: AWS::S3::Bucket, CloudFormation User Guide
Explore this further in Docker Cheatsheet
AWSTemplateFormatVersion: '2010-09-09'
Description: Versioned artifact bucket with a scoped writer role
Parameters:
EnvName: { Type: String, Default: dev }
Conditions:
IsProd: !Equals [!Ref EnvName, prod]
Resources:
ArtifactBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Properties:
BucketName: !Sub 'artifacts-${EnvName}-${AWS::AccountId}'
VersioningConfiguration:
Status: !If [IsProd, Enabled, Suspended]
PublicAccessBlockConfiguration:
BlockPublicAcls: true
RestrictPublicBuckets: true
WriterRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- { Effect: Allow, Principal: { Service: ec2.amazonaws.com }, Action: 'sts:AssumeRole' }
Policies:
- PolicyName: write-artifacts
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: ['s3:PutObject', 's3:GetObject']
Resource: !Sub '${ArtifactBucket.Arn}/*'
Outputs:
BucketName:
Value: !Ref ArtifactBucket
Export:
Name: !Sub '${EnvName}-artifact-bucket'
CLI: Deploy & Stack Lifecycle
Docs: cloudformation, AWS CLI Command Reference
Discover related concepts in Python Basics & CLI Cheatsheet
# One command, idempotent - creates or updates (my default)
aws cloudformation deploy \
--stack-name app-dev \
--template-file template.yaml \
--parameter-overrides EnvName=dev VpcCidr=10.1.0.0/16 \
--capabilities CAPABILITY_NAMED_IAM \
--no-fail-on-empty-changeset
# Explicit create / update
aws cloudformation create-stack --stack-name app-dev \
--template-body file://template.yaml \
--parameters ParameterKey=EnvName,ParameterValue=dev \
--capabilities CAPABILITY_IAM
aws cloudformation update-stack --stack-name app-dev \
--template-body file://template.yaml \
--parameters ParameterKey=EnvName,UsePreviousValue=true
# Wait + inspect
aws cloudformation wait stack-create-complete --stack-name app-dev
aws cloudformation describe-stacks --stack-name app-dev --query 'Stacks[0].Outputs'
aws cloudformation describe-stack-events --stack-name app-dev \
--query 'StackEvents[?ResourceStatus==`CREATE_FAILED`]'
# Delete
aws cloudformation delete-stack --stack-name app-dev
Change Sets
Docs: Updating stacks using change sets, CloudFormation User Guide
Preview exactly what an update will touch before executing. Mandatory habit for prod:
aws cloudformation create-change-set \
--stack-name app-prod --change-set-name add-alarms \
--template-body file://template.yaml \
--capabilities CAPABILITY_NAMED_IAM
aws cloudformation describe-change-set \
--stack-name app-prod --change-set-name add-alarms \
--query 'Changes[].ResourceChange.{Action:Action,Resource:LogicalResourceId,Replacement:Replacement}'
aws cloudformation execute-change-set \
--stack-name app-prod --change-set-name add-alarms
Replacement: True means the resource gets destroyed and recreated. Check this column every time.
Uncover more details in Bash sed & awk Cheatsheet
Drift Detection
Docs: Detecting stack drift, CloudFormation User Guide
Journey deeper into this topic with Kubernetes Cheatsheet
aws cloudformation detect-stack-drift --stack-name app-prod
aws cloudformation describe-stack-drift-detection-status --stack-drift-detection-id <id>
aws cloudformation describe-stack-resource-drifts --stack-name app-prod \
--stack-resource-drift-status-filters MODIFIED DELETED
Stack Policies & Termination Protection
# Termination protection - flip on for anything prod
aws cloudformation update-termination-protection \
--stack-name app-prod --enable-termination-protection
{
"Statement": [
{ "Effect": "Allow", "Action": "Update:*", "Principal": "*", "Resource": "*" },
{ "Effect": "Deny", "Action": ["Update:Replace", "Update:Delete"],
"Principal": "*", "Resource": "LogicalResourceId/ProdDatabase" }
]
}
aws cloudformation set-stack-policy --stack-name app-prod \
--stack-policy-body file://policy.json
Also set DeletionPolicy: Retain (and UpdateReplacePolicy: Retain) on stateful resources: databases, buckets, EFS.
Enrich your learning with Docker Cheatsheet
Nested Stacks & Exports
Resources:
NetworkStack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/my-templates/network.yaml
Parameters:
EnvName: !Ref EnvName
App:
Type: AWS::EC2::Instance
Properties:
SubnetId: !GetAtt NetworkStack.Outputs.PublicSubnetId
Cross-stack (not nested): export in one stack’s Outputs, then !ImportValue prod-vpc-id elsewhere. You cannot delete or change an export while another stack imports it. Nested stacks avoid that coupling; exports make it explicit.
Gain comprehensive insights from Python Basics & CLI Cheatsheet
Pseudo Parameters
Docs: Pseudo parameters reference, CloudFormation User Guide
Master this concept through Jenkins Cheatsheet
| Parameter | Example value |
|---|---|
AWS::AccountId | 123456789012 |
AWS::Region | ca-central-1 |
AWS::StackName | app-prod |
AWS::Partition | aws (or aws-cn, aws-us-gov) |
AWS::NoValue | Removes a property when used with !If |
Validation & Linting
aws cloudformation validate-template --template-body file://template.yaml
pip install cfn-lint
cfn-lint templates/**/*.yaml # catches type errors, bad refs, region issues
validate-template only checks syntax; cfn-lint checks semantics against the real resource specs. Run both in CI.
Delve into specifics at Bash Basics Cheatsheet
Rollback Behavior
Docs: Continue rolling back an update, CloudFormation User Guide
0Deepen your understanding in Ansible Cheatsheet
- Create fails →
ROLLBACK_COMPLETE: stack is dead, delete it and recreate. - Update fails → automatic rollback to previous working state (
UPDATE_ROLLBACK_COMPLETE); if that rollback fails,continue-update-rollback(optionally--resources-to-skip). --disable-rollback/--on-failure DO_NOTHINGon create keeps failed resources up for debugging.
ROLLBACK_COMPLETE after a failed create can never be updated, only deleted. Delete it, fix the template, and create again. This surprises everyone exactly once.Common Errors
Docs: Troubleshooting CloudFormation, CloudFormation User Guide
1Deepen your understanding in Ansible Cheatsheet
| Error | Cause | Fix |
|---|---|---|
No updates are to be performed | Template unchanged | Use deploy with --no-fail-on-empty-changeset |
Requires capabilities: [CAPABILITY_IAM] | Template creates IAM resources | Add --capabilities CAPABILITY_IAM (or CAPABILITY_NAMED_IAM for named ones) |
Export ... cannot be deleted as it is in use | Another stack imports the value | Update/delete importing stacks first |
Resource ... already exists | Name collision with unmanaged resource | Remove hardcoded name or import the resource (import change set type) |
Template format error: Unresolved resource dependencies | !Ref/!GetAtt to a typo’d logical ID | Fix the logical ID; cfn-lint catches this |
Stuck in UPDATE_ROLLBACK_FAILED | Rollback blocked (e.g. deleted resource) | continue-update-rollback --resources-to-skip |
Rate exceeded | API throttling on big stacks | Retry with backoff; split mega-stacks into nested stacks |
Circular dependency between resources | Mutual !Refs (common with SGs) | Split with AWS::EC2::SecurityGroupIngress standalone resources |
Related Cheatsheets
- Ansible: configuration management for the instances these stacks provision, with modules, handlers, roles, and Vault
- Python Boto3: the imperative side, with clients, paginators, waiters, and ClientError handling for anything a template can’t express
- Kubernetes: manifests, rollouts, and kubectl triage for the workloads that land on the clusters these stacks create
The rest of the DevOps Tooling group is one click away, or start from the top at the cheatsheet library.
Similar Articles
Related Content
More from devops
Jenkins cheatsheet with declarative pipeline syntax, credentials, parameters, parallel stages, …
Docker cheatsheet with the commands I use daily as a DevOps engineer: image builds, run flags, …
You Might Also Like
Ansible cheatsheet with inventory formats, ad-hoc commands, playbook anatomy, common modules, …
Boto3 cheatsheet for AWS automation: sessions, S3, EC2, Lambda, DynamoDB, SSM, presigned URLs, …
Quick-reference Amazon Linux 2 cheatsheet for EC2: yum, amazon-linux-extras, SSM Session Manager, …
