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

machine-images.mddocs/

Machine Images

Machine image management in AWS CDK EC2 provides comprehensive support for AMI selection, including Amazon Linux, Windows, custom AMIs, and dynamic image lookup.

MachineImage Abstract Class

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'
}

Amazon Linux Images

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'
}

Windows Images

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'
}

Generic Images

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;
}

SSM Parameter Images

For AMI IDs stored in Systems Manager Parameter Store:

interface SsmParameterImageOptions {
  readonly os: OperatingSystemType;
  readonly userData?: UserData;
  readonly cachedInContext?: boolean;
}

Dynamic Image Lookup

For runtime AMI discovery:

interface LookupMachineImageProps {
  readonly name: string;
  readonly owners?: string[];
  readonly filters?: {[key: string]: string[]};
  readonly windows?: boolean;
  readonly userData?: UserData;
}

Usage Examples

Amazon Linux Images

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 Images

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

Custom AMI Mapping

// 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
});

SSM Parameter-Based Images

// 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
});

Dynamic Image Lookup

// 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
});

Images with User Data

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
});

Architecture-Specific Images

// 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
  })
});

Image Caching

// 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
  }
);

Multiple Image Types in Stack

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
    });
  }
}

Best Practices

  1. Use Latest Images: Always use the latest available images for security patches
  2. Architecture Matching: Ensure AMI architecture matches instance type architecture
  3. Region Compatibility: Use region-appropriate AMIs or multi-region mappings
  4. Caching: Enable context caching for faster deployments in development
  5. Golden Images: Create and maintain standardized golden images for your organization
  6. Parameterization: Use SSM parameters for centralized AMI management
  7. Testing: Test new AMI versions in non-production environments first
  8. Documentation: Document custom AMI creation and maintenance processes
  9. Security: Regularly update and patch golden images
  10. Compliance: Ensure AMIs meet organizational compliance requirements