EC2 Launch Templates

A Complete Guide to Launch Templates for Auto Scaling Groups

What is a Launch Template?

A Launch Template is an AWS feature that provides a way to store launch parameters for EC2 instances, making it easier to launch instances with predefined configurations. Launch Templates contain all the parameters required to launch an EC2 instance, such as the AMI ID, instance type, security groups, and more.

Key Characteristics

  • Reusable configuration for EC2 instances
  • Supports versioning for configuration management
  • Can specify all EC2 launch parameters in one place
  • Integrates with Auto Scaling Groups
  • Supports both On-Demand and Spot Instances
  • Enables instance metadata options configuration

Launch Templates vs Launch Configurations

Launch Templates vs Launch Configurations

Key Differences

Feature Launch Templates Launch Configurations
Versioning Yes No
Modification Create new version Create new configuration
Spot Instances Full support Limited support
T2/T3 Unlimited Supported Not supported
Capacity Reservations Supported Not supported

Launch Template Components

Basic Parameters

  • AMI ID
  • Instance type
  • Key pair
  • Security groups
  • Subnet
  • IAM instance profile
  • User data

Advanced Parameters

  • EBS volumes
  • Network interfaces
  • Placement groups
  • Capacity reservations
  • Tenancy options
  • Metadata options
  • Credit specification (T instances)

Purchasing Options

  • On-Demand Instances
  • Spot Instances
  • Spot price limits
  • Spot instance interruption behavior
  • Capacity block reservations
  • Dedicated Hosts
  • Mixed instance policies

Versioning Capabilities

Launch Templates support versioning, allowing you to:

  • Create multiple versions of a template
  • Set a default version
  • Revert to previous configurations
  • Track configuration changes over time
  • Test new configurations without affecting production
  • Implement gradual rollouts of configuration changes

Creating Launch Templates

Using AWS Console

Steps to create a Launch Template via the AWS Console:

  1. Navigate to EC2 Dashboard
  2. Select "Launch Templates" from the left menu
  3. Click "Create launch template"
  4. Provide a name and description
  5. Configure AMI, instance type, and other parameters
  6. Add storage, networking, and security settings
  7. Configure advanced options if needed
  8. Click "Create launch template"

Using AWS CLI

# Create a basic launch template
aws ec2 create-launch-template \
  --launch-template-name "my-template" \
  --version-description "Initial version" \
  --launch-template-data '{
    "ImageId": "ami-0abcdef1234567890",
    "InstanceType": "t3.micro",
    "KeyName": "my-key-pair",
    "SecurityGroupIds": ["sg-0123456789abcdef0"],
    "UserData": "IyEvYmluL2Jhc2gKZWNobyAiSGVsbG8gV29ybGQi"
  }'

# Create a more complex launch template
aws ec2 create-launch-template \
  --launch-template-name "web-server-template" \
  --version-description "Web server config" \
  --launch-template-data file://web-server-config.json

Using CloudFormation

Resources:
  MyLaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateName: my-web-server-template
      VersionDescription: Initial version
      LaunchTemplateData:
        ImageId: ami-0abcdef1234567890
        InstanceType: t3.micro
        KeyName: my-key-pair
        SecurityGroupIds:
          - sg-0123456789abcdef0
        UserData:
          Fn::Base64: |
            #!/bin/bash
            yum update -y
            yum install -y httpd
            systemctl start httpd
            systemctl enable httpd
        BlockDeviceMappings:
          - DeviceName: /dev/xvda
            Ebs:
              VolumeSize: 20
              VolumeType: gp3
              DeleteOnTermination: true
        TagSpecifications:
          - ResourceType: instance
            Tags:
              - Key: Name
                Value: web-server
          - ResourceType: volume
            Tags:
              - Key: Name
                Value: web-server-volume

Using with Auto Scaling Groups

Creating an ASG with Launch Template

Steps to create an Auto Scaling Group using a Launch Template:

  1. Navigate to EC2 Dashboard
  2. Select "Auto Scaling Groups" from the left menu
  3. Click "Create Auto Scaling group"
  4. Enter a name for the ASG
  5. Select "Launch Template" as the launch option
  6. Choose your Launch Template and version
  7. Configure instance purchase options (On-Demand/Spot mix)
  8. Configure network settings and scaling policies
  9. Review and create the ASG

