or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cloudformation-init.mdec2-instances.mdflow-logs.mdindex.mdlaunch-templates.mdmachine-images.mdnetwork-acl.mdsecurity-groups.mdstorage-volumes.mdsubnets-networking.mduser-data.mdvpc-endpoints.mdvpc-management.mdvpn-connectivity.md
tile.json

launch-templates.mddocs/

Launch Templates

Launch templates in AWS CDK EC2 provide a way to store launch parameters for EC2 instances, enabling consistent instance configuration and simplified Auto Scaling group management.

LaunchTemplate Class

The LaunchTemplate class creates and manages EC2 launch templates:

class LaunchTemplate extends Resource implements ILaunchTemplate {
  constructor(scope: Construct, id: string, props?: LaunchTemplateProps);
  
  readonly launchTemplateId: string;
  readonly launchTemplateName: string;
  readonly versionNumber: string;
  readonly imageId: string;
  readonly instanceType?: InstanceType;
  readonly role?: iam.IRole;
  readonly userData?: UserData;
  readonly connections: Connections;
  readonly grantPrincipal: IPrincipal;
  readonly osType: OperatingSystemType;
  readonly tags: TagManager;
  
  static fromLaunchTemplateAttributes(scope: Construct, id: string, attrs: LaunchTemplateAttributes): ILaunchTemplate;
  
  addSecurityGroup(securityGroup: ISecurityGroup): void;
  addToRolePolicy(statement: iam.PolicyStatement): void;
}

interface ILaunchTemplate extends IResource {
  readonly versionNumber: string;
}

interface LaunchTemplateAttributes {
  readonly launchTemplateId?: string;
  readonly launchTemplateName?: string;
  readonly versionNumber?: string;
}

Launch Template Properties

Comprehensive configuration options for launch templates:

interface LaunchTemplateProps {
  readonly launchTemplateName?: string;
  readonly versionDescription?: string;
  
  // Instance configuration
  readonly instanceType?: InstanceType;
  readonly machineImage?: IMachineImage;
  readonly keyName?: string;
  readonly role?: iam.IRole;
  readonly userData?: UserData;
  readonly securityGroup?: ISecurityGroup;
  
  // Instance behavior
  readonly detailedMonitoring?: boolean;
  readonly disableApiTermination?: boolean;
  readonly ebsOptimized?: boolean;
  readonly instanceInitiatedShutdownBehavior?: InstanceInitiatedShutdownBehavior;
  readonly nitroEnclaveEnabled?: boolean;
  
  // Metadata service configuration
  readonly httpEndpoint?: boolean;
  readonly httpProtocolIpv6?: boolean;
  readonly httpPutResponseHopLimit?: number;
  readonly httpTokens?: LaunchTemplateHttpTokens;
  
  // Spot instances
  readonly spotOptions?: LaunchTemplateSpotOptions;
  
  // Storage
  readonly blockDevices?: BlockDevice[];
  
  // CPU credits for burstable instances
  readonly cpuCredits?: CpuCredits;
}

Launch Template Enumerations

Various enums for launch template configuration:

enum CpuCredits {
  STANDARD = 'standard',
  UNLIMITED = 'unlimited'
}

enum InstanceInitiatedShutdownBehavior {
  STOP = 'stop',
  TERMINATE = 'terminate'
}

enum LaunchTemplateHttpTokens {
  OPTIONAL = 'optional',
  REQUIRED = 'required'
}

interface LaunchTemplateSpotOptions {
  readonly blockDurationMinutes?: number;
  readonly instanceInterruptionBehavior?: SpotInstanceInterruption;
  readonly maxPrice?: string;
  readonly requestType?: SpotRequestType;
  readonly validUntil?: string;
}

enum SpotInstanceInterruption {
  HIBERNATE = 'hibernate',
  STOP = 'stop',
  TERMINATE = 'terminate'
}

enum SpotRequestType {
  ONE_TIME = 'one-time',
  PERSISTENT = 'persistent'
}

Usage Examples

