Package software.amazon.awscdk.services.imagebuilder.alpha
EC2 Image Builder Construct Library
---
The APIs of higher level constructs in this module are experimental and under active development. They are subject to non-backward compatible changes or removal in any future version. These are not subject to the Semantic Versioning model and breaking changes will be announced in the release notes. This means that while you may use them, you may need to update your source code when upgrading to a newer version of this package.
This module is part of the AWS Cloud Development Kit project.
README
Amazon EC2 Image Builder is a fully managed AWS service that helps you automate the creation, management, and deployment of customized, secure, and up-to-date server images. You can use Image Builder to create Amazon Machine Images (AMIs) and container images for use across AWS Regions.
This module is part of the AWS Cloud Development Kit project. It allows you to define Image Builder pipelines, images, recipes, components, workflows, and lifecycle policies. A component defines the sequence of steps required to customize an instance during image creation (build component) or test an instance launched from the created image (test component). Components are created from declarative YAML or JSON documents that describe runtime configuration for building, validating, or testing instances. Components are included when added to the image recipe or container recipe for an image build.
EC2 Image Builder supports AWS-managed components for common tasks, AWS Marketplace components, and custom components that you create. Components run during specific workflow phases: build and validate phases during the build stage, and test phase during the test stage.
Image Pipeline
An image pipeline provides the automation framework for building secure AMIs and container images. The pipeline orchestrates the entire image creation process by combining an image recipe or container recipe with infrastructure configuration and distribution configuration. Pipelines can run on a schedule or be triggered manually, and they manage the build, test, and distribution phases automatically.
Image Pipeline Basic Usage
Create a simple AMI pipeline with just an image recipe:
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "MyImageRecipe")
.baseImage(BaseImage.fromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"))
.build();
ImagePipeline imagePipeline = ImagePipeline.Builder.create(this, "MyImagePipeline")
.recipe(exampleImageRecipe)
.build();
Create a simple container pipeline with just a container recipe:
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "MyContainerRecipe")
.baseImage(BaseContainerImage.fromDockerHub("amazonlinux", "latest"))
.targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
.build();
ImagePipeline containerPipeline = ImagePipeline.Builder.create(this, "MyContainerPipeline")
.recipe(exampleContainerRecipe)
.build();
Image Pipeline Scheduling
Manual Pipeline Execution
Create a pipeline that runs only when manually triggered:
ImagePipeline manualPipeline = ImagePipeline.Builder.create(this, "ManualPipeline")
.imagePipelineName("my-manual-pipeline")
.description("Pipeline triggered manually for production builds")
.recipe(exampleImageRecipe)
.build();
// Grant Lambda function permission to trigger the pipeline
manualPipeline.grantStartExecution(lambdaRole);
Automated Pipeline Scheduling
Schedule a pipeline to run automatically using cron expressions:
ImagePipeline weeklyPipeline = ImagePipeline.Builder.create(this, "WeeklyPipeline")
.imagePipelineName("weekly-build-pipeline")
.recipe(exampleImageRecipe)
.schedule(ImagePipelineSchedule.builder()
.expression(Schedule.cron(CronOptions.builder()
.minute("0")
.hour("6")
.weekDay("MON")
.build()))
.build())
.build();
Use rate expressions for regular intervals:
ImagePipeline dailyPipeline = ImagePipeline.Builder.create(this, "DailyPipeline")
.recipe(exampleContainerRecipe)
.schedule(ImagePipelineSchedule.builder()
.expression(Schedule.rate(Duration.days(1)))
.build())
.build();
Pipeline Schedule Configuration
Configure advanced scheduling options:
ImagePipeline advancedSchedulePipeline = ImagePipeline.Builder.create(this, "AdvancedSchedulePipeline")
.recipe(exampleImageRecipe)
.schedule(ImagePipelineSchedule.builder()
.expression(Schedule.rate(Duration.days(7)))
// Only trigger when dependencies are updated (new base images, components, etc.)
.startCondition(ScheduleStartCondition.EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE)
// Automatically disable after 3 consecutive failures
.autoDisableFailureCount(3)
.build())
// Start enabled
.status(ImagePipelineStatus.ENABLED)
.build();
Image Pipeline Configuration
Infrastructure and Distribution in Image Pipelines
Configure custom infrastructure and distribution settings:
InfrastructureConfiguration infrastructureConfiguration = InfrastructureConfiguration.Builder.create(this, "Infrastructure")
.infrastructureConfigurationName("production-infrastructure")
.instanceTypes(List.of(InstanceType.of(InstanceClass.COMPUTE7_INTEL, InstanceSize.LARGE)))
.vpc(vpc)
.subnetSelection(SubnetSelection.builder().subnetType(SubnetType.PRIVATE_WITH_EGRESS).build())
.build();
DistributionConfiguration distributionConfiguration = new DistributionConfiguration(this, "Distribution");
distributionConfiguration.addAmiDistributions(AmiDistribution.builder()
.amiName("production-ami-{{ imagebuilder:buildDate }}")
.amiTargetAccountIds(List.of("123456789012", "098765432109"))
.build());
ImagePipeline productionPipeline = ImagePipeline.Builder.create(this, "ProductionPipeline")
.recipe(exampleImageRecipe)
.infrastructureConfiguration(infrastructureConfiguration)
.distributionConfiguration(distributionConfiguration)
.build();
Pipeline Logging Configuration
Configure custom CloudWatch log groups for pipeline and image logs:
LogGroup pipelineLogGroup = LogGroup.Builder.create(this, "PipelineLogGroup")
.logGroupName("/custom/imagebuilder/pipeline/logs")
.retention(RetentionDays.ONE_MONTH)
.build();
LogGroup imageLogGroup = LogGroup.Builder.create(this, "ImageLogGroup")
.logGroupName("/custom/imagebuilder/image/logs")
.retention(RetentionDays.ONE_WEEK)
.build();
ImagePipeline loggedPipeline = ImagePipeline.Builder.create(this, "LoggedPipeline")
.recipe(exampleImageRecipe)
.imagePipelineLogGroup(pipelineLogGroup)
.imageLogGroup(imageLogGroup)
.build();
Workflow Integration in Image Pipelines
Use AWS-managed workflows for common pipeline phases:
ImagePipeline workflowPipeline = ImagePipeline.Builder.create(this, "WorkflowPipeline")
.recipe(exampleImageRecipe)
.workflows(List.of(WorkflowConfiguration.builder().workflow(AmazonManagedWorkflow.buildImage(this, "BuildWorkflow")).build(), WorkflowConfiguration.builder().workflow(AmazonManagedWorkflow.testImage(this, "TestWorkflow")).build()))
.build();
For container pipelines, use container-specific workflows:
ImagePipeline containerWorkflowPipeline = ImagePipeline.Builder.create(this, "ContainerWorkflowPipeline")
.recipe(exampleContainerRecipe)
.workflows(List.of(WorkflowConfiguration.builder().workflow(AmazonManagedWorkflow.buildContainer(this, "BuildContainer")).build(), WorkflowConfiguration.builder().workflow(AmazonManagedWorkflow.testContainer(this, "TestContainer")).build(), WorkflowConfiguration.builder().workflow(AmazonManagedWorkflow.distributeContainer(this, "DistributeContainer")).build()))
.build();
Advanced Features in Image Pipelines
Configure image scanning for container pipelines:
Repository scanningRepository = new Repository(this, "ScanningRepo");
ImagePipeline scannedContainerPipeline = ImagePipeline.Builder.create(this, "ScannedContainerPipeline")
.recipe(exampleContainerRecipe)
.imageScanningEnabled(true)
.imageScanningEcrRepository(scanningRepository)
.imageScanningEcrTags(List.of("security-scan", "latest"))
.build();
Control metadata collection and testing:
ImagePipeline controlledPipeline = ImagePipeline.Builder.create(this, "ControlledPipeline")
.recipe(exampleImageRecipe)
.enhancedImageMetadataEnabled(true) // Collect detailed OS and package info
.imageTestsEnabled(false)
.build();
Image Pipeline Events
Pipeline Event Handling
Handle specific pipeline events:
// Monitor CVE detection
examplePipeline.onCVEDetected("CVEAlert", OnEventOptions.builder()
.target(new SnsTopic(topic))
.build());
// Handle pipeline auto-disable events
examplePipeline.onImagePipelineAutoDisabled("PipelineDisabledAlert", OnEventOptions.builder()
.target(new LambdaFunction(lambdaFunction))
.build());
Importing Image Pipelines
Reference existing pipelines created outside CDK:
// Import by name
IImagePipeline existingPipelineByName = ImagePipeline.fromImagePipelineName(this, "ExistingPipelineByName", "my-existing-pipeline");
// Import by ARN
IImagePipeline existingPipelineByArn = ImagePipeline.fromImagePipelineArn(this, "ExistingPipelineByArn", "arn:aws:imagebuilder:us-east-1:123456789012:image-pipeline/imported-pipeline");
// Grant permissions to imported pipelines
Role automationRole = Role.Builder.create(this, "AutomationRole")
.assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
.build();
existingPipelineByName.grantStartExecution(automationRole);
existingPipelineByArn.grantRead(lambdaRole);
Image
An image is the output resource created by Image Builder, consisting of an AMI or container image plus metadata such as version, platform, and creation details. Images are used as base images for future builds and can be shared across AWS accounts. While images are the output from image pipeline executions, they can also be created in an ad-hoc manner outside a pipeline, defined as a standalone resource.
Image Basic Usage
Create a simple AMI-based image from an image recipe:
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "MyImageRecipe")
.baseImage(BaseImage.fromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"))
.build();
Image amiImage = Image.Builder.create(this, "MyAmiImage")
.recipe(imageRecipe)
.build();
Create a simple container image from a container recipe:
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "MyContainerRecipe")
.baseImage(BaseContainerImage.fromDockerHub("amazonlinux", "latest"))
.targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
.build();
Image containerImage = Image.Builder.create(this, "MyContainerImage")
.recipe(containerRecipe)
.build();
AWS-Managed Images
Pre-defined OS Images
Use AWS-managed images for common operating systems:
// Amazon Linux 2023 AMI for x86_64
IImage amazonLinux2023Ami = AmazonManagedImage.amazonLinux2023(this, "AmazonLinux2023", AmazonManagedImageOptions.builder()
.imageType(ImageType.AMI)
.imageArchitecture(ImageArchitecture.X86_64)
.build());
// Ubuntu 22.04 AMI for ARM64
IImage ubuntu2204Ami = AmazonManagedImage.ubuntuServer2204(this, "Ubuntu2204", AmazonManagedImageOptions.builder()
.imageType(ImageType.AMI)
.imageArchitecture(ImageArchitecture.ARM64)
.build());
// Windows Server 2022 Full AMI
IImage windows2022Ami = AmazonManagedImage.windowsServer2022Full(this, "Windows2022", AmazonManagedImageOptions.builder()
.imageType(ImageType.AMI)
.imageArchitecture(ImageArchitecture.X86_64)
.build());
// Use as base image in recipe
ImageRecipe managedImageRecipe = ImageRecipe.Builder.create(this, "ManagedImageRecipe")
.baseImage(amazonLinux2023Ami.toBaseImage())
.build();
Custom AWS-Managed Images
Import AWS-managed images by name or attributes:
// Import by name
IImage managedImageByName = AmazonManagedImage.fromAmazonManagedImageName(this, "ManagedImageByName", "amazon-linux-2023-x86");
// Import by attributes with specific version
IImage managedImageByAttributes = AmazonManagedImage.fromAmazonManagedImageAttributes(this, "ManagedImageByAttributes", AmazonManagedImageAttributes.builder()
.imageName("ubuntu-server-22-lts-x86")
.imageVersion("2024.11.25")
.build());
Image Configuration
Infrastructure and Distribution in Images
Configure custom infrastructure and distribution settings:
InfrastructureConfiguration infrastructureConfiguration = InfrastructureConfiguration.Builder.create(this, "Infrastructure")
.infrastructureConfigurationName("production-infrastructure")
.instanceTypes(List.of(InstanceType.of(InstanceClass.COMPUTE7_INTEL, InstanceSize.LARGE)))
.vpc(vpc)
.subnetSelection(SubnetSelection.builder().subnetType(SubnetType.PRIVATE_WITH_EGRESS).build())
.build();
DistributionConfiguration distributionConfiguration = new DistributionConfiguration(this, "Distribution");
distributionConfiguration.addAmiDistributions(AmiDistribution.builder()
.amiName("production-ami-{{ imagebuilder:buildDate }}")
.amiTargetAccountIds(List.of("123456789012", "098765432109"))
.build());
Image productionImage = Image.Builder.create(this, "ProductionImage")
.recipe(exampleImageRecipe)
.infrastructureConfiguration(infrastructureConfiguration)
.distributionConfiguration(distributionConfiguration)
.build();
Logging Configuration
Configure custom CloudWatch log groups for image builds:
LogGroup logGroup = LogGroup.Builder.create(this, "ImageLogGroup")
.logGroupName("/custom/imagebuilder/image/logs")
.retention(RetentionDays.ONE_MONTH)
.build();
Image loggedImage = Image.Builder.create(this, "LoggedImage")
.recipe(exampleImageRecipe)
.logGroup(logGroup)
.build();
Workflow Integration in Images
Use workflows for custom build, test, and distribution processes:
Image imageWithWorkflows = Image.Builder.create(this, "ImageWithWorkflows")
.recipe(exampleImageRecipe)
.workflows(List.of(WorkflowConfiguration.builder().workflow(AmazonManagedWorkflow.buildImage(this, "BuildWorkflow")).build(), WorkflowConfiguration.builder().workflow(AmazonManagedWorkflow.testImage(this, "TestWorkflow")).build()))
.build();
Advanced Features in Images
Configure image scanning, metadata collection, and testing:
Repository scanningRepository = new Repository(this, "ScanningRepository");
Image advancedContainerImage = Image.Builder.create(this, "AdvancedContainerImage")
.recipe(exampleContainerRecipe)
.imageScanningEnabled(true)
.imageScanningEcrRepository(scanningRepository)
.imageScanningEcrTags(List.of("security-scan", "latest"))
.enhancedImageMetadataEnabled(true)
.imageTestsEnabled(false)
.build();
Importing Images
Reference existing images created outside CDK:
// Import by name
IImage existingImageByName = Image.fromImageName(this, "ExistingImageByName", "my-existing-image");
// Import by ARN
IImage existingImageByArn = Image.fromImageArn(this, "ExistingImageByArn", "arn:aws:imagebuilder:us-east-1:123456789012:image/imported-image/1.0.0");
// Import by attributes
IImage existingImageByAttributes = Image.fromImageAttributes(this, "ExistingImageByAttributes", ImageAttributes.builder()
.imageName("shared-base-image")
.imageVersion("2024.11.25")
.build());
// Grant permissions to imported images
Role role = Role.Builder.create(this, "ImageAccessRole")
.assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
.build();
existingImageByName.grantRead(role);
existingImageByArn.grant(role, "imagebuilder:GetImage", "imagebuilder:ListImagePackages");
Image Recipe
Image Recipe Basic Usage
Create an image recipe with the required base image:
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "MyImageRecipe")
.baseImage(BaseImage.fromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"))
.build();
Image Recipe Base Images
To create a recipe, you have to select a base image to build and customize from. This base image can be referenced from various sources, such as from SSM parameters, AWS Marketplace products, and AMI IDs directly.
SSM Parameters
Using SSM parameter references:
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "SsmImageRecipe")
.baseImage(BaseImage.fromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"))
.build();
// Using an SSM parameter construct
IStringParameter parameter = StringParameter.fromStringParameterName(this, "BaseImageParameter", "/aws/service/ami-windows-latest/Windows_Server-2022-English-Full-Base");
ImageRecipe windowsRecipe = ImageRecipe.Builder.create(this, "WindowsImageRecipe")
.baseImage(BaseImage.fromSsmParameter(parameter))
.build();
AMI IDs
When you have a specific AMI to use:
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "AmiImageRecipe")
.baseImage(BaseImage.fromAmiId("ami-12345678"))
.build();
Marketplace Images
For marketplace base images:
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "MarketplaceImageRecipe")
.baseImage(BaseImage.fromMarketplaceProductId("prod-1234567890abcdef0"))
.build();
Image Recipe Components
Components from various sources, such as custom-owned, AWS-owned, or AWS Marketplace-owned, can optionally be included in recipes. For parameterized components, you are able to provide the parameters to use in the recipe, which will be applied during the image build when executing components.
Custom Components in Image Recipes
Add your own components to the recipe:
Component customComponent = Component.Builder.create(this, "MyComponent")
.platform(Platform.LINUX)
.data(ComponentData.fromJsonObject(Map.of(
"schemaVersion", ComponentSchemaVersion.V1_0,
"phases", List.of(Map.of(
"name", ComponentPhaseName.BUILD,
"steps", List.of(Map.of(
"name", "install-app",
"action", ComponentAction.EXECUTE_BASH,
"inputs", Map.of(
"commands", List.of("yum install -y my-application")))))))))
.build();
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "ComponentImageRecipe")
.baseImage(BaseImage.fromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"))
.components(List.of(ComponentConfiguration.builder()
.component(customComponent)
.build()))
.build();
AWS-Managed Components in Image Recipes
Use pre-built AWS components:
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "AmazonManagedImageRecipe")
.baseImage(BaseImage.fromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"))
.components(List.of(ComponentConfiguration.builder()
.component(AmazonManagedComponent.updateOs(this, "UpdateOS", AmazonManagedComponentOptions.builder()
.platform(Platform.LINUX)
.build()))
.build(), ComponentConfiguration.builder()
.component(AmazonManagedComponent.awsCliV2(this, "AwsCli", AmazonManagedComponentOptions.builder()
.platform(Platform.LINUX)
.build()))
.build()))
.build();
Component Parameters in Image Recipes
Pass parameters to components that accept them:
IComponent parameterizedComponent = Component.fromComponentName(this, "ParameterizedComponent", "my-parameterized-component");
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "ParameterizedImageRecipe")
.baseImage(BaseImage.fromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"))
.components(List.of(ComponentConfiguration.builder()
.component(parameterizedComponent)
.parameters(Map.of(
"environment", ComponentParameterValue.fromString("production"),
"version", ComponentParameterValue.fromString("1.0.0")))
.build()))
.build();
Image Recipe Configuration
Block Device Configuration
Configure storage for the build instance:
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "BlockDeviceImageRecipe")
.baseImage(BaseImage.fromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"))
.blockDevices(List.of(BlockDevice.builder()
.deviceName("/dev/sda1")
.volume(BlockDeviceVolume.ebs(100, EbsDeviceOptions.builder()
.encrypted(true)
.volumeType(EbsDeviceVolumeType.GENERAL_PURPOSE_SSD_GP3)
.build()))
.build()))
.build();
AMI Tagging
Tag the output AMI:
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "TaggedImageRecipe")
.baseImage(BaseImage.fromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"))
.amiTags(Map.of(
"Environment", "Production",
"Application", "WebServer",
"Owner", "DevOps Team"))
.build();
Container Recipe
A container recipe is similar to an image recipe but specifically for container images. It defines the base container image and components applied to produce the desired configuration for the output container image. Container recipes work with Docker images from DockerHub, Amazon ECR, or Amazon-managed container images as starting points.
Container Recipe Basic Usage
Create a container recipe with the required base image and target repository:
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "MyContainerRecipe")
.baseImage(BaseContainerImage.fromDockerHub("amazonlinux", "latest"))
.targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
.build();
Container Recipe Base Images
DockerHub Images
Using public Docker Hub images:
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "DockerHubContainerRecipe")
.baseImage(BaseContainerImage.fromDockerHub("amazonlinux", "latest"))
.targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
.build();
ECR Images
Using images from your own ECR repositories:
IRepository sourceRepo = Repository.fromRepositoryName(this, "SourceRepo", "my-base-image");
IRepository targetRepo = Repository.fromRepositoryName(this, "TargetRepo", "my-container-repo");
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "EcrContainerRecipe")
.baseImage(BaseContainerImage.fromEcr(sourceRepo, "1.0.0"))
.targetRepository(Repository.fromEcr(targetRepo))
.build();
ECR Public Images
Using images from Amazon ECR Public:
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "EcrPublicContainerRecipe")
.baseImage(BaseContainerImage.fromEcrPublic("amazonlinux", "amazonlinux", "2023"))
.targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
.build();
Container Recipe Components
Custom Components in Container Recipes
Add your own components to the container recipe:
Component customComponent = Component.Builder.create(this, "MyComponent")
.platform(Platform.LINUX)
.data(ComponentData.fromJsonObject(Map.of(
"schemaVersion", ComponentSchemaVersion.V1_0,
"phases", List.of(Map.of(
"name", ComponentPhaseName.BUILD,
"steps", List.of(Map.of(
"name", "install-app",
"action", ComponentAction.EXECUTE_BASH,
"inputs", Map.of(
"commands", List.of("yum install -y my-container-application")))))))))
.build();
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "ComponentContainerRecipe")
.baseImage(BaseContainerImage.fromDockerHub("amazonlinux", "latest"))
.targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
.components(List.of(ComponentConfiguration.builder()
.component(customComponent)
.build()))
.build();
AWS-Managed Components in Container Recipes
Use pre-built AWS components:
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "AmazonManagedContainerRecipe")
.baseImage(BaseContainerImage.fromDockerHub("amazonlinux", "latest"))
.targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
.components(List.of(ComponentConfiguration.builder()
.component(AmazonManagedComponent.updateOs(this, "UpdateOS", AmazonManagedComponentOptions.builder()
.platform(Platform.LINUX)
.build()))
.build(), ComponentConfiguration.builder()
.component(AmazonManagedComponent.awsCliV2(this, "AwsCli", AmazonManagedComponentOptions.builder()
.platform(Platform.LINUX)
.build()))
.build()))
.build();
Container Recipe Configuration
Custom Dockerfile
Provide your own Dockerfile template:
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "CustomDockerfileContainerRecipe")
.baseImage(BaseContainerImage.fromDockerHub("amazonlinux", "latest"))
.targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
.dockerfile(DockerfileData.fromInline("\nFROM {{{ imagebuilder:parentImage }}}\nCMD [\"echo\", \"Hello, world!\"]\n{{{ imagebuilder:environments }}}\n{{{ imagebuilder:components }}}\n"))
.build();
Instance Configuration
Configure the build instance:
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "InstanceConfigContainerRecipe")
.baseImage(BaseContainerImage.fromDockerHub("amazonlinux", "latest"))
.targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
// Custom ECS-optimized AMI for building
.instanceImage(ContainerInstanceImage.fromSsmParameterName("/aws/service/ecs/optimized-ami/amazon-linux-2023/recommended/image_id"))
// Additional storage for build process
.instanceBlockDevices(List.of(BlockDevice.builder()
.deviceName("/dev/xvda")
.volume(BlockDeviceVolume.ebs(50, EbsDeviceOptions.builder()
.encrypted(true)
.volumeType(EbsDeviceVolumeType.GENERAL_PURPOSE_SSD_GP3)
.build()))
.build()))
.build();
Component
A component defines the sequence of steps required to customize an instance during image creation (build component) or test an instance launched from the created image (test component). Components are created from declarative YAML or JSON documents that describe runtime configuration for building, validating, or testing instances. Components are included when added to the image recipe or container recipe for an image build.
EC2 Image Builder supports AWS-managed components for common tasks, AWS Marketplace components, and custom components that you create. Components run during specific workflow phases: build and validate phases during the build stage, and test phase during the test stage.
Basic Component Usage
Create a component with the required properties: platform and component data.
Component component = Component.Builder.create(this, "MyComponent")
.platform(Platform.LINUX)
.data(ComponentData.fromJsonObject(Map.of(
"schemaVersion", ComponentSchemaVersion.V1_0,
"phases", List.of(Map.of(
"name", ComponentPhaseName.BUILD,
"steps", List.of(Map.of(
"name", "install-app",
"action", ComponentAction.EXECUTE_BASH,
"inputs", Map.of(
"commands", List.of("echo \"Installing my application...\"", "yum update -y")))))))))
.build();
Component Data Sources
Inline Component Data
Use ComponentData.fromInline() for existing YAML/JSON definitions:
Component component = Component.Builder.create(this, "InlineComponent")
.platform(Platform.LINUX)
.data(ComponentData.fromInline("\nname: my-component\nschemaVersion: 1.0\nphases:\n - name: build\n steps:\n - name: update-os\n action: ExecuteBash\n inputs:\n commands: ['yum update -y']\n"))
.build();
JSON Object Component Data
Most developer-friendly approach using objects:
Component component = Component.Builder.create(this, "JsonComponent")
.platform(Platform.LINUX)
.data(ComponentData.fromJsonObject(Map.of(
"schemaVersion", ComponentSchemaVersion.V1_0,
"phases", List.of(Map.of(
"name", ComponentPhaseName.BUILD,
"steps", List.of(Map.of(
"name", "configure-app",
"action", ComponentAction.CREATE_FILE,
"inputs", Map.of(
"path", "/etc/myapp/config.json",
"content", "{\"env\": \"production\"}"))))))))
.build();
Structured Component Document
For type-safe, CDK-native definitions with enhanced properties like timeout and onFailure.
Defining a component step
You can define steps in the component which will be executed in order when the component is applied:
ComponentDocumentStep step = ComponentDocumentStep.builder()
.name("configure-app")
.action(ComponentAction.CREATE_FILE)
.inputs(ComponentStepInputs.fromObject(Map.of(
"path", "/etc/myapp/config.json",
"content", "{\"env\": \"production\"}")))
.build();
Defining a component phase
Phases group steps together, which run in sequence when building, validating or testing in the component:
ComponentDocumentPhase phase = ComponentDocumentPhase.builder()
.name(ComponentPhaseName.BUILD)
.steps(List.of(ComponentDocumentStep.builder()
.name("configure-app")
.action(ComponentAction.CREATE_FILE)
.inputs(ComponentStepInputs.fromObject(Map.of(
"path", "/etc/myapp/config.json",
"content", "{\"env\": \"production\"}")))
.build()))
.build();
Defining a component
The component data defines all steps across the provided phases to execute during the build:
Component component = Component.Builder.create(this, "StructuredComponent")
.platform(Platform.LINUX)
.data(ComponentData.fromComponentDocumentJsonObject(ComponentDocument.builder()
.schemaVersion(ComponentSchemaVersion.V1_0)
.phases(List.of(ComponentDocumentPhase.builder()
.name(ComponentPhaseName.BUILD)
.steps(List.of(ComponentDocumentStep.builder()
.name("install-with-timeout")
.action(ComponentAction.EXECUTE_BASH)
.timeout(Duration.minutes(10))
.onFailure(ComponentOnFailure.CONTINUE)
.inputs(ComponentStepInputs.fromObject(Map.of(
"commands", List.of("./install-script.sh"))))
.build()))
.build()))
.build()))
.build();
S3 Component Data
For those components you want to upload or have uploaded to S3:
// Upload a local file
Component componentFromAsset = Component.Builder.create(this, "AssetComponent")
.platform(Platform.LINUX)
.data(ComponentData.fromAsset(this, "ComponentAsset", "./my-component.yml"))
.build();
// Reference an existing S3 object
IBucket bucket = Bucket.fromBucketName(this, "ComponentBucket", "my-components-bucket");
Component componentFromS3 = Component.Builder.create(this, "S3Component")
.platform(Platform.LINUX)
.data(ComponentData.fromS3(bucket, "components/my-component.yml"))
.build();
Encrypt component data with a KMS key
You can encrypt component data with a KMS key, so that only principals with access to decrypt with the key are able to access the component data.
Component component = Component.Builder.create(this, "EncryptedComponent")
.platform(Platform.LINUX)
.kmsKey(new Key(this, "ComponentKey"))
.data(ComponentData.fromJsonObject(Map.of(
"schemaVersion", ComponentSchemaVersion.V1_0,
"phases", List.of(Map.of(
"name", ComponentPhaseName.BUILD,
"steps", List.of(Map.of(
"name", "secure-setup",
"action", ComponentAction.EXECUTE_BASH,
"inputs", Map.of(
"commands", List.of("echo \"This component data is encrypted with KMS\"")))))))))
.build();
AWS-Managed Components
AWS provides a collection of managed components for common tasks:
// Install AWS CLI v2
IComponent awsCliComponent = AmazonManagedComponent.awsCliV2(this, "AwsCli", AmazonManagedComponentOptions.builder()
.platform(Platform.LINUX)
.build());
// Update the operating system
IComponent updateComponent = AmazonManagedComponent.updateOs(this, "UpdateOS", AmazonManagedComponentOptions.builder()
.platform(Platform.LINUX)
.build());
// Reference any AWS-managed component by name
IComponent customAwsComponent = AmazonManagedComponent.fromAmazonManagedComponentName(this, "CloudWatchAgent", "amazon-cloudwatch-agent-linux");
AWS Marketplace Components
You can reference AWS Marketplace components using the marketplace component name and its product ID:
IComponent marketplaceComponent = AwsMarketplaceComponent.fromAwsMarketplaceComponentAttributes(this, "MarketplaceComponent", AwsMarketplaceComponentAttributes.builder()
.componentName("my-marketplace-component")
.marketplaceProductId("prod-1234567890abcdef0")
.build());
Infrastructure Configuration
Infrastructure configuration defines the compute resources and environment settings used during the image building process. This includes instance types, IAM instance profile, VPC settings, subnets, security groups, SNS topics for notifications, logging configuration, and troubleshooting settings like whether to terminate instances on failure or keep them running for debugging. These settings are applied to builds when included in an image or an image pipeline.
InfrastructureConfiguration infrastructureConfiguration = InfrastructureConfiguration.Builder.create(this, "InfrastructureConfiguration")
.infrastructureConfigurationName("test-infrastructure-configuration")
.description("An Infrastructure Configuration")
// Optional - instance types to use for build/test
.instanceTypes(List.of(InstanceType.of(InstanceClass.STANDARD7_INTEL, InstanceSize.LARGE), InstanceType.of(InstanceClass.BURSTABLE3, InstanceSize.LARGE)))
// Optional - create an instance profile with necessary permissions
.instanceProfile(InstanceProfile.Builder.create(this, "InstanceProfile")
.instanceProfileName("test-instance-profile")
.role(Role.Builder.create(this, "InstanceProfileRole")
.assumedBy(ServicePrincipal.fromStaticServicePrincipleName("ec2.amazonaws.com"))
.managedPolicies(List.of(ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore"), ManagedPolicy.fromAwsManagedPolicyName("EC2InstanceProfileForImageBuilder")))
.build())
.build())
// Use VPC network configuration
.vpc(vpc)
.subnetSelection(SubnetSelection.builder().subnetType(SubnetType.PUBLIC).build())
.securityGroups(List.of(SecurityGroup.fromSecurityGroupId(this, "SecurityGroup", vpc.getVpcDefaultSecurityGroup())))
.keyPair(KeyPair.fromKeyPairName(this, "KeyPair", "imagebuilder-instance-key-pair"))
.terminateInstanceOnFailure(true)
// Optional - IMDSv2 settings
.httpTokens(HttpTokens.REQUIRED)
.httpPutResponseHopLimit(1)
// Optional - publish image completion messages to an SNS topic
.notificationTopic(Topic.fromTopicArn(this, "Topic", this.formatArn(ArnComponents.builder().service("sns").resource("image-builder-topic").build())))
// Optional - log settings. Logging is enabled by default
.logging(InfrastructureConfigurationLogging.builder()
.s3Bucket(Bucket.fromBucketName(this, "LogBucket", String.format("imagebuilder-logging-%s", Aws.ACCOUNT_ID)))
.s3KeyPrefix("imagebuilder-logs")
.build())
// Optional - host placement settings
.ec2InstanceAvailabilityZone(Stack.of(this).getAvailabilityZones()[0])
.ec2InstanceHostId(dedicatedHost.getAttrHostId())
.ec2InstanceTenancy(Tenancy.HOST)
.resourceTags(Map.of(
"Environment", "production"))
.build();
Distribution Configuration
Distribution configuration defines how and where your built images are distributed after successful creation. For AMIs, this includes target AWS Regions, KMS encryption keys, account sharing permissions, License Manager associations, and launch template configurations. For container images, it specifies the target Amazon ECR repositories across regions. A distribution configuration can be associated with an image or an image pipeline to define these distribution settings for image builds.
AMI Distributions
AMI distributions can be defined to copy and modify AMIs in different accounts and regions, and apply them to launch templates, SSM parameters, etc.:
DistributionConfiguration distributionConfiguration = DistributionConfiguration.Builder.create(this, "DistributionConfiguration")
.distributionConfigurationName("test-distribution-configuration")
.description("A Distribution Configuration")
.amiDistributions(List.of(AmiDistribution.builder()
// Distribute AMI to us-east-2 and publish the AMI ID to an SSM parameter
.region("us-east-2")
.ssmParameters(List.of(SSMParameterConfigurations.builder()
.parameter(StringParameter.fromStringParameterAttributes(this, "CrossRegionParameter", StringParameterAttributes.builder()
.parameterName("/imagebuilder/ami")
.forceDynamicReference(true)
.build()))
.build()))
.build()))
.build();
// For AMI-based image builds - add an AMI distribution in the current region
distributionConfiguration.addAmiDistributions(AmiDistribution.builder()
.amiName("imagebuilder-{{ imagebuilder:buildDate }}")
.amiDescription("Build AMI")
.amiKmsKey(Key.fromLookup(this, "ComponentKey", KeyLookupOptions.builder().aliasName("alias/distribution-encryption-key").build()))
// Copy the AMI to different accounts
.amiTargetAccountIds(List.of("123456789012", "098765432109"))
// Add launch permissions on the AMI
.amiLaunchPermission(AmiLaunchPermission.builder()
.organizationArns(List.of(this.formatArn(ArnComponents.builder().region("").service("organizations").resource("organization").resourceName("o-1234567abc").build())))
.organizationalUnitArns(List.of(this.formatArn(ArnComponents.builder()
.region("")
.service("organizations")
.resource("ou")
.resourceName("o-1234567abc/ou-a123-b4567890")
.build())))
.isPublicUserGroup(true)
.accountIds(List.of("234567890123"))
.build())
// Attach tags to the AMI
.amiTags(Map.of(
"Environment", "production",
"Version", "{{ imagebuilder:buildVersion }}"))
// Optional - publish the distributed AMI ID to an SSM parameter
.ssmParameters(List.of(SSMParameterConfigurations.builder()
.parameter(StringParameter.fromStringParameterAttributes(this, "Parameter", StringParameterAttributes.builder()
.parameterName("/imagebuilder/ami")
.forceDynamicReference(true)
.build()))
.build(), SSMParameterConfigurations.builder()
.amiAccount("098765432109")
.dataType(ParameterDataType.TEXT)
.parameter(StringParameter.fromStringParameterAttributes(this, "CrossAccountParameter", StringParameterAttributes.builder()
.parameterName("imagebuilder-prod-ami")
.forceDynamicReference(true)
.build()))
.build()))
// Optional - create a new launch template version with the distributed AMI ID
.launchTemplates(List.of(LaunchTemplateConfiguration.builder()
.launchTemplate(LaunchTemplate.fromLaunchTemplateAttributes(this, "LaunchTemplate", LaunchTemplateAttributes.builder()
.launchTemplateId("lt-1234")
.build()))
.setDefaultVersion(true)
.build(), LaunchTemplateConfiguration.builder()
.accountId("123456789012")
.launchTemplate(LaunchTemplate.fromLaunchTemplateAttributes(this, "CrossAccountLaunchTemplate", LaunchTemplateAttributes.builder()
.launchTemplateId("lt-5678")
.build()))
.setDefaultVersion(true)
.build()))
// Optional - enable Fast Launch on an imported launch template
.fastLaunchConfigurations(List.of(FastLaunchConfiguration.builder()
.enabled(true)
.launchTemplate(LaunchTemplate.fromLaunchTemplateAttributes(this, "FastLaunchLT", LaunchTemplateAttributes.builder()
.launchTemplateName("fast-launch-lt")
.build()))
.maxParallelLaunches(10)
.targetSnapshotCount(2)
.build()))
// Optional - license configurations to apply to the AMI
.licenseConfigurationArns(List.of("arn:aws:license-manager:us-west-2:123456789012:license-configuration:lic-abcdefghijklmnopqrstuvwxyz"))
.build());
Container Distributions
Container repositories
Container distributions can be configured to distribute to ECR repositories:
IRepository ecrRepository = Repository.fromRepositoryName(this, "ECRRepository", "my-repo"); Repository imageBuilderRepository = Repository.fromEcr(ecrRepository);
Defining a container distribution
You can configure the container repositories as well as the description and tags applied to the distributed container images:
IRepository ecrRepository = Repository.fromRepositoryName(this, "ECRRepository", "my-repo");
Repository containerRepository = Repository.fromEcr(ecrRepository);
DistributionConfiguration containerDistributionConfiguration = new DistributionConfiguration(this, "ContainerDistributionConfiguration");
containerDistributionConfiguration.addContainerDistributions(ContainerDistribution.builder()
.containerRepository(containerRepository)
.containerDescription("Test container image")
.containerTags(List.of("latest", "latest-1.0"))
.build());
Workflow
Workflows define the sequence of steps that Image Builder performs during image creation. There are three workflow types: BUILD (image building), TEST (testing images), and DISTRIBUTION (distributing container images).
Basic Workflow Usage
Create a workflow with the required properties: workflow type and workflow data.
Workflow workflow = Workflow.Builder.create(this, "MyWorkflow")
.workflowType(WorkflowType.BUILD)
.data(WorkflowData.fromJsonObject(Map.of(
"schemaVersion", WorkflowSchemaVersion.V1_0,
"steps", List.of(Map.of(
"name", "LaunchBuildInstance",
"action", WorkflowAction.LAUNCH_INSTANCE,
"onFailure", WorkflowOnFailure.ABORT,
"inputs", Map.of(
"waitFor", "ssmAgent")), Map.of(
"name", "ExecuteComponents",
"action", WorkflowAction.EXECUTE_COMPONENTS,
"onFailure", WorkflowOnFailure.ABORT,
"inputs", Map.of(
"instanceId", "i-123")), Map.of(
"name", "CreateImage",
"action", WorkflowAction.CREATE_IMAGE,
"onFailure", WorkflowOnFailure.ABORT,
"inputs", Map.of(
"instanceId", "i-123")), Map.of(
"name", "TerminateInstance",
"action", WorkflowAction.TERMINATE_INSTANCE,
"onFailure", WorkflowOnFailure.CONTINUE,
"inputs", Map.of(
"instanceId", "i-123"))),
"outputs", List.of(Map.of(
"name", "ImageId",
"value", "$.stepOutputs.CreateImage.imageId")))))
.build();
Workflow Data Sources
Inline Workflow Data
Use WorkflowData.fromInline() for existing YAML/JSON definitions:
Workflow workflow = Workflow.Builder.create(this, "InlineWorkflow")
.workflowType(WorkflowType.TEST)
.data(WorkflowData.fromInline("\nschemaVersion: 1.0\nsteps:\n - name: LaunchTestInstance\n action: LaunchInstance\n onFailure: Abort\n inputs:\n waitFor: ssmAgent\n - name: RunTests\n action: RunCommand\n onFailure: Abort\n inputs:\n instanceId.$: \"$.stepOutputs.LaunchTestInstance.instanceId\"\n commands: ['./run-tests.sh']\n - name: TerminateTestInstance\n action: TerminateInstance\n onFailure: Continue\n inputs:\n instanceId.$: \"$.stepOutputs.LaunchTestInstance.instanceId\"\n"))
.build();
JSON Object Workflow Data
Most developer-friendly approach using JavaScript objects:
Workflow workflow = Workflow.Builder.create(this, "JsonWorkflow")
.workflowType(WorkflowType.BUILD)
.data(WorkflowData.fromJsonObject(Map.of(
"schemaVersion", WorkflowSchemaVersion.V1_0,
"steps", List.of(Map.of(
"name", "LaunchBuildInstance",
"action", WorkflowAction.LAUNCH_INSTANCE,
"onFailure", WorkflowOnFailure.ABORT,
"inputs", Map.of(
"waitFor", "ssmAgent")), Map.of(
"name", "ExecuteComponents",
"action", WorkflowAction.EXECUTE_COMPONENTS,
"onFailure", WorkflowOnFailure.ABORT,
"inputs", Map.of(
"instanceId", "i-123")), Map.of(
"name", "CreateImage",
"action", WorkflowAction.CREATE_IMAGE,
"onFailure", WorkflowOnFailure.ABORT,
"inputs", Map.of(
"instanceId", "i-123")), Map.of(
"name", "TerminateInstance",
"action", WorkflowAction.TERMINATE_INSTANCE,
"onFailure", WorkflowOnFailure.CONTINUE,
"inputs", Map.of(
"instanceId", "i-123"))),
"outputs", List.of(Map.of(
"name", "ImageId",
"value", "$.stepOutputs.CreateImage.imageId")))))
.build();
S3 Workflow Data
For those workflows you want to upload or have uploaded to S3:
// Upload a local file
Workflow workflowFromAsset = Workflow.Builder.create(this, "AssetWorkflow")
.workflowType(WorkflowType.BUILD)
.data(WorkflowData.fromAsset(this, "WorkflowAsset", "./my-workflow.yml"))
.build();
// Reference an existing S3 object
IBucket bucket = Bucket.fromBucketName(this, "WorkflowBucket", "my-workflows-bucket");
Workflow workflowFromS3 = Workflow.Builder.create(this, "S3Workflow")
.workflowType(WorkflowType.BUILD)
.data(WorkflowData.fromS3(bucket, "workflows/my-workflow.yml"))
.build();
Encrypt workflow data with a KMS key
You can encrypt workflow data with a KMS key, so that only principals with access to decrypt with the key are able to access the workflow data.
Workflow workflow = Workflow.Builder.create(this, "EncryptedWorkflow")
.workflowType(WorkflowType.BUILD)
.kmsKey(new Key(this, "WorkflowKey"))
.data(WorkflowData.fromJsonObject(Map.of(
"schemaVersion", WorkflowSchemaVersion.V1_0,
"steps", List.of(Map.of(
"name", "LaunchBuildInstance",
"action", WorkflowAction.LAUNCH_INSTANCE,
"onFailure", WorkflowOnFailure.ABORT,
"inputs", Map.of(
"waitFor", "ssmAgent")), Map.of(
"name", "CreateImage",
"action", WorkflowAction.CREATE_IMAGE,
"onFailure", WorkflowOnFailure.ABORT,
"inputs", Map.of(
"instanceId", "i-123")), Map.of(
"name", "TerminateInstance",
"action", WorkflowAction.TERMINATE_INSTANCE,
"onFailure", WorkflowOnFailure.CONTINUE,
"inputs", Map.of(
"instanceId", "i-123"))),
"outputs", List.of(Map.of(
"name", "ImageId",
"value", "$.stepOutputs.CreateImage.imageId")))))
.build();
AWS-Managed Workflows
AWS provides a collection of workflows for common scenarios:
// Build workflows IWorkflow buildImageWorkflow = AmazonManagedWorkflow.buildImage(this, "BuildImage"); IWorkflow buildContainerWorkflow = AmazonManagedWorkflow.buildContainer(this, "BuildContainer"); // Test workflows IWorkflow testImageWorkflow = AmazonManagedWorkflow.testImage(this, "TestImage"); IWorkflow testContainerWorkflow = AmazonManagedWorkflow.testContainer(this, "TestContainer"); // Distribution workflows IWorkflow distributeContainerWorkflow = AmazonManagedWorkflow.distributeContainer(this, "DistributeContainer");
Lifecycle Policy
Lifecycle policies help you manage the retention and cleanup of Image Builder resources automatically. These policies define rules for deprecating or deleting old image versions, managing AMI snapshots, and controlling resource costs by removing unused images based on age, count, or other criteria.
Lifecycle Policy Basic Usage
Create a lifecycle policy to automatically delete old AMI images after 30 days:
LifecyclePolicy lifecyclePolicy = LifecyclePolicy.Builder.create(this, "MyLifecyclePolicy")
.resourceType(LifecyclePolicyResourceType.AMI_IMAGE)
.details(List.of(LifecyclePolicyDetail.builder()
.action(LifecyclePolicyAction.builder().type(LifecyclePolicyActionType.DELETE).build())
.filter(LifecyclePolicyFilter.builder().ageFilter(LifecyclePolicyAgeFilter.builder().age(Duration.days(30)).build()).build())
.build()))
.resourceSelection(LifecyclePolicyResourceSelection.builder()
.tags(Map.of("Environment", "development"))
.build())
.build();
Create a lifecycle policy to keep only the 10 most recent container images:
LifecyclePolicy containerLifecyclePolicy = LifecyclePolicy.Builder.create(this, "ContainerLifecyclePolicy")
.resourceType(LifecyclePolicyResourceType.CONTAINER_IMAGE)
.details(List.of(LifecyclePolicyDetail.builder()
.action(LifecyclePolicyAction.builder().type(LifecyclePolicyActionType.DELETE).build())
.filter(LifecyclePolicyFilter.builder().countFilter(LifecyclePolicyCountFilter.builder().count(10).build()).build())
.build()))
.resourceSelection(LifecyclePolicyResourceSelection.builder()
.tags(Map.of("Application", "web-app"))
.build())
.build();
Lifecycle Policy Resource Selection
Tag-Based Resource Selection
Apply lifecycle policies to images with specific tags:
LifecyclePolicy tagBasedPolicy = LifecyclePolicy.Builder.create(this, "TagBasedPolicy")
.resourceType(LifecyclePolicyResourceType.AMI_IMAGE)
.details(List.of(LifecyclePolicyDetail.builder()
.action(LifecyclePolicyAction.builder().type(LifecyclePolicyActionType.DELETE).build())
.filter(LifecyclePolicyFilter.builder().ageFilter(LifecyclePolicyAgeFilter.builder().age(Duration.days(90)).build()).build())
.build()))
.resourceSelection(LifecyclePolicyResourceSelection.builder()
.tags(Map.of(
"Environment", "staging",
"Team", "backend"))
.build())
.build();
Recipe-Based Resource Selection
Apply lifecycle policies to specific image or container recipes:
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "MyImageRecipe")
.baseImage(BaseImage.fromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"))
.build();
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "MyContainerRecipe")
.baseImage(BaseContainerImage.fromDockerHub("amazonlinux", "latest"))
.targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
.build();
LifecyclePolicy recipeBasedPolicy = LifecyclePolicy.Builder.create(this, "RecipeBasedPolicy")
.resourceType(LifecyclePolicyResourceType.AMI_IMAGE)
.details(List.of(LifecyclePolicyDetail.builder()
.action(LifecyclePolicyAction.builder().type(LifecyclePolicyActionType.DELETE).build())
.filter(LifecyclePolicyFilter.builder().countFilter(LifecyclePolicyCountFilter.builder().count(5).build()).build())
.build()))
.resourceSelection(LifecyclePolicyResourceSelection.builder()
.recipes(List.of(imageRecipe, containerRecipe))
.build())
.build();
Lifecycle Policy Rules
Age-Based Rules
Delete images older than a specific time period:
LifecyclePolicy ageBasedPolicy = LifecyclePolicy.Builder.create(this, "AgeBasedPolicy")
.resourceType(LifecyclePolicyResourceType.AMI_IMAGE)
.details(List.of(LifecyclePolicyDetail.builder()
.action(LifecyclePolicyAction.builder()
.type(LifecyclePolicyActionType.DELETE)
.includeAmis(true)
.includeSnapshots(true)
.build())
.filter(LifecyclePolicyFilter.builder()
.ageFilter(LifecyclePolicyAgeFilter.builder()
.age(Duration.days(60))
.retainAtLeast(3)
.build())
.build())
.build()))
.resourceSelection(LifecyclePolicyResourceSelection.builder()
.tags(Map.of("Environment", "testing"))
.build())
.build();
Count-Based Rules
Keep only a specific number of the most recent images:
LifecyclePolicy countBasedPolicy = LifecyclePolicy.Builder.create(this, "CountBasedPolicy")
.resourceType(LifecyclePolicyResourceType.CONTAINER_IMAGE)
.details(List.of(LifecyclePolicyDetail.builder()
.action(LifecyclePolicyAction.builder().type(LifecyclePolicyActionType.DELETE).build())
.filter(LifecyclePolicyFilter.builder().countFilter(LifecyclePolicyCountFilter.builder().count(15).build()).build())
.build()))
.resourceSelection(LifecyclePolicyResourceSelection.builder()
.tags(Map.of("Application", "microservice"))
.build())
.build();
Multiple Lifecycle Rules
Implement a graduated approach with multiple actions:
LifecyclePolicy graduatedPolicy = LifecyclePolicy.Builder.create(this, "GraduatedPolicy")
.resourceType(LifecyclePolicyResourceType.AMI_IMAGE)
.details(List.of(LifecyclePolicyDetail.builder()
// First: Deprecate images after 30 days
.action(LifecyclePolicyAction.builder()
.type(LifecyclePolicyActionType.DEPRECATE)
.includeAmis(true)
.build())
.filter(LifecyclePolicyFilter.builder()
.ageFilter(LifecyclePolicyAgeFilter.builder()
.age(Duration.days(30))
.retainAtLeast(5)
.build())
.build())
.build(), LifecyclePolicyDetail.builder()
// Second: Disable images after 60 days
.action(LifecyclePolicyAction.builder()
.type(LifecyclePolicyActionType.DISABLE)
.includeAmis(true)
.build())
.filter(LifecyclePolicyFilter.builder()
.ageFilter(LifecyclePolicyAgeFilter.builder()
.age(Duration.days(60))
.retainAtLeast(3)
.build())
.build())
.build(), LifecyclePolicyDetail.builder()
// Finally: Delete images after 90 days
.action(LifecyclePolicyAction.builder()
.type(LifecyclePolicyActionType.DELETE)
.includeAmis(true)
.includeSnapshots(true)
.build())
.filter(LifecyclePolicyFilter.builder()
.ageFilter(LifecyclePolicyAgeFilter.builder()
.age(Duration.days(90))
.retainAtLeast(1)
.build())
.build())
.build()))
.resourceSelection(LifecyclePolicyResourceSelection.builder()
.tags(Map.of("Environment", "production"))
.build())
.build();
Lifecycle Policy Exclusion Rules
AMI Exclusion Rules
Exclude specific AMIs from lifecycle actions based on various criteria:
LifecyclePolicy excludeAmisPolicy = LifecyclePolicy.Builder.create(this, "ExcludeAmisPolicy")
.resourceType(LifecyclePolicyResourceType.AMI_IMAGE)
.details(List.of(LifecyclePolicyDetail.builder()
.action(LifecyclePolicyAction.builder().type(LifecyclePolicyActionType.DELETE).build())
.filter(LifecyclePolicyFilter.builder().ageFilter(LifecyclePolicyAgeFilter.builder().age(Duration.days(30)).build()).build())
.exclusionRules(LifecyclePolicyExclusionRules.builder()
.amiExclusionRules(LifecyclePolicyAmiExclusionRules.builder()
.isPublic(true) // Exclude public AMIs
.lastLaunched(Duration.days(7)) // Exclude AMIs launched in last 7 days
.regions(List.of("us-west-2", "eu-west-1")) // Exclude AMIs in specific regions
.sharedAccounts(List.of("123456789012")) // Exclude AMIs shared with specific accounts
.tags(Map.of(
"Protected", "true",
"Environment", "production"))
.build())
.build())
.build()))
.resourceSelection(LifecyclePolicyResourceSelection.builder()
.tags(Map.of("Team", "infrastructure"))
.build())
.build();
Image Exclusion Rules
Exclude Image Builder images with protective tags:
LifecyclePolicy excludeImagesPolicy = LifecyclePolicy.Builder.create(this, "ExcludeImagesPolicy")
.resourceType(LifecyclePolicyResourceType.CONTAINER_IMAGE)
.details(List.of(LifecyclePolicyDetail.builder()
.action(LifecyclePolicyAction.builder().type(LifecyclePolicyActionType.DELETE).build())
.filter(LifecyclePolicyFilter.builder().countFilter(LifecyclePolicyCountFilter.builder().count(20).build()).build())
.exclusionRules(LifecyclePolicyExclusionRules.builder()
.imageExclusionRules(LifecyclePolicyImageExclusionRules.builder()
.tags(Map.of(
"DoNotDelete", "true",
"Critical", "baseline"))
.build())
.build())
.build()))
.resourceSelection(LifecyclePolicyResourceSelection.builder()
.tags(Map.of("Application", "frontend"))
.build())
.build();
Advanced Lifecycle Configuration
Custom Execution Roles
Provide your own IAM execution role with specific permissions:
Role executionRole = Role.Builder.create(this, "LifecycleExecutionRole")
.assumedBy(new ServicePrincipal("imagebuilder.amazonaws.com"))
.managedPolicies(List.of(ManagedPolicy.fromAwsManagedPolicyName("service-role/EC2ImageBuilderLifecycleExecutionPolicy")))
.build();
LifecyclePolicy customRolePolicy = LifecyclePolicy.Builder.create(this, "CustomRolePolicy")
.resourceType(LifecyclePolicyResourceType.AMI_IMAGE)
.executionRole(executionRole)
.details(List.of(LifecyclePolicyDetail.builder()
.action(LifecyclePolicyAction.builder().type(LifecyclePolicyActionType.DELETE).build())
.filter(LifecyclePolicyFilter.builder().ageFilter(LifecyclePolicyAgeFilter.builder().age(Duration.days(45)).build()).build())
.build()))
.resourceSelection(LifecyclePolicyResourceSelection.builder()
.tags(Map.of("Environment", "development"))
.build())
.build();
Lifecycle Policy Status
Control whether the lifecycle policy is active:
LifecyclePolicy disabledPolicy = LifecyclePolicy.Builder.create(this, "DisabledPolicy")
.lifecyclePolicyName("my-disabled-policy")
.description("A lifecycle policy that is temporarily disabled")
.status(LifecyclePolicyStatus.DISABLED)
.resourceType(LifecyclePolicyResourceType.AMI_IMAGE)
.details(List.of(LifecyclePolicyDetail.builder()
.action(LifecyclePolicyAction.builder().type(LifecyclePolicyActionType.DELETE).build())
.filter(LifecyclePolicyFilter.builder().ageFilter(LifecyclePolicyAgeFilter.builder().age(Duration.days(30)).build()).build())
.build()))
.resourceSelection(LifecyclePolicyResourceSelection.builder()
.tags(Map.of("Environment", "testing"))
.build())
.tags(Map.of(
"Owner", "DevOps",
"CostCenter", "Engineering"))
.build();
Importing Lifecycle Policies
Reference lifecycle policies created outside CDK:
// Import by name ILifecyclePolicy importedByName = LifecyclePolicy.fromLifecyclePolicyName(this, "ImportedByName", "existing-lifecycle-policy"); // Import by ARN ILifecyclePolicy importedByArn = LifecyclePolicy.fromLifecyclePolicyArn(this, "ImportedByArn", "arn:aws:imagebuilder:us-east-1:123456789012:lifecycle-policy/my-policy"); importedByName.grantRead(lambdaRole); importedByArn.grant(lambdaRole, "imagebuilder:UpdateLifecyclePolicy");
-
ClassDescription(experimental) Helper class for working with Amazon-managed components.(experimental) Properties for an EC2 Image Builder Amazon-managed component.A builder for
AmazonManagedComponentAttributesAn implementation forAmazonManagedComponentAttributes(experimental) Options for selecting a predefined Amazon-managed image.A builder forAmazonManagedComponentOptionsAn implementation forAmazonManagedComponentOptions(experimental) Helper class for working with Amazon-managed images.(experimental) Attributes for importing an Amazon-managed image by name (and optionally a version).A builder forAmazonManagedImageAttributesAn implementation forAmazonManagedImageAttributes(experimental) Options for selecting a predefined Amazon-managed image.A builder forAmazonManagedImageOptionsAn implementation forAmazonManagedImageOptions(experimental) Helper class for working with Amazon-managed workflows.(experimental) Properties for an EC2 Image Builder Amazon-managed workflow.A builder forAmazonManagedWorkflowAttributesAn implementation forAmazonManagedWorkflowAttributes(experimental) The regional distribution settings to use for an AMI build.A builder forAmiDistributionAn implementation forAmiDistribution(experimental) The launch permissions for the AMI, defining which principals are allowed to access the AMI.A builder forAmiLaunchPermissionAn implementation forAmiLaunchPermission(experimental) Helper class for working with AWS Marketplace components.(experimental) Properties for an EC2 Image Builder AWS Marketplace component.A builder forAwsMarketplaceComponentAttributesAn implementation forAwsMarketplaceComponentAttributes(experimental) Represents a base image that is used to start from in EC2 Image Builder image builds.(experimental) Represents a base image that is used to start from in EC2 Image Builder image builds.(experimental) Represents an EC2 Image Builder Component.(experimental) A fluent builder forComponent.(experimental) The action for a step within the component document.(experimental) Properties for an EC2 Image Builder component.A builder forComponentAttributesAn implementation forComponentAttributes(experimental) Configuration details for a component, to include in a recipe.A builder forComponentConfigurationAn implementation forComponentConfiguration(experimental) The value of a constant in a component document.(experimental) Helper class for referencing and uploading component data.(experimental) The rendered component data value, for use in CloudFormation.A builder forComponentDataConfigAn implementation forComponentDataConfig(experimental) Properties of an EC2 Image Builder Component Document.A builder forComponentDocumentAn implementation forComponentDocument(experimental) The for loop iterates on a range of integers specified within a boundary outlined by the start and end of the variables.A builder forComponentDocumentForLoopAn implementation forComponentDocumentForLoop(experimental) The looping construct of a component defines a repeated sequence of instructions.A builder forComponentDocumentLoopAn implementation forComponentDocumentLoop(experimental) The definition of the parameter.A builder forComponentDocumentParameterDefinitionAn implementation forComponentDocumentParameterDefinition(experimental) The phase to run in a specific workflow in an image build, which define the steps to execute to customize or test the instance.A builder forComponentDocumentPhaseAn implementation forComponentDocumentPhase(experimental) The step to run in a specific phase of the image build, which defines the step to execute to customize or test the instance.A builder forComponentDocumentStepAn implementation forComponentDocumentStep(experimental) Specifies what the step should do in case of failure.(experimental) The parameter type in a component document.(experimental) The parameter value for a component parameter.(experimental) The phases of a component document.(experimental) Properties for creating a Component resource.A builder forComponentPropsAn implementation forComponentProps(experimental) The schema version of the component.(experimental) Represents anifcondition in the component document.(experimental) Represents the inputs for a step in the component document.(experimental) The regional distribution settings to use for a container build.A builder forContainerDistributionAn implementation forContainerDistribution(experimental) Represents a container instance image that is used to launch the instance used for building the container for an EC2 Image Builder container build.(experimental) Represents an EC2 Image Builder Container Recipe.(experimental) A fluent builder forContainerRecipe.(experimental) Properties for an EC2 Image Builder container recipe.A builder forContainerRecipeAttributesAn implementation forContainerRecipeAttributes(experimental) A new or imported Container Recipe.(experimental) Properties for creating a Container Recipe resource.A builder forContainerRecipePropsAn implementation forContainerRecipeProps(experimental) The type of the container being used in the container recipe.(experimental) Represents an EC2 Image Builder Distribution Configuration.(experimental) A fluent builder forDistributionConfiguration.(experimental) Properties for creating a Distribution Configuration resource.A builder forDistributionConfigurationPropsAn implementation forDistributionConfigurationProps(experimental) Helper class for referencing and uploading dockerfile data for the container recipe.(experimental) The rendered Dockerfile value, for use in CloudFormation.A builder forDockerfileTemplateConfigAn implementation forDockerfileTemplateConfig(experimental) The EC2 Fast Launch configuration to use for the Windows AMI.A builder forFastLaunchConfigurationAn implementation forFastLaunchConfiguration(experimental) Indicates whether a signed token header is required for instance metadata retrieval requests.(experimental) An EC2 Image Builder Component.Internal default implementation forIComponent.A proxy class which represents a concrete javascript instance of this type.(experimental) An EC2 Image Builder Container Recipe.Internal default implementation forIContainerRecipe.A proxy class which represents a concrete javascript instance of this type.(experimental) An EC2 Image Builder Distribution Configuration.Internal default implementation forIDistributionConfiguration.A proxy class which represents a concrete javascript instance of this type.(experimental) An EC2 Image Builder Image.Internal default implementation forIImage.A proxy class which represents a concrete javascript instance of this type.(experimental) An EC2 Image Builder Image Pipeline.Internal default implementation forIImagePipeline.A proxy class which represents a concrete javascript instance of this type.(experimental) An EC2 Image Builder Image Recipe.Internal default implementation forIImageRecipe.A proxy class which represents a concrete javascript instance of this type.(experimental) An EC2 Image Builder Infrastructure Configuration.Internal default implementation forIInfrastructureConfiguration.A proxy class which represents a concrete javascript instance of this type.(experimental) An EC2 Image Builder Lifecycle Policy.Internal default implementation forILifecyclePolicy.A proxy class which represents a concrete javascript instance of this type.(experimental) Represents an EC2 Image Builder Image.(experimental) A fluent builder forImage.(experimental) The architecture of the image.(experimental) Properties for an EC2 Image Builder image.A builder forImageAttributesAn implementation forImageAttributes(experimental) Represents an EC2 Image Builder Image Pipeline.(experimental) A fluent builder forImagePipeline.(experimental) Properties for creating an Image Pipeline resource.A builder forImagePipelinePropsAn implementation forImagePipelineProps(experimental) The schedule settings for the image pipeline, which defines when a pipeline should be triggered.A builder forImagePipelineScheduleAn implementation forImagePipelineSchedule(experimental) Indicates whether the pipeline is enabled to be triggered by the provided schedule.(experimental) Properties for creating an Image resource.A builder forImagePropsAn implementation forImageProps(experimental) Represents an EC2 Image Builder Image Recipe.(experimental) A fluent builder forImageRecipe.(experimental) Properties for an EC2 Image Builder image recipe.A builder forImageRecipeAttributesAn implementation forImageRecipeAttributes(experimental) Properties for creating an Image Recipe resource.A builder forImageRecipePropsAn implementation forImageRecipeProps(experimental) The type of the image.(experimental) Represents an EC2 Image Builder Infrastructure Configuration.(experimental) A fluent builder forInfrastructureConfiguration.(experimental) The log settings for detailed build logging.A builder forInfrastructureConfigurationLoggingAn implementation forInfrastructureConfigurationLogging(experimental) Properties for creating an Infrastructure Configuration resource.A builder forInfrastructureConfigurationPropsAn implementation forInfrastructureConfigurationProps(experimental) A base interface for EC2 Image Builder recipes.Internal default implementation forIRecipeBase.A proxy class which represents a concrete javascript instance of this type.(experimental) An EC2 Image Builder Workflow.Internal default implementation forIWorkflow.A proxy class which represents a concrete javascript instance of this type.(experimental) The launch template to apply the distributed AMI to.A builder forLaunchTemplateConfigurationAn implementation forLaunchTemplateConfiguration(experimental) Represents an EC2 Image Builder Lifecycle Policy.(experimental) A fluent builder forLifecyclePolicy.(experimental) The action to perform in the lifecycle policy rule.A builder forLifecyclePolicyActionAn implementation forLifecyclePolicyAction(experimental) The action to perform on the resources which the policy applies to.(experimental) The age-based filtering to apply in a lifecycle policy rule.A builder forLifecyclePolicyAgeFilterAn implementation forLifecyclePolicyAgeFilter(experimental) The rules to apply for excluding AMIs from the lifecycle policy rule.A builder forLifecyclePolicyAmiExclusionRulesAn implementation forLifecyclePolicyAmiExclusionRules(experimental) The count-based filtering to apply in a lifecycle policy rule.A builder forLifecyclePolicyCountFilterAn implementation forLifecyclePolicyCountFilter(experimental) Configuration details for the lifecycle policy rules.A builder forLifecyclePolicyDetailAn implementation forLifecyclePolicyDetail(experimental) The rules to apply for excluding resources from the lifecycle policy rule.A builder forLifecyclePolicyExclusionRulesAn implementation forLifecyclePolicyExclusionRules(experimental) The resource filtering to apply in the lifecycle policy rule.A builder forLifecyclePolicyFilterAn implementation forLifecyclePolicyFilter(experimental) The rules to apply for excluding EC2 Image Builder images from the lifecycle policy rule.A builder forLifecyclePolicyImageExclusionRulesAn implementation forLifecyclePolicyImageExclusionRules(experimental) Properties for creating a Lifecycle Policy resource.A builder forLifecyclePolicyPropsAn implementation forLifecyclePolicyProps(experimental) Selection criteria for the resources that the lifecycle policy applies to.A builder forLifecyclePolicyResourceSelectionAn implementation forLifecyclePolicyResourceSelection(experimental) The resource type which the lifecycle policy is applied to.(experimental) The status of the lifecycle policy, indicating whether it will run.(experimental) Represents an OS version for an EC2 Image Builder image.(experimental) Represents a platform for an EC2 Image Builder image.(experimental) A container repository used to distribute container images in EC2 Image Builder.(experimental) The service in which a container should be registered.(experimental) Helper class for S3-based component data references, containing additional permission grant methods on the S3 object.(experimental) Helper class for S3-based dockerfile data references, containing additional permission grant methods on the S3 object.(experimental) Helper class for S3-based workflow data references, containing additional permission grant methods on the S3 object.(experimental) The start condition for the pipeline, indicating the condition under which a pipeline should be triggered.(experimental) The SSM parameters to create or update for the distributed AMIs.A builder forSSMParameterConfigurationsAn implementation forSSMParameterConfigurations(experimental) The tenancy to use for an instance.(experimental) Represents an EC2 Image Builder Workflow.(experimental) A fluent builder forWorkflow.(experimental) The action for a step within the workflow document.(experimental) Properties for an EC2 Image Builder Workflow.A builder forWorkflowAttributesAn implementation forWorkflowAttributes(experimental) Configuration details for a workflow.A builder forWorkflowConfigurationAn implementation forWorkflowConfiguration(experimental) Helper class for referencing and uploading workflow data.(experimental) The rendered workflow data value, for use in CloudFormation.A builder forWorkflowDataConfigAn implementation forWorkflowDataConfig(experimental) The action to take if the workflow fails.(experimental) The parameter type for the workflow parameter.(experimental) The parameter value for a workflow parameter.(experimental) Properties for creating a Workflow resource.A builder forWorkflowPropsAn implementation forWorkflowProps(experimental) The schema version of the workflow.(experimental) The type of the workflow.