Launch Configurations vs Launch Templates: the basics
What is AutoScaling.9 actually checking?
An Auto Scaling Group (ASG) needs a recipe that tells it how to launch new instances — which AMI, which instance type, which key pair, which security groups, which user data. AWS has shipped two versions of that recipe over the years: the original Launch Configuration (LC) from 2011, and Launch Templates (LT) introduced in 2017. LCs are immutable single-version blobs; LTs are versioned, support every modern EC2 feature, and can be referenced by multiple ASGs at once.
Security Hub control AutoScaling.9 fails any ASG that still uses an LC instead of an LT. AWS announced LC deprecation in 2022 and stopped allowing new accounts to create them — if you're in a sufficiently old account you can still create LCs today, but the API is on its way out. AutoScaling.9 is AWS telling you: cut over now, while it's a planned migration, not later when a forced cutoff turns it into an incident.
An ASG "in violation" looks like this: the ASG has LaunchConfigurationName set instead of LaunchTemplate. Functionally it still scales; structurally it's locked out of IMDSv2 enforcement, Mixed Instance Policies, Spot Allocation Strategies, T-instance unlimited mode, Capacity Reservations, and the version pinning that makes safe rollouts possible. Every one of those gaps is a feature your security and FinOps teams already want.
In this lesson you'll learn why AWS deprecated Launch Configurations, what Launch Templates unlock, and how to migrate a running ASG with zero downtime. You'll see the CLI calls to discover LC-backed ASGs, create an equivalent Launch Template from existing settings, attach it to the ASG, and roll the fleet via instance refresh — plus the field-mapping gotchas that trip up most migrations.
Created in 2017, still ignored in 2024
Launch Templates have been available since November 2017. When AWS announced LC deprecation in October 2022 — five years later — they reported that the majority of active ASGs were still LC-backed. The Auto Scaling team's blog post politely called this "unexpected." Operationally it meant most accounts had spent half a decade unable to enforce IMDSv2 on autoscaled fleets, the single biggest hardening move available against SSRF-driven credential theft (see the 2019 Capital One breach). AutoScaling.9 exists because nudging didn't work.
Migrating an ASG in action
Marco runs platform engineering at a fintech. A quarterly Security Hub review hands him a list of 23 AutoScaling.9 findings across production accounts — every ASG older than 2020 still backed by a Launch Configuration. The CISO wants IMDSv2 enforced everywhere by quarter-end, which means the LCs have to go first.
He picks the lowest-risk ASG to migrate first: a stateless API tier with rolling deploys already wired up. The plan is straightforward — inventory the LC's settings, create an equivalent LT with IMDSv2=required, attach it to the ASG, then trigger an instance refresh to roll the fleet.
He starts by listing every ASG and flagging which ones are still LC-backed.
First, find every ASG that still uses a Launch Configuration. The query slices to just the fields that decide whether AutoScaling.9 fires.
ASG inventory — anything in the LC column needs migrating.
Next, create a Launch Template that mirrors the existing LC's settings, plus IMDSv2=required and any other modern hardening you want from day one.
New Launch Template, version 1, ready to attach.
What changes at the ASG API layerdeep dive
An ASG's launch source is one of three mutually exclusive fields: LaunchConfigurationName (the legacy single-version blob), LaunchTemplate (a versioned reference, optionally pinned to a specific version or $Latest/$Default), or MixedInstancesPolicy (a Launch Template plus Spot/On-Demand mixing rules). The migration call is a single update-auto-scaling-group that swaps one for the other — AWS clears the LC reference automatically when you set an LT.
Running instances keep running. The ASG only consults the launch source when it has to launch a new instance — for scale-out, replacement of a terminated host, or an instance refresh. That's what makes the migration safe online: you cut over the recipe at any time, then control rollout speed through instance refresh's MinHealthyPercentage and InstanceWarmup knobs.
Field mapping is mostly 1:1 but watch three gotchas. First, BlockDeviceMappings use a different JSON shape — LC uses string sizes ("VolumeSize": "100"), LT uses integers ("VolumeSize": 100). Second, the IAM instance profile is referenced by name in an LC but by ARN or name in an LT (ARN is safer — names get reused). Third, LCs don't have a MetadataOptions block at all; you add it in the LT to enforce IMDSv2 (HttpTokens: required, HttpPutResponseHopLimit: 1).
# Inspect the source LC's settings before writing the LT JSON.
aws autoscaling describe-launch-configurations \
--launch-configuration-names prod-api-lc-2019 \
--query 'LaunchConfigurations[0].{AMI:ImageId,Type:InstanceType,Key:KeyName,SGs:SecurityGroups,Profile:IamInstanceProfile,UserData:UserData}'
# AutoScaling.9 detection — any ASG with a non-null LC name is a finding.
aws autoscaling describe-auto-scaling-groups \
--query "AutoScalingGroups[?LaunchConfigurationName!=null].AutoScalingGroupName" What is the impact of staying on Launch Configurations?
The most direct impact is the features you can't have. LCs don't support IMDSv2 enforcement at all — every instance the ASG launches has IMDSv1 reachable, which is the exact attack surface that exfiltrated Capital One's credentials in 2019. AutoScaling.9 and EC2.8 are linked findings; you can't close the second without closing the first.
The second-order impact is FinOps. LCs can't reference a Mixed Instance Policy, which is the only way to combine Spot and On-Demand capacity in one ASG. Teams on LCs end up running parallel ASGs — one Spot, one On-Demand — and reinventing the allocation strategy AWS already provides for free. The Spot Allocation Strategies (price-capacity-optimized, capacity-optimized) that consistently produce 60-90% savings on stateless workloads are LT-only.
The third-order impact is operational. LCs are immutable — every change creates a brand-new LC that you have to re-attach to the ASG manually. LTs are versioned: you create version 2, point the ASG at $Latest, instance refresh rolls the fleet. Roll-back is one CLI call to flip the default version. On LCs, rollback means re-creating the old LC from memory or version control because the original is gone.
And there's the deprecation cliff. AWS has not announced a hard end-of-life date, but new accounts have been blocked from creating LCs since 2023. When the hard cutoff comes (AWS deprecation timelines historically run 18-36 months from announcement), every LC-backed ASG that hasn't migrated stops being able to launch new instances — which means it stops being able to scale or replace failed hosts. Migrating now is planned work; migrating then is an outage.
How do you migrate ASGs to Launch Templates safely?
Migration is a four-step loop per ASG. Done in order, every step is reversible and the fleet keeps serving traffic the whole way through.
1. Inventory every LC-backed ASG and IaC source
Run describe-auto-scaling-groups filtered on non-null LaunchConfigurationName to get the runtime list. Then check your CloudFormation/Terraform/CDK sources — if the LC is managed in IaC, you have to update the source concurrently or the next apply will recreate it. CloudFormation has AWS::EC2::LaunchTemplate; Terraform has aws_launch_template plus launch_template on aws_autoscaling_group. Don't migrate runtime and then let IaC drift it back.
2. Create the Launch Template with hardening built in
Pull the LC's current settings and translate them into LT JSON — AMI, instance type, key pair, security group IDs, user data (base64-encoded), IAM instance profile ARN. Add a MetadataOptions block with HttpTokens: required to enforce IMDSv2 from day one. This is the moment to close AutoScaling.9 and EC2.8 in the same change.
3. Attach the LT and roll the fleet via instance refresh
update-auto-scaling-group --launch-template LaunchTemplateId=lt-...,Version=$Latest swaps the source in place — existing instances keep running. Then start-instance-refresh with a sane MinHealthyPercentage (90 for stateless tiers, higher for stateful) drains and replaces each instance against the new template. Watch the refresh status; abort and roll back the LT version if anything goes wrong.
4. Prevent recurrence with AWS Config and SCPs
Enable the AWS Config managed rule autoscaling-launch-config-prohibited to fail-fast on any newly-created LC-backed ASG. For prevention at the org level, attach a Service Control Policy that denies autoscaling:CreateLaunchConfiguration outright — there's no legitimate reason to create a new LC in 2026. Add an alarm on the AutoScaling.9 control so a fresh finding pages someone before it ages.
# Swap the ASG's launch source from LC to LT — running instances are untouched.
aws autoscaling update-auto-scaling-group \
--auto-scaling-group-name prod-api-asg \
--launch-template LaunchTemplateId=lt-0fe3d2c1b4a5968e7,Version='$Latest'
# Roll the fleet to the new template at 90% min-healthy.
aws autoscaling start-instance-refresh \
--auto-scaling-group-name prod-api-asg \
--preferences '{"MinHealthyPercentage":90,"InstanceWarmup":120}'
# Verify the LC reference is gone — AutoScaling.9 should clear on next eval.
aws autoscaling describe-auto-scaling-groups \
--auto-scaling-group-names prod-api-asg \
--query 'AutoScalingGroups[0].{LC:LaunchConfigurationName,LT:LaunchTemplate}' Quick quiz
Question 1 of 5You’ve inventoried 23 LC-backed ASGs. What’s the right first move for the lowest-risk ASG?
You scored
0 / 5
Keep learning
Dig deeper into Launch Templates, instance refresh, and AutoScaling hardening.
- AWS Security Hub control AutoScaling.9 The exact rule definition, severity, and remediation guidance from AWS.
- Migrating from Launch Configurations to Launch Templates Official migration guide including the field-mapping table and CLI workflow.
- Auto Scaling Instance Refresh How to roll a fleet onto a new launch template version with controlled health checks.
- Capital One breach — IMDSv2 context Why IMDSv2 enforcement is the headline benefit of leaving Launch Configurations behind.
You've completed Migrate ASGs from Launch Configurations to Launch Templates. You can now find every LC-backed ASG in an account, translate its settings into a Launch Template with IMDSv2 enforced, swap the launch source in place, and roll the fleet via instance refresh without touching running traffic. The next time AutoScaling.9 fires, you'll have a four-step loop ready to run — and you'll close EC2.8 in the same change window.
Back to the library