AWS CLI Example

# Create an Auto Scaling Group with a Launch Template
aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name "my-asg" \
  --launch-template "LaunchTemplateName=my-template,Version=1" \
  --min-size 2 \
  --max-size 10 \
  --desired-capacity 2 \
  --vpc-zone-identifier "subnet-0123456789abcdef0,subnet-0123456789abcdef1" \
  --tags "Key=Environment,Value=Production,PropagateAtLaunch=true"

# Update an existing ASG to use a new Launch Template version
aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name "my-asg" \
  --launch-template "LaunchTemplateName=my-template,Version=2"

Mixed Instances Policy

Configure a mix of instance types for cost optimization:

aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name "mixed-instances-asg" \
  --min-size 2 \
  --max-size 10 \
  --vpc-zone-identifier "subnet-0123456789abcdef0,subnet-0123456789abcdef1" \
  --mixed-instances-policy '{
    "LaunchTemplate": {
      "LaunchTemplateSpecification": {
        "LaunchTemplateName": "my-template",
        "Version": "$Default"
      },
      "Overrides": [
        {"InstanceType": "c5.large"},
        {"InstanceType": "c5a.large"},
        {"InstanceType": "m5.large"},
        {"InstanceType": "m5a.large"}
      ]
    },
    "InstancesDistribution": {
      "OnDemandBaseCapacity": 1,
      "OnDemandPercentageAboveBaseCapacity": 25,
      "SpotAllocationStrategy": "capacity-optimized"
    }
  }'

Managing Launch Template Versions

Creating New Versions

Steps to create a new version of an existing Launch Template:

  1. Navigate to EC2 Dashboard > Launch Templates
  2. Select the template you want to modify
  3. Click "Actions" > "Modify template (Create new version)"
  4. Make your changes to the configuration
  5. Provide a description for the new version
  6. Click "Create launch template version"
# Create a new version via CLI
aws ec2 create-launch-template-version \
  --launch-template-name "my-template" \
  --version-description "Updated AMI" \
  --source-version 1 \
  --launch-template-data '{
    "ImageId": "ami-0987654321fedcba0"
  }'

Managing Default Versions

Set a specific version as the default:

# Set a specific version as default
aws ec2 modify-launch-template \
  --launch-template-name "my-template" \
  --default-version 2

# Get the default version
aws ec2 describe-launch-templates \
  --launch-template-names "my-template" \
  --query "LaunchTemplates[0].DefaultVersionNumber"

# List all versions of a template
aws ec2 describe-launch-template-versions \
  --launch-template-name "my-template"

Special version references:

  • $Latest: Always use the most recent version
  • $Default: Use the version marked as default
  • Specific number: Use a specific version (e.g., 3)

Deployment Strategies

Best practices for deploying new Launch Template versions:

Rolling Update

Update the ASG to use a new template version and set instance refresh parameters to gradually replace instances.

aws autoscaling start-instance-refresh \
  --auto-scaling-group-name "my-asg" \
  --preferences '{"MinHealthyPercentage": 90, "InstanceWarmup": 300}'

Blue/Green Deployment

Create a new ASG with the updated template, then gradually shift traffic from the old to the new ASG.

# Create new ASG with updated template
aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name "my-asg-green" \
  --launch-template "LaunchTemplateName=my-template,Version=2" \
  --min-size 0 \
  --max-size 10 \
  --desired-capacity 0 \
  --vpc-zone-identifier "subnet-0123456789abcdef0,subnet-0123456789abcdef1"

Canary Deployment

Deploy a small percentage of instances with the new template version to test before full rollout.

# Create a mixed ASG with both versions
aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name "canary-asg" \
  --mixed-instances-policy '{
    "LaunchTemplate": {
      "LaunchTemplateSpecification": {
        "LaunchTemplateName": "my-template",
        "Version": "1"
      },
      "Overrides": [
        {"LaunchTemplateSpecification": {"LaunchTemplateName": "my-template", "Version": "1"}},
        {"LaunchTemplateSpecification": {"LaunchTemplateName": "my-template", "Version": "2"}}
      ]
    },
    "InstancesDistribution": {
      "OnDemandPercentageAboveBaseCapacity": 100,
      "SpotAllocationStrategy": "lowest-price"
    }
  }'

