Launch Templates
Every time you launch an EC2 (Elastic Compute Cloud — Amazon’s virtual server service) instance, you pick the same set of details: which AMI, which instance type, which key pair, which security groups, and what user data to run. A launch template captures all of those choices once, as a reusable, versioned blueprint. After that, launching an identical instance — by hand, with the CLI, or automatically through Auto Scaling — is a single reference instead of a long form. Templates are the modern, recommended way to standardize launches across a team and across an environment.
What a launch template is
A launch template is a named, saved set of launch parameters. Think of it as a recipe for an instance: AMI (Amazon Machine Image — the OS template), instance type (such as t3.micro), key pair, security groups, subnet, IAM instance profile, user data, storage (EBS volumes), tags, and dozens of other options. None of these are required in the template — you can leave any of them out and supply them at launch time — which makes templates flexible building blocks rather than rigid forms.
The defining feature is versioning. Every time you change a template you create a new numbered version (1, 2, 3, …). Old versions are kept, so you can roll forward or roll back. You can mark one version as the default, and consumers can ask for a specific version number, the special value $Default, or $Latest.
When to use this (and when not to)
| Use a launch template when… | You might skip it when… |
|---|---|
| You run an Auto Scaling group (ASG — a service that adds/removes instances automatically) | You launch a single throwaway instance once and delete it |
| Multiple people or pipelines launch the same kind of instance | You are just experimenting in the console for five minutes |
| You want a version history and easy rollback of launch settings | — |
| You use newer EC2 features (Spot options, multiple network interfaces, Nitro features) | — |
For anything that lives longer than a quick test, use a launch template. It is free, and it removes an entire class of “someone launched it with the wrong security group” mistakes.
Launch templates vs launch configurations
You may still see launch configurations in older guides. They are the original way Auto Scaling defined how to launch instances. AWS has deprecated launch configurations — you can no longer create them for newer instance types, and they never received support for modern features. Launch templates replaced them entirely.
| Feature | Launch template (use this) | Launch configuration (legacy) |
|---|---|---|
| Versioning | Yes — full version history | No — immutable, must recreate |
| Supports newest instance types | Yes | No (blocked for new types) |
| Spot + On-Demand mix in one ASG | Yes | No |
| Multiple network interfaces, T-unlimited, placement groups | Yes | Limited or none |
| Used by | ASGs, EC2 Fleet, Spot Fleet, manual launches | ASGs only |
| AWS recommendation | Recommended | Deprecated — migrate away |
Gotcha: If you inherited an Auto Scaling group still using a launch configuration, migrate it to a launch template. The console has a one-click “Copy to launch template” action, and the CLI offers
aws autoscaling start-instance-refreshto roll the change out safely.
Creating a launch template in the Console
- Open the EC2 console and choose Launch templates in the left navigation, then Create launch template.
- Give it a name (for example
web-tier) and an optional version description likeInitial nginx template. - Choose the AMI (for example
ami-0abcdef1234567890). - Choose the instance type (for example
t3.micro). - Select a key pair for SSH access (for example
my-key). - Under Network settings, pick or create the security groups (for example
sg-0a1b2c3d). Leave the subnet blank if an ASG will choose it. - Expand Advanced details and paste your user data script if you bootstrap at boot.
- Click Create launch template. This becomes Version 1.
To change anything later, select the template and choose Actions → Modify template (Create new version). You never edit a version in place — you create a new one.
Creating a launch template with the CLI
The CLI takes the launch parameters as JSON via --launch-template-data.
aws ec2 create-launch-template \
--launch-template-name web-tier \
--version-description "Initial nginx template" \
--launch-template-data '{
"ImageId": "ami-0abcdef1234567890",
"InstanceType": "t3.micro",
"KeyName": "my-key",
"SecurityGroupIds": ["sg-0a1b2c3d"],
"UserData": "I2EvYmluL2Jhc2gKZG5mIGluc3RhbGwgLXkgbmdpbng=",
"TagSpecifications": [{
"ResourceType": "instance",
"Tags": [{"Key": "Name", "Value": "web-01"}]
}]
}'
Note that UserData in the JSON must be base64-encoded (unlike run-instances, which encodes it for you). Generate it with base64 -w0 bootstrap.sh.
Output:
{
"LaunchTemplate": {
"LaunchTemplateId": "lt-0a1b2c3d4e5f",
"LaunchTemplateName": "web-tier",
"DefaultVersionNumber": 1,
"LatestVersionNumber": 1
}
}
To add a new version (say, a bigger instance type) and make it the default:
aws ec2 create-launch-template-version \
--launch-template-name web-tier \
--source-version 1 \
--version-description "Bump to t3.small" \
--launch-template-data '{"InstanceType": "t3.small"}'
aws ec2 modify-launch-template \
--launch-template-name web-tier \
--default-version 2
Using --source-version 1 copies everything from version 1 and applies only the fields you override — so you do not have to re-specify the whole template.
Launching from a template
A launch template is just a blueprint until something uses it. You can launch one instance directly:
aws ec2 run-instances \
--launch-template "LaunchTemplateName=web-tier,Version=\$Latest" \
--count 1
You can also override any single field at launch — for example, launch the web-tier template but in a specific subnet:
aws ec2 run-instances \
--launch-template "LaunchTemplateName=web-tier,Version=2" \
--subnet-id subnet-0a1b2c3d \
--count 1
Versions and Auto Scaling
This is where versioning earns its keep. An Auto Scaling group references a template and a version. You have three choices:
| Version setting | Behavior | Use when |
|---|---|---|
A fixed number (e.g. 2) | ASG always launches version 2, even if you add version 3 | You want changes to roll out only on your command |
$Default | ASG follows whichever version you marked default | You control rollout by changing the default pointer |
$Latest | ASG always uses the newest version automatically | You want the freshest config with no extra step |
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name web-asg \
--launch-template "LaunchTemplateName=web-tier,Version=\$Latest" \
--min-size 2 --max-size 6 --desired-capacity 2 \
--vpc-zone-identifier "subnet-0a1b2c3d,subnet-0b2c3d4e"
Tip: Pinning a fixed version (or
$Default) in production is safer than$Latest. With$Latest, the moment anyone creates a new template version, the next scale-out launches it — possibly an untested change. Pin a number, test, then bump the default deliberately.
There is no charge for launch templates themselves. You pay only the normal rates for the instances, EBS storage, and data transfer they create.
Best practices
- Use launch templates, never launch configurations — configurations are deprecated and block newer instance types and features.
- Treat each change as a new version with a clear
--version-description, so the history reads like a changelog. - In production ASGs, pin a specific version or
$Defaultrather than$Latestto control exactly when changes roll out. - Use
--source-version(or “Modify template” in the console) so new versions inherit prior settings and you only change what is needed. - Keep bootstrapping in user data inside the template so every launch is identical and repeatable.
- After changing the version an ASG uses, run an instance refresh to replace running instances with the new config gradually.
- Tag instances within the template’s
TagSpecificationsso every launched instance is labeled consistently for cost and ownership tracking.