Skip to content
v2.274.0

EC2 Image Builder Construct Library ​

Version 2.274.0-alpha.0

Separate package

@aws-cdk/aws-imagebuilder-alpha is not part of aws-cdk-lib — install it separately:

sh
npm install @aws-cdk/aws-imagebuilder-alpha
pip install aws-cdk.aws-imagebuilder-alpha

This module is experimental (alpha): its API may change in any release, without a major version bump.


cdk-constructs: Experimental

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:

ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'MyImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromSsmParameterName(
    '/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
  )
});

const imagePipeline = new imagebuilder.ImagePipeline(this, 'MyImagePipeline', {
  recipe: exampleImageRecipe
});
python
image_recipe = imagebuilder.ImageRecipe(self, "MyImageRecipe",
    base_image=imagebuilder.BaseImage.from_ssm_parameter_name("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")
)

image_pipeline = imagebuilder.ImagePipeline(self, "MyImagePipeline",
    recipe=example_image_recipe
)
java
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();
csharp
var imageRecipe = new ImageRecipe(this, "MyImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")
});

var imagePipeline = new ImagePipeline(this, "MyImagePipeline", new ImagePipelineProps {
    Recipe = exampleImageRecipe
});
go
imageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("MyImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_*FromSsmParameterName(jsii.String("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")),
})

imagePipeline := imagebuilder.NewImagePipeline(this, jsii.String("MyImagePipeline"), &ImagePipelineProps{
	Recipe: exampleImageRecipe,
})

Create a simple container pipeline with just a container recipe:

ts
const containerRecipe = new imagebuilder.ContainerRecipe(this, 'MyContainerRecipe', {
  baseImage: imagebuilder.BaseContainerImage.fromDockerHub('amazonlinux', 'latest'),
  targetRepository: imagebuilder.Repository.fromEcr(
    ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
  )
});

const containerPipeline = new imagebuilder.ImagePipeline(this, 'MyContainerPipeline', {
  recipe: exampleContainerRecipe
});
python
container_recipe = imagebuilder.ContainerRecipe(self, "MyContainerRecipe",
    base_image=imagebuilder.BaseContainerImage.from_docker_hub("amazonlinux", "latest"),
    target_repository=imagebuilder.Repository.from_ecr(
        ecr.Repository.from_repository_name(self, "Repository", "my-container-repo"))
)

container_pipeline = imagebuilder.ImagePipeline(self, "MyContainerPipeline",
    recipe=example_container_recipe
)
java
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();
csharp
var containerRecipe = new ContainerRecipe(this, "MyContainerRecipe", new ContainerRecipeProps {
    BaseImage = BaseContainerImage.FromDockerHub("amazonlinux", "latest"),
    TargetRepository = Repository.FromEcr(Repository.FromRepositoryName(this, "Repository", "my-container-repo"))
});

var containerPipeline = new ImagePipeline(this, "MyContainerPipeline", new ImagePipelineProps {
    Recipe = exampleContainerRecipe
});
go
containerRecipe := imagebuilder.NewContainerRecipe(this, jsii.String("MyContainerRecipe"), &ContainerRecipeProps{
	BaseImage: imagebuilder.BaseContainerImage_*FromDockerHub(jsii.String("amazonlinux"), jsii.String("latest")),
	TargetRepository: imagebuilder.Repository_*FromEcr(ecr.Repository_*FromRepositoryName(this, jsii.String("Repository"), jsii.String("my-container-repo"))),
})

containerPipeline := imagebuilder.NewImagePipeline(this, jsii.String("MyContainerPipeline"), &ImagePipelineProps{
	Recipe: exampleContainerRecipe,
})

Image Pipeline Scheduling ​

Manual Pipeline Execution ​

Create a pipeline that runs only when manually triggered:

ts
const manualPipeline = new imagebuilder.ImagePipeline(this, 'ManualPipeline', {
  imagePipelineName: 'my-manual-pipeline',
  description: 'Pipeline triggered manually for production builds',
  recipe: exampleImageRecipe
  // No schedule property - manual execution only
});

// Grant Lambda function permission to trigger the pipeline
manualPipeline.grantStartExecution(lambdaRole);
python
manual_pipeline = imagebuilder.ImagePipeline(self, "ManualPipeline",
    image_pipeline_name="my-manual-pipeline",
    description="Pipeline triggered manually for production builds",
    recipe=example_image_recipe
)

# Grant Lambda function permission to trigger the pipeline
manual_pipeline.grant_start_execution(lambda_role)
java
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);
csharp
var manualPipeline = new ImagePipeline(this, "ManualPipeline", new ImagePipelineProps {
    ImagePipelineName = "my-manual-pipeline",
    Description = "Pipeline triggered manually for production builds",
    Recipe = exampleImageRecipe
});

// Grant Lambda function permission to trigger the pipeline
manualPipeline.GrantStartExecution(lambdaRole);
go
manualPipeline := imagebuilder.NewImagePipeline(this, jsii.String("ManualPipeline"), &ImagePipelineProps{
	ImagePipelineName: jsii.String("my-manual-pipeline"),
	Description: jsii.String("Pipeline triggered manually for production builds"),
	Recipe: exampleImageRecipe,
})

// Grant Lambda function permission to trigger the pipeline
manualPipeline.grantStartExecution(lambdaRole)
Automated Pipeline Scheduling ​

Schedule a pipeline to run automatically using cron expressions:

ts
const weeklyPipeline = new imagebuilder.ImagePipeline(this, 'WeeklyPipeline', {
  imagePipelineName: 'weekly-build-pipeline',
  recipe: exampleImageRecipe,
  schedule: {
    expression: events.Schedule.cron({
      minute: '0',
      hour: '6',
      weekDay: 'MON'
    })
  }
});
python
weekly_pipeline = imagebuilder.ImagePipeline(self, "WeeklyPipeline",
    image_pipeline_name="weekly-build-pipeline",
    recipe=example_image_recipe,
    schedule=imagebuilder.ImagePipelineSchedule(
        expression=events.Schedule.cron(
            minute="0",
            hour="6",
            week_day="MON"
        )
    )
)
java
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();
csharp
var weeklyPipeline = new ImagePipeline(this, "WeeklyPipeline", new ImagePipelineProps {
    ImagePipelineName = "weekly-build-pipeline",
    Recipe = exampleImageRecipe,
    Schedule = new ImagePipelineSchedule {
        Expression = Schedule.Cron(new CronOptions {
            Minute = "0",
            Hour = "6",
            WeekDay = "MON"
        })
    }
});
go
weeklyPipeline := imagebuilder.NewImagePipeline(this, jsii.String("WeeklyPipeline"), &ImagePipelineProps{
	ImagePipelineName: jsii.String("weekly-build-pipeline"),
	Recipe: exampleImageRecipe,
	Schedule: &ImagePipelineSchedule{
		Expression: events.Schedule_Cron(&CronOptions{
			Minute: jsii.String("0"),
			Hour: jsii.String("6"),
			WeekDay: jsii.String("MON"),
		}),
	},
})

Use rate expressions for regular intervals:

ts
const dailyPipeline = new imagebuilder.ImagePipeline(this, 'DailyPipeline', {
  recipe: exampleContainerRecipe,
  schedule: {
    expression: events.Schedule.rate(Duration.days(1))
  }
});
python
daily_pipeline = imagebuilder.ImagePipeline(self, "DailyPipeline",
    recipe=example_container_recipe,
    schedule=imagebuilder.ImagePipelineSchedule(
        expression=events.Schedule.rate(Duration.days(1))
    )
)
java
ImagePipeline dailyPipeline = ImagePipeline.Builder.create(this, "DailyPipeline")
        .recipe(exampleContainerRecipe)
        .schedule(ImagePipelineSchedule.builder()
                .expression(Schedule.rate(Duration.days(1)))
                .build())
        .build();
csharp
var dailyPipeline = new ImagePipeline(this, "DailyPipeline", new ImagePipelineProps {
    Recipe = exampleContainerRecipe,
    Schedule = new ImagePipelineSchedule {
        Expression = Schedule.Rate(Duration.Days(1))
    }
});
go
dailyPipeline := imagebuilder.NewImagePipeline(this, jsii.String("DailyPipeline"), &ImagePipelineProps{
	Recipe: exampleContainerRecipe,
	Schedule: &ImagePipelineSchedule{
		Expression: events.Schedule_Rate(awscdk.Duration_Days(jsii.Number(1))),
	},
})
Pipeline Schedule Configuration ​

Configure advanced scheduling options:

ts
const advancedSchedulePipeline = new imagebuilder.ImagePipeline(this, 'AdvancedSchedulePipeline', {
  recipe: exampleImageRecipe,
  schedule: {
    expression: events.Schedule.rate(Duration.days(7)),
    // Only trigger when dependencies are updated (new base images, components, etc.)
    startCondition: imagebuilder.ScheduleStartCondition.EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE,
    // Automatically disable after 3 consecutive failures
    autoDisableFailureCount: 3
  },
  // Start enabled
  status: imagebuilder.ImagePipelineStatus.ENABLED
});
python
advanced_schedule_pipeline = imagebuilder.ImagePipeline(self, "AdvancedSchedulePipeline",
    recipe=example_image_recipe,
    schedule=imagebuilder.ImagePipelineSchedule(
        expression=events.Schedule.rate(Duration.days(7)),
        # Only trigger when dependencies are updated (new base images, components, etc.)
        start_condition=imagebuilder.ScheduleStartCondition.EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE,
        # Automatically disable after 3 consecutive failures
        auto_disable_failure_count=3
    ),
    # Start enabled
    status=imagebuilder.ImagePipelineStatus.ENABLED
)
java
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();
csharp
var advancedSchedulePipeline = new ImagePipeline(this, "AdvancedSchedulePipeline", new ImagePipelineProps {
    Recipe = exampleImageRecipe,
    Schedule = new ImagePipelineSchedule {
        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
    },
    // Start enabled
    Status = ImagePipelineStatus.ENABLED
});
go
advancedSchedulePipeline := imagebuilder.NewImagePipeline(this, jsii.String("AdvancedSchedulePipeline"), &ImagePipelineProps{
	Recipe: exampleImageRecipe,
	Schedule: &ImagePipelineSchedule{
		Expression: events.Schedule_Rate(awscdk.Duration_Days(jsii.Number(7))),
		// Only trigger when dependencies are updated (new base images, components, etc.)
		StartCondition: imagebuilder.ScheduleStartCondition_EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE,
		// Automatically disable after 3 consecutive failures
		AutoDisableFailureCount: jsii.Number(3),
	},
	// Start enabled
	Status: imagebuilder.ImagePipelineStatus_ENABLED,
})

Image Pipeline Configuration ​

Infrastructure and Distribution in Image Pipelines ​

Configure custom infrastructure and distribution settings:

ts
const infrastructureConfiguration = new imagebuilder.InfrastructureConfiguration(this, 'Infrastructure', {
  infrastructureConfigurationName: 'production-infrastructure',
  instanceTypes: [
    ec2.InstanceType.of(ec2.InstanceClass.COMPUTE7_INTEL, ec2.InstanceSize.LARGE)
  ],
  vpc: vpc,
  subnetSelection: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }
});

const distributionConfiguration = new imagebuilder.DistributionConfiguration(this, 'Distribution');
distributionConfiguration.addAmiDistributions({
  amiName: 'production-ami-{{ imagebuilder:buildDate }}',
  amiTargetAccountIds: ['123456789012', '098765432109']
});

const productionPipeline = new imagebuilder.ImagePipeline(this, 'ProductionPipeline', {
  recipe: exampleImageRecipe,
  infrastructureConfiguration: infrastructureConfiguration,
  distributionConfiguration: distributionConfiguration
});
python
infrastructure_configuration = imagebuilder.InfrastructureConfiguration(self, "Infrastructure",
    infrastructure_configuration_name="production-infrastructure",
    instance_types=[
        ec2.InstanceType.of(ec2.InstanceClass.COMPUTE7_INTEL, ec2.InstanceSize.LARGE)
    ],
    vpc=vpc,
    subnet_selection=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS)
)

distribution_configuration = imagebuilder.DistributionConfiguration(self, "Distribution")
distribution_configuration.add_ami_distributions(
    ami_name="production-ami-{{ imagebuilder:buildDate }}",
    ami_target_account_ids=["123456789012", "098765432109"]
)

production_pipeline = imagebuilder.ImagePipeline(self, "ProductionPipeline",
    recipe=example_image_recipe,
    infrastructure_configuration=infrastructure_configuration,
    distribution_configuration=distribution_configuration
)
java
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();
csharp
var infrastructureConfiguration = new InfrastructureConfiguration(this, "Infrastructure", new InfrastructureConfigurationProps {
    InfrastructureConfigurationName = "production-infrastructure",
    InstanceTypes = new [] { InstanceType.Of(InstanceClass.COMPUTE7_INTEL, InstanceSize.LARGE) },
    Vpc = vpc,
    SubnetSelection = new SubnetSelection { SubnetType = SubnetType.PRIVATE_WITH_EGRESS }
});

var distributionConfiguration = new DistributionConfiguration(this, "Distribution");
distributionConfiguration.AddAmiDistributions(new AmiDistribution {
    AmiName = "production-ami-{{ imagebuilder:buildDate }}",
    AmiTargetAccountIds = new [] { "123456789012", "098765432109" }
});

var productionPipeline = new ImagePipeline(this, "ProductionPipeline", new ImagePipelineProps {
    Recipe = exampleImageRecipe,
    InfrastructureConfiguration = infrastructureConfiguration,
    DistributionConfiguration = distributionConfiguration
});
go
infrastructureConfiguration := imagebuilder.NewInfrastructureConfiguration(this, jsii.String("Infrastructure"), &InfrastructureConfigurationProps{
	InfrastructureConfigurationName: jsii.String("production-infrastructure"),
	InstanceTypes: []InstanceType{
		ec2.InstanceType_*Of(ec2.InstanceClass_COMPUTE7_INTEL, ec2.InstanceSize_LARGE),
	},
	Vpc: vpc,
	SubnetSelection: &SubnetSelection{
		SubnetType: ec2.SubnetType_PRIVATE_WITH_EGRESS,
	},
})

distributionConfiguration := imagebuilder.NewDistributionConfiguration(this, jsii.String("Distribution"))
distributionConfiguration.AddAmiDistributions(&AmiDistribution{
	AmiName: jsii.String("production-ami-{{ imagebuilder:buildDate }}"),
	AmiTargetAccountIds: []*string{
		jsii.String("123456789012"),
		jsii.String("098765432109"),
	},
})

productionPipeline := imagebuilder.NewImagePipeline(this, jsii.String("ProductionPipeline"), &ImagePipelineProps{
	Recipe: exampleImageRecipe,
	InfrastructureConfiguration: infrastructureConfiguration,
	DistributionConfiguration: distributionConfiguration,
})
Pipeline Logging Configuration ​

Configure custom CloudWatch log groups for pipeline and image logs:

ts
const pipelineLogGroup = new logs.LogGroup(this, 'PipelineLogGroup', {
  logGroupName: '/custom/imagebuilder/pipeline/logs',
  retention: logs.RetentionDays.ONE_MONTH
});

const imageLogGroup = new logs.LogGroup(this, 'ImageLogGroup', {
  logGroupName: '/custom/imagebuilder/image/logs',
  retention: logs.RetentionDays.ONE_WEEK
});

const loggedPipeline = new imagebuilder.ImagePipeline(this, 'LoggedPipeline', {
  recipe: exampleImageRecipe,
  imagePipelineLogGroup: pipelineLogGroup,
  imageLogGroup: imageLogGroup
});
python
pipeline_log_group = logs.LogGroup(self, "PipelineLogGroup",
    log_group_name="/custom/imagebuilder/pipeline/logs",
    retention=logs.RetentionDays.ONE_MONTH
)

image_log_group = logs.LogGroup(self, "ImageLogGroup",
    log_group_name="/custom/imagebuilder/image/logs",
    retention=logs.RetentionDays.ONE_WEEK
)

logged_pipeline = imagebuilder.ImagePipeline(self, "LoggedPipeline",
    recipe=example_image_recipe,
    image_pipeline_log_group=pipeline_log_group,
    image_log_group=image_log_group
)
java
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();
csharp
var pipelineLogGroup = new LogGroup(this, "PipelineLogGroup", new LogGroupProps {
    LogGroupName = "/custom/imagebuilder/pipeline/logs",
    Retention = RetentionDays.ONE_MONTH
});

var imageLogGroup = new LogGroup(this, "ImageLogGroup", new LogGroupProps {
    LogGroupName = "/custom/imagebuilder/image/logs",
    Retention = RetentionDays.ONE_WEEK
});

var loggedPipeline = new ImagePipeline(this, "LoggedPipeline", new ImagePipelineProps {
    Recipe = exampleImageRecipe,
    ImagePipelineLogGroup = pipelineLogGroup,
    ImageLogGroup = imageLogGroup
});
go
pipelineLogGroup := logs.NewLogGroup(this, jsii.String("PipelineLogGroup"), &LogGroupProps{
	LogGroupName: jsii.String("/custom/imagebuilder/pipeline/logs"),
	Retention: logs.RetentionDays_ONE_MONTH,
})

imageLogGroup := logs.NewLogGroup(this, jsii.String("ImageLogGroup"), &LogGroupProps{
	LogGroupName: jsii.String("/custom/imagebuilder/image/logs"),
	Retention: logs.RetentionDays_ONE_WEEK,
})

loggedPipeline := imagebuilder.NewImagePipeline(this, jsii.String("LoggedPipeline"), &ImagePipelineProps{
	Recipe: exampleImageRecipe,
	ImagePipelineLogGroup: pipelineLogGroup,
	ImageLogGroup: imageLogGroup,
})
Workflow Integration in Image Pipelines ​

Use AWS-managed workflows for common pipeline phases:

ts
const workflowPipeline = new imagebuilder.ImagePipeline(this, 'WorkflowPipeline', {
  recipe: exampleImageRecipe,
  workflows: [
    { workflow: imagebuilder.AmazonManagedWorkflow.buildImage(this, 'BuildWorkflow') },
    { workflow: imagebuilder.AmazonManagedWorkflow.testImage(this, 'TestWorkflow') }
  ]
});
python
workflow_pipeline = imagebuilder.ImagePipeline(self, "WorkflowPipeline",
    recipe=example_image_recipe,
    workflows=[imagebuilder.WorkflowConfiguration(workflow=imagebuilder.AmazonManagedWorkflow.build_image(self, "BuildWorkflow")), imagebuilder.WorkflowConfiguration(workflow=imagebuilder.AmazonManagedWorkflow.test_image(self, "TestWorkflow"))
    ]
)
java
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();
csharp
var workflowPipeline = new ImagePipeline(this, "WorkflowPipeline", new ImagePipelineProps {
    Recipe = exampleImageRecipe,
    Workflows = new [] { new WorkflowConfiguration { Workflow = AmazonManagedWorkflow.BuildImage(this, "BuildWorkflow") }, new WorkflowConfiguration { Workflow = AmazonManagedWorkflow.TestImage(this, "TestWorkflow") } }
});
go
workflowPipeline := imagebuilder.NewImagePipeline(this, jsii.String("WorkflowPipeline"), &ImagePipelineProps{
	Recipe: exampleImageRecipe,
	Workflows: []WorkflowConfiguration{
		&WorkflowConfiguration{
			Workflow: imagebuilder.AmazonManagedWorkflow_BuildImage(this, jsii.String("BuildWorkflow")),
		},
		&WorkflowConfiguration{
			Workflow: imagebuilder.AmazonManagedWorkflow_TestImage(this, jsii.String("TestWorkflow")),
		},
	},
})

For container pipelines, use container-specific workflows:

ts
const containerWorkflowPipeline = new imagebuilder.ImagePipeline(this, 'ContainerWorkflowPipeline', {
  recipe: exampleContainerRecipe,
  workflows: [
    { workflow: imagebuilder.AmazonManagedWorkflow.buildContainer(this, 'BuildContainer') },
    { workflow: imagebuilder.AmazonManagedWorkflow.testContainer(this, 'TestContainer') },
    { workflow: imagebuilder.AmazonManagedWorkflow.distributeContainer(this, 'DistributeContainer') }
  ]
});
python
container_workflow_pipeline = imagebuilder.ImagePipeline(self, "ContainerWorkflowPipeline",
    recipe=example_container_recipe,
    workflows=[imagebuilder.WorkflowConfiguration(workflow=imagebuilder.AmazonManagedWorkflow.build_container(self, "BuildContainer")), imagebuilder.WorkflowConfiguration(workflow=imagebuilder.AmazonManagedWorkflow.test_container(self, "TestContainer")), imagebuilder.WorkflowConfiguration(workflow=imagebuilder.AmazonManagedWorkflow.distribute_container(self, "DistributeContainer"))
    ]
)
java
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();
csharp
var containerWorkflowPipeline = new ImagePipeline(this, "ContainerWorkflowPipeline", new ImagePipelineProps {
    Recipe = exampleContainerRecipe,
    Workflows = new [] { new WorkflowConfiguration { Workflow = AmazonManagedWorkflow.BuildContainer(this, "BuildContainer") }, new WorkflowConfiguration { Workflow = AmazonManagedWorkflow.TestContainer(this, "TestContainer") }, new WorkflowConfiguration { Workflow = AmazonManagedWorkflow.DistributeContainer(this, "DistributeContainer") } }
});
go
containerWorkflowPipeline := imagebuilder.NewImagePipeline(this, jsii.String("ContainerWorkflowPipeline"), &ImagePipelineProps{
	Recipe: exampleContainerRecipe,
	Workflows: []WorkflowConfiguration{
		&WorkflowConfiguration{
			Workflow: imagebuilder.AmazonManagedWorkflow_BuildContainer(this, jsii.String("BuildContainer")),
		},
		&WorkflowConfiguration{
			Workflow: imagebuilder.AmazonManagedWorkflow_TestContainer(this, jsii.String("TestContainer")),
		},
		&WorkflowConfiguration{
			Workflow: imagebuilder.AmazonManagedWorkflow_DistributeContainer(this, jsii.String("DistributeContainer")),
		},
	},
})
Advanced Features in Image Pipelines ​

Configure image scanning for container pipelines:

ts
const scanningRepository = new ecr.Repository(this, 'ScanningRepo');

const scannedContainerPipeline = new imagebuilder.ImagePipeline(this, 'ScannedContainerPipeline', {
  recipe: exampleContainerRecipe,
  imageScanningEnabled: true,
  imageScanningEcrRepository: scanningRepository,
  imageScanningEcrTags: ['security-scan', 'latest']
});
python
scanning_repository = ecr.Repository(self, "ScanningRepo")

scanned_container_pipeline = imagebuilder.ImagePipeline(self, "ScannedContainerPipeline",
    recipe=example_container_recipe,
    image_scanning_enabled=True,
    image_scanning_ecr_repository=scanning_repository,
    image_scanning_ecr_tags=["security-scan", "latest"]
)
java
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();
csharp
var scanningRepository = new Repository(this, "ScanningRepo");

var scannedContainerPipeline = new ImagePipeline(this, "ScannedContainerPipeline", new ImagePipelineProps {
    Recipe = exampleContainerRecipe,
    ImageScanningEnabled = true,
    ImageScanningEcrRepository = scanningRepository,
    ImageScanningEcrTags = new [] { "security-scan", "latest" }
});
go
scanningRepository := ecr.NewRepository(this, jsii.String("ScanningRepo"))

scannedContainerPipeline := imagebuilder.NewImagePipeline(this, jsii.String("ScannedContainerPipeline"), &ImagePipelineProps{
	Recipe: exampleContainerRecipe,
	ImageScanningEnabled: jsii.Boolean(true),
	ImageScanningEcrRepository: scanningRepository,
	ImageScanningEcrTags: []*string{
		jsii.String("security-scan"),
		jsii.String("latest"),
	},
})

Control metadata collection and testing:

ts
const controlledPipeline = new imagebuilder.ImagePipeline(this, 'ControlledPipeline', {
  recipe: exampleImageRecipe,
  enhancedImageMetadataEnabled: true,  // Collect detailed OS and package info
  imageTestsEnabled: false  // Skip testing phase for faster builds
});
python
controlled_pipeline = imagebuilder.ImagePipeline(self, "ControlledPipeline",
    recipe=example_image_recipe,
    enhanced_image_metadata_enabled=True,  # Collect detailed OS and package info
    image_tests_enabled=False
)
java
ImagePipeline controlledPipeline = ImagePipeline.Builder.create(this, "ControlledPipeline")
        .recipe(exampleImageRecipe)
        .enhancedImageMetadataEnabled(true) // Collect detailed OS and package info
        .imageTestsEnabled(false)
        .build();
csharp
var controlledPipeline = new ImagePipeline(this, "ControlledPipeline", new ImagePipelineProps {
    Recipe = exampleImageRecipe,
    EnhancedImageMetadataEnabled = true,  // Collect detailed OS and package info
    ImageTestsEnabled = false
});
go
controlledPipeline := imagebuilder.NewImagePipeline(this, jsii.String("ControlledPipeline"), &ImagePipelineProps{
	Recipe: exampleImageRecipe,
	EnhancedImageMetadataEnabled: jsii.Boolean(true),
	 // Collect detailed OS and package info
	ImageTestsEnabled: jsii.Boolean(false),
})

Image Pipeline Events ​

Pipeline Event Handling ​

Handle specific pipeline events:

ts
// Monitor CVE detection
examplePipeline.onCVEDetected('CVEAlert', {
  target: new targets.SnsTopic(topic)
});

// Handle pipeline auto-disable events
examplePipeline.onImagePipelineAutoDisabled('PipelineDisabledAlert', {
  target: new targets.LambdaFunction(lambdaFunction)
});
python
# Monitor CVE detection
example_pipeline.on_cve_detected("CVEAlert",
    target=targets.SnsTopic(topic)
)

# Handle pipeline auto-disable events
example_pipeline.on_image_pipeline_auto_disabled("PipelineDisabledAlert",
    target=targets.LambdaFunction(lambda_function)
)
java
// 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());
csharp
// Monitor CVE detection
examplePipeline.OnCVEDetected("CVEAlert", new OnEventOptions {
    Target = new SnsTopic(topic)
});

// Handle pipeline auto-disable events
examplePipeline.OnImagePipelineAutoDisabled("PipelineDisabledAlert", new OnEventOptions {
    Target = new LambdaFunction(lambdaFunction)
});
go
// Monitor CVE detection
examplePipeline.onCVEDetected(jsii.String("CVEAlert"), &OnEventOptions{
	Target: targets.NewSnsTopic(topic),
})

// Handle pipeline auto-disable events
examplePipeline.onImagePipelineAutoDisabled(jsii.String("PipelineDisabledAlert"), &OnEventOptions{
	Target: targets.NewLambdaFunction(lambdaFunction),
})

Importing Image Pipelines ​

Reference existing pipelines created outside CDK:

ts
// Import by name
const existingPipelineByName = imagebuilder.ImagePipeline.fromImagePipelineName(
  this,
  'ExistingPipelineByName',
  'my-existing-pipeline'
);

// Import by ARN
const existingPipelineByArn = imagebuilder.ImagePipeline.fromImagePipelineArn(
  this,
  'ExistingPipelineByArn',
  'arn:aws:imagebuilder:us-east-1:123456789012:image-pipeline/imported-pipeline'
);

// Grant permissions to imported pipelines
const automationRole = new iam.Role(this, 'AutomationRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com')
});