Spot Instance Configuration

Basic Spot Configuration

Configure a Launch Template for Spot Instances:

aws ec2 create-launch-template \
  --launch-template-name "spot-template" \
  --version-description "Spot configuration" \
  --launch-template-data '{
    "ImageId": "ami-0abcdef1234567890",
    "InstanceType": "c5.large",
    "SecurityGroupIds": ["sg-0123456789abcdef0"],
    "InstanceMarketOptions": {
      "MarketType": "spot",
      "SpotOptions": {
        "MaxPrice": "0.05",
        "SpotInstanceType": "persistent",
        "InstanceInterruptionBehavior": "stop"
      }
    }
  }'

Advanced Spot Strategies

Optimize Spot usage with mixed instances policy:

aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name "spot-optimized-asg" \
  --min-size 2 \
  --max-size 10 \
  --vpc-zone-identifier "subnet-0123456789abcdef0,subnet-0123456789abcdef1" \
  --mixed-instances-policy '{
    "LaunchTemplate": {
      "LaunchTemplateSpecification": {
        "LaunchTemplateName": "spot-template",
        "Version": "$Default"
      },
      "Overrides": [
        {"InstanceType": "c5.large"},
        {"InstanceType": "c5a.large"},
        {"InstanceType": "c5n.large"},
        {"InstanceType": "m5.large"},
        {"InstanceType": "m5a.large"},
        {"InstanceType": "r5.large"},
        {"InstanceType": "r5a.large"}
      ]
    },
    "InstancesDistribution": {
      "OnDemandBaseCapacity": 1,
      "OnDemandPercentageAboveBaseCapacity": 0,
      "SpotAllocationStrategy": "capacity-optimized",
      "SpotInstancePools": 0
    }
  }'

Spot allocation strategies:

  • capacity-optimized: Instances from pools with optimal capacity
  • lowest-price: Instances from the lowest-priced pools
  • price-capacity-optimized: Balances price and availability
  • diversified: Distributes instances across all pools

User Data and Bootstrapping

Basic User Data

Configure instance bootstrapping with user data:

#!/bin/bash
# Basic web server setup
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "Hello from $(hostname)" > /var/www/html/index.html

Adding user data to a Launch Template:

                                aws ec2 create-launch-template \
                                  --launch-template-name "web-server-template" \
                                  --version-description "Web server with user data" \
                                  --launch-template-data '{
                                    "ImageId": "ami-0abcdef1234567890",
                                    "InstanceType": "t3.micro",
                                    "SecurityGroupIds": ["sg-0123456789abcdef0"],
                                    "UserData": "IyEvYmluL2Jhc2gKeXVtIHVwZGF0ZSAteQp5dW0gaW5zdGFsbCAteSBodHRwZApzeXN0ZW1jdGwgc3RhcnQgaHR0cGQKc3lzdGVtY3RsIGVuYWJsZSBodHRwZAplY2hvICJIZWxsbyBmcm9tICQoaG9zdG5hbWUpIiA+IC92YXIvd3d3L2h0bWwvaW5kZXguaHRtbA=="
                                  }'

Note: User data must be base64 encoded when using the AWS CLI.

Dynamic Configuration

Use dynamic data in user scripts:

                                #!/bin/bash
                                # Get instance metadata
                                INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
                                REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/region)
                                AZ=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
                                
                                # Install AWS CLI
                                yum install -y aws-cli
                                
                                # Tag EBS volumes
                                VOLUMES=$(aws ec2 describe-instances \
                                  --region $REGION \
                                  --instance-id $INSTANCE_ID \
                                  --query "Reservations[0].Instances[0].BlockDeviceMappings[*].Ebs.VolumeId" \
                                  --output text)
                                
                                for VOLUME_ID in $VOLUMES; do
                                  aws ec2 create-tags \
                                    --region $REGION \
                                    --resources $VOLUME_ID \
                                    --tags Key=Name,Value=vol-$INSTANCE_ID
                                done
                                
                                # Register with load balancer
                                aws elbv2 register-targets \
                                  --region $REGION \
                                  --target-group-arn arn:aws:elasticloadbalancing:$REGION:123456789012:targetgroup/my-targets/73e2d6bc24d8a067 \
                                  --targets Id=$INSTANCE_ID

