A Simple Introduction to AWS CloudFormation Part 4: Change Sets = Dry Run Mode
UPDATE 2022/8/12: Check out the improved CloudFormation Fundamentals Introductory Course.
I am a big fan of AWS CloudFormation because it gives you the power to codify the infrastructure and provision it in a repeatable way. One thing that I’ve always wished that CloudFormation had was the ability to see the what changes would be applied ahead of time before hitting that update-stack button. Who wants to hit a big scary red button without knowing what is about to happen? I don’t.
In the puppet world, this preview run is called dry-run or noop mode. In terraform world, this is known as a terraform plan. In response, the AWS team has released something called Change Sets.
When I first heard of Change Sets, the name made me think of git changesets. I assumed that this meant I would have to write a “change set” and then apply this change set to the CloudFormation stack. The same way a git patch file can be applied to your source code. This sounded like a lot of work and not what I was looking for. But I’ve had a chance to look at change sets recently, and my understanding of them was completely wrong. CloudFormation Change Sets is dry run mode! It’s AWS way of generating a preview of what the stack update will do. This is exactly what I’ve been looking for.
Previewing Your Changes: dry-run in action
Building upon Part 1, Part 2 and Part 3 blog posts we will use this dry-run ability to preview what will change when we update a stack and add a route53 record to it. We will also preview the deletion of the route53 record.
First, let’s create an example stack to work with:
$ aws cloudformation create-stack --stack-name example --template-body file://templates/single-instance.yml --parameters file://parameters/single-instance.json
To create the change set:
$ aws cloudformation create-change-set --stack-name example --template-body file://templates/instance-and-route53.yml --parameters file://parameters/instance-and-route53.json --change-set-name changeset-1
You should see output like this:
{
"StackId": "arn:aws:cloudformation:us-west-2:160619113767:stack/example/7dddd1d0-3ea3-11e7-a894-503ac9841afd",
"Id": "arn:aws:cloudformation:us-west-2:160619113767:changeSet/changeset-1/4acb3939-5677-4973-a6cb-f5aed16689de"
}
Now to see a preview of the changes you use describe-change-set
aws cloudformation describe-change-set --stack-name example --change-set-name changeset-1 | jq '.Changes[]'
You should see this output:
{
"ResourceChange": {
"Action": "Add",
"ResourceType": "AWS::Route53::RecordSet",
"Scope": [],
"Details": [],
"LogicalResourceId": "DnsRecord"
},
"Type": "Resource"
}
You can see that the Changes attribute out of the output confirm that an AWS::Route53::RecordSet DNS record will be added.
You can also view the Change Set in the CloudFormation Console, which is even easier on the eyes. Click on the stack’s “Change Sets” tab and click on the Change Set you just created. Here you can preview the details of the changes.
On the same Change Set Detail page, you can also choose to execute the Change Set right from where you preview it!
Updating the Stack
This gives you 2 ways to update a stack. You can go back and run the update-stack command as we did in the Part 3 post. Here is the command again.
aws cloudformation update-stack --stack-name example --template-body file://templates/instance-and-route53.yml --parameters file://parameters/instance-and-route53.json
Or you can execute the Change Set from the CloudFormation console, which is super simple. Here’s the equivalent CLI command:
aws cloudformation execute-change-set --stack-name example --change-set-name changeset-1
Both ways accomplish the same end result. You get one nice additional benefit if you use execute-change-set
method; it shows that the Change Set was applied and thereby provides a clear audit trail.
Preview Again: Deleting the Route53 Record
Let’s apply another change set again, this time to remove the route53 record.
$ aws cloudformation create-change-set --stack-name example --template-body file://templates/single-instance.yml --parameters file://parameters/single-instance.json --change-set-name changeset-2
$ aws cloudformation execute-change-set --stack-name example --change-set-name changeset-2
You can view the results in the CloudFormation console.
Summary
Change Sets is such a powerful addition to CloudFormation that I cannot believe it took me so long to realize that it is the dry-run mode holy grail feature that I’ve been waiting for.
After using Change Sets, I’ve realized that it is even better than a dry run. When working alone a dry-run more where you can preview the changes by yourself as a lone developer having the dry-run as part of one command flow makes a lot of sense. However, a huge advantage of change sets is that it gives you the ability to show to your co-workers what changes you are trying to apply to the stack. They can quickly review it in the CloudFormation console and give you the thumbs up or execute it. The fact that it’s viewable in a web browser as well as from the CLI makes it extremely convenient for sharing.
In the next post, I’ll show you how to simplify working with CloudFormation templates with a tool I wrote called lono: Generating Hundreds of CloudFormation Templates with Lono.
Update: Simplify AWS CloudFormation Change Set usage with lono cfn preview, covered here AWS CloudFormation dry-run with lono-cfn preview.
Posts in This Series
- A Simple Introduction to AWS CloudFormation Part 1: EC2 Instance
- A Simple Introduction to AWS CloudFormation Part 2: EC2 Instance and Route53
- A Simple Introduction to AWS CloudFormation Part 3: Updating a Stack
- A Simple Introduction to AWS CloudFormation Part 4: Change Sets = Dry Run Mode
You may also be interested in the Lono CloudFormation Framework Introduction Series.
Thanks for reading this far. If you found this article useful, I'd really appreciate it if you share this article so others can find it too! Thanks 😁 Also follow me on Twitter.
Got questions? Check out BoltOps.
You might also like
More tools:
-
Kubes
Kubes: Kubernetes Deployment Tool
Kubes is a Kubernetes Deployment Tool. It builds the docker image, creates the Kubernetes YAML, and runs kubectl apply. It automates the deployment process and saves you precious finger-typing energy.
-
Jets
Jets: The Ruby Serverless Framework
Ruby on Jets allows you to create and deploy serverless services with ease, and to seamlessly glue AWS services together with the most beautiful dynamic language: Ruby. It includes everything you need to build an API and deploy it to AWS Lambda. Jets leverages the power of Ruby to make serverless joyful for everyone.
-
Lono
Lono: The CloudFormation Framework
Building infrastructure-as-code is challenging. Lono makes it much easier and fun. It includes everything you need to manage and deploy infrastructure-as-code.