existingPipelineByName.grantStartExecution(automationRole);
existingPipelineByArn.grantRead(lambdaRole);
python
# Import by name
existing_pipeline_by_name = imagebuilder.ImagePipeline.from_image_pipeline_name(self, "ExistingPipelineByName", "my-existing-pipeline")

# Import by ARN
existing_pipeline_by_arn = imagebuilder.ImagePipeline.from_image_pipeline_arn(self, "ExistingPipelineByArn", "arn:aws:imagebuilder:us-east-1:123456789012:image-pipeline/imported-pipeline")

# Grant permissions to imported pipelines
automation_role = iam.Role(self, "AutomationRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com")
)

existing_pipeline_by_name.grant_start_execution(automation_role)
existing_pipeline_by_arn.grant_read(lambda_role)
java
// 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);
csharp
// Import by name
var existingPipelineByName = ImagePipeline.FromImagePipelineName(this, "ExistingPipelineByName", "my-existing-pipeline");

// Import by ARN
var existingPipelineByArn = ImagePipeline.FromImagePipelineArn(this, "ExistingPipelineByArn", "arn:aws:imagebuilder:us-east-1:123456789012:image-pipeline/imported-pipeline");

// Grant permissions to imported pipelines
var automationRole = new Role(this, "AutomationRole", new RoleProps {
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com")
});

existingPipelineByName.GrantStartExecution(automationRole);
existingPipelineByArn.GrantRead(lambdaRole);
go
// Import by name
existingPipelineByName := imagebuilder.ImagePipeline_FromImagePipelineName(this, jsii.String("ExistingPipelineByName"), jsii.String("my-existing-pipeline"))

// Import by ARN
existingPipelineByArn := imagebuilder.ImagePipeline_FromImagePipelineArn(this, jsii.String("ExistingPipelineByArn"), jsii.String("arn:aws:imagebuilder:us-east-1:123456789012:image-pipeline/imported-pipeline"))

// Grant permissions to imported pipelines
automationRole := iam.NewRole(this, jsii.String("AutomationRole"), &RoleProps{
	AssumedBy: iam.NewServicePrincipal(jsii.String("lambda.amazonaws.com")),
})

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:

ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'MyImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromSsmParameterName(
    '/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
  )
});

const amiImage = new imagebuilder.Image(this, 'MyAmiImage', {
  recipe: imageRecipe
});
python
image_recipe = imagebuilder.ImageRecipe(self, "MyImageRecipe",
    base_image=imagebuilder.BaseImage.from_ssm_parameter_name("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")
)

ami_image = imagebuilder.Image(self, "MyAmiImage",
    recipe=image_recipe
)
java
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();
csharp
var imageRecipe = new ImageRecipe(this, "MyImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")
});

var amiImage = new Image(this, "MyAmiImage", new ImageProps {
    Recipe = imageRecipe
});
go
imageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("MyImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_*FromSsmParameterName(jsii.String("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")),
})

amiImage := imagebuilder.NewImage(this, jsii.String("MyAmiImage"), &ImageProps{
	Recipe: imageRecipe,
})

Create a simple container image from a container recipe:

ts
const containerRecipe = new imagebuilder.ContainerRecipe(this, 'MyContainerRecipe', {
  baseImage: imagebuilder.BaseContainerImage.fromDockerHub('amazonlinux', 'latest'),
  targetRepository: imagebuilder.Repository.fromEcr(
    ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
  )
});

const containerImage = new imagebuilder.Image(this, 'MyContainerImage', {
  recipe: containerRecipe
});
python
container_recipe = imagebuilder.ContainerRecipe(self, "MyContainerRecipe",
    base_image=imagebuilder.BaseContainerImage.from_docker_hub("amazonlinux", "latest"),
    target_repository=imagebuilder.Repository.from_ecr(
        ecr.Repository.from_repository_name(self, "Repository", "my-container-repo"))
)

container_image = imagebuilder.Image(self, "MyContainerImage",
    recipe=container_recipe
)
java
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();
csharp
var containerRecipe = new ContainerRecipe(this, "MyContainerRecipe", new ContainerRecipeProps {
    BaseImage = BaseContainerImage.FromDockerHub("amazonlinux", "latest"),
    TargetRepository = Repository.FromEcr(Repository.FromRepositoryName(this, "Repository", "my-container-repo"))
});

var containerImage = new Image(this, "MyContainerImage", new ImageProps {
    Recipe = containerRecipe
});
go
containerRecipe := imagebuilder.NewContainerRecipe(this, jsii.String("MyContainerRecipe"), &ContainerRecipeProps{
	BaseImage: imagebuilder.BaseContainerImage_*FromDockerHub(jsii.String("amazonlinux"), jsii.String("latest")),
	TargetRepository: imagebuilder.Repository_*FromEcr(ecr.Repository_*FromRepositoryName(this, jsii.String("Repository"), jsii.String("my-container-repo"))),
})

containerImage := imagebuilder.NewImage(this, jsii.String("MyContainerImage"), &ImageProps{
	Recipe: containerRecipe,
})

AWS-Managed Images ​

Pre-defined OS Images ​

Use AWS-managed images for common operating systems:

ts
// Amazon Linux 2023 AMI for x86_64
const amazonLinux2023Ami = imagebuilder.AmazonManagedImage.amazonLinux2023(this, 'AmazonLinux2023', {
  imageType: imagebuilder.ImageType.AMI,
  imageArchitecture: imagebuilder.ImageArchitecture.X86_64
});

// Ubuntu 22.04 AMI for ARM64
const ubuntu2204Ami = imagebuilder.AmazonManagedImage.ubuntuServer2204(this, 'Ubuntu2204', {
  imageType: imagebuilder.ImageType.AMI,
  imageArchitecture: imagebuilder.ImageArchitecture.ARM64
});

// Windows Server 2022 Full AMI
const windows2022Ami = imagebuilder.AmazonManagedImage.windowsServer2022Full(this, 'Windows2022', {
  imageType: imagebuilder.ImageType.AMI,
  imageArchitecture: imagebuilder.ImageArchitecture.X86_64
});

// Use as base image in recipe
const managedImageRecipe = new imagebuilder.ImageRecipe(this, 'ManagedImageRecipe', {
  baseImage: amazonLinux2023Ami.toBaseImage()
});
python
# Amazon Linux 2023 AMI for x86_64
amazon_linux2023_ami = imagebuilder.AmazonManagedImage.amazon_linux2023(self, "AmazonLinux2023",
    image_type=imagebuilder.ImageType.AMI,
    image_architecture=imagebuilder.ImageArchitecture.X86_64
)

# Ubuntu 22.04 AMI for ARM64
ubuntu2204_ami = imagebuilder.AmazonManagedImage.ubuntu_server2204(self, "Ubuntu2204",
    image_type=imagebuilder.ImageType.AMI,
    image_architecture=imagebuilder.ImageArchitecture.ARM64
)

# Windows Server 2022 Full AMI
windows2022_ami = imagebuilder.AmazonManagedImage.windows_server2022_full(self, "Windows2022",
    image_type=imagebuilder.ImageType.AMI,
    image_architecture=imagebuilder.ImageArchitecture.X86_64
)

# Use as base image in recipe
managed_image_recipe = imagebuilder.ImageRecipe(self, "ManagedImageRecipe",
    base_image=amazon_linux2023_ami.to_base_image()
)
java
// 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();
csharp
// Amazon Linux 2023 AMI for x86_64
var amazonLinux2023Ami = AmazonManagedImage.AmazonLinux2023(this, "AmazonLinux2023", new AmazonManagedImageOptions {
    ImageType = ImageType.AMI,
    ImageArchitecture = ImageArchitecture.X86_64
});

// Ubuntu 22.04 AMI for ARM64
var ubuntu2204Ami = AmazonManagedImage.UbuntuServer2204(this, "Ubuntu2204", new AmazonManagedImageOptions {
    ImageType = ImageType.AMI,
    ImageArchitecture = ImageArchitecture.ARM64
});

// Windows Server 2022 Full AMI
var windows2022Ami = AmazonManagedImage.WindowsServer2022Full(this, "Windows2022", new AmazonManagedImageOptions {
    ImageType = ImageType.AMI,
    ImageArchitecture = ImageArchitecture.X86_64
});

// Use as base image in recipe
var managedImageRecipe = new ImageRecipe(this, "ManagedImageRecipe", new ImageRecipeProps {
    BaseImage = amazonLinux2023Ami.ToBaseImage()
});
go
// Amazon Linux 2023 AMI for x86_64
amazonLinux2023Ami := imagebuilder.AmazonManagedImage_AmazonLinux2023(this, jsii.String("AmazonLinux2023"), &AmazonManagedImageOptions{
	ImageType: imagebuilder.ImageType_AMI,
	ImageArchitecture: imagebuilder.ImageArchitecture_X86_64,
})

// Ubuntu 22.04 AMI for ARM64
ubuntu2204Ami := imagebuilder.AmazonManagedImage_UbuntuServer2204(this, jsii.String("Ubuntu2204"), &AmazonManagedImageOptions{
	ImageType: imagebuilder.ImageType_AMI,
	ImageArchitecture: imagebuilder.ImageArchitecture_ARM64,
})

// Windows Server 2022 Full AMI
windows2022Ami := imagebuilder.AmazonManagedImage_WindowsServer2022Full(this, jsii.String("Windows2022"), &AmazonManagedImageOptions{
	ImageType: imagebuilder.ImageType_AMI,
	ImageArchitecture: imagebuilder.ImageArchitecture_X86_64,
})

// Use as base image in recipe
managedImageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("ManagedImageRecipe"), &ImageRecipeProps{
	BaseImage: amazonLinux2023Ami.ToBaseImage(),
})
Custom AWS-Managed Images ​

Import AWS-managed images by name or attributes:

ts
// Import by name
const managedImageByName = imagebuilder.AmazonManagedImage.fromAmazonManagedImageName(
  this,
  'ManagedImageByName',
  'amazon-linux-2023-x86'
);

// Import by attributes with specific version
const managedImageByAttributes = imagebuilder.AmazonManagedImage.fromAmazonManagedImageAttributes(this, 'ManagedImageByAttributes', {
  imageName: 'ubuntu-server-22-lts-x86',
  imageVersion: '2024.11.25'
});
python
# Import by name
managed_image_by_name = imagebuilder.AmazonManagedImage.from_amazon_managed_image_name(self, "ManagedImageByName", "amazon-linux-2023-x86")

# Import by attributes with specific version
managed_image_by_attributes = imagebuilder.AmazonManagedImage.from_amazon_managed_image_attributes(self, "ManagedImageByAttributes",
    image_name="ubuntu-server-22-lts-x86",
    image_version="2024.11.25"
)
java
// 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());
csharp
// Import by name
var managedImageByName = AmazonManagedImage.FromAmazonManagedImageName(this, "ManagedImageByName", "amazon-linux-2023-x86");

// Import by attributes with specific version
var managedImageByAttributes = AmazonManagedImage.FromAmazonManagedImageAttributes(this, "ManagedImageByAttributes", new AmazonManagedImageAttributes {
    ImageName = "ubuntu-server-22-lts-x86",
    ImageVersion = "2024.11.25"
});
go
// Import by name
managedImageByName := imagebuilder.AmazonManagedImage_FromAmazonManagedImageName(this, jsii.String("ManagedImageByName"), jsii.String("amazon-linux-2023-x86"))

// Import by attributes with specific version
managedImageByAttributes := imagebuilder.AmazonManagedImage_FromAmazonManagedImageAttributes(this, jsii.String("ManagedImageByAttributes"), &AmazonManagedImageAttributes{
	ImageName: jsii.String("ubuntu-server-22-lts-x86"),
	ImageVersion: jsii.String("2024.11.25"),
})

Image Configuration ​

Infrastructure and Distribution in Images ​

Configure custom infrastructure and distribution settings:

ts
const infrastructureConfiguration = new imagebuilder.InfrastructureConfiguration(this, 'Infrastructure', {
  infrastructureConfigurationName: 'production-infrastructure',
  instanceTypes: [
    ec2.InstanceType.of(ec2.InstanceClass.COMPUTE7_INTEL, ec2.InstanceSize.LARGE)
  ],
  vpc: vpc,
  subnetSelection: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }
});

const distributionConfiguration = new imagebuilder.DistributionConfiguration(this, 'Distribution');
distributionConfiguration.addAmiDistributions({
  amiName: 'production-ami-{{ imagebuilder:buildDate }}',
  amiTargetAccountIds: ['123456789012', '098765432109']
});

const productionImage = new imagebuilder.Image(this, 'ProductionImage', {
  recipe: exampleImageRecipe,
  infrastructureConfiguration: infrastructureConfiguration,
  distributionConfiguration: distributionConfiguration
});
python
infrastructure_configuration = imagebuilder.InfrastructureConfiguration(self, "Infrastructure",
    infrastructure_configuration_name="production-infrastructure",
    instance_types=[
        ec2.InstanceType.of(ec2.InstanceClass.COMPUTE7_INTEL, ec2.InstanceSize.LARGE)
    ],
    vpc=vpc,
    subnet_selection=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS)
)

distribution_configuration = imagebuilder.DistributionConfiguration(self, "Distribution")
distribution_configuration.add_ami_distributions(
    ami_name="production-ami-{{ imagebuilder:buildDate }}",
    ami_target_account_ids=["123456789012", "098765432109"]
)

production_image = imagebuilder.Image(self, "ProductionImage",
    recipe=example_image_recipe,
    infrastructure_configuration=infrastructure_configuration,
    distribution_configuration=distribution_configuration
)
java
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();
csharp
var infrastructureConfiguration = new InfrastructureConfiguration(this, "Infrastructure", new InfrastructureConfigurationProps {
    InfrastructureConfigurationName = "production-infrastructure",
    InstanceTypes = new [] { InstanceType.Of(InstanceClass.COMPUTE7_INTEL, InstanceSize.LARGE) },
    Vpc = vpc,
    SubnetSelection = new SubnetSelection { SubnetType = SubnetType.PRIVATE_WITH_EGRESS }
});

var distributionConfiguration = new DistributionConfiguration(this, "Distribution");
distributionConfiguration.AddAmiDistributions(new AmiDistribution {
    AmiName = "production-ami-{{ imagebuilder:buildDate }}",
    AmiTargetAccountIds = new [] { "123456789012", "098765432109" }
});

var productionImage = new Image(this, "ProductionImage", new ImageProps {
    Recipe = exampleImageRecipe,
    InfrastructureConfiguration = infrastructureConfiguration,
    DistributionConfiguration = distributionConfiguration
});
go
infrastructureConfiguration := imagebuilder.NewInfrastructureConfiguration(this, jsii.String("Infrastructure"), &InfrastructureConfigurationProps{
	InfrastructureConfigurationName: jsii.String("production-infrastructure"),
	InstanceTypes: []InstanceType{
		ec2.InstanceType_*Of(ec2.InstanceClass_COMPUTE7_INTEL, ec2.InstanceSize_LARGE),
	},
	Vpc: vpc,
	SubnetSelection: &SubnetSelection{
		SubnetType: ec2.SubnetType_PRIVATE_WITH_EGRESS,
	},
})

distributionConfiguration := imagebuilder.NewDistributionConfiguration(this, jsii.String("Distribution"))
distributionConfiguration.AddAmiDistributions(&AmiDistribution{
	AmiName: jsii.String("production-ami-{{ imagebuilder:buildDate }}"),
	AmiTargetAccountIds: []*string{
		jsii.String("123456789012"),
		jsii.String("098765432109"),
	},
})

productionImage := imagebuilder.NewImage(this, jsii.String("ProductionImage"), &ImageProps{
	Recipe: exampleImageRecipe,
	InfrastructureConfiguration: infrastructureConfiguration,
	DistributionConfiguration: distributionConfiguration,
})
Logging Configuration ​

Configure custom CloudWatch log groups for image builds:

ts
const logGroup = new logs.LogGroup(this, 'ImageLogGroup', {
  logGroupName: '/custom/imagebuilder/image/logs',
  retention: logs.RetentionDays.ONE_MONTH
});

const loggedImage = new imagebuilder.Image(this, 'LoggedImage', {
  recipe: exampleImageRecipe,
  logGroup: logGroup
});
python
log_group = logs.LogGroup(self, "ImageLogGroup",
    log_group_name="/custom/imagebuilder/image/logs",
    retention=logs.RetentionDays.ONE_MONTH
)

logged_image = imagebuilder.Image(self, "LoggedImage",
    recipe=example_image_recipe,
    log_group=log_group
)
java
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();
csharp
var logGroup = new LogGroup(this, "ImageLogGroup", new LogGroupProps {
    LogGroupName = "/custom/imagebuilder/image/logs",
    Retention = RetentionDays.ONE_MONTH
});

var loggedImage = new Image(this, "LoggedImage", new ImageProps {
    Recipe = exampleImageRecipe,
    LogGroup = logGroup
});
go
logGroup := logs.NewLogGroup(this, jsii.String("ImageLogGroup"), &LogGroupProps{
	LogGroupName: jsii.String("/custom/imagebuilder/image/logs"),
	Retention: logs.RetentionDays_ONE_MONTH,
})

loggedImage := imagebuilder.NewImage(this, jsii.String("LoggedImage"), &ImageProps{
	Recipe: exampleImageRecipe,
	LogGroup: logGroup,
})
Workflow Integration in Images ​

Use workflows for custom build, test, and distribution processes:

ts
const imageWithWorkflows = new imagebuilder.Image(this, 'ImageWithWorkflows', {
  recipe: exampleImageRecipe,
  workflows: [
    { workflow: imagebuilder.AmazonManagedWorkflow.buildImage(this, 'BuildWorkflow') },
    { workflow: imagebuilder.AmazonManagedWorkflow.testImage(this, 'TestWorkflow') }
  ]
});
python
image_with_workflows = imagebuilder.Image(self, "ImageWithWorkflows",
    recipe=example_image_recipe,
    workflows=[imagebuilder.WorkflowConfiguration(workflow=imagebuilder.AmazonManagedWorkflow.build_image(self, "BuildWorkflow")), imagebuilder.WorkflowConfiguration(workflow=imagebuilder.AmazonManagedWorkflow.test_image(self, "TestWorkflow"))
    ]
)
java
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();
csharp
var imageWithWorkflows = new Image(this, "ImageWithWorkflows", new ImageProps {
    Recipe = exampleImageRecipe,
    Workflows = new [] { new WorkflowConfiguration { Workflow = AmazonManagedWorkflow.BuildImage(this, "BuildWorkflow") }, new WorkflowConfiguration { Workflow = AmazonManagedWorkflow.TestImage(this, "TestWorkflow") } }
});
go
imageWithWorkflows := imagebuilder.NewImage(this, jsii.String("ImageWithWorkflows"), &ImageProps{
	Recipe: exampleImageRecipe,
	Workflows: []WorkflowConfiguration{
		&WorkflowConfiguration{
			Workflow: imagebuilder.AmazonManagedWorkflow_BuildImage(this, jsii.String("BuildWorkflow")),
		},
		&WorkflowConfiguration{
			Workflow: imagebuilder.AmazonManagedWorkflow_TestImage(this, jsii.String("TestWorkflow")),
		},
	},
})
Advanced Features in Images ​

Configure image scanning, metadata collection, and testing:

ts
const scanningRepository = new ecr.Repository(this, 'ScanningRepository');

const advancedContainerImage = new imagebuilder.Image(this, 'AdvancedContainerImage', {
  recipe: exampleContainerRecipe,
  imageScanningEnabled: true,
  imageScanningEcrRepository: scanningRepository,
  imageScanningEcrTags: ['security-scan', 'latest'],
  enhancedImageMetadataEnabled: true,
  imageTestsEnabled: false  // Skip testing for faster builds
});
python
scanning_repository = ecr.Repository(self, "ScanningRepository")

advanced_container_image = imagebuilder.Image(self, "AdvancedContainerImage",
    recipe=example_container_recipe,
    image_scanning_enabled=True,
    image_scanning_ecr_repository=scanning_repository,
    image_scanning_ecr_tags=["security-scan", "latest"],
    enhanced_image_metadata_enabled=True,
    image_tests_enabled=False
)
java
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();
csharp
var scanningRepository = new Repository(this, "ScanningRepository");

var advancedContainerImage = new Image(this, "AdvancedContainerImage", new ImageProps {
    Recipe = exampleContainerRecipe,
    ImageScanningEnabled = true,
    ImageScanningEcrRepository = scanningRepository,
    ImageScanningEcrTags = new [] { "security-scan", "latest" },
    EnhancedImageMetadataEnabled = true,
    ImageTestsEnabled = false
});
go
scanningRepository := ecr.NewRepository(this, jsii.String("ScanningRepository"))

advancedContainerImage := imagebuilder.NewImage(this, jsii.String("AdvancedContainerImage"), &ImageProps{
	Recipe: exampleContainerRecipe,
	ImageScanningEnabled: jsii.Boolean(true),
	ImageScanningEcrRepository: scanningRepository,
	ImageScanningEcrTags: []*string{
		jsii.String("security-scan"),
		jsii.String("latest"),
	},
	EnhancedImageMetadataEnabled: jsii.Boolean(true),
	ImageTestsEnabled: jsii.Boolean(false),
})

Importing Images ​

Reference existing images created outside CDK:

ts
// Import by name
const existingImageByName = imagebuilder.Image.fromImageName(
  this,
  'ExistingImageByName',
  'my-existing-image'
);

// Import by ARN
const existingImageByArn = imagebuilder.Image.fromImageArn(
  this,
  'ExistingImageByArn',
  'arn:aws:imagebuilder:us-east-1:123456789012:image/imported-image/1.0.0'
);

// Import by attributes
const existingImageByAttributes = imagebuilder.Image.fromImageAttributes(this, 'ExistingImageByAttributes', {
  imageName: 'shared-base-image',
  imageVersion: '2024.11.25'
});

// Grant permissions to imported images
const role = new iam.Role(this, 'ImageAccessRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com')
});

existingImageByName.grantRead(role);
existingImageByArn.grant(role, 'imagebuilder:GetImage', 'imagebuilder:ListImagePackages');
python
# Import by name
existing_image_by_name = imagebuilder.Image.from_image_name(self, "ExistingImageByName", "my-existing-image")

# Import by ARN
existing_image_by_arn = imagebuilder.Image.from_image_arn(self, "ExistingImageByArn", "arn:aws:imagebuilder:us-east-1:123456789012:image/imported-image/1.0.0")

# Import by attributes
existing_image_by_attributes = imagebuilder.Image.from_image_attributes(self, "ExistingImageByAttributes",
    image_name="shared-base-image",
    image_version="2024.11.25"
)

# Grant permissions to imported images
role = iam.Role(self, "ImageAccessRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com")
)

existing_image_by_name.grant_read(role)
existing_image_by_arn.grant(role, "imagebuilder:GetImage", "imagebuilder:ListImagePackages")
java
// 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");
csharp
// Import by name
var existingImageByName = Image.FromImageName(this, "ExistingImageByName", "my-existing-image");

// Import by ARN
var existingImageByArn = Image.FromImageArn(this, "ExistingImageByArn", "arn:aws:imagebuilder:us-east-1:123456789012:image/imported-image/1.0.0");

// Import by attributes
var existingImageByAttributes = Image.FromImageAttributes(this, "ExistingImageByAttributes", new ImageAttributes {
    ImageName = "shared-base-image",
    ImageVersion = "2024.11.25"
});

// Grant permissions to imported images
var role = new Role(this, "ImageAccessRole", new RoleProps {
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com")
});

existingImageByName.GrantRead(role);
existingImageByArn.Grant(role, "imagebuilder:GetImage", "imagebuilder:ListImagePackages");
go
// Import by name
existingImageByName := imagebuilder.Image_FromImageName(this, jsii.String("ExistingImageByName"), jsii.String("my-existing-image"))

// Import by ARN
existingImageByArn := imagebuilder.Image_FromImageArn(this, jsii.String("ExistingImageByArn"), jsii.String("arn:aws:imagebuilder:us-east-1:123456789012:image/imported-image/1.0.0"))

// Import by attributes
existingImageByAttributes := imagebuilder.Image_FromImageAttributes(this, jsii.String("ExistingImageByAttributes"), &ImageAttributes{
	ImageName: jsii.String("shared-base-image"),
	ImageVersion: jsii.String("2024.11.25"),
})

// Grant permissions to imported images
role := iam.NewRole(this, jsii.String("ImageAccessRole"), &RoleProps{
	AssumedBy: iam.NewServicePrincipal(jsii.String("lambda.amazonaws.com")),
})

existingImageByName.GrantRead(role)
existingImageByArn.Grant(role, jsii.String("imagebuilder:GetImage"), jsii.String("imagebuilder:ListImagePackages"))

Image Recipe ​

Image Recipe Basic Usage ​

Create an image recipe with the required base image:

ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'MyImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromSsmParameterName(
    '/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
  )
});
python
image_recipe = imagebuilder.ImageRecipe(self, "MyImageRecipe",
    base_image=imagebuilder.BaseImage.from_ssm_parameter_name("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")
)
java
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "MyImageRecipe")
        .baseImage(BaseImage.fromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"))
        .build();
csharp
var imageRecipe = new ImageRecipe(this, "MyImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")
});
go
imageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("MyImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_*FromSsmParameterName(jsii.String("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")),
})

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:

ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'SsmImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromSsmParameterName(
    '/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
  )
});

// Using an SSM parameter construct
const parameter = ssm.StringParameter.fromStringParameterName(
  this,
  'BaseImageParameter',
  '/aws/service/ami-windows-latest/Windows_Server-2022-English-Full-Base'
);
const windowsRecipe = new imagebuilder.ImageRecipe(this, 'WindowsImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromSsmParameter(parameter)
});
python
image_recipe = imagebuilder.ImageRecipe(self, "SsmImageRecipe",
    base_image=imagebuilder.BaseImage.from_ssm_parameter_name("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")
)

# Using an SSM parameter construct
parameter = ssm.StringParameter.from_string_parameter_name(self, "BaseImageParameter", "/aws/service/ami-windows-latest/Windows_Server-2022-English-Full-Base")
windows_recipe = imagebuilder.ImageRecipe(self, "WindowsImageRecipe",
    base_image=imagebuilder.BaseImage.from_ssm_parameter(parameter)
)
java
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();
csharp
var imageRecipe = new ImageRecipe(this, "SsmImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")
});

// Using an SSM parameter construct
var parameter = StringParameter.FromStringParameterName(this, "BaseImageParameter", "/aws/service/ami-windows-latest/Windows_Server-2022-English-Full-Base");
var windowsRecipe = new ImageRecipe(this, "WindowsImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromSsmParameter(parameter)
});
go
imageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("SsmImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_*FromSsmParameterName(jsii.String("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")),
})

// Using an SSM parameter construct
parameter := ssm.StringParameter_FromStringParameterName(this, jsii.String("BaseImageParameter"), jsii.String("/aws/service/ami-windows-latest/Windows_Server-2022-English-Full-Base"))
windowsRecipe := imagebuilder.NewImageRecipe(this, jsii.String("WindowsImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_FromSsmParameter(parameter),
})
AMI IDs ​

When you have a specific AMI to use:

ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'AmiImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromAmiId('ami-12345678')
});
python
image_recipe = imagebuilder.ImageRecipe(self, "AmiImageRecipe",
    base_image=imagebuilder.BaseImage.from_ami_id("ami-12345678")
)
java
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "AmiImageRecipe")
        .baseImage(BaseImage.fromAmiId("ami-12345678"))
        .build();
