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.
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;
}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;
}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'
}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"
});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"
});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"
});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"
});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"
});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
});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"
});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);// 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"
});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");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
}
});// 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"
}
);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
});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 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) }
]
}
});