/user/kayd @ devops :~$ cat cloudformation.md

AWS CloudFormation Cheatsheet AWS CloudFormation Cheatsheet

QR Code linking to: AWS CloudFormation Cheatsheet
Karandeep Singh
Karandeep Singh
• 6 minutes

Summary

Quick-reference CloudFormation guide. Template sections, intrinsic functions, stack lifecycle CLI commands, change sets, drift detection, and error fixes.

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

Docs: Template anatomy, CloudFormation User Guide

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).

Intrinsic Functions

Docs: Intrinsic function reference, CloudFormation User Guide

FunctionShort formWhat it does
Ref!RefParameter value or resource’s default ID (e.g. VPC ID, bucket name)
Fn::GetAtt!GetAtt Res.AttrNamed 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 nameRead 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:

BucketArn: !Sub 'arn:${AWS::Partition}:s3:::${MyBucket}/*'

Sample Template: S3 + IAM

Docs: AWS::S3::Bucket, CloudFormation User Guide

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

# 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.

Drift Detection

Docs: Detecting stack drift, CloudFormation User Guide

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

Docs: Stack policies, CloudFormation User Guide

# 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.

Nested Stacks & Exports

Docs: Working with nested stacks, CloudFormation User Guide

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.

Pseudo Parameters

Docs: Pseudo parameters reference, CloudFormation User Guide

ParameterExample value
AWS::AccountId123456789012
AWS::Regionca-central-1
AWS::StackNameapp-prod
AWS::Partitionaws (or aws-cn, aws-us-gov)
AWS::NoValueRemoves a property when used with !If

Validation & Linting

Docs: validate-template, AWS CLI Command Reference

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.

Rollback Behavior

Docs: Continue rolling back an update, CloudFormation User Guide

0
  • 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_NOTHING on create keeps failed resources up for debugging.

Common Errors

Docs: Troubleshooting CloudFormation, CloudFormation User Guide

1
ErrorCauseFix
No updates are to be performedTemplate unchangedUse deploy with --no-fail-on-empty-changeset
Requires capabilities: [CAPABILITY_IAM]Template creates IAM resourcesAdd --capabilities CAPABILITY_IAM (or CAPABILITY_NAMED_IAM for named ones)
Export ... cannot be deleted as it is in useAnother stack imports the valueUpdate/delete importing stacks first
Resource ... already existsName collision with unmanaged resourceRemove hardcoded name or import the resource (import change set type)
Template format error: Unresolved resource dependencies!Ref/!GetAtt to a typo’d logical IDFix the logical ID; cfn-lint catches this
Stuck in UPDATE_ROLLBACK_FAILEDRollback blocked (e.g. deleted resource)continue-update-rollback --resources-to-skip
Rate exceededAPI throttling on big stacksRetry with backoff; split mega-stacks into nested stacks
Circular dependency between resourcesMutual !Refs (common with SGs)Split with AWS::EC2::SecurityGroupIngress standalone resources
  • 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

More from devops

tmux Cheatsheet

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

Jenkins Cheatsheet

Jenkins cheatsheet with declarative pipeline syntax, credentials, parameters, parallel stages, …

Docker Cheatsheet

Docker cheatsheet with the commands I use daily as a DevOps engineer: image builds, run flags, …

Ansible Cheatsheet

Ansible cheatsheet with inventory formats, ad-hoc commands, playbook anatomy, common modules, …

Python Boto3 Cheatsheet

Boto3 cheatsheet for AWS automation: sessions, S3, EC2, Lambda, DynamoDB, SSM, presigned URLs, …