csharp
var imageRecipe = new ImageRecipe(this, "AmiImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromAmiId("ami-12345678")
});
go
imageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("AmiImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_FromAmiId(jsii.String("ami-12345678")),
})
Marketplace Images ​

For marketplace base images:

ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'MarketplaceImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromMarketplaceProductId('prod-1234567890abcdef0')
});
python
image_recipe = imagebuilder.ImageRecipe(self, "MarketplaceImageRecipe",
    base_image=imagebuilder.BaseImage.from_marketplace_product_id("prod-1234567890abcdef0")
)
java
ImageRecipe imageRecipe = ImageRecipe.Builder.create(this, "MarketplaceImageRecipe")
        .baseImage(BaseImage.fromMarketplaceProductId("prod-1234567890abcdef0"))
        .build();
csharp
var imageRecipe = new ImageRecipe(this, "MarketplaceImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromMarketplaceProductId("prod-1234567890abcdef0")
});
go
imageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("MarketplaceImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_FromMarketplaceProductId(jsii.String("prod-1234567890abcdef0")),
})

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:

ts
const customComponent = new imagebuilder.Component(this, 'MyComponent', {
  platform: imagebuilder.Platform.LINUX,
  data: imagebuilder.ComponentData.fromJsonObject({
    schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0,
    phases: [
      {
        name: imagebuilder.ComponentPhaseName.BUILD,
        steps: [
          {
            name: 'install-app',
            action: imagebuilder.ComponentAction.EXECUTE_BASH,
            inputs: {
              commands: ['yum install -y my-application']
            }
          }
        ]
      }
    ]
  })
});

const imageRecipe = new imagebuilder.ImageRecipe(this, 'ComponentImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromSsmParameterName(
    '/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
  ),
  components: [
    {
      component: customComponent
    }
  ]
});
python
custom_component = imagebuilder.Component(self, "MyComponent",
    platform=imagebuilder.Platform.LINUX,
    data=imagebuilder.ComponentData.from_json_object({
        "schema_version": imagebuilder.ComponentSchemaVersion.V1_0,
        "phases": [{
            "name": imagebuilder.ComponentPhaseName.BUILD,
            "steps": [{
                "name": "install-app",
                "action": imagebuilder.ComponentAction.EXECUTE_BASH,
                "inputs": {
                    "commands": ["yum install -y my-application"]
                }
            }
            ]
        }
        ]
    })
)

image_recipe = imagebuilder.ImageRecipe(self, "ComponentImageRecipe",
    base_image=imagebuilder.BaseImage.from_ssm_parameter_name("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"),
    components=[imagebuilder.ComponentConfiguration(
        component=custom_component
    )
    ]
)
java
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();
csharp
var customComponent = new Component(this, "MyComponent", new ComponentProps {
    Platform = Platform.LINUX,
    Data = ComponentData.FromJsonObject(new Dictionary<string, object> {
        { "schemaVersion", ComponentSchemaVersion.V1_0 },
        { "phases", new [] { new Dictionary<string, object> {
            { "name", ComponentPhaseName.BUILD },
            { "steps", new [] { new Struct {
                Name = "install-app",
                Action = ComponentAction.EXECUTE_BASH,
                Inputs = new Struct {
                    Commands = new [] { "yum install -y my-application" }
                }
            } } }
        } } }
    })
});

var imageRecipe = new ImageRecipe(this, "ComponentImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"),
    Components = new [] { new ComponentConfiguration {
        Component = customComponent
    } }
});
go
customComponent := imagebuilder.NewComponent(this, jsii.String("MyComponent"), &ComponentProps{
	Platform: imagebuilder.Platform_LINUX,
	Data: imagebuilder.ComponentData_FromJsonObject(map[string]interface{}{
		"schemaVersion": imagebuilder.ComponentSchemaVersion_V1_0,
		"phases": []interface{}{
			map[string]interface{}{
				"name": imagebuilder.ComponentPhaseName_BUILD,
				"steps": []map[string]interface{}{
					map[string]interface{}{
						"name": jsii.String("install-app"),
						"action": imagebuilder.ComponentAction_EXECUTE_BASH,
						"inputs": map[string][]*string{
							"commands": []*string{
								jsii.String("yum install -y my-application"),
							},
						},
					},
				},
			},
		},
	}),
})

imageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("ComponentImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_*FromSsmParameterName(jsii.String("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")),
	Components: []ComponentConfiguration{
		&ComponentConfiguration{
			Component: customComponent,
		},
	},
})
AWS-Managed Components in Image Recipes ​

Use pre-built AWS components:

ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'AmazonManagedImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromSsmParameterName(
    '/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
  ),
  components: [
    {
      component: imagebuilder.AmazonManagedComponent.updateOs(this, 'UpdateOS', {
        platform: imagebuilder.Platform.LINUX
      })
    },
    {
      component: imagebuilder.AmazonManagedComponent.awsCliV2(this, 'AwsCli', {
        platform: imagebuilder.Platform.LINUX
      })
    }
  ]
});
python
image_recipe = imagebuilder.ImageRecipe(self, "AmazonManagedImageRecipe",
    base_image=imagebuilder.BaseImage.from_ssm_parameter_name("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"),
    components=[imagebuilder.ComponentConfiguration(
        component=imagebuilder.AmazonManagedComponent.update_os(self, "UpdateOS",
            platform=imagebuilder.Platform.LINUX
        )
    ), imagebuilder.ComponentConfiguration(
        component=imagebuilder.AmazonManagedComponent.aws_cli_v2(self, "AwsCli",
            platform=imagebuilder.Platform.LINUX
        )
    )
    ]
)
java
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();
csharp
var imageRecipe = new ImageRecipe(this, "AmazonManagedImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"),
    Components = new [] { new ComponentConfiguration {
        Component = AmazonManagedComponent.UpdateOs(this, "UpdateOS", new AmazonManagedComponentOptions {
            Platform = Platform.LINUX
        })
    }, new ComponentConfiguration {
        Component = AmazonManagedComponent.AwsCliV2(this, "AwsCli", new AmazonManagedComponentOptions {
            Platform = Platform.LINUX
        })
    } }
});
go
imageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("AmazonManagedImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_*FromSsmParameterName(jsii.String("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")),
	Components: []ComponentConfiguration{
		&ComponentConfiguration{
			Component: imagebuilder.AmazonManagedComponent_UpdateOs(this, jsii.String("UpdateOS"), &AmazonManagedComponentOptions{
				Platform: imagebuilder.Platform_LINUX,
			}),
		},
		&ComponentConfiguration{
			Component: imagebuilder.AmazonManagedComponent_AwsCliV2(this, jsii.String("AwsCli"), &AmazonManagedComponentOptions{
				Platform: imagebuilder.Platform_LINUX,
			}),
		},
	},
})
Component Parameters in Image Recipes ​

Pass parameters to components that accept them:

ts
const parameterizedComponent = imagebuilder.Component.fromComponentName(
  this,
  'ParameterizedComponent',
  'my-parameterized-component'
);

const imageRecipe = new imagebuilder.ImageRecipe(this, 'ParameterizedImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromSsmParameterName(
    '/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
  ),
  components: [
    {
      component: parameterizedComponent,
      parameters: {
        environment: imagebuilder.ComponentParameterValue.fromString('production'),
        version: imagebuilder.ComponentParameterValue.fromString('1.0.0')
      }
    }
  ]
});
python
parameterized_component = imagebuilder.Component.from_component_name(self, "ParameterizedComponent", "my-parameterized-component")

image_recipe = imagebuilder.ImageRecipe(self, "ParameterizedImageRecipe",
    base_image=imagebuilder.BaseImage.from_ssm_parameter_name("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"),
    components=[imagebuilder.ComponentConfiguration(
        component=parameterized_component,
        parameters={
            "environment": imagebuilder.ComponentParameterValue.from_string("production"),
            "version": imagebuilder.ComponentParameterValue.from_string("1.0.0")
        }
    )
    ]
)
java
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();
csharp
var parameterizedComponent = Component.FromComponentName(this, "ParameterizedComponent", "my-parameterized-component");

var imageRecipe = new ImageRecipe(this, "ParameterizedImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"),
    Components = new [] { new ComponentConfiguration {
        Component = parameterizedComponent,
        Parameters = new Dictionary<string, ComponentParameterValue> {
            { "environment", ComponentParameterValue.FromString("production") },
            { "version", ComponentParameterValue.FromString("1.0.0") }
        }
    } }
});
go
parameterizedComponent := imagebuilder.Component_FromComponentName(this, jsii.String("ParameterizedComponent"), jsii.String("my-parameterized-component"))

imageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("ParameterizedImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_*FromSsmParameterName(jsii.String("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")),
	Components: []ComponentConfiguration{
		&ComponentConfiguration{
			Component: parameterizedComponent,
			Parameters: map[string]ComponentParameterValue{
				"environment": imagebuilder.ComponentParameterValue_fromString(jsii.String("production")),
				"version": imagebuilder.ComponentParameterValue_fromString(jsii.String("1.0.0")),
			},
		},
	},
})

Image Recipe Configuration ​

Block Device Configuration ​

Configure storage for the build instance:

ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'BlockDeviceImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromSsmParameterName(
    '/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
  ),
  blockDevices: [
    {
      deviceName: '/dev/sda1',
      volume: ec2.BlockDeviceVolume.ebs(100, {
        encrypted: true,
        volumeType: ec2.EbsDeviceVolumeType.GENERAL_PURPOSE_SSD_GP3
      })
    }
  ]
});
python
image_recipe = imagebuilder.ImageRecipe(self, "BlockDeviceImageRecipe",
    base_image=imagebuilder.BaseImage.from_ssm_parameter_name("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"),
    block_devices=[ec2.BlockDevice(
        device_name="/dev/sda1",
        volume=ec2.BlockDeviceVolume.ebs(100,
            encrypted=True,
            volume_type=ec2.EbsDeviceVolumeType.GENERAL_PURPOSE_SSD_GP3
        )
    )
    ]
)
java
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();
csharp
var imageRecipe = new ImageRecipe(this, "BlockDeviceImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"),
    BlockDevices = new [] { new BlockDevice {
        DeviceName = "/dev/sda1",
        Volume = BlockDeviceVolume.Ebs(100, new EbsDeviceOptions {
            Encrypted = true,
            VolumeType = EbsDeviceVolumeType.GENERAL_PURPOSE_SSD_GP3
        })
    } }
});
go
imageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("BlockDeviceImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_*FromSsmParameterName(jsii.String("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")),
	BlockDevices: []BlockDevice{
		&BlockDevice{
			DeviceName: jsii.String("/dev/sda1"),
			Volume: ec2.BlockDeviceVolume_Ebs(jsii.Number(100), &EbsDeviceOptions{
				Encrypted: jsii.Boolean(true),
				VolumeType: ec2.EbsDeviceVolumeType_GENERAL_PURPOSE_SSD_GP3,
			}),
		},
	},
})
AMI Tagging ​

Tag the output AMI:

ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'TaggedImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromSsmParameterName(
    '/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
  ),
  amiTags: {
    Environment: 'Production',
    Application: 'WebServer',
    Owner: 'DevOps Team'
  }
});
python
image_recipe = imagebuilder.ImageRecipe(self, "TaggedImageRecipe",
    base_image=imagebuilder.BaseImage.from_ssm_parameter_name("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"),
    ami_tags={
        "Environment": "Production",
        "Application": "WebServer",
        "Owner": "DevOps Team"
    }
)
java
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();
csharp
var imageRecipe = new ImageRecipe(this, "TaggedImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"),
    AmiTags = new Dictionary<string, string> {
        { "Environment", "Production" },
        { "Application", "WebServer" },
        { "Owner", "DevOps Team" }
    }
});
go
imageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("TaggedImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_*FromSsmParameterName(jsii.String("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")),
	AmiTags: map[string]*string{
		"Environment": jsii.String("Production"),
		"Application": jsii.String("WebServer"),
		"Owner": jsii.String("DevOps Team"),
	},
})

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:

ts
const containerRecipe = new imagebuilder.ContainerRecipe(this, 'MyContainerRecipe', {
  baseImage: imagebuilder.BaseContainerImage.fromDockerHub('amazonlinux', 'latest'),
  targetRepository: imagebuilder.Repository.fromEcr(
    ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
  )
});
python
container_recipe = imagebuilder.ContainerRecipe(self, "MyContainerRecipe",
    base_image=imagebuilder.BaseContainerImage.from_docker_hub("amazonlinux", "latest"),
    target_repository=imagebuilder.Repository.from_ecr(
        ecr.Repository.from_repository_name(self, "Repository", "my-container-repo"))
)
java
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "MyContainerRecipe")
        .baseImage(BaseContainerImage.fromDockerHub("amazonlinux", "latest"))
        .targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
        .build();
csharp
var containerRecipe = new ContainerRecipe(this, "MyContainerRecipe", new ContainerRecipeProps {
    BaseImage = BaseContainerImage.FromDockerHub("amazonlinux", "latest"),
    TargetRepository = Repository.FromEcr(Repository.FromRepositoryName(this, "Repository", "my-container-repo"))
});
go
containerRecipe := imagebuilder.NewContainerRecipe(this, jsii.String("MyContainerRecipe"), &ContainerRecipeProps{
	BaseImage: imagebuilder.BaseContainerImage_*FromDockerHub(jsii.String("amazonlinux"), jsii.String("latest")),
	TargetRepository: imagebuilder.Repository_*FromEcr(ecr.Repository_*FromRepositoryName(this, jsii.String("Repository"), jsii.String("my-container-repo"))),
})

Container Recipe Base Images ​

DockerHub Images ​

Using public Docker Hub images:

ts
const containerRecipe = new imagebuilder.ContainerRecipe(this, 'DockerHubContainerRecipe', {
  baseImage: imagebuilder.BaseContainerImage.fromDockerHub('amazonlinux', 'latest'),
  targetRepository: imagebuilder.Repository.fromEcr(
    ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
  )
});
python
container_recipe = imagebuilder.ContainerRecipe(self, "DockerHubContainerRecipe",
    base_image=imagebuilder.BaseContainerImage.from_docker_hub("amazonlinux", "latest"),
    target_repository=imagebuilder.Repository.from_ecr(
        ecr.Repository.from_repository_name(self, "Repository", "my-container-repo"))
)
java
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "DockerHubContainerRecipe")
        .baseImage(BaseContainerImage.fromDockerHub("amazonlinux", "latest"))
        .targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
        .build();
csharp
var containerRecipe = new ContainerRecipe(this, "DockerHubContainerRecipe", new ContainerRecipeProps {
    BaseImage = BaseContainerImage.FromDockerHub("amazonlinux", "latest"),
    TargetRepository = Repository.FromEcr(Repository.FromRepositoryName(this, "Repository", "my-container-repo"))
});
go
containerRecipe := imagebuilder.NewContainerRecipe(this, jsii.String("DockerHubContainerRecipe"), &ContainerRecipeProps{
	BaseImage: imagebuilder.BaseContainerImage_*FromDockerHub(jsii.String("amazonlinux"), jsii.String("latest")),
	TargetRepository: imagebuilder.Repository_*FromEcr(ecr.Repository_*FromRepositoryName(this, jsii.String("Repository"), jsii.String("my-container-repo"))),
})
ECR Images ​

Using images from your own ECR repositories:

ts
const sourceRepo = ecr.Repository.fromRepositoryName(this, 'SourceRepo', 'my-base-image');
const targetRepo = ecr.Repository.fromRepositoryName(this, 'TargetRepo', 'my-container-repo');

const containerRecipe = new imagebuilder.ContainerRecipe(this, 'EcrContainerRecipe', {
  baseImage: imagebuilder.BaseContainerImage.fromEcr(sourceRepo, '1.0.0'),
  targetRepository: imagebuilder.Repository.fromEcr(targetRepo)
});
python
source_repo = ecr.Repository.from_repository_name(self, "SourceRepo", "my-base-image")
target_repo = ecr.Repository.from_repository_name(self, "TargetRepo", "my-container-repo")

container_recipe = imagebuilder.ContainerRecipe(self, "EcrContainerRecipe",
    base_image=imagebuilder.BaseContainerImage.from_ecr(source_repo, "1.0.0"),
    target_repository=imagebuilder.Repository.from_ecr(target_repo)
)
java
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();
csharp
var sourceRepo = Repository.FromRepositoryName(this, "SourceRepo", "my-base-image");
var targetRepo = Repository.FromRepositoryName(this, "TargetRepo", "my-container-repo");

var containerRecipe = new ContainerRecipe(this, "EcrContainerRecipe", new ContainerRecipeProps {
    BaseImage = BaseContainerImage.FromEcr(sourceRepo, "1.0.0"),
    TargetRepository = Repository.FromEcr(targetRepo)
});
go
sourceRepo := ecr.Repository_FromRepositoryName(this, jsii.String("SourceRepo"), jsii.String("my-base-image"))
targetRepo := ecr.Repository_FromRepositoryName(this, jsii.String("TargetRepo"), jsii.String("my-container-repo"))

containerRecipe := imagebuilder.NewContainerRecipe(this, jsii.String("EcrContainerRecipe"), &ContainerRecipeProps{
	BaseImage: imagebuilder.BaseContainerImage_FromEcr(sourceRepo, jsii.String("1.0.0")),
	TargetRepository: imagebuilder.Repository_*FromEcr(targetRepo),
})
ECR Public Images ​

Using images from Amazon ECR Public:

ts
const containerRecipe = new imagebuilder.ContainerRecipe(this, 'EcrPublicContainerRecipe', {
  baseImage: imagebuilder.BaseContainerImage.fromEcrPublic('amazonlinux', 'amazonlinux', '2023'),
  targetRepository: imagebuilder.Repository.fromEcr(
    ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
  )
});
python
container_recipe = imagebuilder.ContainerRecipe(self, "EcrPublicContainerRecipe",
    base_image=imagebuilder.BaseContainerImage.from_ecr_public("amazonlinux", "amazonlinux", "2023"),
    target_repository=imagebuilder.Repository.from_ecr(
        ecr.Repository.from_repository_name(self, "Repository", "my-container-repo"))
)
java
ContainerRecipe containerRecipe = ContainerRecipe.Builder.create(this, "EcrPublicContainerRecipe")
        .baseImage(BaseContainerImage.fromEcrPublic("amazonlinux", "amazonlinux", "2023"))
        .targetRepository(Repository.fromEcr(Repository.fromRepositoryName(this, "Repository", "my-container-repo")))
        .build();
csharp
var containerRecipe = new ContainerRecipe(this, "EcrPublicContainerRecipe", new ContainerRecipeProps {
    BaseImage = BaseContainerImage.FromEcrPublic("amazonlinux", "amazonlinux", "2023"),
    TargetRepository = Repository.FromEcr(Repository.FromRepositoryName(this, "Repository", "my-container-repo"))
});
go
containerRecipe := imagebuilder.NewContainerRecipe(this, jsii.String("EcrPublicContainerRecipe"), &ContainerRecipeProps{
	BaseImage: imagebuilder.BaseContainerImage_FromEcrPublic(jsii.String("amazonlinux"), jsii.String("amazonlinux"), jsii.String("2023")),
	TargetRepository: imagebuilder.Repository_*FromEcr(ecr.Repository_*FromRepositoryName(this, jsii.String("Repository"), jsii.String("my-container-repo"))),
})

Container Recipe Components ​

Custom Components in Container Recipes ​

Add your own components to the container recipe:

ts
const customComponent = new imagebuilder.Component(this, 'MyComponent', {
  platform: imagebuilder.Platform.LINUX,
  data: imagebuilder.ComponentData.fromJsonObject({
    schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0,
    phases: [
      {
        name: imagebuilder.ComponentPhaseName.BUILD,
        steps: [
          {
            name: 'install-app',
            action: imagebuilder.ComponentAction.EXECUTE_BASH,
            inputs: {
              commands: ['yum install -y my-container-application']
            }
          }
        ]
      }
    ]
  })
});

const containerRecipe = new imagebuilder.ContainerRecipe(this, 'ComponentContainerRecipe', {
  baseImage: imagebuilder.BaseContainerImage.fromDockerHub('amazonlinux', 'latest'),
  targetRepository: imagebuilder.Repository.fromEcr(
    ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
  ),
  components: [
    {
      component: customComponent
    }
  ]
});
python
custom_component = imagebuilder.Component(self, "MyComponent",
    platform=imagebuilder.Platform.LINUX,
    data=imagebuilder.ComponentData.from_json_object({
        "schema_version": imagebuilder.ComponentSchemaVersion.V1_0,
        "phases": [{
            "name": imagebuilder.ComponentPhaseName.BUILD,
            "steps": [{
                "name": "install-app",
                "action": imagebuilder.ComponentAction.EXECUTE_BASH,
                "inputs": {
                    "commands": ["yum install -y my-container-application"]
                }
            }
            ]
        }
        ]
    })
)

container_recipe = imagebuilder.ContainerRecipe(self, "ComponentContainerRecipe",
    base_image=imagebuilder.BaseContainerImage.from_docker_hub("amazonlinux", "latest"),
    target_repository=imagebuilder.Repository.from_ecr(
        ecr.Repository.from_repository_name(self, "Repository", "my-container-repo")),
    components=[imagebuilder.ComponentConfiguration(
        component=custom_component
    )
    ]
)
java
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();
csharp
var customComponent = new Component(this, "MyComponent", new ComponentProps {
    Platform = Platform.LINUX,
    Data = ComponentData.FromJsonObject(new Dictionary<string, object> {
        { "schemaVersion", ComponentSchemaVersion.V1_0 },
        { "phases", new [] { new Dictionary<string, object> {
            { "name", ComponentPhaseName.BUILD },
            { "steps", new [] { new Struct {
                Name = "install-app",
                Action = ComponentAction.EXECUTE_BASH,
                Inputs = new Struct {
                    Commands = new [] { "yum install -y my-container-application" }
                }
            } } }
        } } }
    })
});

var containerRecipe = new ContainerRecipe(this, "ComponentContainerRecipe", new ContainerRecipeProps {
    BaseImage = BaseContainerImage.FromDockerHub("amazonlinux", "latest"),
    TargetRepository = Repository.FromEcr(Repository.FromRepositoryName(this, "Repository", "my-container-repo")),
    Components = new [] { new ComponentConfiguration {
        Component = customComponent
    } }
});
go
customComponent := imagebuilder.NewComponent(this, jsii.String("MyComponent"), &ComponentProps{
	Platform: imagebuilder.Platform_LINUX,
	Data: imagebuilder.ComponentData_FromJsonObject(map[string]interface{}{
		"schemaVersion": imagebuilder.ComponentSchemaVersion_V1_0,
		"phases": []interface{}{
			map[string]interface{}{
				"name": imagebuilder.ComponentPhaseName_BUILD,
				"steps": []map[string]interface{}{
					map[string]interface{}{
						"name": jsii.String("install-app"),
						"action": imagebuilder.ComponentAction_EXECUTE_BASH,
						"inputs": map[string][]*string{
							"commands": []*string{
								jsii.String("yum install -y my-container-application"),
							},
						},
					},
				},
			},
		},
	}),
})

containerRecipe := imagebuilder.NewContainerRecipe(this, jsii.String("ComponentContainerRecipe"), &ContainerRecipeProps{
	BaseImage: imagebuilder.BaseContainerImage_*FromDockerHub(jsii.String("amazonlinux"), jsii.String("latest")),
	TargetRepository: imagebuilder.Repository_*FromEcr(ecr.Repository_*FromRepositoryName(this, jsii.String("Repository"), jsii.String("my-container-repo"))),
	Components: []ComponentConfiguration{
		&ComponentConfiguration{
			Component: customComponent,
		},
	},
})
AWS-Managed Components in Container Recipes ​

Use pre-built AWS components:

ts
const containerRecipe = new imagebuilder.ContainerRecipe(this, 'AmazonManagedContainerRecipe', {
  baseImage: imagebuilder.BaseContainerImage.fromDockerHub('amazonlinux', 'latest'),
  targetRepository: imagebuilder.Repository.fromEcr(
    ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
  ),
  components: [
    {
      component: imagebuilder.AmazonManagedComponent.updateOs(this, 'UpdateOS', {
        platform: imagebuilder.Platform.LINUX
      })
    },
    {
      component: imagebuilder.AmazonManagedComponent.awsCliV2(this, 'AwsCli', {
        platform: imagebuilder.Platform.LINUX
      })
    }
  ]
});
python
container_recipe = imagebuilder.ContainerRecipe(self, "AmazonManagedContainerRecipe",
    base_image=imagebuilder.BaseContainerImage.from_docker_hub("amazonlinux", "latest"),
    target_repository=imagebuilder.Repository.from_ecr(
        ecr.Repository.from_repository_name(self, "Repository", "my-container-repo")),
    components=[imagebuilder.ComponentConfiguration(
        component=imagebuilder.AmazonManagedComponent.update_os(self, "UpdateOS",
            platform=imagebuilder.Platform.LINUX
        )
    ), imagebuilder.ComponentConfiguration(
        component=imagebuilder.AmazonManagedComponent.aws_cli_v2(self, "AwsCli",
            platform=imagebuilder.Platform.LINUX
        )
    )
    ]
)
java
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();
csharp
var containerRecipe = new ContainerRecipe(this, "AmazonManagedContainerRecipe", new ContainerRecipeProps {
    BaseImage = BaseContainerImage.FromDockerHub("amazonlinux", "latest"),
    TargetRepository = Repository.FromEcr(Repository.FromRepositoryName(this, "Repository", "my-container-repo")),
    Components = new [] { new ComponentConfiguration {
        Component = AmazonManagedComponent.UpdateOs(this, "UpdateOS", new AmazonManagedComponentOptions {
            Platform = Platform.LINUX
        })
    }, new ComponentConfiguration {
        Component = AmazonManagedComponent.AwsCliV2(this, "AwsCli", new AmazonManagedComponentOptions {
            Platform = Platform.LINUX
        })
    } }
});
go
containerRecipe := imagebuilder.NewContainerRecipe(this, jsii.String("AmazonManagedContainerRecipe"), &ContainerRecipeProps{
	BaseImage: imagebuilder.BaseContainerImage_*FromDockerHub(jsii.String("amazonlinux"), jsii.String("latest")),
	TargetRepository: imagebuilder.Repository_*FromEcr(ecr.Repository_*FromRepositoryName(this, jsii.String("Repository"), jsii.String("my-container-repo"))),
	Components: []ComponentConfiguration{
		&ComponentConfiguration{
			Component: imagebuilder.AmazonManagedComponent_UpdateOs(this, jsii.String("UpdateOS"), &AmazonManagedComponentOptions{
				Platform: imagebuilder.Platform_LINUX,
			}),
		},
		&ComponentConfiguration{
			Component: imagebuilder.AmazonManagedComponent_AwsCliV2(this, jsii.String("AwsCli"), &AmazonManagedComponentOptions{
				Platform: imagebuilder.Platform_LINUX,
			}),
		},
	},
})

Container Recipe Configuration ​

Custom Dockerfile ​

Provide your own Dockerfile template:

ts
const containerRecipe = new imagebuilder.ContainerRecipe(this, 'CustomDockerfileContainerRecipe', {
  baseImage: imagebuilder.BaseContainerImage.fromDockerHub('amazonlinux', 'latest'),
  targetRepository: imagebuilder.Repository.fromEcr(
    ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
  ),
  dockerfile: imagebuilder.DockerfileData.fromInline(`
FROM {{{ imagebuilder:parentImage }}}
CMD ["echo", "Hello, world!"]
{{{ imagebuilder:environments }}}
{{{ imagebuilder:components }}}
`)
});
python
container_recipe = imagebuilder.ContainerRecipe(self, "CustomDockerfileContainerRecipe",
    base_image=imagebuilder.BaseContainerImage.from_docker_hub("amazonlinux", "latest"),
    target_repository=imagebuilder.Repository.from_ecr(
        ecr.Repository.from_repository_name(self, "Repository", "my-container-repo")),
    dockerfile=imagebuilder.DockerfileData.from_inline("""
        FROM {{{ imagebuilder:parentImage }}}
        CMD ["echo", "Hello, world!"]
        {{{ imagebuilder:environments }}}
        {{{ imagebuilder:components }}}
        """)
)
java
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();
csharp
var containerRecipe = new ContainerRecipe(this, "CustomDockerfileContainerRecipe", new ContainerRecipeProps {
    BaseImage = BaseContainerImage.FromDockerHub("amazonlinux", "latest"),
    TargetRepository = Repository.FromEcr(Repository.FromRepositoryName(this, "Repository", "my-container-repo")),
    Dockerfile = DockerfileData.FromInline(@"
    FROM {{{ imagebuilder:parentImage }}}
    CMD [""echo"", ""Hello, world!""]
    {{{ imagebuilder:environments }}}
    {{{ imagebuilder:components }}}
    ")
});
go
containerRecipe := imagebuilder.NewContainerRecipe(this, jsii.String("CustomDockerfileContainerRecipe"), &ContainerRecipeProps{
	BaseImage: imagebuilder.BaseContainerImage_*FromDockerHub(jsii.String("amazonlinux"), jsii.String("latest")),
	TargetRepository: imagebuilder.Repository_*FromEcr(ecr.Repository_*FromRepositoryName(this, jsii.String("Repository"), jsii.String("my-container-repo"))),
	Dockerfile: imagebuilder.DockerfileData_FromInline(jsii.String(`
	FROM {{{ imagebuilder:parentImage }}}
	CMD ["echo", "Hello, world!"]
	{{{ imagebuilder:environments }}}
	{{{ imagebuilder:components }}}
	`)),
})
Instance Configuration ​

Configure the build instance:

ts
const containerRecipe = new imagebuilder.ContainerRecipe(this, 'InstanceConfigContainerRecipe', {
  baseImage: imagebuilder.BaseContainerImage.fromDockerHub('amazonlinux', 'latest'),
  targetRepository: imagebuilder.Repository.fromEcr(
    ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
  ),
  // Custom ECS-optimized AMI for building
  instanceImage: imagebuilder.ContainerInstanceImage.fromSsmParameterName(
    '/aws/service/ecs/optimized-ami/amazon-linux-2023/recommended/image_id'
  ),
  // Additional storage for build process
  instanceBlockDevices: [
    {
      deviceName: '/dev/xvda',
      volume: ec2.BlockDeviceVolume.ebs(50, {
        encrypted: true,
        volumeType: ec2.EbsDeviceVolumeType.GENERAL_PURPOSE_SSD_GP3
      })
    }
  ]
});
python
container_recipe = imagebuilder.ContainerRecipe(self, "InstanceConfigContainerRecipe",
    base_image=imagebuilder.BaseContainerImage.from_docker_hub("amazonlinux", "latest"),
    target_repository=imagebuilder.Repository.from_ecr(
        ecr.Repository.from_repository_name(self, "Repository", "my-container-repo")),
    # Custom ECS-optimized AMI for building
    instance_image=imagebuilder.ContainerInstanceImage.from_ssm_parameter_name("/aws/service/ecs/optimized-ami/amazon-linux-2023/recommended/image_id"),
    # Additional storage for build process
    instance_block_devices=[ec2.BlockDevice(
        device_name="/dev/xvda",
        volume=ec2.BlockDeviceVolume.ebs(50,
            encrypted=True,
            volume_type=ec2.EbsDeviceVolumeType.GENERAL_PURPOSE_SSD_GP3
        )
    )
    ]
)
java
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();
csharp
var containerRecipe = new ContainerRecipe(this, "InstanceConfigContainerRecipe", new ContainerRecipeProps {
    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 = new [] { new BlockDevice {
        DeviceName = "/dev/xvda",
        Volume = BlockDeviceVolume.Ebs(50, new EbsDeviceOptions {
            Encrypted = true,
            VolumeType = EbsDeviceVolumeType.GENERAL_PURPOSE_SSD_GP3
        })
    } }
});
go
containerRecipe := imagebuilder.NewContainerRecipe(this, jsii.String("InstanceConfigContainerRecipe"), &ContainerRecipeProps{
	BaseImage: imagebuilder.BaseContainerImage_*FromDockerHub(jsii.String("amazonlinux"), jsii.String("latest")),
	TargetRepository: imagebuilder.Repository_*FromEcr(ecr.Repository_*FromRepositoryName(this, jsii.String("Repository"), jsii.String("my-container-repo"))),
	// Custom ECS-optimized AMI for building
	InstanceImage: imagebuilder.ContainerInstanceImage_FromSsmParameterName(jsii.String("/aws/service/ecs/optimized-ami/amazon-linux-2023/recommended/image_id")),
	// Additional storage for build process
	InstanceBlockDevices: []BlockDevice{
		&BlockDevice{
			DeviceName: jsii.String("/dev/xvda"),
			Volume: ec2.BlockDeviceVolume_Ebs(jsii.Number(50), &EbsDeviceOptions{
				Encrypted: jsii.Boolean(true),
				VolumeType: ec2.EbsDeviceVolumeType_GENERAL_PURPOSE_SSD_GP3,
			}),
		},
	},
})

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.

ts
const component = new imagebuilder.Component(this, 'MyComponent', {
  platform: imagebuilder.Platform.LINUX,
  data: imagebuilder.ComponentData.fromJsonObject({
    schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0,
    phases: [
      {
        name: imagebuilder.ComponentPhaseName.BUILD,
        steps: [
          {
            name: 'install-app',
            action: imagebuilder.ComponentAction.EXECUTE_BASH,
            inputs: {
              commands: ['echo "Installing my application..."', 'yum update -y'],
            },
          },
        ],
      },
    ],
  }),
});
python
component = imagebuilder.Component(self, "MyComponent",
    platform=imagebuilder.Platform.LINUX,
    data=imagebuilder.ComponentData.from_json_object({
        "schema_version": imagebuilder.ComponentSchemaVersion.V1_0,
        "phases": [{
            "name": imagebuilder.ComponentPhaseName.BUILD,
            "steps": [{
                "name": "install-app",
                "action": imagebuilder.ComponentAction.EXECUTE_BASH,
                "inputs": {
                    "commands": ["echo \"Installing my application...\"", "yum update -y"]
                }
            }
            ]
        }
        ]
    })
)
java
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();
csharp
var component = new Component(this, "MyComponent", new ComponentProps {
    Platform = Platform.LINUX,
    Data = ComponentData.FromJsonObject(new Dictionary<string, object> {
        { "schemaVersion", ComponentSchemaVersion.V1_0 },
        { "phases", new [] { new Dictionary<string, object> {
            { "name", ComponentPhaseName.BUILD },
            { "steps", new [] { new Struct {
                Name = "install-app",
                Action = ComponentAction.EXECUTE_BASH,
                Inputs = new Struct {
                    Commands = new [] { "echo \"Installing my application...\"", "yum update -y" }
                }
            } } }
        } } }
    })
});
go
component := imagebuilder.NewComponent(this, jsii.String("MyComponent"), &ComponentProps{
	Platform: imagebuilder.Platform_LINUX,
	Data: imagebuilder.ComponentData_FromJsonObject(map[string]interface{}{
		"schemaVersion": imagebuilder.ComponentSchemaVersion_V1_0,
		"phases": []interface{}{
			map[string]interface{}{
				"name": imagebuilder.ComponentPhaseName_BUILD,
				"steps": []map[string]interface{}{
					map[string]interface{}{
						"name": jsii.String("install-app"),
						"action": imagebuilder.ComponentAction_EXECUTE_BASH,
						"inputs": map[string][]*string{
							"commands": []*string{
								jsii.String("echo \"Installing my application...\""),
								jsii.String("yum update -y"),
							},
						},
					},
				},
			},
		},
	}),
})

Component Data Sources ​

Inline Component Data ​

Use ComponentData.fromInline() for existing YAML/JSON definitions:

ts
const component = new imagebuilder.Component(this, 'InlineComponent', {
  platform: imagebuilder.Platform.LINUX,
  data: imagebuilder.ComponentData.fromInline(`
name: my-component
schemaVersion: 1.0
phases:
  - name: build
    steps:
      - name: update-os
        action: ExecuteBash
        inputs:
          commands: ['yum update -y']
`)
});
python
component = imagebuilder.Component(self, "InlineComponent",
    platform=imagebuilder.Platform.LINUX,
    data=imagebuilder.ComponentData.from_inline("""
        name: my-component
        schemaVersion: 1.0
        phases:
          - name: build
            steps:
              - name: update-os
                action: ExecuteBash
                inputs:
                  commands: ['yum update -y']
        """)
)
java
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();
csharp
var component = new Component(this, "InlineComponent", new ComponentProps {
    Platform = Platform.LINUX,
    Data = ComponentData.FromInline(@"
    name: my-component
    schemaVersion: 1.0
    phases:
      - name: build
        steps:
          - name: update-os
            action: ExecuteBash
            inputs:
              commands: ['yum update -y']
    ")
});
go
component := imagebuilder.NewComponent(this, jsii.String("InlineComponent"), &ComponentProps{
	Platform: imagebuilder.Platform_LINUX,
	Data: imagebuilder.ComponentData_FromInline(jsii.String(`
	name: my-component
	schemaVersion: 1.0
	phases:
	  - name: build
	    steps:
	      - name: update-os
	        action: ExecuteBash
	        inputs:
	          commands: ['yum update -y']
	`)),
})
JSON Object Component Data ​

Most developer-friendly approach using objects:

ts

const component = new imagebuilder.Component(this, 'JsonComponent', {
  platform: imagebuilder.Platform.LINUX,
  data: imagebuilder.ComponentData.fromJsonObject({
    schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0,
    phases: [
      {
        name: imagebuilder.ComponentPhaseName.BUILD,
        steps: [
          {
            name: 'configure-app',
            action: imagebuilder.ComponentAction.CREATE_FILE,
            inputs: {
              path: '/etc/myapp/config.json',
              content: '{"env": "production"}'
            }
          }
        ]
      }
    ]
  })
});
python
component = imagebuilder.Component(self, "JsonComponent",
    platform=imagebuilder.Platform.LINUX,
    data=imagebuilder.ComponentData.from_json_object({
        "schema_version": imagebuilder.ComponentSchemaVersion.V1_0,
        "phases": [{
            "name": imagebuilder.ComponentPhaseName.BUILD,
            "steps": [{
                "name": "configure-app",
                "action": imagebuilder.ComponentAction.CREATE_FILE,
                "inputs": {
                    "path": "/etc/myapp/config.json",
                    "content": "{\"env\": \"production\"}"
                }
            }
            ]
        }
        ]
    })
)
java
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();
csharp
var component = new Component(this, "JsonComponent", new ComponentProps {
    Platform = Platform.LINUX,
    Data = ComponentData.FromJsonObject(new Dictionary<string, object> {
        { "schemaVersion", ComponentSchemaVersion.V1_0 },
        { "phases", new [] { new Dictionary<string, object> {
            { "name", ComponentPhaseName.BUILD },
            { "steps", new [] { new Struct {
                Name = "configure-app",
                Action = ComponentAction.CREATE_FILE,
                Inputs = new Struct {
                    Path = "/etc/myapp/config.json",
                    Content = "{\"env\": \"production\"}"
                }
            } } }
        } } }
    })
});
go
component := imagebuilder.NewComponent(this, jsii.String("JsonComponent"), &ComponentProps{
	Platform: imagebuilder.Platform_LINUX,
	Data: imagebuilder.ComponentData_FromJsonObject(map[string]interface{}{
		"schemaVersion": imagebuilder.ComponentSchemaVersion_V1_0,
		"phases": []interface{}{
			map[string]interface{}{
				"name": imagebuilder.ComponentPhaseName_BUILD,
				"steps": []map[string]interface{}{
					map[string]interface{}{
						"name": jsii.String("configure-app"),
						"action": imagebuilder.ComponentAction_CREATE_FILE,
						"inputs": map[string]*string{
							"path": jsii.String("/etc/myapp/config.json"),
							"content": jsii.String("{\"env\": \"production\"}"),
						},
					},
				},
			},
		},
	}),
})
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:

ts
const step: imagebuilder.ComponentDocumentStep = {
  name: 'configure-app',
  action: imagebuilder.ComponentAction.CREATE_FILE,
  inputs: imagebuilder.ComponentStepInputs.fromObject({
    path: '/etc/myapp/config.json',
    content: '{"env": "production"}'
  })
};
python
step = imagebuilder.ComponentDocumentStep(
    name="configure-app",
    action=imagebuilder.ComponentAction.CREATE_FILE,
    inputs=imagebuilder.ComponentStepInputs.from_object({
        "path": "/etc/myapp/config.json",
        "content": "{\"env\": \"production\"}"
    })
)
java
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();
csharp
var step = new ComponentDocumentStep {
    Name = "configure-app",
    Action = ComponentAction.CREATE_FILE,
    Inputs = ComponentStepInputs.FromObject(new Dictionary<string, object> {
        { "path", "/etc/myapp/config.json" },
        { "content", "{\"env\": \"production\"}" }
    })
};
go
step := &ComponentDocumentStep{
	Name: jsii.String("configure-app"),
	Action: imagebuilder.ComponentAction_CREATE_FILE,
	Inputs: imagebuilder.ComponentStepInputs_FromObject(map[string]interface{}{
		"path": jsii.String("/etc/myapp/config.json"),
		"content": jsii.String("{\"env\": \"production\"}"),
	}),
}
Defining a component phase ​

Phases group steps together, which run in sequence when building, validating or testing in the component:

ts
const phase: imagebuilder.ComponentDocumentPhase = {
  name: imagebuilder.ComponentPhaseName.BUILD,
  steps: [
    {
      name: 'configure-app',
      action: imagebuilder.ComponentAction.CREATE_FILE,
      inputs: imagebuilder.ComponentStepInputs.fromObject({
        path: '/etc/myapp/config.json',
        content: '{"env": "production"}'
      })
    }
  ]
};
python
phase = imagebuilder.ComponentDocumentPhase(
    name=imagebuilder.ComponentPhaseName.BUILD,
    steps=[imagebuilder.ComponentDocumentStep(
        name="configure-app",
        action=imagebuilder.ComponentAction.CREATE_FILE,
        inputs=imagebuilder.ComponentStepInputs.from_object({
            "path": "/etc/myapp/config.json",
            "content": "{\"env\": \"production\"}"
        })
    )
    ]
)
java
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();
csharp
var phase = new ComponentDocumentPhase {
    Name = ComponentPhaseName.BUILD,
    Steps = new [] { new ComponentDocumentStep {
        Name = "configure-app",
        Action = ComponentAction.CREATE_FILE,
        Inputs = ComponentStepInputs.FromObject(new Dictionary<string, object> {
            { "path", "/etc/myapp/config.json" },
            { "content", "{\"env\": \"production\"}" }
        })
    } }
};
go
phase := &ComponentDocumentPhase{
	Name: imagebuilder.ComponentPhaseName_BUILD,
	Steps: []ComponentDocumentStep{
		&ComponentDocumentStep{
			Name: jsii.String("configure-app"),
			Action: imagebuilder.ComponentAction_CREATE_FILE,
			Inputs: imagebuilder.ComponentStepInputs_FromObject(map[string]interface{}{
				"path": jsii.String("/etc/myapp/config.json"),
				"content": jsii.String("{\"env\": \"production\"}"),
			}),
		},
	},
}
Defining a component ​

The component data defines all steps across the provided phases to execute during the build:

ts
const component = new imagebuilder.Component(this, 'StructuredComponent', {
  platform: imagebuilder.Platform.LINUX,
  data: imagebuilder.ComponentData.fromComponentDocumentJsonObject({
    schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0,
    phases: [
      {
        name: imagebuilder.ComponentPhaseName.BUILD,
        steps: [
          {
            name: 'install-with-timeout',
            action: imagebuilder.ComponentAction.EXECUTE_BASH,
            timeout: Duration.minutes(10),
            onFailure: imagebuilder.ComponentOnFailure.CONTINUE,
            inputs: imagebuilder.ComponentStepInputs.fromObject({
              commands: ['./install-script.sh']
            })
          }
        ]
      }
    ]
  })
});
python
component = imagebuilder.Component(self, "StructuredComponent",
    platform=imagebuilder.Platform.LINUX,
    data=imagebuilder.ComponentData.from_component_document_json_object(
        schema_version=imagebuilder.ComponentSchemaVersion.V1_0,
        phases=[imagebuilder.ComponentDocumentPhase(
            name=imagebuilder.ComponentPhaseName.BUILD,
            steps=[imagebuilder.ComponentDocumentStep(
                name="install-with-timeout",
                action=imagebuilder.ComponentAction.EXECUTE_BASH,
                timeout=Duration.minutes(10),
                on_failure=imagebuilder.ComponentOnFailure.CONTINUE,
                inputs=imagebuilder.ComponentStepInputs.from_object({
                    "commands": ["./install-script.sh"]
                })
            )
            ]
        )
        ]
    )
)
java
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();
csharp
var component = new Component(this, "StructuredComponent", new ComponentProps {
    Platform = Platform.LINUX,
    Data = ComponentData.FromComponentDocumentJsonObject(new ComponentDocument {
        SchemaVersion = ComponentSchemaVersion.V1_0,
        Phases = new [] { new ComponentDocumentPhase {
            Name = ComponentPhaseName.BUILD,
            Steps = new [] { new ComponentDocumentStep {
                Name = "install-with-timeout",
                Action = ComponentAction.EXECUTE_BASH,
                Timeout = Duration.Minutes(10),
                OnFailure = ComponentOnFailure.CONTINUE,
                Inputs = ComponentStepInputs.FromObject(new Dictionary<string, object> {
                    { "commands", new [] { "./install-script.sh" } }
                })
            } }
        } }
    })
});
go
component := imagebuilder.NewComponent(this, jsii.String("StructuredComponent"), &ComponentProps{
	Platform: imagebuilder.Platform_LINUX,
	Data: imagebuilder.ComponentData_FromComponentDocumentJsonObject(&ComponentDocument{
		SchemaVersion: imagebuilder.ComponentSchemaVersion_V1_0,
		Phases: []ComponentDocumentPhase{
			&ComponentDocumentPhase{
				Name: imagebuilder.ComponentPhaseName_BUILD,
				Steps: []ComponentDocumentStep{
					&ComponentDocumentStep{
						Name: jsii.String("install-with-timeout"),
						Action: imagebuilder.ComponentAction_EXECUTE_BASH,
						Timeout: awscdk.Duration_Minutes(jsii.Number(10)),
						OnFailure: imagebuilder.ComponentOnFailure_CONTINUE,
						Inputs: imagebuilder.ComponentStepInputs_FromObject(map[string]interface{}{
							"commands": []interface{}{
								jsii.String("./install-script.sh"),
							},
						}),
					},
				},
			},
		},
	}),
})
S3 Component Data ​

For those components you want to upload or have uploaded to S3:

ts
// Upload a local file
const componentFromAsset = new imagebuilder.Component(this, 'AssetComponent', {
  platform: imagebuilder.Platform.LINUX,
  data: imagebuilder.ComponentData.fromAsset(this, 'ComponentAsset', './my-component.yml'),
});

// Reference an existing S3 object
const bucket = s3.Bucket.fromBucketName(this, 'ComponentBucket', 'my-components-bucket');
const componentFromS3 = new imagebuilder.Component(this, 'S3Component', {
  platform: imagebuilder.Platform.LINUX,
  data: imagebuilder.ComponentData.fromS3(bucket, 'components/my-component.yml'),
});
python
# Upload a local file
component_from_asset = imagebuilder.Component(self, "AssetComponent",
    platform=imagebuilder.Platform.LINUX,
    data=imagebuilder.ComponentData.from_asset(self, "ComponentAsset", "./my-component.yml")
)

# Reference an existing S3 object
bucket = s3.Bucket.from_bucket_name(self, "ComponentBucket", "my-components-bucket")
component_from_s3 = imagebuilder.Component(self, "S3Component",
    platform=imagebuilder.Platform.LINUX,
    data=imagebuilder.ComponentData.from_s3(bucket, "components/my-component.yml")
)
java
// 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();
csharp
// Upload a local file
var componentFromAsset = new Component(this, "AssetComponent", new ComponentProps {
    Platform = Platform.LINUX,
    Data = ComponentData.FromAsset(this, "ComponentAsset", "./my-component.yml")
});

// Reference an existing S3 object
var bucket = Bucket.FromBucketName(this, "ComponentBucket", "my-components-bucket");
var componentFromS3 = new Component(this, "S3Component", new ComponentProps {
    Platform = Platform.LINUX,
    Data = ComponentData.FromS3(bucket, "components/my-component.yml")
});
go
// Upload a local file
componentFromAsset := imagebuilder.NewComponent(this, jsii.String("AssetComponent"), &ComponentProps{
	Platform: imagebuilder.Platform_LINUX,
	Data: imagebuilder.ComponentData_FromAsset(this, jsii.String("ComponentAsset"), jsii.String("./my-component.yml")),
})

// Reference an existing S3 object
bucket := s3.Bucket_FromBucketName(this, jsii.String("ComponentBucket"), jsii.String("my-components-bucket"))
componentFromS3 := imagebuilder.NewComponent(this, jsii.String("S3Component"), &ComponentProps{
	Platform: imagebuilder.Platform_LINUX,
	Data: imagebuilder.ComponentData_FromS3(bucket, jsii.String("components/my-component.yml")),
})

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.

ts
const component = new imagebuilder.Component(this, 'EncryptedComponent', {
  platform: imagebuilder.Platform.LINUX,
  kmsKey: new kms.Key(this, 'ComponentKey'),
  data: imagebuilder.ComponentData.fromJsonObject({
    schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0,
    phases: [
      {
        name: imagebuilder.ComponentPhaseName.BUILD,
        steps: [
          {
            name: 'secure-setup',
            action: imagebuilder.ComponentAction.EXECUTE_BASH,
            inputs: {
              commands: ['echo "This component data is encrypted with KMS"']
            }
          }
        ]
      }
    ]
  })
});
python
component = imagebuilder.Component(self, "EncryptedComponent",
    platform=imagebuilder.Platform.LINUX,
    kms_key=kms.Key(self, "ComponentKey"),
    data=imagebuilder.ComponentData.from_json_object({
        "schema_version": imagebuilder.ComponentSchemaVersion.V1_0,
        "phases": [{
            "name": imagebuilder.ComponentPhaseName.BUILD,
            "steps": [{
                "name": "secure-setup",
                "action": imagebuilder.ComponentAction.EXECUTE_BASH,
                "inputs": {
                    "commands": ["echo \"This component data is encrypted with KMS\""]
                }
            }
            ]
        }
        ]
    })
)
java
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();
csharp
var component = new Component(this, "EncryptedComponent", new ComponentProps {
    Platform = Platform.LINUX,
    KmsKey = new Key(this, "ComponentKey"),
    Data = ComponentData.FromJsonObject(new Dictionary<string, object> {
        { "schemaVersion", ComponentSchemaVersion.V1_0 },
        { "phases", new [] { new Dictionary<string, object> {
            { "name", ComponentPhaseName.BUILD },
            { "steps", new [] { new Struct {
                Name = "secure-setup",
                Action = ComponentAction.EXECUTE_BASH,
                Inputs = new Struct {
                    Commands = new [] { "echo \"This component data is encrypted with KMS\"" }
                }
            } } }
        } } }
    })
});
go
component := imagebuilder.NewComponent(this, jsii.String("EncryptedComponent"), &ComponentProps{
	Platform: imagebuilder.Platform_LINUX,
	KmsKey: kms.NewKey(this, jsii.String("ComponentKey")),
	Data: imagebuilder.ComponentData_FromJsonObject(map[string]interface{}{
		"schemaVersion": imagebuilder.ComponentSchemaVersion_V1_0,
		"phases": []interface{}{
			map[string]interface{}{
				"name": imagebuilder.ComponentPhaseName_BUILD,
				"steps": []map[string]interface{}{
					map[string]interface{}{
						"name": jsii.String("secure-setup"),
						"action": imagebuilder.ComponentAction_EXECUTE_BASH,
						"inputs": map[string][]*string{
							"commands": []*string{
								jsii.String("echo \"This component data is encrypted with KMS\""),
							},
						},
					},
				},
			},
		},
	}),
})

AWS-Managed Components ​

AWS provides a collection of managed components for common tasks:

ts
// Install AWS CLI v2
const awsCliComponent = imagebuilder.AmazonManagedComponent.awsCliV2(this, 'AwsCli', {
  platform: imagebuilder.Platform.LINUX
});

// Update the operating system
const updateComponent = imagebuilder.AmazonManagedComponent.updateOs(this, 'UpdateOS', {
  platform: imagebuilder.Platform.LINUX
});

// Reference any AWS-managed component by name
const customAwsComponent = imagebuilder.AmazonManagedComponent.fromAmazonManagedComponentName(
  this,
  'CloudWatchAgent',
  'amazon-cloudwatch-agent-linux'
);
python
# Install AWS CLI v2
aws_cli_component = imagebuilder.AmazonManagedComponent.aws_cli_v2(self, "AwsCli",
    platform=imagebuilder.Platform.LINUX
)

# Update the operating system
update_component = imagebuilder.AmazonManagedComponent.update_os(self, "UpdateOS",
    platform=imagebuilder.Platform.LINUX
)

# Reference any AWS-managed component by name
custom_aws_component = imagebuilder.AmazonManagedComponent.from_amazon_managed_component_name(self, "CloudWatchAgent", "amazon-cloudwatch-agent-linux")
java
// 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");
csharp
// Install AWS CLI v2
var awsCliComponent = AmazonManagedComponent.AwsCliV2(this, "AwsCli", new AmazonManagedComponentOptions {
    Platform = Platform.LINUX
});

// Update the operating system
var updateComponent = AmazonManagedComponent.UpdateOs(this, "UpdateOS", new AmazonManagedComponentOptions {
    Platform = Platform.LINUX
});

// Reference any AWS-managed component by name
var customAwsComponent = AmazonManagedComponent.FromAmazonManagedComponentName(this, "CloudWatchAgent", "amazon-cloudwatch-agent-linux");
go
// Install AWS CLI v2
awsCliComponent := imagebuilder.AmazonManagedComponent_AwsCliV2(this, jsii.String("AwsCli"), &AmazonManagedComponentOptions{
	Platform: imagebuilder.Platform_LINUX,
})

// Update the operating system
updateComponent := imagebuilder.AmazonManagedComponent_UpdateOs(this, jsii.String("UpdateOS"), &AmazonManagedComponentOptions{
	Platform: imagebuilder.Platform_LINUX,
})

// Reference any AWS-managed component by name
customAwsComponent := imagebuilder.AmazonManagedComponent_FromAmazonManagedComponentName(this, jsii.String("CloudWatchAgent"), jsii.String("amazon-cloudwatch-agent-linux"))

AWS Marketplace Components ​

You can reference AWS Marketplace components using the marketplace component name and its product ID:

ts
const marketplaceComponent = imagebuilder.AwsMarketplaceComponent.fromAwsMarketplaceComponentAttributes(
  this,
  'MarketplaceComponent',
  {
    componentName: 'my-marketplace-component',
    marketplaceProductId: 'prod-1234567890abcdef0',
  }
);
python
marketplace_component = imagebuilder.AwsMarketplaceComponent.from_aws_marketplace_component_attributes(self, "MarketplaceComponent",
    component_name="my-marketplace-component",
    marketplace_product_id="prod-1234567890abcdef0"
)
java
IComponent marketplaceComponent = AwsMarketplaceComponent.fromAwsMarketplaceComponentAttributes(this, "MarketplaceComponent", AwsMarketplaceComponentAttributes.builder()
        .componentName("my-marketplace-component")
        .marketplaceProductId("prod-1234567890abcdef0")
        .build());
csharp
var marketplaceComponent = AwsMarketplaceComponent.FromAwsMarketplaceComponentAttributes(this, "MarketplaceComponent", new AwsMarketplaceComponentAttributes {
    ComponentName = "my-marketplace-component",
    MarketplaceProductId = "prod-1234567890abcdef0"
});
go
marketplaceComponent := imagebuilder.AwsMarketplaceComponent_FromAwsMarketplaceComponentAttributes(this, jsii.String("MarketplaceComponent"), &AwsMarketplaceComponentAttributes{
	ComponentName: jsii.String("my-marketplace-component"),
	MarketplaceProductId: jsii.String("prod-1234567890abcdef0"),
})

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.

ts
const infrastructureConfiguration = new imagebuilder.InfrastructureConfiguration(this, 'InfrastructureConfiguration', {
  infrastructureConfigurationName: 'test-infrastructure-configuration',
  description: 'An Infrastructure Configuration',
  // Optional - instance types to use for build/test
  instanceTypes: [
    ec2.InstanceType.of(ec2.InstanceClass.STANDARD7_INTEL, ec2.InstanceSize.LARGE),
    ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.LARGE)
  ],
  // Optional - create an instance profile with necessary permissions
  instanceProfile: new iam.InstanceProfile(this, 'InstanceProfile', {
    instanceProfileName: 'test-instance-profile',
    role: new iam.Role(this, 'InstanceProfileRole', {
      assumedBy: iam.ServicePrincipal.fromStaticServicePrincipleName('ec2.amazonaws.com'),
      managedPolicies: [
        iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'),
        iam.ManagedPolicy.fromAwsManagedPolicyName('EC2InstanceProfileForImageBuilder')
      ]
    })
  }),
  // Use VPC network configuration
  vpc,
  subnetSelection: { subnetType: ec2.SubnetType.PUBLIC },
  securityGroups: [ec2.SecurityGroup.fromSecurityGroupId(this, 'SecurityGroup', vpc.vpcDefaultSecurityGroup)],
  keyPair: ec2.KeyPair.fromKeyPairName(this, 'KeyPair', 'imagebuilder-instance-key-pair'),
  terminateInstanceOnFailure: true,
  // Optional - IMDSv2 settings
  httpTokens: imagebuilder.HttpTokens.REQUIRED,
  httpPutResponseHopLimit: 1,
  // Optional - publish image completion messages to an SNS topic
  notificationTopic: sns.Topic.fromTopicArn(
    this,
    'Topic',
    this.formatArn({ service: 'sns', resource: 'image-builder-topic' })
  ),
  // Optional - log settings. Logging is enabled by default
  logging: {
    s3Bucket: s3.Bucket.fromBucketName(this, 'LogBucket', `imagebuilder-logging-${Aws.ACCOUNT_ID}`),
    s3KeyPrefix: 'imagebuilder-logs'
  },
  // Optional - host placement settings
  ec2InstanceAvailabilityZone: Stack.of(this).availabilityZones[0],
  ec2InstanceHostId: dedicatedHost.attrHostId,
  ec2InstanceTenancy: imagebuilder.Tenancy.HOST,
  resourceTags: {
    Environment: 'production'
  }
});
python
infrastructure_configuration = imagebuilder.InfrastructureConfiguration(self, "InfrastructureConfiguration",
    infrastructure_configuration_name="test-infrastructure-configuration",
    description="An Infrastructure Configuration",
    # Optional - instance types to use for build/test
    instance_types=[
        ec2.InstanceType.of(ec2.InstanceClass.STANDARD7_INTEL, ec2.InstanceSize.LARGE),
        ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.LARGE)
    ],
    # Optional - create an instance profile with necessary permissions
    instance_profile=iam.InstanceProfile(self, "InstanceProfile",
        instance_profile_name="test-instance-profile",
        role=iam.Role(self, "InstanceProfileRole",
            assumed_by=iam.ServicePrincipal.from_static_service_principle_name("ec2.amazonaws.com"),
            managed_policies=[
                iam.ManagedPolicy.from_aws_managed_policy_name("AmazonSSMManagedInstanceCore"),
                iam.ManagedPolicy.from_aws_managed_policy_name("EC2InstanceProfileForImageBuilder")
            ]
        )
    ),
    # Use VPC network configuration
    vpc=vpc,
    subnet_selection=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC),
    security_groups=[ec2.SecurityGroup.from_security_group_id(self, "SecurityGroup", vpc.vpc_default_security_group)],
    key_pair=ec2.KeyPair.from_key_pair_name(self, "KeyPair", "imagebuilder-instance-key-pair"),
    terminate_instance_on_failure=True,
    # Optional - IMDSv2 settings
    http_tokens=imagebuilder.HttpTokens.REQUIRED,
    http_put_response_hop_limit=1,
    # Optional - publish image completion messages to an SNS topic
    notification_topic=sns.Topic.from_topic_arn(self, "Topic",
        self.format_arn(service="sns", resource="image-builder-topic")),
    # Optional - log settings. Logging is enabled by default
    logging=imagebuilder.InfrastructureConfigurationLogging(
        s3_bucket=s3.Bucket.from_bucket_name(self, "LogBucket", f"imagebuilder-logging-{Aws.ACCOUNT_ID}"),
        s3_key_prefix="imagebuilder-logs"
    ),
    # Optional - host placement settings
    ec2_instance_availability_zone=Stack.of(self).availability_zones[0],
    ec2_instance_host_id=dedicated_host.attr_host_id,
    ec2_instance_tenancy=imagebuilder.Tenancy.HOST,
    resource_tags={
        "Environment": "production"
    }
)
java
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();
csharp
var infrastructureConfiguration = new InfrastructureConfiguration(this, "InfrastructureConfiguration", new InfrastructureConfigurationProps {
    InfrastructureConfigurationName = "test-infrastructure-configuration",
    Description = "An Infrastructure Configuration",
    // Optional - instance types to use for build/test
    InstanceTypes = new [] { InstanceType.Of(InstanceClass.STANDARD7_INTEL, InstanceSize.LARGE), InstanceType.Of(InstanceClass.BURSTABLE3, InstanceSize.LARGE) },
    // Optional - create an instance profile with necessary permissions
    InstanceProfile = new InstanceProfile(this, "InstanceProfile", new InstanceProfileProps {
        InstanceProfileName = "test-instance-profile",
        Role = new Role(this, "InstanceProfileRole", new RoleProps {
            AssumedBy = ServicePrincipal.FromStaticServicePrincipleName("ec2.amazonaws.com"),
            ManagedPolicies = new [] { ManagedPolicy.FromAwsManagedPolicyName("AmazonSSMManagedInstanceCore"), ManagedPolicy.FromAwsManagedPolicyName("EC2InstanceProfileForImageBuilder") }
        })
    }),
    // Use VPC network configuration
    Vpc = vpc,
    SubnetSelection = new SubnetSelection { SubnetType = SubnetType.PUBLIC },
    SecurityGroups = new [] { SecurityGroup.FromSecurityGroupId(this, "SecurityGroup", vpc.VpcDefaultSecurityGroup) },
    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", FormatArn(new ArnComponents { Service = "sns", Resource = "image-builder-topic" })),
    // Optional - log settings. Logging is enabled by default
    Logging = new InfrastructureConfigurationLogging {
        S3Bucket = Bucket.FromBucketName(this, "LogBucket", $"imagebuilder-logging-{Aws.ACCOUNT_ID}"),
        S3KeyPrefix = "imagebuilder-logs"
    },
    // Optional - host placement settings
    Ec2InstanceAvailabilityZone = Stack.Of(this).AvailabilityZones[0],
    Ec2InstanceHostId = dedicatedHost.AttrHostId,
    Ec2InstanceTenancy = Tenancy.HOST,
    ResourceTags = new Dictionary<string, string> {
        { "Environment", "production" }
    }
});
go
infrastructureConfiguration := imagebuilder.NewInfrastructureConfiguration(this, jsii.String("InfrastructureConfiguration"), &InfrastructureConfigurationProps{
	InfrastructureConfigurationName: jsii.String("test-infrastructure-configuration"),
	Description: jsii.String("An Infrastructure Configuration"),
	// Optional - instance types to use for build/test
	InstanceTypes: []InstanceType{
		ec2.InstanceType_*Of(ec2.InstanceClass_STANDARD7_INTEL, ec2.InstanceSize_LARGE),
		ec2.InstanceType_*Of(ec2.InstanceClass_BURSTABLE3, ec2.InstanceSize_LARGE),
	},
	// Optional - create an instance profile with necessary permissions
	InstanceProfile: iam.NewInstanceProfile(this, jsii.String("InstanceProfile"), &InstanceProfileProps{
		InstanceProfileName: jsii.String("test-instance-profile"),
		Role: iam.NewRole(this, jsii.String("InstanceProfileRole"), &RoleProps{
			AssumedBy: iam.ServicePrincipal_FromStaticServicePrincipleName(jsii.String("ec2.amazonaws.com")),
			ManagedPolicies: []IManagedPolicy{
				iam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("AmazonSSMManagedInstanceCore")),
				iam.ManagedPolicy_*FromAwsManagedPolicyName(jsii.String("EC2InstanceProfileForImageBuilder")),
			},
		}),
	}),
	// Use VPC network configuration
	Vpc: Vpc,
	SubnetSelection: &SubnetSelection{
		SubnetType: ec2.SubnetType_PUBLIC,
	},
	SecurityGroups: []ISecurityGroup{
		ec2.SecurityGroup_FromSecurityGroupId(this, jsii.String("SecurityGroup"), vpc.VpcDefaultSecurityGroup),
	},
	KeyPair: ec2.KeyPair_FromKeyPairName(this, jsii.String("KeyPair"), jsii.String("imagebuilder-instance-key-pair")),
	TerminateInstanceOnFailure: jsii.Boolean(true),
	// Optional - IMDSv2 settings
	HttpTokens: imagebuilder.HttpTokens_REQUIRED,
	HttpPutResponseHopLimit: jsii.Number(1),
	// Optional - publish image completion messages to an SNS topic
	NotificationTopic: sns.Topic_FromTopicArn(this, jsii.String("Topic"), this.FormatArn(&ArnComponents{
		Service: jsii.String("sns"),
		Resource: jsii.String("image-builder-topic"),
	})),
	// Optional - log settings. Logging is enabled by default
	Logging: &InfrastructureConfigurationLogging{
		S3Bucket: s3.Bucket_FromBucketName(this, jsii.String("LogBucket"), fmt.Sprintf("imagebuilder-logging-%v", awscdk.Aws_ACCOUNT_ID())),
		S3KeyPrefix: jsii.String("imagebuilder-logs"),
	},
	// Optional - host placement settings
	Ec2InstanceAvailabilityZone: awscdk.*stack_*Of(this).availabilityZones[jsii.Number(0)],
	Ec2InstanceHostId: dedicatedHost.attrHostId,
	Ec2InstanceTenancy: imagebuilder.Tenancy_HOST,
	ResourceTags: map[string]*string{
		"Environment": jsii.String("production"),
	},
})

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.:

ts
const distributionConfiguration = new imagebuilder.DistributionConfiguration(this, 'DistributionConfiguration', {
  distributionConfigurationName: 'test-distribution-configuration',
  description: 'A Distribution Configuration',
  amiDistributions: [
    {
      // Distribute AMI to us-east-2 and publish the AMI ID to an SSM parameter
      region: 'us-east-2',
      ssmParameters: [
        {
          parameter: ssm.StringParameter.fromStringParameterAttributes(this, 'CrossRegionParameter', {
            parameterName: '/imagebuilder/ami',
            forceDynamicReference: true
          })
        }
      ]
    }
  ]
});

// For AMI-based image builds - add an AMI distribution in the current region
distributionConfiguration.addAmiDistributions({
  amiName: 'imagebuilder-{{ imagebuilder:buildDate }}',
  amiDescription: 'Build AMI',
  amiKmsKey: kms.Key.fromLookup(this, 'ComponentKey', { aliasName: 'alias/distribution-encryption-key' }),
  // Copy the AMI to different accounts
  amiTargetAccountIds: ['123456789012', '098765432109'],
  // Add launch permissions on the AMI
  amiLaunchPermission: {
    organizationArns: [
      this.formatArn({ region: '', service: 'organizations', resource: 'organization', resourceName: 'o-1234567abc' })
    ],
    organizationalUnitArns: [
      this.formatArn({
        region: '',
        service: 'organizations',
        resource: 'ou',
        resourceName: 'o-1234567abc/ou-a123-b4567890'
      })
    ],
    isPublicUserGroup: true,
    accountIds: ['234567890123']
  },
  // Attach tags to the AMI
  amiTags: {
    Environment: 'production',
    Version: '{{ imagebuilder:buildVersion }}'
  },
  // Optional - publish the distributed AMI ID to an SSM parameter
  ssmParameters: [
    {
      parameter: ssm.StringParameter.fromStringParameterAttributes(this, 'Parameter', {
        parameterName: '/imagebuilder/ami',
        forceDynamicReference: true
      })
    },
    {
      amiAccount: '098765432109',
      dataType: ssm.ParameterDataType.TEXT,
      parameter: ssm.StringParameter.fromStringParameterAttributes(this, 'CrossAccountParameter', {
        parameterName: 'imagebuilder-prod-ami',
        forceDynamicReference: true
      })
    }
  ],
  // Optional - create a new launch template version with the distributed AMI ID
  launchTemplates: [
    {
      launchTemplate: ec2.LaunchTemplate.fromLaunchTemplateAttributes(this, 'LaunchTemplate', {
        launchTemplateId: 'lt-1234'
      }),
      setDefaultVersion: true
    },
    {
      accountId: '123456789012',
      launchTemplate: ec2.LaunchTemplate.fromLaunchTemplateAttributes(this, 'CrossAccountLaunchTemplate', {
        launchTemplateId: 'lt-5678'
      }),
      setDefaultVersion: true
    }
  ],
  // Optional - enable Fast Launch on an imported launch template
  fastLaunchConfigurations: [
    {
      enabled: true,
      launchTemplate: ec2.LaunchTemplate.fromLaunchTemplateAttributes(this, 'FastLaunchLT', {
        launchTemplateName: 'fast-launch-lt'
      }),
      maxParallelLaunches: 10,
      targetSnapshotCount: 2
    }
  ],
  // Optional - license configurations to apply to the AMI
  licenseConfigurationArns: [
    'arn:aws:license-manager:us-west-2:123456789012:license-configuration:lic-abcdefghijklmnopqrstuvwxyz'
  ]
});
python
distribution_configuration = imagebuilder.DistributionConfiguration(self, "DistributionConfiguration",
    distribution_configuration_name="test-distribution-configuration",
    description="A Distribution Configuration",
    ami_distributions=[imagebuilder.AmiDistribution(
        # Distribute AMI to us-east-2 and publish the AMI ID to an SSM parameter
        region="us-east-2",
        ssm_parameters=[imagebuilder.SSMParameterConfigurations(
            parameter=ssm.StringParameter.from_string_parameter_attributes(self, "CrossRegionParameter",
                parameter_name="/imagebuilder/ami",
                force_dynamic_reference=True
            )
        )
        ]
    )
    ]
)

# For AMI-based image builds - add an AMI distribution in the current region
distribution_configuration.add_ami_distributions(
    ami_name="imagebuilder-{{ imagebuilder:buildDate }}",
    ami_description="Build AMI",
    ami_kms_key=kms.Key.from_lookup(self, "ComponentKey", alias_name="alias/distribution-encryption-key"),
    # Copy the AMI to different accounts
    ami_target_account_ids=["123456789012", "098765432109"],
    # Add launch permissions on the AMI
    ami_launch_permission=imagebuilder.AmiLaunchPermission(
        organization_arns=[
            self.format_arn(region="", service="organizations", resource="organization", resource_name="o-1234567abc")
        ],
        organizational_unit_arns=[
            self.format_arn(
                region="",
                service="organizations",
                resource="ou",
                resource_name="o-1234567abc/ou-a123-b4567890"
            )
        ],
        is_public_user_group=True,
        account_ids=["234567890123"]
    ),
    # Attach tags to the AMI
    ami_tags={
        "Environment": "production",
        "Version": "{{ imagebuilder:buildVersion }}"
    },
    # Optional - publish the distributed AMI ID to an SSM parameter
    ssm_parameters=[imagebuilder.SSMParameterConfigurations(
        parameter=ssm.StringParameter.from_string_parameter_attributes(self, "Parameter",
            parameter_name="/imagebuilder/ami",
            force_dynamic_reference=True
        )
    ), imagebuilder.SSMParameterConfigurations(
        ami_account="098765432109",
        data_type=ssm.ParameterDataType.TEXT,
        parameter=ssm.StringParameter.from_string_parameter_attributes(self, "CrossAccountParameter",
            parameter_name="imagebuilder-prod-ami",
            force_dynamic_reference=True
        )
    )
    ],
    # Optional - create a new launch template version with the distributed AMI ID
    launch_templates=[imagebuilder.LaunchTemplateConfiguration(
        launch_template=ec2.LaunchTemplate.from_launch_template_attributes(self, "LaunchTemplate",
            launch_template_id="lt-1234"
        ),
        set_default_version=True
    ), imagebuilder.LaunchTemplateConfiguration(
        account_id="123456789012",
        launch_template=ec2.LaunchTemplate.from_launch_template_attributes(self, "CrossAccountLaunchTemplate",
            launch_template_id="lt-5678"
        ),
        set_default_version=True
    )
    ],
    # Optional - enable Fast Launch on an imported launch template
    fast_launch_configurations=[imagebuilder.FastLaunchConfiguration(
        enabled=True,
        launch_template=ec2.LaunchTemplate.from_launch_template_attributes(self, "FastLaunchLT",
            launch_template_name="fast-launch-lt"
        ),
        max_parallel_launches=10,
        target_snapshot_count=2
    )
    ],
    # Optional - license configurations to apply to the AMI
    license_configuration_arns=["arn:aws:license-manager:us-west-2:123456789012:license-configuration:lic-abcdefghijklmnopqrstuvwxyz"
    ]
)
java
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());
csharp
var distributionConfiguration = new DistributionConfiguration(this, "DistributionConfiguration", new DistributionConfigurationProps {
    DistributionConfigurationName = "test-distribution-configuration",
    Description = "A Distribution Configuration",
    AmiDistributions = new [] { new AmiDistribution {
        // Distribute AMI to us-east-2 and publish the AMI ID to an SSM parameter
        Region = "us-east-2",
        SsmParameters = new [] { new SSMParameterConfigurations {
            Parameter = StringParameter.FromStringParameterAttributes(this, "CrossRegionParameter", new StringParameterAttributes {
                ParameterName = "/imagebuilder/ami",
                ForceDynamicReference = true
            })
        } }
    } }
});

// For AMI-based image builds - add an AMI distribution in the current region
distributionConfiguration.AddAmiDistributions(new AmiDistribution {
    AmiName = "imagebuilder-{{ imagebuilder:buildDate }}",
    AmiDescription = "Build AMI",
    AmiKmsKey = Key.FromLookup(this, "ComponentKey", new KeyLookupOptions { AliasName = "alias/distribution-encryption-key" }),
    // Copy the AMI to different accounts
    AmiTargetAccountIds = new [] { "123456789012", "098765432109" },
    // Add launch permissions on the AMI
    AmiLaunchPermission = new AmiLaunchPermission {
        OrganizationArns = new [] { FormatArn(new ArnComponents { Region = "", Service = "organizations", Resource = "organization", ResourceName = "o-1234567abc" }) },
        OrganizationalUnitArns = new [] { FormatArn(new ArnComponents {
            Region = "",
            Service = "organizations",
            Resource = "ou",
            ResourceName = "o-1234567abc/ou-a123-b4567890"
        }) },
        IsPublicUserGroup = true,
        AccountIds = new [] { "234567890123" }
    },
    // Attach tags to the AMI
    AmiTags = new Dictionary<string, string> {
        { "Environment", "production" },
        { "Version", "{{ imagebuilder:buildVersion }}" }
    },
    // Optional - publish the distributed AMI ID to an SSM parameter
    SsmParameters = new [] { new SSMParameterConfigurations {
        Parameter = StringParameter.FromStringParameterAttributes(this, "Parameter", new StringParameterAttributes {
            ParameterName = "/imagebuilder/ami",
            ForceDynamicReference = true
        })
    }, new SSMParameterConfigurations {
        AmiAccount = "098765432109",
        DataType = ParameterDataType.TEXT,
        Parameter = StringParameter.FromStringParameterAttributes(this, "CrossAccountParameter", new StringParameterAttributes {
            ParameterName = "imagebuilder-prod-ami",
            ForceDynamicReference = true
        })
    } },
    // Optional - create a new launch template version with the distributed AMI ID
    LaunchTemplates = new [] { new LaunchTemplateConfiguration {
        LaunchTemplate = LaunchTemplate.FromLaunchTemplateAttributes(this, "LaunchTemplate", new LaunchTemplateAttributes {
            LaunchTemplateId = "lt-1234"
        }),
        SetDefaultVersion = true
    }, new LaunchTemplateConfiguration {
        AccountId = "123456789012",
        LaunchTemplate = LaunchTemplate.FromLaunchTemplateAttributes(this, "CrossAccountLaunchTemplate", new LaunchTemplateAttributes {
            LaunchTemplateId = "lt-5678"
        }),
        SetDefaultVersion = true
    } },
    // Optional - enable Fast Launch on an imported launch template
    FastLaunchConfigurations = new [] { new FastLaunchConfiguration {
        Enabled = true,
        LaunchTemplate = LaunchTemplate.FromLaunchTemplateAttributes(this, "FastLaunchLT", new LaunchTemplateAttributes {
            LaunchTemplateName = "fast-launch-lt"
        }),
        MaxParallelLaunches = 10,
        TargetSnapshotCount = 2
    } },
    // Optional - license configurations to apply to the AMI
    LicenseConfigurationArns = new [] { "arn:aws:license-manager:us-west-2:123456789012:license-configuration:lic-abcdefghijklmnopqrstuvwxyz" }
});
go
distributionConfiguration := imagebuilder.NewDistributionConfiguration(this, jsii.String("DistributionConfiguration"), &DistributionConfigurationProps{
	DistributionConfigurationName: jsii.String("test-distribution-configuration"),
	Description: jsii.String("A Distribution Configuration"),
	AmiDistributions: []AmiDistribution{
		&AmiDistribution{
			// Distribute AMI to us-east-2 and publish the AMI ID to an SSM parameter
			Region: jsii.String("us-east-2"),
			SsmParameters: []SSMParameterConfigurations{
				&SSMParameterConfigurations{
					Parameter: ssm.StringParameter_FromStringParameterAttributes(this, jsii.String("CrossRegionParameter"), &StringParameterAttributes{
						ParameterName: jsii.String("/imagebuilder/ami"),
						ForceDynamicReference: jsii.Boolean(true),
					}),
				},
			},
		},
	},
})

// For AMI-based image builds - add an AMI distribution in the current region
distributionConfiguration.AddAmiDistributions(&AmiDistribution{
	AmiName: jsii.String("imagebuilder-{{ imagebuilder:buildDate }}"),
	AmiDescription: jsii.String("Build AMI"),
	AmiKmsKey: kms.Key_FromLookup(this, jsii.String("ComponentKey"), &KeyLookupOptions{
		AliasName: jsii.String("alias/distribution-encryption-key"),
	}),
	// Copy the AMI to different accounts
	AmiTargetAccountIds: []*string{
		jsii.String("123456789012"),
		jsii.String("098765432109"),
	},
	// Add launch permissions on the AMI
	AmiLaunchPermission: &AmiLaunchPermission{
		OrganizationArns: []*string{
			this.FormatArn(&ArnComponents{
				Region: jsii.String(""),
				Service: jsii.String("organizations"),
				Resource: jsii.String("organization"),
				ResourceName: jsii.String("o-1234567abc"),
			}),
		},
		OrganizationalUnitArns: []*string{
			this.*FormatArn(&ArnComponents{
				Region: jsii.String(""),
				Service: jsii.String("organizations"),
				Resource: jsii.String("ou"),
				ResourceName: jsii.String("o-1234567abc/ou-a123-b4567890"),
			}),
		},
		IsPublicUserGroup: jsii.Boolean(true),
		AccountIds: []*string{
			jsii.String("234567890123"),
		},
	},
	// Attach tags to the AMI
	AmiTags: map[string]*string{
		"Environment": jsii.String("production"),
		"Version": jsii.String("{{ imagebuilder:buildVersion }}"),
	},
	// Optional - publish the distributed AMI ID to an SSM parameter
	SsmParameters: []SSMParameterConfigurations{
		&SSMParameterConfigurations{
			Parameter: ssm.StringParameter_*FromStringParameterAttributes(this, jsii.String("Parameter"), &StringParameterAttributes{
				ParameterName: jsii.String("/imagebuilder/ami"),
				ForceDynamicReference: jsii.Boolean(true),
			}),
		},
		&SSMParameterConfigurations{
			AmiAccount: jsii.String("098765432109"),
			DataType: ssm.ParameterDataType_TEXT,
			Parameter: ssm.StringParameter_*FromStringParameterAttributes(this, jsii.String("CrossAccountParameter"), &StringParameterAttributes{
				ParameterName: jsii.String("imagebuilder-prod-ami"),
				ForceDynamicReference: jsii.Boolean(true),
			}),
		},
	},
	// Optional - create a new launch template version with the distributed AMI ID
	LaunchTemplates: []LaunchTemplateConfiguration{
		&LaunchTemplateConfiguration{
			LaunchTemplate: ec2.LaunchTemplate_FromLaunchTemplateAttributes(this, jsii.String("LaunchTemplate"), &LaunchTemplateAttributes{
				LaunchTemplateId: jsii.String("lt-1234"),
			}),
			SetDefaultVersion: jsii.Boolean(true),
		},
		&LaunchTemplateConfiguration{
			AccountId: jsii.String("123456789012"),
			LaunchTemplate: ec2.LaunchTemplate_*FromLaunchTemplateAttributes(this, jsii.String("CrossAccountLaunchTemplate"), &LaunchTemplateAttributes{
				LaunchTemplateId: jsii.String("lt-5678"),
			}),
			SetDefaultVersion: jsii.Boolean(true),
		},
	},
	// Optional - enable Fast Launch on an imported launch template
	FastLaunchConfigurations: []FastLaunchConfiguration{
		&FastLaunchConfiguration{
			Enabled: jsii.Boolean(true),
			LaunchTemplate: ec2.LaunchTemplate_*FromLaunchTemplateAttributes(this, jsii.String("FastLaunchLT"), &LaunchTemplateAttributes{
				LaunchTemplateName: jsii.String("fast-launch-lt"),
			}),
			MaxParallelLaunches: jsii.Number(10),
			TargetSnapshotCount: jsii.Number(2),
		},
	},
	// Optional - license configurations to apply to the AMI
	LicenseConfigurationArns: []*string{
		jsii.String("arn:aws:license-manager:us-west-2:123456789012:license-configuration:lic-abcdefghijklmnopqrstuvwxyz"),
	},
})