CloudFormation Integration

Use CloudFormation to create templates with dynamic user data:

                                Resources:
                                  WebServerLaunchTemplate:
                                    Type: AWS::EC2::LaunchTemplate
                                    Properties:
                                      LaunchTemplateName: web-server-template
                                      VersionDescription: Web server with dynamic user data
                                      LaunchTemplateData:
                                        ImageId: ami-0abcdef1234567890
                                        InstanceType: t3.micro
                                        SecurityGroupIds:
                                          - !Ref WebServerSecurityGroup
                                        UserData:
                                          Fn::Base64: !Sub |
                                            #!/bin/bash
                                            yum update -y
                                            yum install -y httpd
                                            systemctl start httpd
                                            systemctl enable httpd
                                            echo "Hello from ${AWS::StackName}" > /var/www/html/index.html
                                            aws s3 cp s3://${ConfigBucket}/app.zip /tmp/
                                            unzip /tmp/app.zip -d /var/www/html/
                                            # Signal completion
                                            /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerASG --region ${AWS::Region}

Advanced Networking

Multiple Network Interfaces

Configure multiple ENIs in a Launch Template:

                                aws ec2 create-launch-template \
                                  --launch-template-name "multi-eni-template" \
                                  --version-description "Multiple ENIs" \
                                  --launch-template-data '{
                                    "ImageId": "ami-0abcdef1234567890",
                                    "InstanceType": "c5.large",
                                    "NetworkInterfaces": [
                                      {
                                        "DeviceIndex": 0,
                                        "AssociatePublicIpAddress": true,
                                        "DeleteOnTermination": true,
                                        "Groups": ["sg-0123456789abcdef0"],
                                        "SubnetId": "subnet-0123456789abcdef0"
                                      },
                                      {
                                        "DeviceIndex": 1,
                                        "DeleteOnTermination": true,
                                        "Groups": ["sg-0123456789abcdef1"],
                                        "SubnetId": "subnet-0123456789abcdef1"
                                      }
                                    ]
                                  }'

Use cases for multiple ENIs:

  • Network traffic separation
  • Different security group policies
  • Multi-homed instances (different subnets)
  • Network appliances (firewalls, load balancers)

Enhanced Networking

Enable enhanced networking in a Launch Template:

                                aws ec2 create-launch-template \
                                  --launch-template-name "ena-template" \
                                  --version-description "Enhanced networking" \
                                  --launch-template-data '{
                                    "ImageId": "ami-0abcdef1234567890",
                                    "InstanceType": "c5.large",
                                    "SecurityGroupIds": ["sg-0123456789abcdef0"],
                                    "EnclaveOptions": {
                                      "Enabled": false
                                    },
                                    "NetworkInterfaces": [
                                      {
                                        "DeviceIndex": 0,
                                        "AssociatePublicIpAddress": true,
                                        "DeleteOnTermination": true,
                                        "Groups": ["sg-0123456789abcdef0"],
                                        "InterfaceType": "efa"
                                      }
                                    ]
                                  }'

Enhanced networking options:

  • ENA (Elastic Network Adapter): Up to 100 Gbps
  • EFA (Elastic Fabric Adapter): For HPC and ML workloads
  • Intel 82599 VF: Legacy enhanced networking

Instance Metadata Options

IMDSv2 Configuration

Configure Instance Metadata Service (IMDS) options:

                                aws ec2 create-launch-template \
                                  --launch-template-name "imdsv2-template" \
                                  --version-description "IMDSv2 required" \
                                  --launch-template-data '{
                                    "ImageId": "ami-0abcdef1234567890",
                                    "InstanceType": "t3.micro",
                                    "SecurityGroupIds": ["sg-0123456789abcdef0"],
                                    "MetadataOptions": {
                                      "HttpTokens": "required",
                                      "HttpPutResponseHopLimit": 2,
                                      "HttpEndpoint": "enabled"
                                    }
                                  }'