Basic Launch Template

import * as ec2 from "@aws-cdk/aws-ec2";
import * as iam from "@aws-cdk/aws-iam";

const vpc = new ec2.Vpc(this, "MyVpc");

const basicLaunchTemplate = new ec2.LaunchTemplate(this, "BasicLaunchTemplate", {
  launchTemplateName: "web-server-template",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  keyName: "my-key-pair"
});

Launch Template with Security Group

const webSecurityGroup = new ec2.SecurityGroup(this, "WebSecurityGroup", {
  vpc,
  description: "Security group for web servers",
  allowAllOutbound: true
});

webSecurityGroup.addIngressRule(
  ec2.Peer.anyIpv4(),
  ec2.Port.tcp(80),
  "Allow HTTP"
);

webSecurityGroup.addIngressRule(
  ec2.Peer.anyIpv4(),
  ec2.Port.tcp(443),
  "Allow HTTPS"
);

const webLaunchTemplate = new ec2.LaunchTemplate(this, "WebLaunchTemplate", {
  launchTemplateName: "web-server-template",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.SMALL),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  securityGroup: webSecurityGroup,
  keyName: "web-server-key"
});

Launch Template with User Data

const userData = ec2.UserData.forLinux();
userData.addCommands(
  "yum update -y",
  "yum install -y httpd",
  "systemctl start httpd",
  "systemctl enable httpd",
  "echo '<h1>Hello from Launch Template!</h1>' > /var/www/html/index.html"
);

const userDataLaunchTemplate = new ec2.LaunchTemplate(this, "UserDataLaunchTemplate", {
  launchTemplateName: "web-server-with-userdata",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  userData,
  keyName: "my-key-pair"
});

Launch Template with IAM Role

const webServerRole = new iam.Role(this, "WebServerRole", {
  assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore"),
    iam.ManagedPolicy.fromAwsManagedPolicyName("CloudWatchAgentServerPolicy")
  ]
});

const roleBasedLaunchTemplate = new ec2.LaunchTemplate(this, "RoleBasedLaunchTemplate", {
  launchTemplateName: "web-server-with-role",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.SMALL),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  role: webServerRole,
  keyName: "my-key-pair"
});

Launch Template with Block Devices

const storageLaunchTemplate = new ec2.LaunchTemplate(this, "StorageLaunchTemplate", {
  launchTemplateName: "storage-optimized-template",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  blockDevices: [
    {
      deviceName: "/dev/xvda",
      volume: ec2.BlockDeviceVolume.ebs(50, {
        volumeType: ec2.EbsDeviceVolumeType.GP3,
        encrypted: true,
        deleteOnTermination: true
      })
    },
    {
      deviceName: "/dev/xvdb",
      volume: ec2.BlockDeviceVolume.ebs(100, {
        volumeType: ec2.EbsDeviceVolumeType.GP3,
        iops: 3000,
        throughput: 125,
        encrypted: true,
        deleteOnTermination: false
      })
    }
  ],
  keyName: "storage-key"
});

Launch Template with Advanced Configuration

const advancedLaunchTemplate = new ec2.LaunchTemplate(this, "AdvancedLaunchTemplate", {
  launchTemplateName: "advanced-web-template",
  versionDescription: "Advanced configuration with monitoring and security",
  
  // Instance configuration
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MEDIUM),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  keyName: "advanced-key",
  
  // Performance and monitoring
  detailedMonitoring: true,
  ebsOptimized: true,
  cpuCredits: ec2.CpuCredits.UNLIMITED,
  
  // Security settings
  disableApiTermination: true,
  instanceInitiatedShutdownBehavior: ec2.InstanceInitiatedShutdownBehavior.STOP,
  
  // IMDSv2 configuration
  httpTokens: ec2.LaunchTemplateHttpTokens.REQUIRED,
  httpPutResponseHopLimit: 1,
  httpEndpoint: true,
  httpProtocolIpv6: false,
  
  // Nitro Enclaves
  nitroEnclaveEnabled: false
});