Container Distributions ​

Container repositories ​

Container distributions can be configured to distribute to ECR repositories:

ts
const ecrRepository = ecr.Repository.fromRepositoryName(this, 'ECRRepository', 'my-repo');
const imageBuilderRepository = imagebuilder.Repository.fromEcr(ecrRepository);
python
ecr_repository = ecr.Repository.from_repository_name(self, "ECRRepository", "my-repo")
image_builder_repository = imagebuilder.Repository.from_ecr(ecr_repository)
java
IRepository ecrRepository = Repository.fromRepositoryName(this, "ECRRepository", "my-repo");
Repository imageBuilderRepository = Repository.fromEcr(ecrRepository);
csharp
var ecrRepository = Repository.FromRepositoryName(this, "ECRRepository", "my-repo");
var imageBuilderRepository = Repository.FromEcr(ecrRepository);
go
ecrRepository := ecr.Repository_FromRepositoryName(this, jsii.String("ECRRepository"), jsii.String("my-repo"))
imageBuilderRepository := imagebuilder.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:

ts
const ecrRepository = ecr.Repository.fromRepositoryName(this, 'ECRRepository', 'my-repo');
const containerRepository = imagebuilder.Repository.fromEcr(ecrRepository);
const containerDistributionConfiguration = new imagebuilder.DistributionConfiguration(
  this,
  'ContainerDistributionConfiguration'
);

containerDistributionConfiguration.addContainerDistributions({
  containerRepository,
  containerDescription: 'Test container image',
  containerTags: ['latest', 'latest-1.0']
});
python
ecr_repository = ecr.Repository.from_repository_name(self, "ECRRepository", "my-repo")
container_repository = imagebuilder.Repository.from_ecr(ecr_repository)
container_distribution_configuration = imagebuilder.DistributionConfiguration(self, "ContainerDistributionConfiguration")

container_distribution_configuration.add_container_distributions(
    container_repository=container_repository,
    container_description="Test container image",
    container_tags=["latest", "latest-1.0"]
)
java
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());
csharp
var ecrRepository = Repository.FromRepositoryName(this, "ECRRepository", "my-repo");
var containerRepository = Repository.FromEcr(ecrRepository);
var containerDistributionConfiguration = new DistributionConfiguration(this, "ContainerDistributionConfiguration");

containerDistributionConfiguration.AddContainerDistributions(new ContainerDistribution {
    ContainerRepository = containerRepository,
    ContainerDescription = "Test container image",
    ContainerTags = new [] { "latest", "latest-1.0" }
});
go
ecrRepository := ecr.Repository_FromRepositoryName(this, jsii.String("ECRRepository"), jsii.String("my-repo"))
containerRepository := imagebuilder.Repository_FromEcr(ecrRepository)
containerDistributionConfiguration := imagebuilder.NewDistributionConfiguration(this, jsii.String("ContainerDistributionConfiguration"))

containerDistributionConfiguration.AddContainerDistributions(&ContainerDistribution{
	ContainerRepository: ContainerRepository,
	ContainerDescription: jsii.String("Test container image"),
	ContainerTags: []*string{
		jsii.String("latest"),
		jsii.String("latest-1.0"),
	},
})

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.

ts
const workflow = new imagebuilder.Workflow(this, 'MyWorkflow', {
  workflowType: imagebuilder.WorkflowType.BUILD,
  data: imagebuilder.WorkflowData.fromJsonObject({
    schemaVersion: imagebuilder.WorkflowSchemaVersion.V1_0,
    steps: [
      {
        name: 'LaunchBuildInstance',
        action: imagebuilder.WorkflowAction.LAUNCH_INSTANCE,
        onFailure: imagebuilder.WorkflowOnFailure.ABORT,
        inputs: {
          waitFor: 'ssmAgent',
        },
      },
      {
        name: 'ExecuteComponents',
        action: imagebuilder.WorkflowAction.EXECUTE_COMPONENTS,
        onFailure: imagebuilder.WorkflowOnFailure.ABORT,
        inputs: {
          'instanceId': 'i-123',
        },
      },
      {
        name: 'CreateImage',
        action: imagebuilder.WorkflowAction.CREATE_IMAGE,
        onFailure: imagebuilder.WorkflowOnFailure.ABORT,
        inputs: {
          'instanceId': 'i-123',
        },
      },
      {
        name: 'TerminateInstance',
        action: imagebuilder.WorkflowAction.TERMINATE_INSTANCE,
        onFailure: imagebuilder.WorkflowOnFailure.CONTINUE,
        inputs: {
          'instanceId': 'i-123',
        },
      },
    ],
    outputs: [
      {
        name: 'ImageId',
        value: '$.stepOutputs.CreateImage.imageId',
      },
    ],
  }),
});
python
workflow = imagebuilder.Workflow(self, "MyWorkflow",
    workflow_type=imagebuilder.WorkflowType.BUILD,
    data=imagebuilder.WorkflowData.from_json_object({
        "schema_version": imagebuilder.WorkflowSchemaVersion.V1_0,
        "steps": [{
            "name": "LaunchBuildInstance",
            "action": imagebuilder.WorkflowAction.LAUNCH_INSTANCE,
            "on_failure": imagebuilder.WorkflowOnFailure.ABORT,
            "inputs": {
                "wait_for": "ssmAgent"
            }
        }, {
            "name": "ExecuteComponents",
            "action": imagebuilder.WorkflowAction.EXECUTE_COMPONENTS,
            "on_failure": imagebuilder.WorkflowOnFailure.ABORT,
            "inputs": {
                "instance_id": "i-123"
            }
        }, {
            "name": "CreateImage",
            "action": imagebuilder.WorkflowAction.CREATE_IMAGE,
            "on_failure": imagebuilder.WorkflowOnFailure.ABORT,
            "inputs": {
                "instance_id": "i-123"
            }
        }, {
            "name": "TerminateInstance",
            "action": imagebuilder.WorkflowAction.TERMINATE_INSTANCE,
            "on_failure": imagebuilder.WorkflowOnFailure.CONTINUE,
            "inputs": {
                "instance_id": "i-123"
            }
        }
        ],
        "outputs": [{
            "name": "ImageId",
            "value": "$.stepOutputs.CreateImage.imageId"
        }
        ]
    })
)
java
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();
csharp
var workflow = new Workflow(this, "MyWorkflow", new WorkflowProps {
    WorkflowType = WorkflowType.BUILD,
    Data = WorkflowData.FromJsonObject(new Dictionary<string, object> {
        { "schemaVersion", WorkflowSchemaVersion.V1_0 },
        { "steps", new [] { new Dictionary<string, object> {
            { "name", "LaunchBuildInstance" },
            { "action", WorkflowAction.LAUNCH_INSTANCE },
            { "onFailure", WorkflowOnFailure.ABORT },
            { "inputs", new Struct {
                WaitFor = "ssmAgent"
            } }
        }, new Dictionary<string, object> {
            { "name", "ExecuteComponents" },
            { "action", WorkflowAction.EXECUTE_COMPONENTS },
            { "onFailure", WorkflowOnFailure.ABORT },
            { "inputs", new Struct {
                InstanceId = "i-123"
            } }
        }, new Dictionary<string, object> {
            { "name", "CreateImage" },
            { "action", WorkflowAction.CREATE_IMAGE },
            { "onFailure", WorkflowOnFailure.ABORT },
            { "inputs", new Struct {
                InstanceId = "i-123"
            } }
        }, new Dictionary<string, object> {
            { "name", "TerminateInstance" },
            { "action", WorkflowAction.TERMINATE_INSTANCE },
            { "onFailure", WorkflowOnFailure.CONTINUE },
            { "inputs", new Struct {
                InstanceId = "i-123"
            } }
        } } },
        { "outputs", new [] { new Dictionary<string, string> {
            { "name", "ImageId" },
            { "value", "$.stepOutputs.CreateImage.imageId" }
        } } }
    })
});
go
workflow := imagebuilder.NewWorkflow(this, jsii.String("MyWorkflow"), &WorkflowProps{
	WorkflowType: imagebuilder.WorkflowType_BUILD,
	Data: imagebuilder.WorkflowData_FromJsonObject(map[string]interface{}{
		"schemaVersion": imagebuilder.WorkflowSchemaVersion_V1_0,
		"steps": []interface{}{
			map[string]interface{}{
				"name": jsii.String("LaunchBuildInstance"),
				"action": imagebuilder.WorkflowAction_LAUNCH_INSTANCE,
				"onFailure": imagebuilder.WorkflowOnFailure_ABORT,
				"inputs": map[string]*string{
					"waitFor": jsii.String("ssmAgent"),
				},
			},
			map[string]interface{}{
				"name": jsii.String("ExecuteComponents"),
				"action": imagebuilder.WorkflowAction_EXECUTE_COMPONENTS,
				"onFailure": imagebuilder.WorkflowOnFailure_ABORT,
				"inputs": map[string]*string{
					"instanceId": jsii.String("i-123"),
				},
			},
			map[string]interface{}{
				"name": jsii.String("CreateImage"),
				"action": imagebuilder.WorkflowAction_CREATE_IMAGE,
				"onFailure": imagebuilder.WorkflowOnFailure_ABORT,
				"inputs": map[string]*string{
					"instanceId": jsii.String("i-123"),
				},
			},
			map[string]interface{}{
				"name": jsii.String("TerminateInstance"),
				"action": imagebuilder.WorkflowAction_TERMINATE_INSTANCE,
				"onFailure": imagebuilder.WorkflowOnFailure_CONTINUE,
				"inputs": map[string]*string{
					"instanceId": jsii.String("i-123"),
				},
			},
		},
		"outputs": []interface{}{
			map[string]*string{
				"name": jsii.String("ImageId"),
				"value": jsii.String("$.stepOutputs.CreateImage.imageId"),
			},
		},
	}),
})

Workflow Data Sources ​

Inline Workflow Data ​

Use WorkflowData.fromInline() for existing YAML/JSON definitions:

ts
const workflow = new imagebuilder.Workflow(this, 'InlineWorkflow', {
  workflowType: imagebuilder.WorkflowType.TEST,
  data: imagebuilder.WorkflowData.fromInline(`
schemaVersion: 1.0
steps:
  - name: LaunchTestInstance
    action: LaunchInstance
    onFailure: Abort
    inputs:
      waitFor: ssmAgent
  - name: RunTests
    action: RunCommand
    onFailure: Abort
    inputs:
      instanceId.$: "$.stepOutputs.LaunchTestInstance.instanceId"
      commands: ['./run-tests.sh']
  - name: TerminateTestInstance
    action: TerminateInstance
    onFailure: Continue
    inputs:
      instanceId.$: "$.stepOutputs.LaunchTestInstance.instanceId"
`),
});
python
workflow = imagebuilder.Workflow(self, "InlineWorkflow",
    workflow_type=imagebuilder.WorkflowType.TEST,
    data=imagebuilder.WorkflowData.from_inline("""
        schemaVersion: 1.0
        steps:
          - name: LaunchTestInstance
            action: LaunchInstance
            onFailure: Abort
            inputs:
              waitFor: ssmAgent
          - name: RunTests
            action: RunCommand
            onFailure: Abort
            inputs:
              instanceId.$: "$.stepOutputs.LaunchTestInstance.instanceId"
              commands: ['./run-tests.sh']
          - name: TerminateTestInstance
            action: TerminateInstance
            onFailure: Continue
            inputs:
              instanceId.$: "$.stepOutputs.LaunchTestInstance.instanceId"
        """)
)
java
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();
csharp
var workflow = new Workflow(this, "InlineWorkflow", new WorkflowProps {
    WorkflowType = WorkflowType.TEST,
    Data = WorkflowData.FromInline(@"
    schemaVersion: 1.0
    steps:
      - name: LaunchTestInstance
        action: LaunchInstance
        onFailure: Abort
        inputs:
          waitFor: ssmAgent
      - name: RunTests
        action: RunCommand
        onFailure: Abort
        inputs:
          instanceId.$: ""$.stepOutputs.LaunchTestInstance.instanceId""
          commands: ['./run-tests.sh']
      - name: TerminateTestInstance
        action: TerminateInstance
        onFailure: Continue
        inputs:
          instanceId.$: ""$.stepOutputs.LaunchTestInstance.instanceId""
    ")
});
go
workflow := imagebuilder.NewWorkflow(this, jsii.String("InlineWorkflow"), &WorkflowProps{
	WorkflowType: imagebuilder.WorkflowType_TEST,
	Data: imagebuilder.WorkflowData_FromInline(jsii.String(`
	schemaVersion: 1.0
	steps:
	  - name: LaunchTestInstance
	    action: LaunchInstance
	    onFailure: Abort
	    inputs:
	      waitFor: ssmAgent
	  - name: RunTests
	    action: RunCommand
	    onFailure: Abort
	    inputs:
	      instanceId.$: "$.stepOutputs.LaunchTestInstance.instanceId"
	      commands: ['./run-tests.sh']
	  - name: TerminateTestInstance
	    action: TerminateInstance
	    onFailure: Continue
	    inputs:
	      instanceId.$: "$.stepOutputs.LaunchTestInstance.instanceId"
	`)),
})
JSON Object Workflow Data ​

Most developer-friendly approach using JavaScript objects:

ts
const workflow = new imagebuilder.Workflow(this, 'JsonWorkflow', {
  workflowType: imagebuilder.WorkflowType.BUILD,
  data: imagebuilder.WorkflowData.fromJsonObject({
    schemaVersion: imagebuilder.WorkflowSchemaVersion.V1_0,
    steps: [
      {
        name: 'LaunchBuildInstance',
        action: imagebuilder.WorkflowAction.LAUNCH_INSTANCE,
        onFailure: imagebuilder.WorkflowOnFailure.ABORT,
        inputs: {
          waitFor: 'ssmAgent'
        }
      },
      {
        name: 'ExecuteComponents',
        action: imagebuilder.WorkflowAction.EXECUTE_COMPONENTS,
        onFailure: imagebuilder.WorkflowOnFailure.ABORT,
        inputs: {
          'instanceId': 'i-123'
        }
      },
      {
        name: 'CreateImage',
        action: imagebuilder.WorkflowAction.CREATE_IMAGE,
        onFailure: imagebuilder.WorkflowOnFailure.ABORT,
        inputs: {
          'instanceId': 'i-123'
        }
      },
      {
        name: 'TerminateInstance',
        action: imagebuilder.WorkflowAction.TERMINATE_INSTANCE,
        onFailure: imagebuilder.WorkflowOnFailure.CONTINUE,
        inputs: {
          'instanceId': 'i-123'
        }
      }
    ],
    outputs: [
      {
        name: 'ImageId',
        value: '$.stepOutputs.CreateImage.imageId'
      }
    ]
  })
});
python
workflow = imagebuilder.Workflow(self, "JsonWorkflow",
    workflow_type=imagebuilder.WorkflowType.BUILD,
    data=imagebuilder.WorkflowData.from_json_object({
        "schema_version": imagebuilder.WorkflowSchemaVersion.V1_0,
        "steps": [{
            "name": "LaunchBuildInstance",
            "action": imagebuilder.WorkflowAction.LAUNCH_INSTANCE,
            "on_failure": imagebuilder.WorkflowOnFailure.ABORT,
            "inputs": {
                "wait_for": "ssmAgent"
            }
        }, {
            "name": "ExecuteComponents",
            "action": imagebuilder.WorkflowAction.EXECUTE_COMPONENTS,
            "on_failure": imagebuilder.WorkflowOnFailure.ABORT,
            "inputs": {
                "instance_id": "i-123"
            }
        }, {
            "name": "CreateImage",
            "action": imagebuilder.WorkflowAction.CREATE_IMAGE,
            "on_failure": imagebuilder.WorkflowOnFailure.ABORT,
            "inputs": {
                "instance_id": "i-123"
            }
        }, {
            "name": "TerminateInstance",
            "action": imagebuilder.WorkflowAction.TERMINATE_INSTANCE,
            "on_failure": imagebuilder.WorkflowOnFailure.CONTINUE,
            "inputs": {
                "instance_id": "i-123"
            }
        }
        ],
        "outputs": [{
            "name": "ImageId",
            "value": "$.stepOutputs.CreateImage.imageId"
        }
        ]
    })
)
java
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();
csharp
var workflow = new Workflow(this, "JsonWorkflow", new WorkflowProps {
    WorkflowType = WorkflowType.BUILD,
    Data = WorkflowData.FromJsonObject(new Dictionary<string, object> {
        { "schemaVersion", WorkflowSchemaVersion.V1_0 },
        { "steps", new [] { new Dictionary<string, object> {
            { "name", "LaunchBuildInstance" },
            { "action", WorkflowAction.LAUNCH_INSTANCE },
            { "onFailure", WorkflowOnFailure.ABORT },
            { "inputs", new Struct {
                WaitFor = "ssmAgent"
            } }
        }, new Dictionary<string, object> {
            { "name", "ExecuteComponents" },
            { "action", WorkflowAction.EXECUTE_COMPONENTS },
            { "onFailure", WorkflowOnFailure.ABORT },
            { "inputs", new Struct {
                InstanceId = "i-123"
            } }
        }, new Dictionary<string, object> {
            { "name", "CreateImage" },
            { "action", WorkflowAction.CREATE_IMAGE },
            { "onFailure", WorkflowOnFailure.ABORT },
            { "inputs", new Struct {
                InstanceId = "i-123"
            } }
        }, new Dictionary<string, object> {
            { "name", "TerminateInstance" },
            { "action", WorkflowAction.TERMINATE_INSTANCE },
            { "onFailure", WorkflowOnFailure.CONTINUE },
            { "inputs", new Struct {
                InstanceId = "i-123"
            } }
        } } },
        { "outputs", new [] { new Dictionary<string, string> {
            { "name", "ImageId" },
            { "value", "$.stepOutputs.CreateImage.imageId" }
        } } }
    })
});
go
workflow := imagebuilder.NewWorkflow(this, jsii.String("JsonWorkflow"), &WorkflowProps{
	WorkflowType: imagebuilder.WorkflowType_BUILD,
	Data: imagebuilder.WorkflowData_FromJsonObject(map[string]interface{}{
		"schemaVersion": imagebuilder.WorkflowSchemaVersion_V1_0,
		"steps": []interface{}{
			map[string]interface{}{
				"name": jsii.String("LaunchBuildInstance"),
				"action": imagebuilder.WorkflowAction_LAUNCH_INSTANCE,
				"onFailure": imagebuilder.WorkflowOnFailure_ABORT,
				"inputs": map[string]*string{
					"waitFor": jsii.String("ssmAgent"),
				},
			},
			map[string]interface{}{
				"name": jsii.String("ExecuteComponents"),
				"action": imagebuilder.WorkflowAction_EXECUTE_COMPONENTS,
				"onFailure": imagebuilder.WorkflowOnFailure_ABORT,
				"inputs": map[string]*string{
					"instanceId": jsii.String("i-123"),
				},
			},
			map[string]interface{}{
				"name": jsii.String("CreateImage"),
				"action": imagebuilder.WorkflowAction_CREATE_IMAGE,
				"onFailure": imagebuilder.WorkflowOnFailure_ABORT,
				"inputs": map[string]*string{
					"instanceId": jsii.String("i-123"),
				},
			},
			map[string]interface{}{
				"name": jsii.String("TerminateInstance"),
				"action": imagebuilder.WorkflowAction_TERMINATE_INSTANCE,
				"onFailure": imagebuilder.WorkflowOnFailure_CONTINUE,
				"inputs": map[string]*string{
					"instanceId": jsii.String("i-123"),
				},
			},
		},
		"outputs": []interface{}{
			map[string]*string{
				"name": jsii.String("ImageId"),
				"value": jsii.String("$.stepOutputs.CreateImage.imageId"),
			},
		},
	}),
})
S3 Workflow Data ​

For those workflows you want to upload or have uploaded to S3:

ts
// Upload a local file
const workflowFromAsset = new imagebuilder.Workflow(this, 'AssetWorkflow', {
  workflowType: imagebuilder.WorkflowType.BUILD,
  data: imagebuilder.WorkflowData.fromAsset(this, 'WorkflowAsset', './my-workflow.yml'),
});

// Reference an existing S3 object
const bucket = s3.Bucket.fromBucketName(this, 'WorkflowBucket', 'my-workflows-bucket');
const workflowFromS3 = new imagebuilder.Workflow(this, 'S3Workflow', {
  workflowType: imagebuilder.WorkflowType.BUILD,
  data: imagebuilder.WorkflowData.fromS3(bucket, 'workflows/my-workflow.yml'),
});
python
# Upload a local file
workflow_from_asset = imagebuilder.Workflow(self, "AssetWorkflow",
    workflow_type=imagebuilder.WorkflowType.BUILD,
    data=imagebuilder.WorkflowData.from_asset(self, "WorkflowAsset", "./my-workflow.yml")
)

# Reference an existing S3 object
bucket = s3.Bucket.from_bucket_name(self, "WorkflowBucket", "my-workflows-bucket")
workflow_from_s3 = imagebuilder.Workflow(self, "S3Workflow",
    workflow_type=imagebuilder.WorkflowType.BUILD,
    data=imagebuilder.WorkflowData.from_s3(bucket, "workflows/my-workflow.yml")
)
java
// 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();
csharp
// Upload a local file
var workflowFromAsset = new Workflow(this, "AssetWorkflow", new WorkflowProps {
    WorkflowType = WorkflowType.BUILD,
    Data = WorkflowData.FromAsset(this, "WorkflowAsset", "./my-workflow.yml")
});

// Reference an existing S3 object
var bucket = Bucket.FromBucketName(this, "WorkflowBucket", "my-workflows-bucket");
var workflowFromS3 = new Workflow(this, "S3Workflow", new WorkflowProps {
    WorkflowType = WorkflowType.BUILD,
    Data = WorkflowData.FromS3(bucket, "workflows/my-workflow.yml")
});
go
// Upload a local file
workflowFromAsset := imagebuilder.NewWorkflow(this, jsii.String("AssetWorkflow"), &WorkflowProps{
	WorkflowType: imagebuilder.WorkflowType_BUILD,
	Data: imagebuilder.WorkflowData_FromAsset(this, jsii.String("WorkflowAsset"), jsii.String("./my-workflow.yml")),
})

// Reference an existing S3 object
bucket := s3.Bucket_FromBucketName(this, jsii.String("WorkflowBucket"), jsii.String("my-workflows-bucket"))
workflowFromS3 := imagebuilder.NewWorkflow(this, jsii.String("S3Workflow"), &WorkflowProps{
	WorkflowType: imagebuilder.WorkflowType_BUILD,
	Data: imagebuilder.WorkflowData_FromS3(bucket, jsii.String("workflows/my-workflow.yml")),
})

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.

ts
const workflow = new imagebuilder.Workflow(this, 'EncryptedWorkflow', {
  workflowType: imagebuilder.WorkflowType.BUILD,
  kmsKey: new kms.Key(this, 'WorkflowKey'),
  data: imagebuilder.WorkflowData.fromJsonObject({
    schemaVersion: imagebuilder.WorkflowSchemaVersion.V1_0,
    steps: [
      {
        name: 'LaunchBuildInstance',
        action: imagebuilder.WorkflowAction.LAUNCH_INSTANCE,
        onFailure: imagebuilder.WorkflowOnFailure.ABORT,
        inputs: {
          waitFor: 'ssmAgent',
        },
      },
      {
        name: 'CreateImage',
        action: imagebuilder.WorkflowAction.CREATE_IMAGE,
        onFailure: imagebuilder.WorkflowOnFailure.ABORT,
        inputs: {
          'instanceId': 'i-123',
        },
      },
      {
        name: 'TerminateInstance',
        action: imagebuilder.WorkflowAction.TERMINATE_INSTANCE,
        onFailure: imagebuilder.WorkflowOnFailure.CONTINUE,
        inputs: {
          'instanceId': 'i-123',
        },
      },
    ],
    outputs: [
      {
        name: 'ImageId',
        value: '$.stepOutputs.CreateImage.imageId',
      },
    ],
  }),
});
python
workflow = imagebuilder.Workflow(self, "EncryptedWorkflow",
    workflow_type=imagebuilder.WorkflowType.BUILD,
    kms_key=kms.Key(self, "WorkflowKey"),
    data=imagebuilder.WorkflowData.from_json_object({
        "schema_version": imagebuilder.WorkflowSchemaVersion.V1_0,
        "steps": [{
            "name": "LaunchBuildInstance",
            "action": imagebuilder.WorkflowAction.LAUNCH_INSTANCE,
            "on_failure": imagebuilder.WorkflowOnFailure.ABORT,
            "inputs": {
                "wait_for": "ssmAgent"
            }
        }, {
            "name": "CreateImage",
            "action": imagebuilder.WorkflowAction.CREATE_IMAGE,
            "on_failure": imagebuilder.WorkflowOnFailure.ABORT,
            "inputs": {
                "instance_id": "i-123"
            }
        }, {
            "name": "TerminateInstance",
            "action": imagebuilder.WorkflowAction.TERMINATE_INSTANCE,
            "on_failure": imagebuilder.WorkflowOnFailure.CONTINUE,
            "inputs": {
                "instance_id": "i-123"
            }
        }
        ],
        "outputs": [{
            "name": "ImageId",
            "value": "$.stepOutputs.CreateImage.imageId"
        }
        ]
    })
)
java
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();
csharp
var workflow = new Workflow(this, "EncryptedWorkflow", new WorkflowProps {
    WorkflowType = WorkflowType.BUILD,
    KmsKey = new Key(this, "WorkflowKey"),
    Data = WorkflowData.FromJsonObject(new Dictionary<string, object> {
        { "schemaVersion", WorkflowSchemaVersion.V1_0 },
        { "steps", new [] { new Dictionary<string, object> {
            { "name", "LaunchBuildInstance" },
            { "action", WorkflowAction.LAUNCH_INSTANCE },
            { "onFailure", WorkflowOnFailure.ABORT },
            { "inputs", new Struct {
                WaitFor = "ssmAgent"
            } }
        }, new Dictionary<string, object> {
            { "name", "CreateImage" },
            { "action", WorkflowAction.CREATE_IMAGE },
            { "onFailure", WorkflowOnFailure.ABORT },
            { "inputs", new Struct {
                InstanceId = "i-123"
            } }
        }, new Dictionary<string, object> {
            { "name", "TerminateInstance" },
            { "action", WorkflowAction.TERMINATE_INSTANCE },
            { "onFailure", WorkflowOnFailure.CONTINUE },
            { "inputs", new Struct {
                InstanceId = "i-123"
            } }
        } } },
        { "outputs", new [] { new Dictionary<string, string> {
            { "name", "ImageId" },
            { "value", "$.stepOutputs.CreateImage.imageId" }
        } } }
    })
});
go
workflow := imagebuilder.NewWorkflow(this, jsii.String("EncryptedWorkflow"), &WorkflowProps{
	WorkflowType: imagebuilder.WorkflowType_BUILD,
	KmsKey: kms.NewKey(this, jsii.String("WorkflowKey")),
	Data: imagebuilder.WorkflowData_FromJsonObject(map[string]interface{}{
		"schemaVersion": imagebuilder.WorkflowSchemaVersion_V1_0,
		"steps": []interface{}{
			map[string]interface{}{
				"name": jsii.String("LaunchBuildInstance"),
				"action": imagebuilder.WorkflowAction_LAUNCH_INSTANCE,
				"onFailure": imagebuilder.WorkflowOnFailure_ABORT,
				"inputs": map[string]*string{
					"waitFor": jsii.String("ssmAgent"),
				},
			},
			map[string]interface{}{
				"name": jsii.String("CreateImage"),
				"action": imagebuilder.WorkflowAction_CREATE_IMAGE,
				"onFailure": imagebuilder.WorkflowOnFailure_ABORT,
				"inputs": map[string]*string{
					"instanceId": jsii.String("i-123"),
				},
			},
			map[string]interface{}{
				"name": jsii.String("TerminateInstance"),
				"action": imagebuilder.WorkflowAction_TERMINATE_INSTANCE,
				"onFailure": imagebuilder.WorkflowOnFailure_CONTINUE,
				"inputs": map[string]*string{
					"instanceId": jsii.String("i-123"),
				},
			},
		},
		"outputs": []interface{}{
			map[string]*string{
				"name": jsii.String("ImageId"),
				"value": jsii.String("$.stepOutputs.CreateImage.imageId"),
			},
		},
	}),
})

AWS-Managed Workflows ​

AWS provides a collection of workflows for common scenarios:

ts
// Build workflows
const buildImageWorkflow = imagebuilder.AmazonManagedWorkflow.buildImage(this, 'BuildImage');
const buildContainerWorkflow = imagebuilder.AmazonManagedWorkflow.buildContainer(this, 'BuildContainer');

// Test workflows
const testImageWorkflow = imagebuilder.AmazonManagedWorkflow.testImage(this, 'TestImage');
const testContainerWorkflow = imagebuilder.AmazonManagedWorkflow.testContainer(this, 'TestContainer');

// Distribution workflows
const distributeContainerWorkflow = imagebuilder.AmazonManagedWorkflow.distributeContainer(this, 'DistributeContainer');
python
# Build workflows
build_image_workflow = imagebuilder.AmazonManagedWorkflow.build_image(self, "BuildImage")
build_container_workflow = imagebuilder.AmazonManagedWorkflow.build_container(self, "BuildContainer")

# Test workflows
test_image_workflow = imagebuilder.AmazonManagedWorkflow.test_image(self, "TestImage")
test_container_workflow = imagebuilder.AmazonManagedWorkflow.test_container(self, "TestContainer")

# Distribution workflows
distribute_container_workflow = imagebuilder.AmazonManagedWorkflow.distribute_container(self, "DistributeContainer")
java
// 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");
csharp
// Build workflows
var buildImageWorkflow = AmazonManagedWorkflow.BuildImage(this, "BuildImage");
var buildContainerWorkflow = AmazonManagedWorkflow.BuildContainer(this, "BuildContainer");

// Test workflows
var testImageWorkflow = AmazonManagedWorkflow.TestImage(this, "TestImage");
var testContainerWorkflow = AmazonManagedWorkflow.TestContainer(this, "TestContainer");

// Distribution workflows
var distributeContainerWorkflow = AmazonManagedWorkflow.DistributeContainer(this, "DistributeContainer");
go
// Build workflows
buildImageWorkflow := imagebuilder.AmazonManagedWorkflow_BuildImage(this, jsii.String("BuildImage"))
buildContainerWorkflow := imagebuilder.AmazonManagedWorkflow_BuildContainer(this, jsii.String("BuildContainer"))

// Test workflows
testImageWorkflow := imagebuilder.AmazonManagedWorkflow_TestImage(this, jsii.String("TestImage"))
testContainerWorkflow := imagebuilder.AmazonManagedWorkflow_TestContainer(this, jsii.String("TestContainer"))

// Distribution workflows
distributeContainerWorkflow := imagebuilder.AmazonManagedWorkflow_DistributeContainer(this, jsii.String("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:

ts
const lifecyclePolicy = new imagebuilder.LifecyclePolicy(this, 'MyLifecyclePolicy', {
  resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
  details: [
    {
      action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
      filter: { ageFilter: { age: Duration.days(30) } }
    }
  ],
  resourceSelection: {
    tags: { Environment: 'development' }
  }
});
python
lifecycle_policy = imagebuilder.LifecyclePolicy(self, "MyLifecyclePolicy",
    resource_type=imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
    details=[imagebuilder.LifecyclePolicyDetail(
        action=imagebuilder.LifecyclePolicyAction(type=imagebuilder.LifecyclePolicyActionType.DELETE),
        filter=imagebuilder.LifecyclePolicyFilter(age_filter=imagebuilder.LifecyclePolicyAgeFilter(age=Duration.days(30)))
    )
    ],
    resource_selection=imagebuilder.LifecyclePolicyResourceSelection(
        tags={"Environment": "development"}
    )
)
java
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();
csharp
var lifecyclePolicy = new LifecyclePolicy(this, "MyLifecyclePolicy", new LifecyclePolicyProps {
    ResourceType = LifecyclePolicyResourceType.AMI_IMAGE,
    Details = new [] { new LifecyclePolicyDetail {
        Action = new LifecyclePolicyAction { Type = LifecyclePolicyActionType.DELETE },
        Filter = new LifecyclePolicyFilter { AgeFilter = new LifecyclePolicyAgeFilter { Age = Duration.Days(30) } }
    } },
    ResourceSelection = new LifecyclePolicyResourceSelection {
        Tags = new Dictionary<string, string> { { "Environment", "development" } }
    }
});
go
lifecyclePolicy := imagebuilder.NewLifecyclePolicy(this, jsii.String("MyLifecyclePolicy"), &LifecyclePolicyProps{
	ResourceType: imagebuilder.LifecyclePolicyResourceType_AMI_IMAGE,
	Details: []LifecyclePolicyDetail{
		&LifecyclePolicyDetail{
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DELETE,
			},
			Filter: &LifecyclePolicyFilter{
				AgeFilter: &LifecyclePolicyAgeFilter{
					Age: awscdk.Duration_Days(jsii.Number(30)),
				},
			},
		},
	},
	ResourceSelection: &LifecyclePolicyResourceSelection{
		Tags: map[string]*string{
			"Environment": jsii.String("development"),
		},
	},
})

Create a lifecycle policy to keep only the 10 most recent container images:

ts
const containerLifecyclePolicy = new imagebuilder.LifecyclePolicy(this, 'ContainerLifecyclePolicy', {
  resourceType: imagebuilder.LifecyclePolicyResourceType.CONTAINER_IMAGE,
  details: [
    {
      action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
      filter: { countFilter: { count: 10 } }
    }
  ],
  resourceSelection: {
    tags: { Application: 'web-app' }
  }
});
python
container_lifecycle_policy = imagebuilder.LifecyclePolicy(self, "ContainerLifecyclePolicy",
    resource_type=imagebuilder.LifecyclePolicyResourceType.CONTAINER_IMAGE,
    details=[imagebuilder.LifecyclePolicyDetail(
        action=imagebuilder.LifecyclePolicyAction(type=imagebuilder.LifecyclePolicyActionType.DELETE),
        filter=imagebuilder.LifecyclePolicyFilter(count_filter=imagebuilder.LifecyclePolicyCountFilter(count=10))
    )
    ],
    resource_selection=imagebuilder.LifecyclePolicyResourceSelection(
        tags={"Application": "web-app"}
    )
)
java
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();
csharp
var containerLifecyclePolicy = new LifecyclePolicy(this, "ContainerLifecyclePolicy", new LifecyclePolicyProps {
    ResourceType = LifecyclePolicyResourceType.CONTAINER_IMAGE,
    Details = new [] { new LifecyclePolicyDetail {
        Action = new LifecyclePolicyAction { Type = LifecyclePolicyActionType.DELETE },
        Filter = new LifecyclePolicyFilter { CountFilter = new LifecyclePolicyCountFilter { Count = 10 } }
    } },
    ResourceSelection = new LifecyclePolicyResourceSelection {
        Tags = new Dictionary<string, string> { { "Application", "web-app" } }
    }
});
go
containerLifecyclePolicy := imagebuilder.NewLifecyclePolicy(this, jsii.String("ContainerLifecyclePolicy"), &LifecyclePolicyProps{
	ResourceType: imagebuilder.LifecyclePolicyResourceType_CONTAINER_IMAGE,
	Details: []LifecyclePolicyDetail{
		&LifecyclePolicyDetail{
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DELETE,
			},
			Filter: &LifecyclePolicyFilter{
				CountFilter: &LifecyclePolicyCountFilter{
					Count: jsii.Number(10),
				},
			},
		},
	},
	ResourceSelection: &LifecyclePolicyResourceSelection{
		Tags: map[string]*string{
			"Application": jsii.String("web-app"),
		},
	},
})

Lifecycle Policy Resource Selection ​

Tag-Based Resource Selection ​

Apply lifecycle policies to images with specific tags:

ts
const tagBasedPolicy = new imagebuilder.LifecyclePolicy(this, 'TagBasedPolicy', {
  resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
  details: [
    {
      action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
      filter: { ageFilter: { age: Duration.days(90) } }
    }
  ],
  resourceSelection: {
    tags: {
      Environment: 'staging',
      Team: 'backend'
    }
  }
});
python
tag_based_policy = imagebuilder.LifecyclePolicy(self, "TagBasedPolicy",
    resource_type=imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
    details=[imagebuilder.LifecyclePolicyDetail(
        action=imagebuilder.LifecyclePolicyAction(type=imagebuilder.LifecyclePolicyActionType.DELETE),
        filter=imagebuilder.LifecyclePolicyFilter(age_filter=imagebuilder.LifecyclePolicyAgeFilter(age=Duration.days(90)))
    )
    ],
    resource_selection=imagebuilder.LifecyclePolicyResourceSelection(
        tags={
            "Environment": "staging",
            "Team": "backend"
        }
    )
)
java
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();
csharp
var tagBasedPolicy = new LifecyclePolicy(this, "TagBasedPolicy", new LifecyclePolicyProps {
    ResourceType = LifecyclePolicyResourceType.AMI_IMAGE,
    Details = new [] { new LifecyclePolicyDetail {
        Action = new LifecyclePolicyAction { Type = LifecyclePolicyActionType.DELETE },
        Filter = new LifecyclePolicyFilter { AgeFilter = new LifecyclePolicyAgeFilter { Age = Duration.Days(90) } }
    } },
    ResourceSelection = new LifecyclePolicyResourceSelection {
        Tags = new Dictionary<string, string> {
            { "Environment", "staging" },
            { "Team", "backend" }
        }
    }
});
go
tagBasedPolicy := imagebuilder.NewLifecyclePolicy(this, jsii.String("TagBasedPolicy"), &LifecyclePolicyProps{
	ResourceType: imagebuilder.LifecyclePolicyResourceType_AMI_IMAGE,
	Details: []LifecyclePolicyDetail{
		&LifecyclePolicyDetail{
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DELETE,
			},
			Filter: &LifecyclePolicyFilter{
				AgeFilter: &LifecyclePolicyAgeFilter{
					Age: awscdk.Duration_Days(jsii.Number(90)),
				},
			},
		},
	},
	ResourceSelection: &LifecyclePolicyResourceSelection{
		Tags: map[string]*string{
			"Environment": jsii.String("staging"),
			"Team": jsii.String("backend"),
		},
	},
})
Recipe-Based Resource Selection ​