IMDSv2 security benefits:

  • Protects against SSRF vulnerabilities
  • Requires token-based sessions
  • Limits metadata access to authorized processes
  • Controls hop limit for metadata requests

Accessing Metadata in User Data

Access instance metadata with IMDSv2:

                                #!/bin/bash
                                # Get IMDSv2 token
                                TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
                                
                                # Use token to get metadata
                                INSTANCE_ID=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id)
                                INSTANCE_TYPE=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-type)
                                AZ=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/availability-zone)
                                
                                # Use metadata in configuration
                                echo "Instance ID: $INSTANCE_ID" > /var/www/html/instance-info.html
                                echo "Instance Type: $INSTANCE_TYPE" >> /var/www/html/instance-info.html
                                echo "Availability Zone: $AZ" >> /var/www/html/instance-info.html

Web Application Deployment

Architecture

Auto-scaling web application with Launch Templates:

  • Multi-AZ deployment for high availability
  • Application Load Balancer for traffic distribution
  • Auto Scaling Group with Launch Template
  • CloudWatch alarms for scaling policies
  • RDS database backend

Benefits of this approach:

  • Automatic scaling based on demand
  • Self-healing infrastructure
  • Cost optimization with right-sized instances
  • Consistent deployment across instances

Implementation

                                # Create Launch Template for web servers
                                aws ec2 create-launch-template \
                                  --launch-template-name "web-app-template" \
                                  --version-description "Web application servers" \
                                  --launch-template-data '{
                                    "ImageId": "ami-0abcdef1234567890",
                                    "InstanceType": "t3.medium",
                                    "SecurityGroupIds": ["sg-0123456789abcdef0"],
                                    "IamInstanceProfile": {
                                      "Name": "WebAppInstanceProfile"
                                    },
                                    "BlockDeviceMappings": [
                                      {
                                        "DeviceName": "/dev/xvda",
                                        "Ebs": {
                                          "VolumeSize": 20,
                                          "VolumeType": "gp3",
                                          "DeleteOnTermination": true,
                                          "Encrypted": true
                                        }
                                      }
                                    ],
                                    "UserData": "IyEvYmluL2Jhc2gKIyBJbnN0YWxsIGRlcGVuZGVuY2llcwp5dW0gdXBkYXRlIC15CnltIGluc3RhbGwgLXkgaHR0cGQgcGhwIHBocC1teXNxbCBhd3MtY2xpCgojIEdldCBhcHBsaWNhdGlvbiBjb2RlCmF3cyBzMyBjcCBzMzovL215LWFwcC1idWNrZXQvYXBwLnppcCAvdG1wLwpjZCAvdmFyL3d3dy9odG1sCnVuemlwIC90bXAvYXBwLnppcAoKIyBDb25maWd1cmUgYXBwbGljYXRpb24KY2F0ID4gL3Zhci93d3cvaHRtbC9jb25maWcucGhwIDw8RU9GCjw/cGhwCiRkYl9ob3N0ID0gIiR7REJfSE9TVH0iOwokZGJfdXNlciA9ICIke0RCX1VTRVJ9IjsKJGRiX3Bhc3N3b3JkID0gIiR7REJfUEFTU1dPUkR9IjsKJGRiX25hbWUgPSAiJHtEQl9OQU1FfSI7CiRyZWdpb24gPSAiJHtSRUdJT059IjsKPz4KRU9GCgojIFN0YXJ0IHNlcnZpY2VzCnN5c3RlbWN0bCBzdGFydCBodHRwZApzeXN0ZW1jdGwgZW5hYmxlIGh0dHBkCgojIFJlZ2lzdGVyIHdpdGggbG9hZCBiYWxhbmNlcgpJTlNUQU5DRV9JRCA9ICQoY3VybCAtcyBodHRwOi8vMTY5LjI1NC4xNjkuMjU0L2xhdGVzdC9tZXRhLWRhdGEvaW5zdGFuY2UtaWQpClJFR0lPTiA9ICQoY3VybCAtcyBodHRwOi8vMTY5LjI1NC4xNjkuMjU0L2xhdGVzdC9tZXRhLWRhdGEvcGxhY2VtZW50L3JlZ2lvbikKYXdzIGVsYnYyIHJlZ2lzdGVyLXRhcmdldHMgLS1yZWdpb24gJFJFR0lPTiAtLXRhcmdldC1ncm91cC1hcm4gYXJuOmF3czplbGFzdGljbG9hZGJhbGFuY2luZzokUkVHSU9OOjEyMzQ1Njc4OTAxMjp0YXJnZXRncm91cC93ZWItdGFyZ2V0cy83M2UyZDZiYzI0ZDhhMDY3IC0tdGFyZ2V0cyBJZD0kSU5TVEFOQ0VfSUQ="
                                  }'
                                
                                # Create Auto Scaling Group
                                aws autoscaling create-auto-scaling-group \
                                  --auto-scaling-group-name "web-app-asg" \
                                  --launch-template "LaunchTemplateName=web-app-template,Version=$Default" \
                                  --min-size 2 \
                                  --max-size 10 \
                                  --desired-capacity 2 \
                                  --vpc-zone-identifier "subnet-0123456789abcdef0,subnet-0123456789abcdef1" \
                                  --target-group-arns "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/web-targets/73e2d6bc24d8a067" \
                                  --health-check-type "ELB" \
                                  --health-check-grace-period 300 \
                                  --tags "Key=Environment,Value=Production,PropagateAtLaunch=true"

