Skip to main content

The CDK Construct Library for EC2 Image Builder

Project description

EC2 Image Builder Construct Library

---

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.

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 Usage

Create a component with the required properties: platform and component data.

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"]
                }
            }
            ]
        }
        ]
    })
)

Component Data Sources

Inline Component Data

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

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']
        """)
)
JSON Object Component Data

Most developer-friendly approach using objects:

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\"}"
                }
            }
            ]
        }
        ]
    })
)
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:

step = imagebuilder.ComponentDocumentStep(
    name="configure-app",
    action=imagebuilder.ComponentAction.CREATE_FILE,
    inputs=imagebuilder.ComponentStepInputs.from_object({
        "path": "/etc/myapp/config.json",
        "content": "{\"env\": \"production\"}"
    })
)
Defining a component phase

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

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\"}"
        })
    )
    ]
)
Defining a component

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

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"]
                })
            )
            ]
        )
        ]
    )
)
S3 Component Data

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

# 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")
)

Encrypt component data with a KMS key

You can encrypt component data with a KMS key, so that only principals with access to decrypt with the key are able to access the component data.

component = 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\""]
                }
            }
            ]
        }
        ]
    })
)

AWS-Managed Components

AWS provides a collection of managed components for common tasks:

# Install AWS CLI v2
aws_cli_component = imagebuilder.AwsManagedComponent.aws_cli_v2(self, "AwsCli",
    platform=imagebuilder.Platform.LINUX
)

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

# Reference any AWS-managed component by name
custom_aws_component = imagebuilder.AwsManagedComponent.from_aws_managed_component_name(self, "CloudWatchAgent", "amazon-cloudwatch-agent-linux")

AWS Marketplace Components

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

marketplace_component = imagebuilder.AwsMarketplaceComponent.from_aws_marketplace_component_attributes(self, "MarketplaceComponent",
    component_name="my-marketplace-component",
    marketplace_product_id="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.

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

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

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"
    ]
)

Container Distributions

Container repositories

Container distributions can be configured to distribute to ECR repositories:

ecr_repository = ecr.Repository.from_repository_name(self, "ECRRepository", "my-repo")
image_builder_repository = imagebuilder.Repository.from_ecr(ecr_repository)
Defining a container distribution

You can configure the container repositories as well as the description and tags applied to the distributed container images:

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"]
)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aws_cdk_aws_imagebuilder_alpha-2.228.0a0.tar.gz (321.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file aws_cdk_aws_imagebuilder_alpha-2.228.0a0.tar.gz.

File metadata

File hashes

Hashes for aws_cdk_aws_imagebuilder_alpha-2.228.0a0.tar.gz
Algorithm Hash digest
SHA256 af2e3fe24cadc455c863b3848ce20f7056a3a274e2e37e862640607914a4ff4c
MD5 8bd148f3bf92b7215c9cc830748e6021
BLAKE2b-256 c7e39a92a857d73f9fa56a926133332d0607f702b5fd67f17321095e96b81bd2

See more details on using hashes here.

File details

Details for the file aws_cdk_aws_imagebuilder_alpha-2.228.0a0-py3-none-any.whl.

File metadata

File hashes

Hashes for aws_cdk_aws_imagebuilder_alpha-2.228.0a0-py3-none-any.whl
Algorithm Hash digest
SHA256 6ef5477baa73c181af980af86252d48fd9755207987de659c9da5ac2be930d4a
MD5 b9415e61be0b875fe9edeba32ee04fd8
BLAKE2b-256 570879c429186893b8be3671d7e4bcc2d52cc741fddba5149ff8a82fb7191dd6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page