Launch Template for Spot Instances

const spotLaunchTemplate = new ec2.LaunchTemplate(this, "SpotLaunchTemplate", {
  launchTemplateName: "spot-instance-template",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  
  spotOptions: {
    requestType: ec2.SpotRequestType.ONE_TIME,
    maxPrice: "0.10",
    instanceInterruptionBehavior: ec2.SpotInstanceInterruption.TERMINATE,
    blockDurationMinutes: 60
  },
  
  keyName: "spot-key"
});

Launch Template with Multiple Security Groups

const webSg = new ec2.SecurityGroup(this, "WebSG", {
  vpc,
  description: "Web traffic"
});

const adminSg = new ec2.SecurityGroup(this, "AdminSG", {
  vpc,
  description: "Admin access"
});

const multiSgLaunchTemplate = new ec2.LaunchTemplate(this, "MultiSGLaunchTemplate", {
  launchTemplateName: "multi-sg-template",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.SMALL),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  securityGroup: webSg
});

// Add additional security group after creation
multiSgLaunchTemplate.addSecurityGroup(adminSg);

Launch Template for Different Operating Systems

// Windows launch template
const windowsLaunchTemplate = new ec2.LaunchTemplate(this, "WindowsLaunchTemplate", {
  launchTemplateName: "windows-server-template",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE),
  machineImage: ec2.MachineImage.latestWindows(
    ec2.WindowsVersion.WINDOWS_SERVER_2022_ENGLISH_FULL_BASE
  ),
  keyName: "windows-key",
  userData: ec2.UserData.forWindows()
});

// Amazon Linux 2 with ARM64
const arm64LaunchTemplate = new ec2.LaunchTemplate(this, "ARM64LaunchTemplate", {
  launchTemplateName: "arm64-template", 
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T4G, ec2.InstanceSize.MICRO),
  machineImage: ec2.MachineImage.latestAmazonLinux({
    generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
    cpuType: ec2.AmazonLinuxCpuType.ARM_64
  }),
  keyName: "arm64-key"
});

Launch Template with Custom Tags

const taggedLaunchTemplate = new ec2.LaunchTemplate(this, "TaggedLaunchTemplate", {
  launchTemplateName: "tagged-template",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
  machineImage: ec2.MachineImage.latestAmazonLinux()
});

// Add tags to launch template
cdk.Tags.of(taggedLaunchTemplate).add("Environment", "Production");
cdk.Tags.of(taggedLaunchTemplate).add("Application", "WebServer");
cdk.Tags.of(taggedLaunchTemplate).add("Owner", "DevOpsTeam");

Using Launch Template with Auto Scaling Group

import * as autoscaling from "@aws-cdk/aws-autoscaling";

const asgLaunchTemplate = new ec2.LaunchTemplate(this, "ASGLaunchTemplate", {
  launchTemplateName: "asg-web-template",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.SMALL),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  userData: userData,
  securityGroup: webSecurityGroup
});

const autoScalingGroup = new autoscaling.AutoScalingGroup(this, "ASG", {
  vpc,
  launchTemplate: asgLaunchTemplate,
  minCapacity: 2,
  maxCapacity: 10,
  desiredCapacity: 3,
  vpcSubnets: {
    subnetType: ec2.SubnetType.PRIVATE_WITH_NAT
  }
});

Importing Existing Launch Template

// Import by launch template ID
const existingTemplate = ec2.LaunchTemplate.fromLaunchTemplateAttributes(
  this,
  "ExistingTemplate",
  {
    launchTemplateId: "lt-12345678901234567"
  }
);

// Import by launch template name
const namedTemplate = ec2.LaunchTemplate.fromLaunchTemplateAttributes(
  this,
  "NamedTemplate",
  {
    launchTemplateName: "my-existing-template"
  }
);

// Import with specific version
const versionedTemplate = ec2.LaunchTemplate.fromLaunchTemplateAttributes(
  this,
  "VersionedTemplate",
  {
    launchTemplateId: "lt-12345678901234567",
    versionNumber: "2"
  }
);