Cost-Optimized Deployment

Architecture

Cost-optimized deployment with mixed instance types:

  • Base capacity with On-Demand instances
  • Burst capacity with Spot instances
  • Multiple instance types for flexibility
  • Multiple Availability Zones for resilience
  • Capacity-optimized Spot allocation strategy

Benefits of this approach:

  • Up to 90% cost savings compared to On-Demand only
  • Improved availability with instance type diversity
  • Reduced risk of Spot interruptions
  • Automatic failover between instance types

Implementation

                                # Create Launch Template
                                aws ec2 create-launch-template \
                                  --launch-template-name "cost-optimized-template" \
                                  --version-description "Base template for mixed instances" \
                                  --launch-template-data '{
                                    "ImageId": "ami-0abcdef1234567890",
                                    "SecurityGroupIds": ["sg-0123456789abcdef0"],
                                    "IamInstanceProfile": {
                                      "Name": "AppInstanceProfile"
                                    },
                                    "BlockDeviceMappings": [
                                      {
                                        "DeviceName": "/dev/xvda",
                                        "Ebs": {
                                          "VolumeSize": 20,
                                          "VolumeType": "gp3",
                                          "DeleteOnTermination": true
                                        }
                                      }
                                    ],
                                    "UserData": "IyEvYmluL2Jhc2gKeXVtIHVwZGF0ZSAteQp5dW0gaW5zdGFsbCAteSBqYXZhLTEuOC4wLW9wZW5qZGsKYXdzIHMzIGNwIHMzOi8vbXktYXBwLWJ1Y2tldC9hcHAuamFyIC9ob21lL2VjMi11c2VyLwpqYXZhIC1qYXIgL2hvbWUvZWMyLXVzZXIvYXBwLmphciAtLXNlcnZlci5wb3J0PTgwODA="
                                  }'
                                
                                # Create Auto Scaling Group with mixed instances
                                aws autoscaling create-auto-scaling-group \
                                  --auto-scaling-group-name "cost-optimized-asg" \
                                  --min-size 4 \
                                  --max-size 20 \
                                  --vpc-zone-identifier "subnet-0123456789abcdef0,subnet-0123456789abcdef1,subnet-0123456789abcdef2" \
                                  --mixed-instances-policy '{
                                    "LaunchTemplate": {
                                      "LaunchTemplateSpecification": {
                                        "LaunchTemplateName": "cost-optimized-template",
                                        "Version": "$Default"
                                      },
                                      "Overrides": [
                                        {"InstanceType": "c5.large"},
                                        {"InstanceType": "c5a.large"},
                                        {"InstanceType": "c5n.large"},
                                        {"InstanceType": "c4.large"},
                                        {"InstanceType": "m5.large"},
                                        {"InstanceType": "m5a.large"},
                                        {"InstanceType": "m4.large"},
                                        {"InstanceType": "r5.large"},
                                        {"InstanceType": "r5a.large"},
                                        {"InstanceType": "r4.large"}
                                      ]
                                    },
                                    "InstancesDistribution": {
                                      "OnDemandBaseCapacity": 2,
                                      "OnDemandPercentageAboveBaseCapacity": 20,
                                      "SpotAllocationStrategy": "capacity-optimized",
                                      "SpotInstancePools": 0
                                    }
                                  }'

