EC2 Launch Templates Explained: Versions, Examples, and Auto Scaling

An EC2 launch template is a reusable, versioned blueprint for launching EC2 instances. It stores your instance settings (AMI, instance type, security groups, IAM role, user data) so you define them once and reference them every time, from a single manual launch to a fleet managed by an Auto Scaling Group.

EC2 launch templates explained

When you launch an EC2 instance, you specify a lot of parameters: which AMI to use, which instance type, which security groups, which key pair, what user data script to run, whether to encrypt the root volume. That is fine for one instance. For ten, it becomes error-prone. For a team where multiple people are launching instances, it becomes inconsistent.

A launch template solves this by saving all those parameters under a single name. When you, an Auto Scaling Group, or a CI/CD pipeline needs a new instance, it references the template instead of re-specifying everything from scratch.

Why launch templates matter

The problems launch templates solve are not obvious until you hit them. Here is what happens without them:

  • Drift. Two engineers launch “the same” instance. One enables detailed monitoring. One uses a different instance type. One forgets to enforce IMDSv2. After a few months, your fleet is inconsistent in ways that are hard to audit.
  • Repetition. Every new instance launch requires the same parameters to be specified again. Mistakes happen: wrong AMI, wrong security group, unencrypted volume.
  • No audit trail. Without a template, there is no record of what configuration was used to launch a given instance. With a versioned template, you can trace exactly which version was active at any point.
  • Unsafe updates. Swapping an AMI or changing user data across a fleet without versioning means all-or-nothing. With templates, you create a new version and roll it out gradually using instance refresh.

For Auto Scaling Groups, launch templates are effectively required. They are how AWS knows what instance to create when scaling out.

How launch templates work

A few key behaviours to understand before using them:

  • Templates store defaults, not requirements. Most fields are optional. You can create a minimal template with just an AMI ID and instance type, then supply everything else at launch time. Or you can lock down every setting.
  • Values can be overridden at launch. When launching an instance or creating an ASG, you can override specific fields from the template (for example, a different subnet or instance type for a specific environment) while inheriting everything else.
  • Versions are additive. Every update creates a new version. Old versions are never modified or deleted automatically. You can reference any version by number, or use the aliases $Latest or $Default.
  • ASGs reference a template and a version. Changing the version in the ASG is how you roll out configuration updates to a running fleet.

What a launch template stores

A launch template can store any combination of these settings. None are mandatory. Include what you want to standardise and leave the rest to be supplied at launch time.

SettingDescription
AMI IDThe OS image to boot from. See AMIs explained.
Instance typeCPU and RAM profile (e.g., t3.medium, m6i.large). See the instance types guide.
Key pairSSH key pair name. Consider using Session Manager to avoid storing key pairs entirely.
Security groupsFirewall rules controlling inbound and outbound traffic on the instance.
Subnet / Network interfaceWhich VPC and subnet to launch into. Often left out of the template and specified at launch time.
IAM instance profileThe IAM role the instance assumes on boot, granting it access to AWS services.
User dataBootstrap script to run on first boot. See user data scripts.
EBS volume configurationRoot volume size, type (gp3), and whether to encrypt. Set Encrypted: true as a baseline default.
Spot request settingsMax price, interruption behaviour (stop/terminate/hibernate).
Instance metadata optionsIMDSv1 vs IMDSv2, hop limit. Set HttpTokens: required to enforce IMDSv2.
MonitoringEnable detailed CloudWatch monitoring (1-minute granularity instead of 5-minute).
TagsTags applied automatically to the launched instance, volumes, and network interfaces.

When to use a launch template

Launch templates are useful any time you want consistent, repeatable EC2 instance launches:

  • Auto Scaling Groups. Required. An ASG needs a launch template (or the legacy launch configuration) to know what instances to create when scaling out.
  • Standardising team launches. If multiple people regularly launch EC2 instances, a template enforces consistent AMIs, security groups, and security settings without relying on documentation or tribal knowledge.
  • Rolling out a new AMI safely. Create a new template version with the updated AMI, then use instance refresh to gradually replace instances in an ASG while keeping a minimum percentage healthy.
  • Mixed Spot and on-demand fleets. Launch templates are required for mixed instance type policies in ASGs. Launch configurations cannot do this.
  • Enforcing security baselines. Bake IMDSv2 enforcement, encrypted root volumes, and an IAM instance profile into the template so every instance is compliant by default, without relying on anyone to remember the settings.
  • Scripted or pipeline-driven launches. Any automated process that launches EC2 instances benefits from a template: fewer parameters to pass, less surface area for mistakes.