Apply lifecycle policies to specific image or container recipes:

ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'MyImageRecipe', {
  baseImage: imagebuilder.BaseImage.fromSsmParameterName(
    '/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
  )
});

const containerRecipe = new imagebuilder.ContainerRecipe(this, 'MyContainerRecipe', {
  baseImage: imagebuilder.BaseContainerImage.fromDockerHub('amazonlinux', 'latest'),
  targetRepository: imagebuilder.Repository.fromEcr(
    ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
  )
});

const recipeBasedPolicy = new imagebuilder.LifecyclePolicy(this, 'RecipeBasedPolicy', {
  resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
  details: [
    {
      action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
      filter: { countFilter: { count: 5 } }
    }
  ],
  resourceSelection: {
    recipes: [imageRecipe, containerRecipe]
  }
});
python
image_recipe = imagebuilder.ImageRecipe(self, "MyImageRecipe",
    base_image=imagebuilder.BaseImage.from_ssm_parameter_name("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")
)

container_recipe = imagebuilder.ContainerRecipe(self, "MyContainerRecipe",
    base_image=imagebuilder.BaseContainerImage.from_docker_hub("amazonlinux", "latest"),
    target_repository=imagebuilder.Repository.from_ecr(
        ecr.Repository.from_repository_name(self, "Repository", "my-container-repo"))
)

recipe_based_policy = imagebuilder.LifecyclePolicy(self, "RecipeBasedPolicy",
    resource_type=imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
    details=[imagebuilder.LifecyclePolicyDetail(
        action=imagebuilder.LifecyclePolicyAction(type=imagebuilder.LifecyclePolicyActionType.DELETE),
        filter=imagebuilder.LifecyclePolicyFilter(count_filter=imagebuilder.LifecyclePolicyCountFilter(count=5))
    )
    ],
    resource_selection=imagebuilder.LifecyclePolicyResourceSelection(
        recipes=[image_recipe, container_recipe]
    )
)
java
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();
csharp
var imageRecipe = new ImageRecipe(this, "MyImageRecipe", new ImageRecipeProps {
    BaseImage = BaseImage.FromSsmParameterName("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")
});

var containerRecipe = new ContainerRecipe(this, "MyContainerRecipe", new ContainerRecipeProps {
    BaseImage = BaseContainerImage.FromDockerHub("amazonlinux", "latest"),
    TargetRepository = Repository.FromEcr(Repository.FromRepositoryName(this, "Repository", "my-container-repo"))
});

var recipeBasedPolicy = new LifecyclePolicy(this, "RecipeBasedPolicy", new LifecyclePolicyProps {
    ResourceType = LifecyclePolicyResourceType.AMI_IMAGE,
    Details = new [] { new LifecyclePolicyDetail {
        Action = new LifecyclePolicyAction { Type = LifecyclePolicyActionType.DELETE },
        Filter = new LifecyclePolicyFilter { CountFilter = new LifecyclePolicyCountFilter { Count = 5 } }
    } },
    ResourceSelection = new LifecyclePolicyResourceSelection {
        Recipes = new [] { imageRecipe, containerRecipe }
    }
});
go
imageRecipe := imagebuilder.NewImageRecipe(this, jsii.String("MyImageRecipe"), &ImageRecipeProps{
	BaseImage: imagebuilder.BaseImage_*FromSsmParameterName(jsii.String("/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64")),
})

containerRecipe := imagebuilder.NewContainerRecipe(this, jsii.String("MyContainerRecipe"), &ContainerRecipeProps{
	BaseImage: imagebuilder.BaseContainerImage_*FromDockerHub(jsii.String("amazonlinux"), jsii.String("latest")),
	TargetRepository: imagebuilder.Repository_*FromEcr(ecr.Repository_*FromRepositoryName(this, jsii.String("Repository"), jsii.String("my-container-repo"))),
})

recipeBasedPolicy := imagebuilder.NewLifecyclePolicy(this, jsii.String("RecipeBasedPolicy"), &LifecyclePolicyProps{
	ResourceType: imagebuilder.LifecyclePolicyResourceType_AMI_IMAGE,
	Details: []LifecyclePolicyDetail{
		&LifecyclePolicyDetail{
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DELETE,
			},
			Filter: &LifecyclePolicyFilter{
				CountFilter: &LifecyclePolicyCountFilter{
					Count: jsii.Number(5),
				},
			},
		},
	},
	ResourceSelection: &LifecyclePolicyResourceSelection{
		Recipes: []IRecipeBase{
			imageRecipe,
			containerRecipe,
		},
	},
})

Lifecycle Policy Rules ​

Age-Based Rules ​

Delete images older than a specific time period:

ts
const ageBasedPolicy = new imagebuilder.LifecyclePolicy(this, 'AgeBasedPolicy', {
  resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
  details: [
    {
      action: {
        type: imagebuilder.LifecyclePolicyActionType.DELETE,
        includeAmis: true,
        includeSnapshots: true
      },
      filter: {
        ageFilter: {
          age: Duration.days(60),
          retainAtLeast: 3  // Always keep at least 3 images
        }
      }
    }
  ],
  resourceSelection: {
    tags: { Environment: 'testing' }
  }
});
python
age_based_policy = imagebuilder.LifecyclePolicy(self, "AgeBasedPolicy",
    resource_type=imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
    details=[imagebuilder.LifecyclePolicyDetail(
        action=imagebuilder.LifecyclePolicyAction(
            type=imagebuilder.LifecyclePolicyActionType.DELETE,
            include_amis=True,
            include_snapshots=True
        ),
        filter=imagebuilder.LifecyclePolicyFilter(
            age_filter=imagebuilder.LifecyclePolicyAgeFilter(
                age=Duration.days(60),
                retain_at_least=3
            )
        )
    )
    ],
    resource_selection=imagebuilder.LifecyclePolicyResourceSelection(
        tags={"Environment": "testing"}
    )
)
java
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();
csharp
var ageBasedPolicy = new LifecyclePolicy(this, "AgeBasedPolicy", new LifecyclePolicyProps {
    ResourceType = LifecyclePolicyResourceType.AMI_IMAGE,
    Details = new [] { new LifecyclePolicyDetail {
        Action = new LifecyclePolicyAction {
            Type = LifecyclePolicyActionType.DELETE,
            IncludeAmis = true,
            IncludeSnapshots = true
        },
        Filter = new LifecyclePolicyFilter {
            AgeFilter = new LifecyclePolicyAgeFilter {
                Age = Duration.Days(60),
                RetainAtLeast = 3
            }
        }
    } },
    ResourceSelection = new LifecyclePolicyResourceSelection {
        Tags = new Dictionary<string, string> { { "Environment", "testing" } }
    }
});
go
ageBasedPolicy := imagebuilder.NewLifecyclePolicy(this, jsii.String("AgeBasedPolicy"), &LifecyclePolicyProps{
	ResourceType: imagebuilder.LifecyclePolicyResourceType_AMI_IMAGE,
	Details: []LifecyclePolicyDetail{
		&LifecyclePolicyDetail{
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DELETE,
				IncludeAmis: jsii.Boolean(true),
				IncludeSnapshots: jsii.Boolean(true),
			},
			Filter: &LifecyclePolicyFilter{
				AgeFilter: &LifecyclePolicyAgeFilter{
					Age: awscdk.Duration_Days(jsii.Number(60)),
					RetainAtLeast: jsii.Number(3),
				},
			},
		},
	},
	ResourceSelection: &LifecyclePolicyResourceSelection{
		Tags: map[string]*string{
			"Environment": jsii.String("testing"),
		},
	},
})
Count-Based Rules ​

Keep only a specific number of the most recent images:

ts
const countBasedPolicy = new imagebuilder.LifecyclePolicy(this, 'CountBasedPolicy', {
  resourceType: imagebuilder.LifecyclePolicyResourceType.CONTAINER_IMAGE,
  details: [
    {
      action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
      filter: { countFilter: { count: 15 } }  // Keep only the 15 most recent images
    }
  ],
  resourceSelection: {
    tags: { Application: 'microservice' }
  }
});
python
count_based_policy = imagebuilder.LifecyclePolicy(self, "CountBasedPolicy",
    resource_type=imagebuilder.LifecyclePolicyResourceType.CONTAINER_IMAGE,
    details=[imagebuilder.LifecyclePolicyDetail(
        action=imagebuilder.LifecyclePolicyAction(type=imagebuilder.LifecyclePolicyActionType.DELETE),
        filter=imagebuilder.LifecyclePolicyFilter(count_filter=imagebuilder.LifecyclePolicyCountFilter(count=15))
    )
    ],
    resource_selection=imagebuilder.LifecyclePolicyResourceSelection(
        tags={"Application": "microservice"}
    )
)
java
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();
csharp
var countBasedPolicy = new LifecyclePolicy(this, "CountBasedPolicy", new LifecyclePolicyProps {
    ResourceType = LifecyclePolicyResourceType.CONTAINER_IMAGE,
    Details = new [] { new LifecyclePolicyDetail {
        Action = new LifecyclePolicyAction { Type = LifecyclePolicyActionType.DELETE },
        Filter = new LifecyclePolicyFilter { CountFilter = new LifecyclePolicyCountFilter { Count = 15 } }
    } },
    ResourceSelection = new LifecyclePolicyResourceSelection {
        Tags = new Dictionary<string, string> { { "Application", "microservice" } }
    }
});
go
countBasedPolicy := imagebuilder.NewLifecyclePolicy(this, jsii.String("CountBasedPolicy"), &LifecyclePolicyProps{
	ResourceType: imagebuilder.LifecyclePolicyResourceType_CONTAINER_IMAGE,
	Details: []LifecyclePolicyDetail{
		&LifecyclePolicyDetail{
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DELETE,
			},
			Filter: &LifecyclePolicyFilter{
				CountFilter: &LifecyclePolicyCountFilter{
					Count: jsii.Number(15),
				},
			},
		},
	},
	ResourceSelection: &LifecyclePolicyResourceSelection{
		Tags: map[string]*string{
			"Application": jsii.String("microservice"),
		},
	},
})
Multiple Lifecycle Rules ​

Implement a graduated approach with multiple actions:

ts
const graduatedPolicy = new imagebuilder.LifecyclePolicy(this, 'GraduatedPolicy', {
  resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
  details: [
    {
      // First: Deprecate images after 30 days
      action: {
        type: imagebuilder.LifecyclePolicyActionType.DEPRECATE,
        includeAmis: true
      },
      filter: {
        ageFilter: {
          age: Duration.days(30),
          retainAtLeast: 5
        }
      }
    },
    {
      // Second: Disable images after 60 days
      action: {
        type: imagebuilder.LifecyclePolicyActionType.DISABLE,
        includeAmis: true
      },
      filter: {
        ageFilter: {
          age: Duration.days(60),
          retainAtLeast: 3
        }
      }
    },
    {
      // Finally: Delete images after 90 days
      action: {
        type: imagebuilder.LifecyclePolicyActionType.DELETE,
        includeAmis: true,
        includeSnapshots: true
      },
      filter: {
        ageFilter: {
          age: Duration.days(90),
          retainAtLeast: 1
        }
      }
    }
  ],
  resourceSelection: {
    tags: { Environment: 'production' }
  }
});
python
graduated_policy = imagebuilder.LifecyclePolicy(self, "GraduatedPolicy",
    resource_type=imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
    details=[imagebuilder.LifecyclePolicyDetail(
        # First: Deprecate images after 30 days
        action=imagebuilder.LifecyclePolicyAction(
            type=imagebuilder.LifecyclePolicyActionType.DEPRECATE,
            include_amis=True
        ),
        filter=imagebuilder.LifecyclePolicyFilter(
            age_filter=imagebuilder.LifecyclePolicyAgeFilter(
                age=Duration.days(30),
                retain_at_least=5
            )
        )
    ), imagebuilder.LifecyclePolicyDetail(
        # Second: Disable images after 60 days
        action=imagebuilder.LifecyclePolicyAction(
            type=imagebuilder.LifecyclePolicyActionType.DISABLE,
            include_amis=True
        ),
        filter=imagebuilder.LifecyclePolicyFilter(
            age_filter=imagebuilder.LifecyclePolicyAgeFilter(
                age=Duration.days(60),
                retain_at_least=3
            )
        )
    ), imagebuilder.LifecyclePolicyDetail(
        # Finally: Delete images after 90 days
        action=imagebuilder.LifecyclePolicyAction(
            type=imagebuilder.LifecyclePolicyActionType.DELETE,
            include_amis=True,
            include_snapshots=True
        ),
        filter=imagebuilder.LifecyclePolicyFilter(
            age_filter=imagebuilder.LifecyclePolicyAgeFilter(
                age=Duration.days(90),
                retain_at_least=1
            )
        )
    )
    ],
    resource_selection=imagebuilder.LifecyclePolicyResourceSelection(
        tags={"Environment": "production"}
    )
)
java
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();
csharp
var graduatedPolicy = new LifecyclePolicy(this, "GraduatedPolicy", new LifecyclePolicyProps {
    ResourceType = LifecyclePolicyResourceType.AMI_IMAGE,
    Details = new [] { new LifecyclePolicyDetail {
        // First: Deprecate images after 30 days
        Action = new LifecyclePolicyAction {
            Type = LifecyclePolicyActionType.DEPRECATE,
            IncludeAmis = true
        },
        Filter = new LifecyclePolicyFilter {
            AgeFilter = new LifecyclePolicyAgeFilter {
                Age = Duration.Days(30),
                RetainAtLeast = 5
            }
        }
    }, new LifecyclePolicyDetail {
        // Second: Disable images after 60 days
        Action = new LifecyclePolicyAction {
            Type = LifecyclePolicyActionType.DISABLE,
            IncludeAmis = true
        },
        Filter = new LifecyclePolicyFilter {
            AgeFilter = new LifecyclePolicyAgeFilter {
                Age = Duration.Days(60),
                RetainAtLeast = 3
            }
        }
    }, new LifecyclePolicyDetail {
        // Finally: Delete images after 90 days
        Action = new LifecyclePolicyAction {
            Type = LifecyclePolicyActionType.DELETE,
            IncludeAmis = true,
            IncludeSnapshots = true
        },
        Filter = new LifecyclePolicyFilter {
            AgeFilter = new LifecyclePolicyAgeFilter {
                Age = Duration.Days(90),
                RetainAtLeast = 1
            }
        }
    } },
    ResourceSelection = new LifecyclePolicyResourceSelection {
        Tags = new Dictionary<string, string> { { "Environment", "production" } }
    }
});
go
graduatedPolicy := imagebuilder.NewLifecyclePolicy(this, jsii.String("GraduatedPolicy"), &LifecyclePolicyProps{
	ResourceType: imagebuilder.LifecyclePolicyResourceType_AMI_IMAGE,
	Details: []LifecyclePolicyDetail{
		&LifecyclePolicyDetail{
			// First: Deprecate images after 30 days
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DEPRECATE,
				IncludeAmis: jsii.Boolean(true),
			},
			Filter: &LifecyclePolicyFilter{
				AgeFilter: &LifecyclePolicyAgeFilter{
					Age: awscdk.Duration_Days(jsii.Number(30)),
					RetainAtLeast: jsii.Number(5),
				},
			},
		},
		&LifecyclePolicyDetail{
			// Second: Disable images after 60 days
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DISABLE,
				IncludeAmis: jsii.Boolean(true),
			},
			Filter: &LifecyclePolicyFilter{
				AgeFilter: &LifecyclePolicyAgeFilter{
					Age: awscdk.Duration_*Days(jsii.Number(60)),
					RetainAtLeast: jsii.Number(3),
				},
			},
		},
		&LifecyclePolicyDetail{
			// Finally: Delete images after 90 days
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DELETE,
				IncludeAmis: jsii.Boolean(true),
				IncludeSnapshots: jsii.Boolean(true),
			},
			Filter: &LifecyclePolicyFilter{
				AgeFilter: &LifecyclePolicyAgeFilter{
					Age: awscdk.Duration_*Days(jsii.Number(90)),
					RetainAtLeast: jsii.Number(1),
				},
			},
		},
	},
	ResourceSelection: &LifecyclePolicyResourceSelection{
		Tags: map[string]*string{
			"Environment": jsii.String("production"),
		},
	},
})