Container Workloads

ECS Cluster with Launch Templates

Configure EC2-based ECS cluster with Launch Templates:

                                # Create Launch Template for ECS container instances
                                aws ec2 create-launch-template \
                                  --launch-template-name "ecs-container-template" \
                                  --version-description "ECS optimized instances" \
                                  --launch-template-data '{
                                    "ImageId": "ami-0abcdef1234567890",
                                    "InstanceType": "c5.large",
                                    "SecurityGroupIds": ["sg-0123456789abcdef0"],
                                    "IamInstanceProfile": {
                                      "Name": "ecsInstanceRole"
                                    },
                                    "BlockDeviceMappings": [
                                      {
                                        "DeviceName": "/dev/xvda",
                                        "Ebs": {
                                          "VolumeSize": 30,
                                          "VolumeType": "gp3",
                                          "DeleteOnTermination": true
                                        }
                                      }
                                    ],
                                    "UserData": "IyEvYmluL2Jhc2gKZWNobyBFQ1NfQ0xVU1RFUj1teS1lY3MtY2x1c3RlciA+PiAvZXRjL2Vjcy9lY3MuY29uZmlnCmVjaG8gRUNTX0JBQ0tFTkRfSE9TVD0gPj4gL2V0Yy9lY3MvZWNzLmNvbmZpZwplY2hvIEVDU19FTkFCTEVfVEFTS19JQU1fUk9MRT10cnVlID4+IC9ldGMvZWNzL2Vjcy5jb25maWcKZWNobyBFQ1NfRU5BQkxFX1NQT1RfSU5TVEFOQ0VfRFJBSU5JTkc9dHJ1ZSA+PiAvZXRjL2Vjcy9lY3MuY29uZmlnCmVjaG8gRUNTX0VOQUJMRV9DT05UQUlORVJfTUVUQURBVEE9dHJ1ZSA+PiAvZXRjL2Vjcy9lY3MuY29uZmlnCmVjaG8gRUNTX0FWQUlMQUJMRV9MT0dHSU5HX0RSSVZFUlM9YXdzbG9ncyBmbHVlbnRkID4+IC9ldGMvZWNzL2Vjcy5jb25maWcKZWNobyBFQ1NfTlVNQl9DUFVfQ09SRV9TVVBQT1JUPXRydWUgPj4gL2V0Yy9lY3MvZWNzLmNvbmZpZw=="
                                  }'
                                
                                # Create Auto Scaling Group for ECS cluster
                                aws autoscaling create-auto-scaling-group \
                                  --auto-scaling-group-name "ecs-container-asg" \
                                  --launch-template "LaunchTemplateName=ecs-container-template,Version=$Default" \
                                  --min-size 2 \
                                  --max-size 10 \
                                  --desired-capacity 2 \
                                  --vpc-zone-identifier "subnet-0123456789abcdef0,subnet-0123456789abcdef1" \
                                  --tags "Key=Name,Value=ECS-Container-Instance,PropagateAtLaunch=true"

EKS Node Groups with Launch Templates

