I was recently invited to a CloudFormation workshop with a group of early CloudFormation users. I soon realized that the group had a good understanding of the basics, so I started to introduce more advanced features.

Today, I would like to share with you six CloudFormation features that have inspired the workshop participants most.

Do you prefer listening to a podcast episode over reading a blog post? Here you go!

Writing CloudFormation templates is error prone. We should use every tool available to make our lives easier. I use the following tools:

yamllint Locally ensures that our yaml is correct cfn-lint Locally checks if the template makes sense aws cloudformation validate-template Sends the template to AWS for validation

yamllint and cfn-lint are integrated into my editor, and I execute aws cloudformation validate-template before I git commit .

Creation policy

A CloudFormation creation policy is helpful if you provision an EC2 instance, typically by using user data. By default, when CloudFormation creates and EC2 instance it will not wait for the operating system and application to be ready. With a creation policy, you can ask CloudFormation to wait for an external signal.

In the following snippet, you find a CreationPolicy that instructs CloudFormation to wait for a signal with a timeout of 10 minutes ( PT10M ). The /opt/aws/bin/cfn-signal command sends the signal to CloudFormation to indicate that the user data script finished successfully ( --exit-code 0 ).



Resources:

VirtualMachine:

Type: 'AWS::EC2::Instance'

CreationPolicy:

ResourceSignal:

Timeout: PT10M

Properties:



UserData:

'Fn::Base64' : !Sub |

#!/bin/bash -ex

# run some commands

/opt/aws/bin/cfn-signal --exit-code 0 --resource VirtualMachine --region ${AWS::Region} --stack ${AWS::StackName}



Keep in mind that the logical id VirtualMachine of the resource needs to be referenced in cfn-signal using --resource VirtualMachine .

You can even improve this snippet to let CloudFormation know if the user data script failed using #!/bin/bash -e , trap , and --exit-code 1 :



Resources:

VirtualMachine:

Type: 'AWS::EC2::Instance'

CreationPolicy:

ResourceSignal:

Timeout: PT10M

Properties:

UserData:

'Fn::Base64' : !Sub |

#!/bin/bash -ex

trap '/opt/aws/bin/cfn-signal --exit-code 1 --resource VirtualMachine --region ${AWS::Region} --stack ${AWS::StackName}' ERR

# run some commands

/opt/aws/bin/cfn-signal --exit-code 0 --resource VirtualMachine --region ${AWS::Region} --stack ${AWS::StackName}



Check out the following links if you are interested in real-world examples:

EC2 instance: CreationPolicy and cfn-signal

Auto Scaling Group: CreationPolicy and cfn-signal (Keep in mind that the CreationPolicy is attached to the auto scaling group while the cfn-signal is added to the user data in the launch configuration)

A CloudFormation update policy triggers a rolling update to make changes to an auto scaling group. A rolling update will execute your change in small batches (e.g., instance by instance).

The following CloudFormation snippet demonstrates a rolling update that waits for signals in the same way you learned about in the creation policy:



Resources:

LaunchConfiguration:

Type: 'AWS::AutoScaling::LaunchConfiguration'

Properties:



AutoScalingGroup:

Type: 'AWS::AutoScaling::AutoScalingGroup'

Properties:



LaunchConfigurationName: !Ref LaunchConfiguration

UpdatePolicy:

AutoScalingRollingUpdate:

PauseTime: PT10M

WaitOnResourceSignals: true



Check out the following links if you are interested in real-world examples:

A update policy can do even more.

Deletion policy

A CloudFormation deletion policy can prevent serious data loss. If CloudFormation deletes a resource, you can instruct CloudFormation to perform a backup first. This works for the following resource types: