Change Sets
Get working knowledge of change sets to modify stacks in AWS CloudFormation.
We'll cover the following
Once we create a stack to provision resources, we might need to modify it. A change set provides a summary of proposed modifications to a CloudFormation stack.
In this lesson, we’ll explore a change set, when we need it, and how it is useful in updating or modifying a stack.
What is a change set?
Once we’ve created a stack, we may want to go back and update the stack to create new resources, modify some resource configurations, or just delete any resources we no longer require. This is often necessary to adapt to changing requirements, improve performance, maintain security, or optimize costs.
When updating an existing stack, CloudFormation will automatically generate a set of changes in the stack based on the modified template we provide. This set of changes is known as a change set.
It’s important to note that this set of changes has not yet been implemented on the stack, and we can preview and validate any creation, modification, or removal of any AWS resources before actually implementing them into the stack.
Note: A change set is not necessarily only made during stack modification but also during stack creation. However, the change set in this case is basically just the addition of all AWS resources that are being created in the stack.
Once the stack is modified, we can still preview the previous change sets, and this can be helpful in keeping track of what changes were made in the stack.
Change sets vs. drifts
Change sets are changes in a stack that are directly made by updating the template through CloudFormation. However, when changes are made directly to the AWS resources outside of CloudFormation without updating the stack through CloudFormation itself, they are detected as drifts using the CloudFormation service.
CloudFormation also allows us to detect and identify these drifts. If we were to compare change sets and drifts, we can describe change sets as intentional changes that will be made by updating templates, while drifts are changes between the actual stack state and the stack proposed in the template. To resolve drifts, we can either update the CloudFormation template to include the new configuration or revert the stack resource to its original state as defined in the template.
Example: Updating the EC2 instance type
For example, let’s say we have provisioned an EC2 instance with the t2.micro
type within a CloudFormation stack.
Introducing a drift
Let’s assume that one of the developers directly changed the instance type of that instance to m4.xlarge
type in the EC2 console for better performance.
This change was made from outside the stack, and when we execute drift detection with CloudFormation, this change will be identified as a drift. This is because the current EC2 instance is of m4.xlarge
type when we originally intended it to be of t2.micro
type with the template.
We can either resolve this drift by accepting the new change or updating the stack again to revert the instance type back to the t2.micro
type.
Creating a change set
Now, assume that we ourselves identified that we need to change the instance type for better performance. We modify the CloudFormation template, changing the instance type from t2.micro
to m4.xlarge
.
We then generated a change set in CloudFormation based on the modified template. This change set does not apply the changes immediately but shows us a preview of what will happen. For example, it might indicate that the EC2 instance will be replaced, resulting in downtime. Here, we can choose to cancel the change because the downtime might have a bigger impact than slow performance.
After reviewing the change set, understanding the impacts, and getting the necessary approvals, we can finally execute the change set to apply the changes.
Update an existing stack with a change set
The following diagram illustrates the workflow of the AWS CloudFormation Service stack modification process:
Here’s a breakdown of the CloudFormation stack update workflow:
Update template: We update the existing CloudFormation template already used to provision a CloudFormation stack.
Upload template or define it inline: We have two approaches here: we can either upload our template to an Amazon S3 bucket and generate the relevant S3 URL for it, or we can define the template inline in the API/SDK request to the AWS CloudFormation service. However, when uploading the CloudFormation template directly to the AWS console, the CloudFormation service automatically uploads the template to an S3 bucket and uses the generated S3 bucket URL to update the stack.
Change set generation: CloudFormation generates a change set representing the updated template. However, these changes are not yet implemented on the CloudFormation stack.
View change set: Once the change set is generated, we can preview the proposed changes and validate them before implementing them into the stack. When viewing the change set, we might want to introduce new changes; hence, we can generate additional change sets to introduce these changes.
Execute change set: After reviewing the change set, we can execute the change set to finally have the CloudFormation stack updated.
Using change sets, we can easily manage any modifications to AWS resources within the CloudFormation stack.
Example: Updating the security group
Let’s explore an example of changing the configuration of a security group assigned to an EC2 instance to also allow public access to it via HTTP calls on port 80
. Assume this was the template we originally used to provision our infrastructure in a stack named my-stk
, where the security group has no inbound rules and, hence, no outside resource can connect to it:
Resources:SecurityGroup:Type: "AWS::EC2::SecurityGroup"Properties:GroupDescription: "Internal Security group for EC2 instance"Instance:Type: AWS::EC2::InstanceProperties:ImageId: ami-0e731c8a588258d0dInstanceType: { "Ref" : "EC2InstanceType" }SecurityGroupIds:- !GetAtt SecurityGroup.GroupId
Here’s a diagram to explain what we’re trying to achieve:
Follow these steps to update the security group through CloudFormation and generate a change set:
Step 1: Modify the template
To update the security group, we simply need to define an inbound rule for it in the template on the port 80
. We also allow connection to the instance from any IP by setting the CIDR IP to 0.0.0.0/0
in the security group’s configuration. We’ve defined the inbound rule on lines 7–11 in the template below:
Resources:SecurityGroup:Type: "AWS::EC2::SecurityGroup"Properties:GroupDescription: "Internal Security group for EC2 instance"SecurityGroupIngress:- IpProtocol: tcpFromPort: 80ToPort: 80CidrIp: 0.0.0.0/0Instance:Type: AWS::EC2::InstanceProperties:ImageId: ami-0e731c8a588258d0dInstanceType: { "Ref" : "EC2InstanceType" }SecurityGroupIds:- !GetAtt SecurityGroup.GroupId
Step 2: Generate a change set
Next, we can upload the template to CloudFormation directly through the CloudFormation console:
In the CloudFormation console, we first need to go to the
my-stk
stack and start generating a change set for it.Next, we upload the modified template to the console and set the name of the change set as
new-change-set
.
Step 3: Review the change set
CloudFormation will ask us to review the changes proposed in the change set, which would include adding an inbound rule to the pre-provisioned security group.
Step 4: Execute the change set
After verifying that the proposed changes are as expected, we can execute the change set. CloudFormation will begin implementing changes in our stack after this.
Step 5: Wait for the stack to update
Watch the progress of the update in the CloudFormation console until it’s complete.
Step 6: Verify updates in the stack
After the update, try connecting to the EC2 instance’s IPv4 link to verify if the security group has been updated.
Best practices
Here are some best practices that we can use when working with change sets and updating CloudFormation stacks:
Manage AWS resources only through templates: We should avoid making any changes to stack resources outside of CloudFormation. Doing so can cause a mismatch between the template version stack and the actual stack, which can cause failures when updating or deleting the stack.
Use drift detection to identify direct changes in stacks: We should avoid changing a stack outside of CloudFormation. If such changes are introduced, we can have CloudFormation to detect and resolve these drifts.
Always create change sets before updating stacks: We should always generate change sets before updating stacks and review those sets of changes before actually having those changes applied to the stack.
Shorten the feedback loop: We need to lessen the feedback time we receive on the AWS infrastructure we provisioned based on the CloudFormation template, i.e., shorten the feedback loop for the CloudFormation template. For example, we can achieve this by adopting practices, like linting our CloudFormation template, that allow for the early detection and resolution of any issues before reaching a formal life cycle environment, like the production environment.
This lesson taught us about CloudFormation change sets, how they compare to drifts in CloudFormation, how they are actually implemented, and the best practices we should follow when updating stacks.
Get hands-on with 1300+ tech skills courses.