Configure EKS node groups with custom Launch Templates:

                                # Create Launch Template for EKS nodes
                                aws ec2 create-launch-template \
                                  --launch-template-name "eks-node-template" \
                                  --version-description "EKS worker nodes" \
                                  --launch-template-data '{
                                    "ImageId": "ami-0abcdef1234567890",
                                    "InstanceType": "m5.large",
                                    "SecurityGroupIds": ["sg-0123456789abcdef0"],
                                    "BlockDeviceMappings": [
                                      {
                                        "DeviceName": "/dev/xvda",
                                        "Ebs": {
                                          "VolumeSize": 50,
                                          "VolumeType": "gp3",
                                          "DeleteOnTermination": true,
                                          "Encrypted": true
                                        }
                                      }
                                    ],
                                    "MetadataOptions": {
                                      "HttpTokens": "required",
                                      "HttpPutResponseHopLimit": 2
                                    },
                                    "TagSpecifications": [
                                      {
                                        "ResourceType": "instance",
                                        "Tags": [
                                          {
                                            "Key": "kubernetes.io/cluster/my-eks-cluster",
                                            "Value": "owned"
                                          }
                                        ]
                                      }
                                    ]
                                  }'
                                
                                # Create EKS node group with the Launch Template
                                aws eks create-nodegroup \
                                  --cluster-name my-eks-cluster \
                                  --nodegroup-name custom-nodes \
                                  --scaling-config minSize=3,maxSize=10,desiredSize=3 \
                                  --subnets subnet-0123456789abcdef0 subnet-0123456789abcdef1 \
                                  --node-role arn:aws:iam::123456789012:role/EKSNodeRole \
                                  --launch-template id=lt-0123456789abcdef0,version=1

Advantages of Launch Templates

Flexibility and Control

  • Versioning support for configuration management
  • Support for all EC2 instance features
  • Ability to mix instance types and purchase options
  • Granular control over instance configuration
  • Support for advanced networking options
  • Integration with placement groups

Operational Benefits

  • Simplified instance management
  • Consistent configuration across deployments
  • Reduced configuration errors
  • Easier testing of configuration changes
  • Improved deployment automation
  • Better integration with CI/CD pipelines

Cost Optimization

  • Support for mixed instance types
  • Advanced Spot Instance configuration
  • Capacity Reservations integration
  • T2/T3 Unlimited mode support
  • Efficient resource allocation
  • Optimized instance selection strategies

Limitations of Launch Templates

Technical Constraints

  • Limited to 5,000 launch templates per region
  • Maximum of 10,000 versions per template
  • Cannot modify an existing version (must create new)
  • Some parameters cannot be overridden at launch
  • Complex configuration for mixed instance types
  • Limited support in some older AWS services

Implementation Challenges

  • Learning curve for complex configurations
  • Requires careful version management
  • Potential for configuration drift
  • Debugging issues can be complex
  • Migration from Launch Configurations requires planning
  • Integration with third-party tools may be limited

Operational Considerations

  • Version proliferation without proper governance
  • Potential for unused templates and versions
  • Need for additional IAM permissions management
  • Requires coordination across teams
  • May need additional monitoring for version usage
  • Rollback process requires careful planning

Launch Templates vs. Alternatives

Feature Launch Templates Launch Configurations CloudFormation EC2 Run Instances
Versioning Yes No Yes (Stack) No
Reusability High Medium High Low
Auto Scaling Integration Native Native Via resources Manual
Spot Instance Support Full Limited Full Basic
Mixed Instance Types Yes No Yes No
Infrastructure as Code Supported Supported Native Limited

Test Your Knowledge

1. What is the primary advantage of Launch Templates over Launch Configurations?

A) They are easier to create
B) They support more instance types
C) They support versioning
D) They have lower latency

2. Which of the following is NOT a valid parameter in a Launch Template?

A) AMI ID
B) Instance type
C) User data
D) Auto Scaling group name

3. What is the benefit of using mixed instances policy with Launch Templates?

A) It automatically updates to newer instance types
B) It allows for cost optimization by using multiple instance types and purchase options
C) It provides better security
D) It reduces the need for Auto Scaling groups

4. When using a Launch Template with an Auto Scaling group, what happens if you update the default version of the template?

A) All instances are immediately replaced with the new version
B) The Auto Scaling group is automatically updated to use the new version
C) New instances will use the new version only if the Auto Scaling group is configured to use the $Default version
D) The Auto Scaling group must be deleted and recreated

5. Which of the following is a best practice when using Launch Templates?

A) Create a new template for every deployment
B) Always use the latest instance types
D) Avoid using user data scripts
C) Use versioning to track changes and enable rollbacks