Launch template vs launch configuration

If you are working with existing AWS infrastructure, you may encounter launch configurations, the older predecessor to launch templates. Here is how they compare:

FeatureLaunch templateLaunch configuration
VersioningYes: unlimited versions, with rollbackNo: immutable once created
UpdatesCreate a new version; old version stays intactMust create an entirely new launch configuration
IMDSv2 supportYesNo
Mixed Spot / on-demand ASGsYesNo
T2/T3 Unlimited modeYesNo
Use outside of Auto ScalingYes: also works for individual instance launchesNo: ASG use only
Actively developed by AWSYesNo: feature frozen
Recommended for new workYesNo
Warning

AWS has stated that launch configurations will not receive new EC2 feature support. If you have existing ASGs using launch configurations, migrating to launch templates is worth prioritising, especially if you want Spot support, IMDSv2 enforcement, or instance refresh. New work should always start with a launch template.

Launch template vs launching EC2 manually

If you are launching your first EC2 instance, doing it manually through the console is completely reasonable. The trade-offs become clear once you do it more than a few times:

Manual launchLaunch template
Setup timeSpecify all parameters each timeSpecify once, reuse indefinitely
ConsistencyDepends on who launches itSame settings every time
Auto ScalingNot possibleRequired for ASGs
Audit trailNoneVersion history in AWS
RollbackRecreate manuallySwitch to a previous version number
Best forOne-off experiments, learningAny repeated or automated launch

Creating a launch template

In the console: go to EC2 → Launch Templates → Create launch template. Fill in the name, then configure settings the same way you would when launching an instance directly: AMI, instance type, key pair, security groups, storage, user data. Every field has a UI.

Via the CLI: pass all settings as a JSON object in the —launch-template-data flag. This example creates a production-ready web server template with encrypted storage and IMDSv2 enforced:

aws ec2 create-launch-template \
  --launch-template-name web-server-template \
  --version-description "Initial version" \
  --launch-template-data '{
    "ImageId": "ami-0abcdef1234567890",
    "InstanceType": "t3.medium",
    "KeyName": "my-key-pair",
    "SecurityGroupIds": ["sg-0abc12345def67890"],
    "IamInstanceProfile": {
      "Name": "WebServerInstanceProfile"
    },
    "UserData": "IyEvYmluL2Jhc2gKZG5mIGluc3RhbGwgLXkgbmdpbngKc3lzdGVtY3RsIGVuYWJsZSBuZ2lueApzeXN0ZW1jdGwgc3RhcnQgbmdpbng=",
    "BlockDeviceMappings": [
      {
        "DeviceName": "/dev/xvda",
        "Ebs": {
          "VolumeSize": 30,
          "VolumeType": "gp3",
          "DeleteOnTermination": true,
          "Encrypted": true
        }
      }
    ],
    "MetadataOptions": {
      "HttpTokens": "required",
      "HttpPutResponseHopLimit": 1
    },
    "TagSpecifications": [
      {
        "ResourceType": "instance",
        "Tags": [
          {"Key": "Role", "Value": "web-server"},
          {"Key": "Environment", "Value": "production"}
        ]
      }
    ]
  }'
Note

The UserData field must be base64-encoded. The string above decodes to a script that installs and starts Nginx. Use —cli-binary-format raw-in-base64-out to pass plain text and have the CLI encode it automatically, or pre-encode your user data script before inserting it here.

Security

Two settings in the template above are non-negotiable for production. HttpTokens: required enforces IMDSv2, blocking SSRF attacks from retrieving IAM credentials via the metadata endpoint. Encrypted: true on the EBS volume encrypts the root disk at rest. Both are free, have no performance trade-off on gp3, and should be in every launch template you create.

Versioning launch templates

Every time you update a launch template, you create a new version. The old version is untouched. You can have as many versions as you need, each independently referenceable, and none are deleted automatically.