Lifecycle Policy Exclusion Rules ​

AMI Exclusion Rules ​

Exclude specific AMIs from lifecycle actions based on various criteria:

ts
const excludeAmisPolicy = new imagebuilder.LifecyclePolicy(this, 'ExcludeAmisPolicy', {
  resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
  details: [
    {
      action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
      filter: { ageFilter: { age: Duration.days(30) } },
      exclusionRules: {
        amiExclusionRules: {
          isPublic: true,  // Exclude public AMIs
          lastLaunched: Duration.days(7),  // Exclude AMIs launched in last 7 days
          regions: ['us-west-2', 'eu-west-1'],  // Exclude AMIs in specific regions
          sharedAccounts: ['123456789012'],  // Exclude AMIs shared with specific accounts
          tags: {
            Protected: 'true',
            Environment: 'production'
          }
        }
      }
    }
  ],
  resourceSelection: {
    tags: { Team: 'infrastructure' }
  }
});
python
exclude_amis_policy = imagebuilder.LifecyclePolicy(self, "ExcludeAmisPolicy",
    resource_type=imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
    details=[imagebuilder.LifecyclePolicyDetail(
        action=imagebuilder.LifecyclePolicyAction(type=imagebuilder.LifecyclePolicyActionType.DELETE),
        filter=imagebuilder.LifecyclePolicyFilter(age_filter=imagebuilder.LifecyclePolicyAgeFilter(age=Duration.days(30))),
        exclusion_rules=imagebuilder.LifecyclePolicyExclusionRules(
            ami_exclusion_rules=imagebuilder.LifecyclePolicyAmiExclusionRules(
                is_public=True,  # Exclude public AMIs
                last_launched=Duration.days(7),  # Exclude AMIs launched in last 7 days
                regions=["us-west-2", "eu-west-1"],  # Exclude AMIs in specific regions
                shared_accounts=["123456789012"],  # Exclude AMIs shared with specific accounts
                tags={
                    "Protected": "true",
                    "Environment": "production"
                }
            )
        )
    )
    ],
    resource_selection=imagebuilder.LifecyclePolicyResourceSelection(
        tags={"Team": "infrastructure"}
    )
)
java
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();
csharp
var excludeAmisPolicy = new LifecyclePolicy(this, "ExcludeAmisPolicy", new LifecyclePolicyProps {
    ResourceType = LifecyclePolicyResourceType.AMI_IMAGE,
    Details = new [] { new LifecyclePolicyDetail {
        Action = new LifecyclePolicyAction { Type = LifecyclePolicyActionType.DELETE },
        Filter = new LifecyclePolicyFilter { AgeFilter = new LifecyclePolicyAgeFilter { Age = Duration.Days(30) } },
        ExclusionRules = new LifecyclePolicyExclusionRules {
            AmiExclusionRules = new LifecyclePolicyAmiExclusionRules {
                IsPublic = true,  // Exclude public AMIs
                LastLaunched = Duration.Days(7),  // Exclude AMIs launched in last 7 days
                Regions = new [] { "us-west-2", "eu-west-1" },  // Exclude AMIs in specific regions
                SharedAccounts = new [] { "123456789012" },  // Exclude AMIs shared with specific accounts
                Tags = new Dictionary<string, string> {
                    { "Protected", "true" },
                    { "Environment", "production" }
                }
            }
        }
    } },
    ResourceSelection = new LifecyclePolicyResourceSelection {
        Tags = new Dictionary<string, string> { { "Team", "infrastructure" } }
    }
});
go
excludeAmisPolicy := imagebuilder.NewLifecyclePolicy(this, jsii.String("ExcludeAmisPolicy"), &LifecyclePolicyProps{
	ResourceType: imagebuilder.LifecyclePolicyResourceType_AMI_IMAGE,
	Details: []LifecyclePolicyDetail{
		&LifecyclePolicyDetail{
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DELETE,
			},
			Filter: &LifecyclePolicyFilter{
				AgeFilter: &LifecyclePolicyAgeFilter{
					Age: awscdk.Duration_Days(jsii.Number(30)),
				},
			},
			ExclusionRules: &LifecyclePolicyExclusionRules{
				AmiExclusionRules: &LifecyclePolicyAmiExclusionRules{
					IsPublic: jsii.Boolean(true),
					 // Exclude public AMIs
					LastLaunched: awscdk.Duration_*Days(jsii.Number(7)),
					 // Exclude AMIs launched in last 7 days
					Regions: []*string{
						jsii.String("us-west-2"),
						jsii.String("eu-west-1"),
					},
					 // Exclude AMIs in specific regions
					SharedAccounts: []*string{
						jsii.String("123456789012"),
					},
					 // Exclude AMIs shared with specific accounts
					Tags: map[string]*string{
						"Protected": jsii.String("true"),
						"Environment": jsii.String("production"),
					},
				},
			},
		},
	},
	ResourceSelection: &LifecyclePolicyResourceSelection{
		Tags: map[string]*string{
			"Team": jsii.String("infrastructure"),
		},
	},
})
Image Exclusion Rules ​

Exclude Image Builder images with protective tags:

ts
const excludeImagesPolicy = new imagebuilder.LifecyclePolicy(this, 'ExcludeImagesPolicy', {
  resourceType: imagebuilder.LifecyclePolicyResourceType.CONTAINER_IMAGE,
  details: [
    {
      action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
      filter: { countFilter: { count: 20 } },
      exclusionRules: {
        imageExclusionRules: {
          tags: {
            DoNotDelete: 'true',
            Critical: 'baseline'
          }
        }
      }
    }
  ],
  resourceSelection: {
    tags: { Application: 'frontend' }
  }
});
python
exclude_images_policy = imagebuilder.LifecyclePolicy(self, "ExcludeImagesPolicy",
    resource_type=imagebuilder.LifecyclePolicyResourceType.CONTAINER_IMAGE,
    details=[imagebuilder.LifecyclePolicyDetail(
        action=imagebuilder.LifecyclePolicyAction(type=imagebuilder.LifecyclePolicyActionType.DELETE),
        filter=imagebuilder.LifecyclePolicyFilter(count_filter=imagebuilder.LifecyclePolicyCountFilter(count=20)),
        exclusion_rules=imagebuilder.LifecyclePolicyExclusionRules(
            image_exclusion_rules=imagebuilder.LifecyclePolicyImageExclusionRules(
                tags={
                    "DoNotDelete": "true",
                    "Critical": "baseline"
                }
            )
        )
    )
    ],
    resource_selection=imagebuilder.LifecyclePolicyResourceSelection(
        tags={"Application": "frontend"}
    )
)
java
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();
csharp
var excludeImagesPolicy = new LifecyclePolicy(this, "ExcludeImagesPolicy", new LifecyclePolicyProps {
    ResourceType = LifecyclePolicyResourceType.CONTAINER_IMAGE,
    Details = new [] { new LifecyclePolicyDetail {
        Action = new LifecyclePolicyAction { Type = LifecyclePolicyActionType.DELETE },
        Filter = new LifecyclePolicyFilter { CountFilter = new LifecyclePolicyCountFilter { Count = 20 } },
        ExclusionRules = new LifecyclePolicyExclusionRules {
            ImageExclusionRules = new LifecyclePolicyImageExclusionRules {
                Tags = new Dictionary<string, string> {
                    { "DoNotDelete", "true" },
                    { "Critical", "baseline" }
                }
            }
        }
    } },
    ResourceSelection = new LifecyclePolicyResourceSelection {
        Tags = new Dictionary<string, string> { { "Application", "frontend" } }
    }
});
go
excludeImagesPolicy := imagebuilder.NewLifecyclePolicy(this, jsii.String("ExcludeImagesPolicy"), &LifecyclePolicyProps{
	ResourceType: imagebuilder.LifecyclePolicyResourceType_CONTAINER_IMAGE,
	Details: []LifecyclePolicyDetail{
		&LifecyclePolicyDetail{
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DELETE,
			},
			Filter: &LifecyclePolicyFilter{
				CountFilter: &LifecyclePolicyCountFilter{
					Count: jsii.Number(20),
				},
			},
			ExclusionRules: &LifecyclePolicyExclusionRules{
				ImageExclusionRules: &LifecyclePolicyImageExclusionRules{
					Tags: map[string]*string{
						"DoNotDelete": jsii.String("true"),
						"Critical": jsii.String("baseline"),
					},
				},
			},
		},
	},
	ResourceSelection: &LifecyclePolicyResourceSelection{
		Tags: map[string]*string{
			"Application": jsii.String("frontend"),
		},
	},
})

Advanced Lifecycle Configuration ​

Custom Execution Roles ​

Provide your own IAM execution role with specific permissions:

ts
const executionRole = new iam.Role(this, 'LifecycleExecutionRole', {
  assumedBy: new iam.ServicePrincipal('imagebuilder.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/EC2ImageBuilderLifecycleExecutionPolicy')
  ]
});

const customRolePolicy = new imagebuilder.LifecyclePolicy(this, 'CustomRolePolicy', {
  resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
  executionRole: executionRole,
  details: [
    {
      action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
      filter: { ageFilter: { age: Duration.days(45) } }
    }
  ],
  resourceSelection: {
    tags: { Environment: 'development' }
  }
});
python
execution_role = iam.Role(self, "LifecycleExecutionRole",
    assumed_by=iam.ServicePrincipal("imagebuilder.amazonaws.com"),
    managed_policies=[
        iam.ManagedPolicy.from_aws_managed_policy_name("service-role/EC2ImageBuilderLifecycleExecutionPolicy")
    ]
)

custom_role_policy = imagebuilder.LifecyclePolicy(self, "CustomRolePolicy",
    resource_type=imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
    execution_role=execution_role,
    details=[imagebuilder.LifecyclePolicyDetail(
        action=imagebuilder.LifecyclePolicyAction(type=imagebuilder.LifecyclePolicyActionType.DELETE),
        filter=imagebuilder.LifecyclePolicyFilter(age_filter=imagebuilder.LifecyclePolicyAgeFilter(age=Duration.days(45)))
    )
    ],
    resource_selection=imagebuilder.LifecyclePolicyResourceSelection(
        tags={"Environment": "development"}
    )
)
java
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();
csharp
var executionRole = new Role(this, "LifecycleExecutionRole", new RoleProps {
    AssumedBy = new ServicePrincipal("imagebuilder.amazonaws.com"),
    ManagedPolicies = new [] { ManagedPolicy.FromAwsManagedPolicyName("service-role/EC2ImageBuilderLifecycleExecutionPolicy") }
});

var customRolePolicy = new LifecyclePolicy(this, "CustomRolePolicy", new LifecyclePolicyProps {
    ResourceType = LifecyclePolicyResourceType.AMI_IMAGE,
    ExecutionRole = executionRole,
    Details = new [] { new LifecyclePolicyDetail {
        Action = new LifecyclePolicyAction { Type = LifecyclePolicyActionType.DELETE },
        Filter = new LifecyclePolicyFilter { AgeFilter = new LifecyclePolicyAgeFilter { Age = Duration.Days(45) } }
    } },
    ResourceSelection = new LifecyclePolicyResourceSelection {
        Tags = new Dictionary<string, string> { { "Environment", "development" } }
    }
});
go
executionRole := iam.NewRole(this, jsii.String("LifecycleExecutionRole"), &RoleProps{
	AssumedBy: iam.NewServicePrincipal(jsii.String("imagebuilder.amazonaws.com")),
	ManagedPolicies: []IManagedPolicy{
		iam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("service-role/EC2ImageBuilderLifecycleExecutionPolicy")),
	},
})

customRolePolicy := imagebuilder.NewLifecyclePolicy(this, jsii.String("CustomRolePolicy"), &LifecyclePolicyProps{
	ResourceType: imagebuilder.LifecyclePolicyResourceType_AMI_IMAGE,
	ExecutionRole: executionRole,
	Details: []LifecyclePolicyDetail{
		&LifecyclePolicyDetail{
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DELETE,
			},
			Filter: &LifecyclePolicyFilter{
				AgeFilter: &LifecyclePolicyAgeFilter{
					Age: awscdk.Duration_Days(jsii.Number(45)),
				},
			},
		},
	},
	ResourceSelection: &LifecyclePolicyResourceSelection{
		Tags: map[string]*string{
			"Environment": jsii.String("development"),
		},
	},
})
Lifecycle Policy Status ​

Control whether the lifecycle policy is active:

ts
const disabledPolicy = new imagebuilder.LifecyclePolicy(this, 'DisabledPolicy', {
  lifecyclePolicyName: 'my-disabled-policy',
  description: 'A lifecycle policy that is temporarily disabled',
  status: imagebuilder.LifecyclePolicyStatus.DISABLED,
  resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
  details: [
    {
      action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
      filter: { ageFilter: { age: Duration.days(30) } }
    }
  ],
  resourceSelection: {
    tags: { Environment: 'testing' }
  },
  tags: {
    Owner: 'DevOps',
    CostCenter: 'Engineering'
  }
});
python
disabled_policy = imagebuilder.LifecyclePolicy(self, "DisabledPolicy",
    lifecycle_policy_name="my-disabled-policy",
    description="A lifecycle policy that is temporarily disabled",
    status=imagebuilder.LifecyclePolicyStatus.DISABLED,
    resource_type=imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
    details=[imagebuilder.LifecyclePolicyDetail(
        action=imagebuilder.LifecyclePolicyAction(type=imagebuilder.LifecyclePolicyActionType.DELETE),
        filter=imagebuilder.LifecyclePolicyFilter(age_filter=imagebuilder.LifecyclePolicyAgeFilter(age=Duration.days(30)))
    )
    ],
    resource_selection=imagebuilder.LifecyclePolicyResourceSelection(
        tags={"Environment": "testing"}
    ),
    tags={
        "Owner": "DevOps",
        "CostCenter": "Engineering"
    }
)
java
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();
csharp
var disabledPolicy = new LifecyclePolicy(this, "DisabledPolicy", new LifecyclePolicyProps {
    LifecyclePolicyName = "my-disabled-policy",
    Description = "A lifecycle policy that is temporarily disabled",
    Status = LifecyclePolicyStatus.DISABLED,
    ResourceType = LifecyclePolicyResourceType.AMI_IMAGE,
    Details = new [] { new LifecyclePolicyDetail {
        Action = new LifecyclePolicyAction { Type = LifecyclePolicyActionType.DELETE },
        Filter = new LifecyclePolicyFilter { AgeFilter = new LifecyclePolicyAgeFilter { Age = Duration.Days(30) } }
    } },
    ResourceSelection = new LifecyclePolicyResourceSelection {
        Tags = new Dictionary<string, string> { { "Environment", "testing" } }
    },
    Tags = new Dictionary<string, string> {
        { "Owner", "DevOps" },
        { "CostCenter", "Engineering" }
    }
});
go
disabledPolicy := imagebuilder.NewLifecyclePolicy(this, jsii.String("DisabledPolicy"), &LifecyclePolicyProps{
	LifecyclePolicyName: jsii.String("my-disabled-policy"),
	Description: jsii.String("A lifecycle policy that is temporarily disabled"),
	Status: imagebuilder.LifecyclePolicyStatus_DISABLED,
	ResourceType: imagebuilder.LifecyclePolicyResourceType_AMI_IMAGE,
	Details: []LifecyclePolicyDetail{
		&LifecyclePolicyDetail{
			Action: &LifecyclePolicyAction{
				Type: imagebuilder.LifecyclePolicyActionType_DELETE,
			},
			Filter: &LifecyclePolicyFilter{
				AgeFilter: &LifecyclePolicyAgeFilter{
					Age: awscdk.Duration_Days(jsii.Number(30)),
				},
			},
		},
	},
	ResourceSelection: &LifecyclePolicyResourceSelection{
		Tags: map[string]*string{
			"Environment": jsii.String("testing"),
		},
	},
	Tags: map[string]*string{
		"Owner": jsii.String("DevOps"),
		"CostCenter": jsii.String("Engineering"),
	},
})
Importing Lifecycle Policies ​

Reference lifecycle policies created outside CDK:

ts
// Import by name
const importedByName = imagebuilder.LifecyclePolicy.fromLifecyclePolicyName(
  this,
  'ImportedByName',
  'existing-lifecycle-policy'
);

// Import by ARN
const importedByArn = imagebuilder.LifecyclePolicy.fromLifecyclePolicyArn(
  this,
  'ImportedByArn',
  'arn:aws:imagebuilder:us-east-1:123456789012:lifecycle-policy/my-policy'
);

importedByName.grantRead(lambdaRole);
importedByArn.grant(lambdaRole, 'imagebuilder:UpdateLifecyclePolicy');
python
# Import by name
imported_by_name = imagebuilder.LifecyclePolicy.from_lifecycle_policy_name(self, "ImportedByName", "existing-lifecycle-policy")

# Import by ARN
imported_by_arn = imagebuilder.LifecyclePolicy.from_lifecycle_policy_arn(self, "ImportedByArn", "arn:aws:imagebuilder:us-east-1:123456789012:lifecycle-policy/my-policy")

imported_by_name.grant_read(lambda_role)
imported_by_arn.grant(lambda_role, "imagebuilder:UpdateLifecyclePolicy")
java
// 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");
csharp
// Import by name
var importedByName = LifecyclePolicy.FromLifecyclePolicyName(this, "ImportedByName", "existing-lifecycle-policy");

// Import by ARN
var importedByArn = LifecyclePolicy.FromLifecyclePolicyArn(this, "ImportedByArn", "arn:aws:imagebuilder:us-east-1:123456789012:lifecycle-policy/my-policy");

importedByName.GrantRead(lambdaRole);
importedByArn.Grant(lambdaRole, "imagebuilder:UpdateLifecyclePolicy");
go
// Import by name
importedByName := imagebuilder.LifecyclePolicy_FromLifecyclePolicyName(this, jsii.String("ImportedByName"), jsii.String("existing-lifecycle-policy"))

// Import by ARN
importedByArn := imagebuilder.LifecyclePolicy_FromLifecyclePolicyArn(this, jsii.String("ImportedByArn"), jsii.String("arn:aws:imagebuilder:us-east-1:123456789012:lifecycle-policy/my-policy"))

importedByName.GrantRead(lambdaRole)
importedByArn.Grant(lambdaRole, jsii.String("imagebuilder:UpdateLifecyclePolicy"))

Types ​

NameKindSummary
ComponentConstruct (L2)Represents an EC2 Image Builder Component.
ContainerRecipeConstruct (L2)Represents an EC2 Image Builder Container Recipe.
ContainerRecipeBaseConstruct (L2)A new or imported Container Recipe.
DistributionConfigurationConstruct (L2)Represents an EC2 Image Builder Distribution Configuration.
ImageConstruct (L2)Represents an EC2 Image Builder Image.
ImagePipelineConstruct (L2)Represents an EC2 Image Builder Image Pipeline.
ImageRecipeConstruct (L2)Represents an EC2 Image Builder Image Recipe.
InfrastructureConfigurationConstruct (L2)Represents an EC2 Image Builder Infrastructure Configuration.
LifecyclePolicyConstruct (L2)Represents an EC2 Image Builder Lifecycle Policy.
WorkflowConstruct (L2)Represents an EC2 Image Builder Workflow.
AmazonManagedComponentClassHelper class for working with Amazon-managed components.
AmazonManagedComponentAttributesStructProperties for an EC2 Image Builder Amazon-managed component.
AmazonManagedComponentOptionsStructOptions for selecting a predefined Amazon-managed image.
AmazonManagedImageClassHelper class for working with Amazon-managed images.
AmazonManagedImageAttributesStructAttributes for importing an Amazon-managed image by name (and optionally a version).
AmazonManagedImageOptionsStructOptions for selecting a predefined Amazon-managed image.
AmazonManagedWorkflowClassHelper class for working with Amazon-managed workflows.
AmazonManagedWorkflowAttributesStructProperties for an EC2 Image Builder Amazon-managed workflow.
AmiDistributionStructThe regional distribution settings to use for an AMI build.
AmiLaunchPermissionStructThe launch permissions for the AMI, defining which principals are allowed to access the AMI.
AwsMarketplaceComponentClassHelper class for working with AWS Marketplace components.
AwsMarketplaceComponentAttributesStructProperties for an EC2 Image Builder AWS Marketplace component.
BaseContainerImageClassRepresents a base image that is used to start from in EC2 Image Builder image builds.
BaseImageClassRepresents a base image that is used to start from in EC2 Image Builder image builds.
ComponentActionEnumThe action for a step within the component document.
ComponentAttributesStructProperties for an EC2 Image Builder component.
ComponentConfigurationStructConfiguration details for a component, to include in a recipe.
ComponentConstantValueClassThe value of a constant in a component document.
ComponentDataClassHelper class for referencing and uploading component data.
ComponentDataConfigStructThe rendered component data value, for use in CloudFormation.
ComponentDocumentStructProperties of an EC2 Image Builder Component Document.
ComponentDocumentForLoopStructThe for loop iterates on a range of integers specified within a boundary outlined by the start and end of the variables.
ComponentDocumentLoopStructThe looping construct of a component defines a repeated sequence of instructions.
ComponentDocumentParameterDefinitionStructThe definition of the parameter.
ComponentDocumentPhaseStructThe phase to run in a specific workflow in an image build, which define the steps to execute to customize or test the instance.
ComponentDocumentStepStructThe step to run in a specific phase of the image build, which defines the step to execute to customize or test the instance.
ComponentOnFailureEnumSpecifies what the step should do in case of failure.
ComponentParameterTypeEnumThe parameter type in a component document.
ComponentParameterValueClassThe parameter value for a component parameter.
ComponentPhaseNameEnumThe phases of a component document.
ComponentPropsStructProperties for creating a Component resource.
ComponentSchemaVersionEnumThe schema version of the component.
ComponentStepIfConditionClassRepresents an if condition in the component document.
ComponentStepInputsClassRepresents the inputs for a step in the component document.
ContainerDistributionStructThe regional distribution settings to use for a container build.
ContainerInstanceImageClassRepresents a container instance image that is used to launch the instance used for building the container for an EC2 Image Builder container build.
ContainerRecipeAttributesStructProperties for an EC2 Image Builder container recipe.
ContainerRecipePropsStructProperties for creating a Container Recipe resource.
ContainerTypeEnumThe type of the container being used in the container recipe.
DistributionConfigurationPropsStructProperties for creating a Distribution Configuration resource.
DockerfileDataClassHelper class for referencing and uploading dockerfile data for the container recipe.
DockerfileTemplateConfigStructThe rendered Dockerfile value, for use in CloudFormation.
FastLaunchConfigurationStructThe EC2 Fast Launch configuration to use for the Windows AMI.
HttpTokensEnumIndicates whether a signed token header is required for instance metadata retrieval requests.
IComponentInterfaceAn EC2 Image Builder Component.
IContainerRecipeInterfaceAn EC2 Image Builder Container Recipe.
IDistributionConfigurationInterfaceAn EC2 Image Builder Distribution Configuration.
IImageInterfaceAn EC2 Image Builder Image.
IImagePipelineInterfaceAn EC2 Image Builder Image Pipeline.
IImageRecipeInterfaceAn EC2 Image Builder Image Recipe.
IInfrastructureConfigurationInterfaceAn EC2 Image Builder Infrastructure Configuration.
ILifecyclePolicyInterfaceAn EC2 Image Builder Lifecycle Policy.
ImageArchitectureEnumThe architecture of the image.
ImageAttributesStructProperties for an EC2 Image Builder image.
ImagePipelinePropsStructProperties for creating an Image Pipeline resource.
ImagePipelineScheduleStructThe schedule settings for the image pipeline, which defines when a pipeline should be triggered.
ImagePipelineStatusEnumIndicates whether the pipeline is enabled to be triggered by the provided schedule.
ImagePropsStructProperties for creating an Image resource.
ImageRecipeAttributesStructProperties for an EC2 Image Builder image recipe.
ImageRecipePropsStructProperties for creating an Image Recipe resource.
ImageTypeEnumThe type of the image.
InfrastructureConfigurationLoggingStructThe log settings for detailed build logging.
InfrastructureConfigurationPropsStructProperties for creating an Infrastructure Configuration resource.
IRecipeBaseInterfaceA base interface for EC2 Image Builder recipes.
IWorkflowInterfaceAn EC2 Image Builder Workflow.
LaunchTemplateConfigurationStructThe launch template to apply the distributed AMI to.
LifecyclePolicyActionStructThe action to perform in the lifecycle policy rule.
LifecyclePolicyActionTypeEnumThe action to perform on the resources which the policy applies to.
LifecyclePolicyAgeFilterStructThe age-based filtering to apply in a lifecycle policy rule.
LifecyclePolicyAmiExclusionRulesStructThe rules to apply for excluding AMIs from the lifecycle policy rule.
LifecyclePolicyCountFilterStructThe count-based filtering to apply in a lifecycle policy rule.
LifecyclePolicyDetailStructConfiguration details for the lifecycle policy rules.
LifecyclePolicyExclusionRulesStructThe rules to apply for excluding resources from the lifecycle policy rule.
LifecyclePolicyFilterStructThe resource filtering to apply in the lifecycle policy rule.
LifecyclePolicyImageExclusionRulesStructThe rules to apply for excluding EC2 Image Builder images from the lifecycle policy rule.
LifecyclePolicyPropsStructProperties for creating a Lifecycle Policy resource.
LifecyclePolicyResourceSelectionStructSelection criteria for the resources that the lifecycle policy applies to.
LifecyclePolicyResourceTypeEnumThe resource type which the lifecycle policy is applied to.
LifecyclePolicyStatusEnumThe status of the lifecycle policy, indicating whether it will run.
OSVersionClassRepresents an OS version for an EC2 Image Builder image.
PlatformEnumRepresents a platform for an EC2 Image Builder image.
RepositoryClassA container repository used to distribute container images in EC2 Image Builder.
RepositoryServiceEnumThe service in which a container should be registered.
S3ComponentDataClassHelper class for S3-based component data references, containing additional permission grant methods on the S3 object.
S3DockerfileDataClassHelper class for S3-based dockerfile data references, containing additional permission grant methods on the S3 object.
S3WorkflowDataClassHelper class for S3-based workflow data references, containing additional permission grant methods on the S3 object.
ScheduleStartConditionEnumThe start condition for the pipeline, indicating the condition under which a pipeline should be triggered.
SSMParameterConfigurationsStructThe SSM parameters to create or update for the distributed AMIs.
TenancyEnumThe tenancy to use for an instance.
WorkflowActionEnumThe action for a step within the workflow document.
WorkflowAttributesStructProperties for an EC2 Image Builder Workflow.
WorkflowConfigurationStructConfiguration details for a workflow.
WorkflowDataClassHelper class for referencing and uploading workflow data.
WorkflowDataConfigStructThe rendered workflow data value, for use in CloudFormation.
WorkflowOnFailureEnumThe action to take if the workflow fails.
WorkflowParameterTypeEnumThe parameter type for the workflow parameter.
WorkflowParameterValueClassThe parameter value for a workflow parameter.
WorkflowPropsStructProperties for creating a Workflow resource.
WorkflowSchemaVersionEnumThe schema version of the workflow.
WorkflowTypeEnumThe type of the workflow.