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
196 changes: 196 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,202 @@ 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.

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

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

##### AMI IDs

When you have a specific AMI to use:

```ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'AmiImageRecipe', {
baseImage: imagebuilder.BaseImage.fromAmiId('ami-12345678')
});
```

##### Marketplace Images

For marketplace base images:

```ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'MarketplaceImageRecipe', {
baseImage: imagebuilder.BaseImage.fromMarketplaceProductId('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
}
]
});
```

##### AWS-Managed Components in Image Recipes

Use pre-built AWS components:

```ts
const imageRecipe = new imagebuilder.ImageRecipe(this, 'AwsManagedImageRecipe', {
baseImage: imagebuilder.BaseImage.fromSsmParameterName(
'/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
),
components: [
{
component: imagebuilder.AwsManagedComponent.updateOS(this, 'UpdateOS', {
platform: imagebuilder.Platform.LINUX
})
},
{
component: imagebuilder.AwsManagedComponent.awsCliV2(this, 'AwsCli', {
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')
}
}
]
});
```

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

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

### Container Recipe

A container recipe is similar to an image recipe but specifically for container images. It defines the base container
Expand Down
62 changes: 61 additions & 1 deletion packages/@aws-cdk/aws-imagebuilder-alpha/lib/base-image.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,66 @@
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 BaseImage {
/**
* The AMI ID to use as a base image in an image recipe
*
* @param amiId The AMI ID to use as the base image
*/
public static fromAmiId(amiId: string): BaseImage {
return new BaseImage(amiId);
}

/**
* The marketplace product ID for an AMI product to use as the base image in an image recipe
*
* @param productId The Marketplace AMI product ID to use as the base image
*/
public static fromMarketplaceProductId(productId: string): BaseImage {
return new BaseImage(productId);
}

/**
* The SSM parameter to use as the base image in an image recipe
*
* @param parameter The SSM parameter to use as the base image
*/
public static fromSsmParameter(parameter: ssm.IParameter): BaseImage {
return new BaseImage(`ssm:${parameter.parameterArn}`);
}

/**
* The parameter name for the SSM parameter to use as the base image in an image recipe
*
* @param parameterName The name of the SSM parameter to use as the base image
*/
public static fromSsmParameterName(parameterName: string): BaseImage {
return new BaseImage(`ssm:${parameterName}`);
}

/**
* The direct string value of the base image to use in an image recipe. This can be an EC2 Image Builder image ARN,
* an SSM parameter, an AWS Marketplace product ID, or an AMI ID.
*
* @param baseImageString The base image as a direct string value
*/
public static fromString(baseImageString: string): BaseImage {
return new BaseImage(baseImageString);
}

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

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

/**
* Represents a base image that is used to start from in EC2 Image Builder image builds
*/
Expand Down Expand Up @@ -80,7 +140,7 @@ export class ContainerInstanceImage {
}

/**
* The name of the SSM parameter used to launch the instance for building the container image
* The ARN 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
*/
Expand Down
10 changes: 10 additions & 0 deletions packages/@aws-cdk/aws-imagebuilder-alpha/lib/container-recipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { propertyInjectable } from 'aws-cdk-lib/core/lib/prop-injectable';
import { Construct } from 'constructs';
import { BaseContainerImage, ContainerInstanceImage } from './base-image';
import { Repository } from './distribution-configuration';
import { IImageRecipe } from './image-recipe';
import { OSVersion } from './os-version';
import { ComponentConfiguration, IRecipeBase } from './recipe-base';

Expand Down Expand Up @@ -378,6 +379,15 @@ export abstract class ContainerRecipeBase extends cdk.Resource implements IConta
public _isContainerRecipe(): this is IContainerRecipe {
return true;
}

/**
* Indicates whether the recipe is an Image Recipe
*
* @internal
*/
public _isImageRecipe(): this is IImageRecipe {
return false;
}
}

/**
Expand Down
Loading
Loading