To create a new version with an updated AMI, specify only what changed. All other settings are inherited from the source version:

aws ec2 create-launch-template-version \
  --launch-template-name web-server-template \
  --source-version 1 \
  --version-description "Updated to Amazon Linux 2023 April patch" \
  --launch-template-data '{
    "ImageId": "ami-0newami1234567890"
  }'

Mark the new version as the default:

aws ec2 modify-launch-template \
  --launch-template-name web-server-template \
  --default-version 2

View all versions and their status:

aws ec2 describe-launch-template-versions \
  --launch-template-name web-server-template \
  --query "LaunchTemplateVersions[*].[VersionNumber,VersionDescription,DefaultVersion]" \
  --output table

To roll back after a bad deployment, set —default-version back to the previous version number and trigger another instance refresh. New instances will pick up the old configuration immediately.

Choosing a version: $Latest vs $Default vs pinned

When you reference a launch template (in an ASG, a CLI command, or infrastructure-as-code) you must specify which version to use. There are three options:

Version referenceWhat it meansWhen to use it
$LatestResolves to the most recently created version at launch timeDevelopment and staging environments where you want new instances to always reflect your latest changes without updating the ASG separately
$DefaultResolves to whichever version is currently marked as the defaultProduction environments. You control rollouts by changing the default version. The ASG itself does not need to be updated.
Specific version (e.g., 3)Always uses that exact version number, regardless of what the default isPinning a resource to a known-good version, canary deployments, or compliance requirements where the configuration must be immutable
Tip

Use $Default for production Auto Scaling Groups. It separates creating a new template version (which anyone can do) from promoting it to production (which requires you to explicitly update the default). This is a lightweight but effective change gate that prevents accidental rollouts.

Using launch templates with Auto Scaling Groups

An Auto Scaling Group uses the launch template to know what instances to create when scaling out. You specify the template name and version when creating or updating the ASG.

aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name web-asg \
  --launch-template "LaunchTemplateName=web-server-template,Version=\$Default" \
  --min-size 2 \
  --max-size 10 \
  --desired-capacity 2 \
  --vpc-zone-identifier "subnet-abc,subnet-def"

Real-world scenario: rolling out a patched AMI. Your security team has released a new AMI and you need to roll it out across 20 production instances without downtime. Here is the process:

  1. Create a new launch template version with the patched AMI (inheriting all other settings from version 1).
  2. Mark the new version as the default.
  3. Trigger an instance refresh on the ASG. AWS will gradually replace instances while keeping at least 90% healthy throughout.
# Step 1: new template version with updated AMI only
aws ec2 create-launch-template-version \
  --launch-template-name web-server-template \
  --source-version 1 \
  --version-description "Patched AMI April 2026" \
  --launch-template-data '{"ImageId": "ami-0patchedami1234567"}'

# Step 2: promote it to default
aws ec2 modify-launch-template \
  --launch-template-name web-server-template \
  --default-version 2

# Step 3: rolling replacement — keeps 90% of instances healthy at all times
aws autoscaling start-instance-refresh \
  --auto-scaling-group-name web-asg \
  --preferences '{"MinHealthyPercentage": 90, "InstanceWarmup": 60}'

AWS gradually terminates old instances and launches new ones using the updated template, maintaining capacity throughout. You can monitor progress in the EC2 console. If something goes wrong, cancel the refresh and roll the default version back to version 1. The ASG will revert on its next scaling event.

Mixed instance types and Spot

Launch templates are required for mixed instance type policies: the ability to run an ASG across multiple instance families and mix Spot instances with on-demand in the same group. This is not possible with launch configurations.

The example below creates an ASG that runs 20% on-demand (stable, always available base) and 80% Spot (cheaper, interruptible). Three instance types are listed so AWS can pick from more capacity pools. This reduces the risk of all Spot capacity being unavailable at once:

aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name mixed-asg \
  --mixed-instances-policy '{
    "LaunchTemplate": {
      "LaunchTemplateSpecification": {
        "LaunchTemplateName": "web-server-template",
        "Version": "$Default"
      },
      "Overrides": [
        {"InstanceType": "t3.medium"},
        {"InstanceType": "t3a.medium"},
        {"InstanceType": "t3.large"}
      ]
    },
    "InstancesDistribution": {
      "OnDemandPercentageAboveBaseCapacity": 20,
      "SpotAllocationStrategy": "capacity-optimized"
    }
  }' \
  --min-size 2 \
  --max-size 10 \
  --desired-capacity 4 \
  --vpc-zone-identifier "subnet-abc,subnet-def"
Tip

Use capacity-optimized as your Spot allocation strategy. It directs AWS to launch from pools with the most available capacity, which also happen to have the lowest interruption rates. Listing three or more instance types in the overrides gives AWS enough flexibility to find available capacity even during peak demand. See the Spot instances guide for detail on interruption handling.

Common mistakes

Watch out

Most launch template mistakes either expose a security gap (unencrypted volumes, IMDSv1) or cause a surprise rollout to production ($Latest in an ASG). Both categories are easy to avoid by building the right defaults into your template from the start.

  1. Using launch configurations for new work. Launch configurations are feature-frozen. They cannot use IMDSv2, cannot support mixed Spot/on-demand fleets, and must be replaced entirely for any change. Always use launch templates for new ASGs. If you have existing launch configurations, migrate them. The process is straightforward and unlocks features you cannot get otherwise.

  2. Hardcoding AMI IDs without a management strategy. An AMI ID is a snapshot in time. When AWS releases a new Amazon Linux 2023 patch or you build an updated golden AMI, you need to create a new template version. Use AWS Systems Manager Parameter Store to store the current AMI ID as a parameter, then reference it in your template. AMI updates then flow through one place instead of requiring manual template edits.

  3. Not enforcing IMDSv2. Always include “MetadataOptions”: {“HttpTokens”: “required”} in every launch template. Without this, the metadata endpoint is accessible via IMDSv1, which is vulnerable to SSRF attacks that can retrieve IAM credentials assigned to the instance. There is no valid reason to leave this out on a new template.

  4. Leaving root volumes unencrypted. Include “Encrypted”: true in the EBS block device mapping. Unencrypted root volumes expose OS and application data to anyone with access to the underlying EBS snapshot. Encryption on gp3 is free and has no performance trade-off.

  5. Using $Latest in production Auto Scaling Groups. With $Latest, any new template version (including a work-in-progress one) immediately affects what instances the ASG launches next. Use $Default in production so you explicitly control when a new version goes live. Reserve $Latest for development environments where iteration speed matters more than stability.

Frequently asked questions

What is the difference between a launch template and a launch configuration?

Launch configurations are the older, legacy method for configuring Auto Scaling Groups. They are immutable: you cannot modify them after creation. Launch templates replace them entirely: they support versioning, can be updated incrementally, support newer EC2 features like IMDSv2 and mixed Spot/on-demand fleets, and can be used outside of Auto Scaling. AWS has stopped adding new EC2 features to launch configurations. Use launch templates for all new work.

Can I use a launch template without Auto Scaling?

Yes. Launch templates work anywhere you launch EC2 instances: from the console, the CLI (aws ec2 run-instances --launch-template), and via the API. Auto Scaling Groups are just the most common use case. You can also use them to ensure consistent, auditable instance launches without each person specifying parameters manually.

Should I use $Latest or $Default in my Auto Scaling Group?

For production Auto Scaling Groups, use $Default. This gives you an explicit control point: you decide exactly when new instances pick up a new configuration by changing which version is marked as default. $Latest is convenient in development where you want instances to always reflect your latest changes, but it can cause unintended rollouts in production if someone creates a new template version without realising the ASG will immediately start using it.

Can I update a launch template without replacing the old version?

Yes. Creating a new version does not touch existing versions. Old versions remain available and can be referenced by version number. This is one of the main advantages over launch configurations, which had to be replaced entirely. You can roll back to any previous version at any time by updating the ASG or launching instances with a specific version number.

What settings belong in a launch template vs at launch time?

Put settings that should be standardised into the template: AMI ID, instance type, IAM role, security groups, EBS encryption, IMDSv2 enforcement, and user data. Override at launch time what varies per environment: subnet, specific tags, instance type for one-off tests. An ASG can also override the instance type from the template to support mixed instance policies.

Last verified: 1 April 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.