Skip to main content
In this lesson we demonstrate immutable infrastructure patterns on AWS using a golden AMI (built via EC2 Image Builder), Launch Templates, Auto Scaling groups (ASGs), and AWS CloudFormation update/creation policies. The goal: deploy new instances from a new AMI rather than mutating running instances in place. Immutable deployments are valuable because they reduce configuration drift and make rollbacks and auditing simpler. In this demo the AMI contains the application and configuration; user data does only minimal startup tasks (for example, starting a simple web server and exposing instance metadata). Quick clarification
  • Immutable infrastructure: replace instances with new instances built from a new AMI.
  • Mutable infrastructure: apply updates directly to running instances.
Here is an example Launch Template (note the AMI, instance type, security group and other instance-level settings):
A screenshot of the AWS EC2 console showing the Launch Template details page for "devops-020-380-lt" (lt-06a29c7cda6f00cce). It displays the template/version info and instance details like AMI, instance type (t3.micro), security group ID, and owner/creation info.
Launch templates often include networking, block device mapping, monitoring, metadata options and (optionally) user data. In an immutable model, bake the application into the AMI and keep user data minimal. Example user data that starts a simple web server and creates a status page showing instance metadata:
CloudFormation template — structure and key parameters If you use AWS CloudFormation to provision this stack, declare parameters and resources such as AMI ID, instance type, Launch Template, Auto Scaling group, target group and listener. Below is a condensed, corrected structure used in the demo. Top of the template — metadata and parameters:
Creating the stack in CloudFormation will show the stack creation progress and events. Example: a stack in CREATE_IN_PROGRESS:
A screenshot of the AWS CloudFormation console showing a list of stacks on the left and details for the selected stack on the right. The selected stack is "devops-020-380-cfn-stack" with status "CREATE_IN_PROGRESS."
AWS CloudFormation property names must be exact. For example, use DefaultActions (plural) in an ALB Listener, not DefaultAction. A small typo will cause stack creation to fail.
Key resource snippets Below are the core resource snippets from the CloudFormation template used in the demo. These show how the Launch Template is parameterized with the golden AMI, and how the ASG is configured for rolling updates and creation-time signals. Launch Template (note UpdateReplacePolicy and DeletionPolicy):
Auto Scaling group with rolling update and creation policies:
Application Target Group and Listener (health check expects HTTP 200 on root path):
cfn-signal and user-data integration When instances boot, user data can wait for the application to respond and then use cfn-signal to notify CloudFormation that the instance is ready. When embedding this script into CloudFormation, supply the user data with Fn::Base64 and Fn::Sub so CloudFormation substitutes ${AWS::StackName} and ${AWS::Region} before the instance runs the script. Also ensure the --resource value matches the logical ID of the AutoScalingGroup in your template.
When embedding this script into a CloudFormation template, provide the user data with Fn::Base64 and Fn::Sub (or !Sub) so CloudFormation substitutes ${AWS::StackName} and ${AWS::Region}. Ensure the --resource flag matches your AutoScalingGroup logical ID (for example, AutoScalingGroup).
Example user-data snippet that waits for HTTP 200 and then calls cfn-signal:
Inspecting the resulting Auto Scaling groups After the stack is created you can inspect ASGs in the EC2 console. This demo shows two ASGs with desired capacity 2:
A screenshot of the AWS EC2 console on the Auto Scaling groups page showing two auto scaling groups (devops-020-380-cfn-stack-asg and devops-020-380-asg) each with desired capacity 2. The left sidebar shows EC2 navigation sections like Elastic Block Store, Network & Security, and Load Balancing.
Zoom in on the CloudFormation-managed ASG to see the in-service instances (desired capacity 2 in this example):
Screenshot of the AWS EC2 Auto Scaling Groups console for the "devops-020-380-cfn-stack-asg" group. It shows desired capacity 2 (scaling limits 2–4) and two InService t3.micro instances listed as Healthy.
Replacing instances with a new AMI You have two common options to replace instances with a new AMI:
  • Update CloudFormation with a new Launch Template version and let the UpdatePolicy (AutoScalingRollingUpdate) perform rolling replacements.
  • Trigger an Auto Scaling group Instance Refresh, which replaces instances to match the current launch template/configuration.
This demo used an instance refresh. The ASG console displays refresh progress:
Screenshot of the AWS EC2 Auto Scaling "Instance refresh" tab showing a green banner that an instance refresh started successfully. The Active instance refresh panel displays details like the refresh ID, minimum healthy percentage (100%), rolling refresh strategy, and a 300-second instance warmup.
Practical notes and exam tips
  • Immutable deployments replace instances (no in-place changes). Mutable deployments modify running instances.
  • Use Launch Templates — Launch Configurations are legacy and lack features like versioning.
  • In CloudFormation, combine UpdatePolicy (AutoScalingRollingUpdate) with CreationPolicy/ResourceSignal to control update behavior and ensure instances are healthy before proceeding.
  • For blue/green patterns you can maintain two ASGs and switch traffic via the ALB; CodeDeploy is the recommended AWS service for exam-style blue/green deployments.
  • Use CloudFormation change sets and drift detection to preview and validate updates before applying them.
Quick resource reference table Links and references Summary Build a golden AMI, reference it in a Launch Template, attach that Launch Template to an Auto Scaling group, and control replacement behavior using CloudFormation UpdatePolicy (rolling updates) or ASG instance refreshes. This approach yields predictable, auditable, and testable immutable infrastructure.

Watch Video

Practice Lab