Launch Template for Database Instances

const dbRole = new iam.Role(this, "DatabaseRole", {
  assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore")
  ]
});

const dbSecurityGroup = new ec2.SecurityGroup(this, "DatabaseSG", {
  vpc,
  description: "Database security group",
  allowAllOutbound: false
});

const dbLaunchTemplate = new ec2.LaunchTemplate(this, "DatabaseLaunchTemplate", {
  launchTemplateName: "database-template",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.R5, ec2.InstanceSize.XLARGE),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  role: dbRole,
  securityGroup: dbSecurityGroup,
  
  blockDevices: [
    {
      deviceName: "/dev/xvda",
      volume: ec2.BlockDeviceVolume.ebs(100, {
        volumeType: ec2.EbsDeviceVolumeType.GP3,
        encrypted: true
      })
    },
    {
      deviceName: "/dev/xvdb",
      volume: ec2.BlockDeviceVolume.ebs(500, {
        volumeType: ec2.EbsDeviceVolumeType.PROVISIONED_IOPS_SSD_IO2,
        iops: 10000,
        encrypted: true
      })
    }
  ],
  
  // Enhanced security for database
  httpTokens: ec2.LaunchTemplateHttpTokens.REQUIRED,
  disableApiTermination: true,
  detailedMonitoring: true
});

Launch Template Versioning

const versionedTemplate = new ec2.LaunchTemplate(this, "VersionedTemplate", {
  launchTemplateName: "versioned-template",
  versionDescription: "Initial version with basic configuration",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
  machineImage: ec2.MachineImage.latestAmazonLinux()
});

// In a later deployment, you would create a new template with updated configuration
const updatedTemplate = new ec2.LaunchTemplate(this, "UpdatedTemplate", {
  launchTemplateName: "versioned-template-v2",
  versionDescription: "Updated version with enhanced security",
  instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.SMALL),
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  httpTokens: ec2.LaunchTemplateHttpTokens.REQUIRED,
  detailedMonitoring: true
});

Launch Template for Mixed Instance Types

// Launch template supporting multiple instance types
const flexibleTemplate = new ec2.LaunchTemplate(this, "FlexibleTemplate", {
  launchTemplateName: "flexible-instance-template",
  // Don't specify instance type here - will be specified in ASG
  machineImage: ec2.MachineImage.latestAmazonLinux(),
  userData,
  securityGroup: webSecurityGroup,
  keyName: "flexible-key"
});

// Use with Auto Scaling Group that supports mixed instances
const mixedInstanceASG = new autoscaling.AutoScalingGroup(this, "MixedInstanceASG", {
  vpc,
  launchTemplate: flexibleTemplate,
  minCapacity: 2,
  maxCapacity: 20,
  mixedInstancesPolicy: {
    instancesDistribution: {
      onDemandPercentageAboveBaseCapacity: 25,
      spotAllocationStrategy: autoscaling.SpotAllocationStrategy.DIVERSIFIED
    },
    launchTemplateOverrides: [
      { instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.SMALL) },
      { instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MEDIUM) },
      { instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3A, ec2.InstanceSize.SMALL) },
      { instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3A, ec2.InstanceSize.MEDIUM) }
    ]
  }
});

Best Practices

  1. Parameterization: Use launch templates to standardize instance configurations across environments
  2. Security: Always configure IMDSv2 and appropriate security groups
  3. Monitoring: Enable detailed monitoring for production workloads
  4. Storage Encryption: Encrypt EBS volumes for sensitive workloads
  5. IAM Roles: Use IAM roles instead of embedded credentials
  6. Versioning: Use descriptive version descriptions for template changes
  7. Resource Optimization: Choose appropriate instance types and storage configurations
  8. Tagging Strategy: Implement consistent tagging across all resources
  9. User Data: Keep user data scripts simple and idempotent
  10. Cost Management: Consider spot instances and appropriate instance sizing for cost optimization