CloudFormation Change Sets are designed to prevent you from deploying unintended infrastructure changes by providing a diff of what will happen before it does happen.
Let’s see it in action. Imagine you have a CloudFormation stack that provisions a simple EC2 instance.
AWSTemplateFormatVersion: '2010-09-09'
Description: A simple EC2 instance.
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0abcdef1234567890 # Example AMI ID
InstanceType: t2.micro
Now, you decide you want to change the InstanceType to t3.micro. Instead of directly updating the stack, you’ll create a change set.
First, you create the change set. You’ll need the stack name, a name for your change set, and the new template body.
aws cloudformation create-change-set \
--stack-name my-ec2-stack \
--change-set-name my-instance-type-change \
--template-body file://new-template.yaml \
--capabilities CAPABILITY_IAM # If your template uses IAM resources
The new-template.yaml file would contain your updated template:
AWSTemplateFormatVersion: '2010-09-09'
Description: A simple EC2 instance.
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0abcdef1234567890 # Example AMI ID
InstanceType: t3.micro # Changed from t2.micro
After running the create-change-set command, it will take a moment for CloudFormation to analyze the changes. You then describe the change set to see the details.
aws cloudformation describe-change-set \
--stack-name my-ec2-stack \
--change-set-name my-instance-type-change
The output will show you exactly what CloudFormation plans to do. You’ll see something like this, detailing the Action (Modify, Add, Delete) and the LogicalResourceId:
{
"ChangeSetName": "my-instance-type-change",
"ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/my-instance-type-change/...",
"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/my-ec2-stack/...",
"StackName": "my-ec2-stack",
"Parameters": [],
"RollbackConfiguration": {
"RollbackOnFailure": true,
"DisableRollback": false
},
"CreationTime": "...",
"ExecutionStatus": "AVAILABLE",
"Status": "CREATE_COMPLETE",
"NotificationARNs": [],
"Capabilities": [
"CAPABILITY_IAM"
],
"Changes": [
{
"ResourceChange": {
"Action": "Modify",
"LogicalResourceId": "MyEC2Instance",
"ResourceType": "AWS::EC2::Instance",
"PhysicalResourceId": "i-0123456789abcdef0",
"Scope": [
"Properties"
],
"Details": [
{
"Name": "InstanceType",
"CurrentValues": "t2.micro",
"TargetValues": "t3.micro"
}
]
}
}
],
"NextToken": null,
"Tags": []
}
This output clearly shows that MyEC2Instance will be Modifyed, and specifically the InstanceType property is changing from t2.micro to t3.micro. This is your chance to confirm the change is what you expect.
If you’re happy with the changes, you can execute the change set.
aws cloudformation execute-change-set \
--change-set-name my-instance-type-change \
--stack-name my-ec2-stack
This command triggers CloudFormation to apply the described changes to your stack. You can then monitor the stack’s progress via the AWS Console or the describe-stacks CLI command.
The core problem CloudFormation Change Sets solve is the "drift" between your understanding of what an infrastructure deployment should do and what it actually does. By providing this intermediate review step, they act as a crucial safety net, especially in complex environments or when multiple team members are contributing to infrastructure-as-code. They force a deliberate, explicit approval of infrastructure modifications, significantly reducing the risk of accidental misconfigurations or service disruptions. The entire system is built around the idea of making changes explicit and reviewable, turning potentially risky updates into controlled, predictable operations.
What most people don’t realize is that change sets are not just for simple property modifications. They are essential for detecting destructive changes, like deleting an entire EC2 instance or a critical RDS database, before they are irrevocably made. When a change set lists an Action as Delete, it’s a strong signal to pause and confirm that this is indeed the intended outcome. Furthermore, change sets can also identify when a resource will be replaced rather than modified in-place. For example, changing certain properties of an EC2 instance might require the instance to be terminated and a new one launched, which would be flagged as a Replace action in the change set, accompanied by a Create and Delete for that specific resource.
Once your change set executes successfully and your stack updates, you’ll likely want to verify the actual state of your resources.