Machine image management in AWS CDK EC2 provides comprehensive support for AMI selection, including Amazon Linux, Windows, custom AMIs, and dynamic image lookup.
The MachineImage class provides factory methods for creating various types of machine images:
abstract class MachineImage {
// Amazon Linux images
static latestAmazonLinux(props?: AmazonLinuxImageProps): IMachineImage;
// Windows images
static latestWindows(version: WindowsVersion, props?: WindowsImageProps): IMachineImage;
// Generic images with AMI mapping
static genericLinux(amiMap: Record<string, string>, props?: GenericLinuxImageProps): IMachineImage;
static genericWindows(amiMap: Record<string, string>, props?: GenericWindowsImageProps): IMachineImage;
// SSM Parameter-based images
static fromSsmParameter(parameterName: string, options?: SsmParameterImageOptions): IMachineImage;
// Dynamic lookup
static lookup(props: LookupMachineImageProps): IMachineImage;
// Abstract method all implementations must provide
abstract getImage(scope: Construct): MachineImageConfig;
}
interface IMachineImage {
getImage(scope: Construct): MachineImageConfig;
}
interface MachineImageConfig {
readonly imageId: string;
readonly osType: OperatingSystemType;
readonly userData: UserData;
}
enum OperatingSystemType {
LINUX = 'linux',
WINDOWS = 'windows',
UNKNOWN = 'unknown'
}Specialized class for Amazon Linux AMI selection:
class AmazonLinuxImage implements IMachineImage {
constructor(props?: AmazonLinuxImageProps);
getImage(scope: Construct): MachineImageConfig;
}
interface AmazonLinuxImageProps {
readonly generation?: AmazonLinuxGeneration;
readonly edition?: AmazonLinuxEdition;
readonly virtualization?: AmazonLinuxVirt;
readonly storage?: AmazonLinuxStorage;
readonly cpuType?: AmazonLinuxCpuType;
readonly userData?: UserData;
readonly cachedInContext?: boolean;
}
enum AmazonLinuxGeneration {
AMAZON_LINUX = 'amazon-linux',
AMAZON_LINUX_2 = 'amazon-linux-2'
}
enum AmazonLinuxEdition {
STANDARD = 'standard',
MINIMAL = 'minimal'
}
enum AmazonLinuxVirt {
HVM = 'hvm',
PV = 'paravirtual'
}
enum AmazonLinuxStorage {
GENERAL_PURPOSE = 'general-purpose',
EBS = 'ebs'
}
enum AmazonLinuxCpuType {
ARM_64 = 'arm64',
X86_64 = 'x86_64'
}Specialized class for Windows AMI selection:
class WindowsImage implements IMachineImage {
constructor(version: WindowsVersion, props?: WindowsImageProps);
getImage(scope: Construct): MachineImageConfig;
}
interface WindowsImageProps {
readonly userData?: UserData;
readonly cachedInContext?: boolean;
}
enum WindowsVersion {
// Windows Server 2008
WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_BASE = 'Windows_Server-2008-R2_SP1-English-64Bit-Base',
WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_CORE = 'Windows_Server-2008-R2_SP1-English-64Bit-Core',
WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_EXPRESS = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2008_Express',
WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_STANDARD = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2008_Standard',
WINDOWS_SERVER_2008_R2_SP1_ENGLISH_64BIT_SQL_2008_WEB = 'Windows_Server-2008-R2_SP1-English-64Bit-SQL_2008_Web',
// Windows Server 2012
WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_BASE = 'Windows_Server-2012-RTM-English-64Bit-Base',
WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_CORE = 'Windows_Server-2012-RTM-English-64Bit-Core',
WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2008_EXPRESS = 'Windows_Server-2012-RTM-English-64Bit-SQL_2008_Express',
WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_EXPRESS = 'Windows_Server-2012-RTM-English-64Bit-SQL_2012_Express',
WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_STANDARD = 'Windows_Server-2012-RTM-English-64Bit-SQL_2012_Standard',
WINDOWS_SERVER_2012_RTM_ENGLISH_64BIT_SQL_2012_WEB = 'Windows_Server-2012-RTM-English-64Bit-SQL_2012_Web',
// Windows Server 2012 R2
WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_BASE = 'Windows_Server-2012-R2-RTM-English-64Bit-Base',
WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_CORE = 'Windows_Server-2012-R2-RTM-English-64Bit-Core',
WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2012_EXPRESS = 'Windows_Server-2012-R2-RTM-English-64Bit-SQL_2012_Express',
WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2012_STANDARD = 'Windows_Server-2012-R2-RTM-English-64Bit-SQL_2012_Standard',
WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2012_WEB = 'Windows_Server-2012-R2-RTM-English-64Bit-SQL_2012_Web',
WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_EXPRESS = 'Windows_Server-2012-R2-RTM-English-64Bit-SQL_2014_Express',
WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_STANDARD = 'Windows_Server-2012-R2-RTM-English-64Bit-SQL_2014_Standard',
WINDOWS_SERVER_2012_R2_RTM_ENGLISH_64BIT_SQL_2014_WEB = 'Windows_Server-2012-R2-RTM-English-64Bit-SQL_2014_Web',
// Windows Server 2016
WINDOWS_SERVER_2016_ENGLISH_FULL_BASE = 'Windows_Server-2016-English-Full-Base',
WINDOWS_SERVER_2016_ENGLISH_FULL_CONTAINERS = 'Windows_Server-2016-English-Full-Containers',
WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_EXPRESS = 'Windows_Server-2016-English-Full-SQL_2016_Express',
WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_STANDARD = 'Windows_Server-2016-English-Full-SQL_2016_Standard',
WINDOWS_SERVER_2016_ENGLISH_FULL_SQL_2016_WEB = 'Windows_Server-2016-English-Full-SQL_2016_Web',
WINDOWS_SERVER_2016_ENGLISH_CORE_BASE = 'Windows_Server-2016-English-Core-Base',
WINDOWS_SERVER_2016_ENGLISH_CORE_CONTAINERS = 'Windows_Server-2016-English-Core-Containers',
// Windows Server 2019
WINDOWS_SERVER_2019_ENGLISH_FULL_BASE = 'Windows_Server-2019-English-Full-Base',
WINDOWS_SERVER_2019_ENGLISH_FULL_CONTAINERS_LATEST = 'Windows_Server-2019-English-Full-ContainersLatest',
WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_EXPRESS = 'Windows_Server-2019-English-Full-SQL_2017_Express',
WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_STANDARD = 'Windows_Server-2019-English-Full-SQL_2017_Standard',
WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2017_WEB = 'Windows_Server-2019-English-Full-SQL_2017_Web',
WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2019_EXPRESS = 'Windows_Server-2019-English-Full-SQL_2019_Express',
WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2019_STANDARD = 'Windows_Server-2019-English-Full-SQL_2019_Standard',
WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2019_WEB = 'Windows_Server-2019-English-Full-SQL_2019_Web',
WINDOWS_SERVER_2019_ENGLISH_CORE_BASE = 'Windows_Server-2019-English-Core-Base',
WINDOWS_SERVER_2019_ENGLISH_CORE_CONTAINERS_LATEST = 'Windows_Server-2019-English-Core-ContainersLatest',
// Windows Server 2022
WINDOWS_SERVER_2022_ENGLISH_FULL_BASE = 'Windows_Server-2022-English-Full-Base',
WINDOWS_SERVER_2022_ENGLISH_FULL_SQL_2019_EXPRESS = 'Windows_Server-2022-English-Full-SQL_2019_Express',
WINDOWS_SERVER_2022_ENGLISH_FULL_SQL_2019_STANDARD = 'Windows_Server-2022-English-Full-SQL_2019_Standard',
WINDOWS_SERVER_2022_ENGLISH_FULL_SQL_2019_WEB = 'Windows_Server-2022-English-Full-SQL_2019_Web',
WINDOWS_SERVER_2022_ENGLISH_CORE_BASE = 'Windows_Server-2022-English-Core-Base'
}For custom AMI mappings across regions:
class GenericLinuxImage implements IMachineImage {
constructor(amiMap: Record<string, string>, props?: GenericLinuxImageProps);
getImage(scope: Construct): MachineImageConfig;
}
class GenericWindowsImage implements IMachineImage {
constructor(amiMap: Record<string, string>, props?: GenericWindowsImageProps);
getImage(scope: Construct): MachineImageConfig;
}
interface GenericLinuxImageProps {
readonly userData?: UserData;
}
interface GenericWindowsImageProps {
readonly userData?: UserData;
}For AMI IDs stored in Systems Manager Parameter Store:
interface SsmParameterImageOptions {
readonly os: OperatingSystemType;
readonly userData?: UserData;
readonly cachedInContext?: boolean;
}For runtime AMI discovery:
interface LookupMachineImageProps {
readonly name: string;
readonly owners?: string[];
readonly filters?: {[key: string]: string[]};
readonly windows?: boolean;
readonly userData?: UserData;
}import * as ec2 from "@aws-cdk/aws-ec2";
// Latest Amazon Linux 2
const amazonLinux2 = ec2.MachineImage.latestAmazonLinux({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
edition: ec2.AmazonLinuxEdition.STANDARD,
virtualization: ec2.AmazonLinuxVirt.HVM,
storage: ec2.AmazonLinuxStorage.GENERAL_PURPOSE
});
// Amazon Linux 2 ARM64
const amazonLinux2Arm = ec2.MachineImage.latestAmazonLinux({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
cpuType: ec2.AmazonLinuxCpuType.ARM_64
});
// Amazon Linux 2 Minimal
const amazonLinux2Minimal = ec2.MachineImage.latestAmazonLinux({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
edition: ec2.AmazonLinuxEdition.MINIMAL
});
// Use with instance
const instance = new ec2.Instance(this, "MyInstance", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
machineImage: amazonLinux2
});// Windows Server 2022 Base
const windows2022 = ec2.MachineImage.latestWindows(
ec2.WindowsVersion.WINDOWS_SERVER_2022_ENGLISH_FULL_BASE
);
// Windows Server 2019 with SQL Server
const windows2019SqlStandard = ec2.MachineImage.latestWindows(
ec2.WindowsVersion.WINDOWS_SERVER_2019_ENGLISH_FULL_SQL_2019_STANDARD
);
// Windows Server 2016 Core
const windows2016Core = ec2.MachineImage.latestWindows(
ec2.WindowsVersion.WINDOWS_SERVER_2016_ENGLISH_CORE_BASE
);
const windowsInstance = new ec2.Instance(this, "WindowsInstance", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.LARGE),
machineImage: windows2022,
keyName: "my-windows-keypair"
});// Multi-region AMI mapping
const customLinuxImage = ec2.MachineImage.genericLinux({
"us-east-1": "ami-12345678",
"us-west-2": "ami-87654321",
"eu-west-1": "ami-abcdef12"
});
const customWindowsImage = ec2.MachineImage.genericWindows({
"us-east-1": "ami-windows123",
"us-west-2": "ami-windows456",
"eu-west-1": "ami-windowsabc"
});
const customInstance = new ec2.Instance(this, "CustomInstance", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.SMALL),
machineImage: customLinuxImage
});// Use AMI ID stored in SSM Parameter Store
const ssmImage = ec2.MachineImage.fromSsmParameter(
"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
{
os: ec2.OperatingSystemType.LINUX
}
);
// Custom SSM parameter
const customSsmImage = ec2.MachineImage.fromSsmParameter(
"/mycompany/golden-image/web-server",
{
os: ec2.OperatingSystemType.LINUX,
cachedInContext: true
}
);
const ssmInstance = new ec2.Instance(this, "SSMInstance", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
machineImage: ssmImage
});// Find latest Ubuntu 20.04 LTS image
const ubuntuImage = ec2.MachineImage.lookup({
name: "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*",
owners: ["099720109477"], // Canonical
filters: {
"virtualization-type": ["hvm"],
"root-device-type": ["ebs"],
"architecture": ["x86_64"]
}
});
// Find latest CentOS image
const centosImage = ec2.MachineImage.lookup({
name: "CentOS Linux 7 x86_64 HVM EBS ENA*",
owners: ["679593333241"] // CentOS official
});
const ubuntuInstance = new ec2.Instance(this, "UbuntuInstance", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.SMALL),
machineImage: ubuntuImage
});const userData = ec2.UserData.forLinux();
userData.addCommands(
"yum update -y",
"yum install -y docker",
"systemctl start docker",
"systemctl enable docker"
);
const amazonLinuxWithUserData = ec2.MachineImage.latestAmazonLinux({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
userData
});
const instanceWithUserData = new ec2.Instance(this, "InstanceWithUserData", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.SMALL),
machineImage: amazonLinuxWithUserData
});// ARM64 instances require ARM64-compatible images
const arm64Instance = new ec2.Instance(this, "ARM64Instance", {
vpc,
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
})
});
// x86_64 instances (default)
const x86Instance = new ec2.Instance(this, "x86Instance", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO),
machineImage: ec2.MachineImage.latestAmazonLinux({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
cpuType: ec2.AmazonLinuxCpuType.X86_64
})
});// Enable context caching for faster deployments
const cachedImage = ec2.MachineImage.latestAmazonLinux({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2,
cachedInContext: true
});
const cachedSsmImage = ec2.MachineImage.fromSsmParameter(
"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
{
os: ec2.OperatingSystemType.LINUX,
cachedInContext: true
}
);export class MultiImageStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const vpc = new ec2.Vpc(this, "VPC");
// Web servers - Amazon Linux 2
const webImage = ec2.MachineImage.latestAmazonLinux({
generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2
});
// Database servers - Custom hardened image
const dbImage = ec2.MachineImage.genericLinux({
"us-east-1": "ami-hardened-db-123",
"us-west-2": "ami-hardened-db-456"
});
// Windows application servers
const appImage = ec2.MachineImage.latestWindows(
ec2.WindowsVersion.WINDOWS_SERVER_2019_ENGLISH_FULL_BASE
);
const webInstance = new ec2.Instance(this, "WebInstance", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.SMALL),
machineImage: webImage
});
const dbInstance = new ec2.Instance(this, "DbInstance", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.R5, ec2.InstanceSize.LARGE),
machineImage: dbImage,
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_NAT }
});
const appInstance = new ec2.Instance(this, "AppInstance", {
vpc,
instanceType: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.XLARGE),
machineImage: appImage
});
}
}