Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 175 additions & 0 deletions packages/@aws-cdk/aws-imagebuilder-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,181 @@ EC2 Image Builder supports AWS-managed components for common tasks, AWS Marketpl
that you create. Components run during specific workflow phases: build and validate phases during the build stage, and
test phase during the test stage.

### 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')
)
});
```

#### 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')
)
});
```

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

##### 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')
)
});
```

#### 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
}
]
});
```

##### AWS-Managed Components in Container Recipes

Use pre-built AWS components:

```ts
const containerRecipe = new imagebuilder.ContainerRecipe(this, 'AwsManagedContainerRecipe', {
baseImage: imagebuilder.BaseContainerImage.fromDockerHub('amazonlinux', 'latest'),
targetRepository: imagebuilder.Repository.fromEcr(
ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
),
components: [
{
component: imagebuilder.AwsManagedComponent.updateOS(this, 'UpdateOS', {
platform: imagebuilder.Platform.LINUX
})
},
{
component: imagebuilder.AwsManagedComponent.awsCliV2(this, 'AwsCli', {
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 }}}
`)
});
```

##### 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
})
}
]
});
```

### Component

A component defines the sequence of steps required to customize an instance during image creation (build component) or
Expand Down
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-imagebuilder-alpha/awslint.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"exclude": [
"props-no-arn-refs:@aws-cdk/aws-imagebuilder-alpha.InfrastructureConfigurationProps.ec2InstanceHostResourceGroupArn"
"props-no-arn-refs:@aws-cdk/aws-imagebuilder-alpha.InfrastructureConfigurationProps.ec2InstanceHostResourceGroupArn",
"no-unused-type:@aws-cdk/aws-imagebuilder-alpha.ContainerType"
]
}
110 changes: 110 additions & 0 deletions packages/@aws-cdk/aws-imagebuilder-alpha/lib/base-image.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import * as ecr from 'aws-cdk-lib/aws-ecr';
import * as ssm from 'aws-cdk-lib/aws-ssm';

/**
* Represents a base image that is used to start from in EC2 Image Builder image builds
*/
export class BaseContainerImage {
/**
* The DockerHub image to use as the base image in a container recipe
*
* @param repository The DockerHub repository where the base image resides in
* @param tag The tag of the base image in the DockerHub repository
*/
public static fromDockerHub(repository: string, tag: string): BaseContainerImage {
return new BaseContainerImage(`${repository}:${tag}`);
}

/**
* The ECR container image to use as the base image in a container recipe
*
* @param repository The ECR repository where the base image resides in
* @param tag The tag of the base image in the ECR repository
*/
public static fromEcr(repository: ecr.IRepository, tag: string): BaseContainerImage {
return new BaseContainerImage(repository.repositoryUriForTag(tag));
}

/**
* The ECR public container image to use as the base image in a container recipe
*
* @param registryAlias The alias of the ECR public registry where the base image resides in
* @param repositoryName The name of the ECR public repository, where the base image resides in
* @param tag The tag of the base image in the ECR public repository
*/
public static fromEcrPublic(registryAlias: string, repositoryName: string, tag: string): BaseContainerImage {
return new BaseContainerImage(`public.ecr.aws/${registryAlias}/${repositoryName}:${tag}`);
}

/**
* The string value of the base image to use in a container recipe. This can be an EC2 Image Builder image ARN,
* an ECR or ECR public image, or a container URI sourced from a third-party container registry such as DockerHub.
*
* @param baseContainerImageString The base image as a direct string value
*/
public static fromString(baseContainerImageString: string): BaseContainerImage {
return new BaseContainerImage(baseContainerImageString);
}

/**
* The rendered base image to use
**/
public readonly image: string;

protected constructor(image: string) {
this.image = image;
}
}

/**
* Represents a container instance image that is used to launch the instance used for building the container for an
* EC2 Image Builder container build.
*/
export class ContainerInstanceImage {
/**
* The AMI ID to use to launch the instance for building the container image
*
* @param amiId The AMI ID to use as the container instance image
*/
public static fromAmiId(amiId: string): ContainerInstanceImage {
return new ContainerInstanceImage(amiId);
}

/**
* The SSM parameter to use to launch the instance for building the container image
*
* @param parameter The SSM parameter to use as the container instance image
*/
public static fromSsmParameter(parameter: ssm.IStringParameter): ContainerInstanceImage {
return new ContainerInstanceImage(`ssm:${parameter.parameterArn}`);
}

/**
* The name of the SSM parameter used to launch the instance for building the container image
*
* @param parameterName The name of the SSM parameter used as the container instance image
*/
public static fromSsmParameterName(parameterName: string): ContainerInstanceImage {
return new ContainerInstanceImage(`ssm:${parameterName}`);
}

/**
* The string value of the container instance image to use in a container recipe. This can either be:
* - an SSM parameter reference, prefixed with `ssm:` and followed by the parameter name or ARN
* - an AMI ID
*
* @param containerInstanceImageString The container instance image as a direct string value
*/
public static fromString(containerInstanceImageString: string): ContainerInstanceImage {
return new ContainerInstanceImage(containerInstanceImageString);
}

/**
* The rendered container instance image to use
**/
public readonly image: string;

protected constructor(image: string) {
this.image = image;
}
}
Loading
Loading