Skip to content

Commit 5ebf07d

Browse files
authored
feat(imagebuilder-alpha): add support for Component Construct (#36006)
### Issue aws/aws-cdk-rfcs#789 ### Reason for this change This change adds a new alpha module for EC2 Image Builder L2 Constructs (`@aws-cdk/aws-imagebuilder-alpha`), as outlined in aws/aws-cdk-rfcs#789. This PR specifically implements the `Component` construct. ### Description of changes This change implements the `Component` construct, which is a higher-level construct of [`CfnComponent`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_imagebuilder.CfnComponent.html). #### Example ```ts const component = new imagebuilder.Component(this, 'Component', { componentName: 'build-and-test-component', componentVersion: '1.0.0', description: 'A build and test component', changeDescription: 'Initial version', // Encrypt component data with a KMS key kmsKey: kms.Key.fromKeyArn( this, 'ComponentKey', this.formatArn({ service: 'kms', resource: 'key', resourceName: '1234abcd-12ab-34cd-56ef-1234567890ab' }) ), platform: imagebuilder.Platform.LINUX, // Include the OS versions this component supports supportedOsVersions: [ imagebuilder.OSVersion.AMAZON_LINUX, imagebuilder.OSVersion.RHEL_10, imagebuilder.OSVersion.SLES_15, imagebuilder.OSVersion.UBUNTU ], // Hello world component data data: imagebuilder.ComponentData.fromJsonObject({ name: 'build-and-test-component', schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0, phases: [ { name: imagebuilder.ComponentPhaseName.BUILD, steps: [ { action: imagebuilder.ComponentAction.EXECUTE_BASH, name: 'hello-world-build', inputs: { commands: ['echo "Hello build!"'] } } ] }, { name: imagebuilder.ComponentPhaseName.VALIDATE, steps: [ { action: imagebuilder.ComponentAction.EXECUTE_BASH, name: 'hello-world-validate', inputs: { commands: ['echo "Hello validate!"'] } } ] }, { name: imagebuilder.ComponentPhaseName.TEST, steps: [ { action: imagebuilder.ComponentAction.EXECUTE_BASH, name: 'hello-world-test', inputs: { commands: ['echo "Hello test!"'] } } ] } ] }) }); ``` ### Describe any new or updated permissions being added N/A - new L2 construct in alpha module ### Description of how you validated changes Validated with unit tests and integration tests. Manually verified generated CFN templates as well. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent e71a8b1 commit 5ebf07d

File tree

45 files changed

+5971
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+5971
-0
lines changed

packages/@aws-cdk/aws-imagebuilder-alpha/README.md

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,210 @@ EC2 Image Builder supports AWS-managed components for common tasks, AWS Marketpl
3636
that you create. Components run during specific workflow phases: build and validate phases during the build stage, and
3737
test phase during the test stage.
3838

39+
### Component
40+
41+
A component defines the sequence of steps required to customize an instance during image creation (build component) or
42+
test an instance launched from the created image (test component). Components are created from declarative YAML or JSON
43+
documents that describe runtime configuration for building, validating, or testing instances. Components are included
44+
when added to the image recipe or container recipe for an image build.
45+
46+
EC2 Image Builder supports AWS-managed components for common tasks, AWS Marketplace components, and custom components
47+
that you create. Components run during specific workflow phases: build and validate phases during the build stage, and
48+
test phase during the test stage.
49+
50+
#### Basic Usage
51+
52+
Create a component with the required properties: platform and component data.
53+
54+
```ts
55+
const component = new imagebuilder.Component(this, 'MyComponent', {
56+
platform: imagebuilder.Platform.LINUX,
57+
data: imagebuilder.ComponentData.fromJsonObject({
58+
schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0,
59+
phases: [
60+
{
61+
name: imagebuilder.ComponentPhaseName.BUILD,
62+
steps: [
63+
{
64+
name: 'install-app',
65+
action: imagebuilder.ComponentAction.EXECUTE_BASH,
66+
inputs: {
67+
commands: ['echo "Installing my application..."', 'yum update -y'],
68+
},
69+
},
70+
],
71+
},
72+
],
73+
}),
74+
});
75+
```
76+
77+
#### Component Data Sources
78+
79+
##### Inline Component Data
80+
81+
Use `ComponentData.fromInline()` for existing YAML/JSON definitions:
82+
83+
```ts
84+
const component = new imagebuilder.Component(this, 'InlineComponent', {
85+
platform: imagebuilder.Platform.LINUX,
86+
data: imagebuilder.ComponentData.fromInline(`
87+
name: my-component
88+
schemaVersion: 1.0
89+
phases:
90+
- name: build
91+
steps:
92+
- name: update-os
93+
action: ExecuteBash
94+
inputs:
95+
commands: ['yum update -y']
96+
`)
97+
});
98+
```
99+
100+
##### JSON Object Component Data
101+
102+
Most developer-friendly approach using objects:
103+
104+
```ts
105+
const component = new imagebuilder.Component(this, 'JsonComponent', {
106+
platform: imagebuilder.Platform.LINUX,
107+
data: imagebuilder.ComponentData.fromJsonObject({
108+
schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0,
109+
phases: [
110+
{
111+
name: imagebuilder.ComponentPhaseName.BUILD,
112+
steps: [
113+
{
114+
name: 'configure-app',
115+
action: imagebuilder.ComponentAction.CREATE_FILE,
116+
inputs: {
117+
path: '/etc/myapp/config.json',
118+
content: '{"env": "production"}',
119+
},
120+
},
121+
],
122+
},
123+
],
124+
}),
125+
});
126+
```
127+
128+
##### Structured Component Document
129+
130+
For type-safe, CDK-native definitions with enhanced properties like `timeout` and `onFailure`:
131+
132+
```ts
133+
const component = new imagebuilder.Component(this, 'StructuredComponent', {
134+
platform: imagebuilder.Platform.LINUX,
135+
data: imagebuilder.ComponentData.fromComponentDocumentJsonObject({
136+
schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0,
137+
phases: [
138+
{
139+
name: imagebuilder.ComponentPhaseName.BUILD,
140+
steps: [
141+
{
142+
name: 'install-with-timeout',
143+
action: imagebuilder.ComponentAction.EXECUTE_BASH,
144+
timeout: Duration.minutes(10),
145+
onFailure: imagebuilder.ComponentOnFailure.CONTINUE,
146+
inputs: {
147+
commands: ['./install-script.sh'],
148+
},
149+
},
150+
],
151+
},
152+
],
153+
}),
154+
});
155+
```
156+
157+
##### S3 Component Data
158+
159+
For those components you want to upload or have uploaded to S3:
160+
161+
```ts
162+
// Upload a local file
163+
const componentFromAsset = new imagebuilder.Component(this, 'AssetComponent', {
164+
platform: imagebuilder.Platform.LINUX,
165+
data: imagebuilder.ComponentData.fromAsset(this, 'ComponentAsset', './my-component.yml'),
166+
});
167+
168+
// Reference an existing S3 object
169+
const bucket = s3.Bucket.fromBucketName(this, 'ComponentBucket', 'my-components-bucket');
170+
const componentFromS3 = new imagebuilder.Component(this, 'S3Component', {
171+
platform: imagebuilder.Platform.LINUX,
172+
data: imagebuilder.ComponentData.fromS3(bucket, 'components/my-component.yml'),
173+
});
174+
```
175+
176+
#### Encrypt component data with a KMS key
177+
178+
You can encrypt component data with a KMS key, so that only principals with access to decrypt with the key are able to
179+
access the component data.
180+
181+
```ts
182+
const component = new imagebuilder.Component(this, 'EncryptedComponent', {
183+
platform: imagebuilder.Platform.LINUX,
184+
kmsKey: new kms.Key(this, 'ComponentKey'),
185+
data: imagebuilder.ComponentData.fromJsonObject({
186+
schemaVersion: imagebuilder.ComponentSchemaVersion.V1_0,
187+
phases: [
188+
{
189+
name: imagebuilder.ComponentPhaseName.BUILD,
190+
steps: [
191+
{
192+
name: 'secure-setup',
193+
action: imagebuilder.ComponentAction.EXECUTE_BASH,
194+
inputs: {
195+
commands: ['echo "This component data is encrypted with KMS"'],
196+
},
197+
},
198+
],
199+
},
200+
],
201+
}),
202+
});
203+
```
204+
205+
#### AWS-Managed Components
206+
207+
AWS provides a collection of managed components for common tasks:
208+
209+
```ts
210+
// Install AWS CLI v2
211+
const awsCliComponent = imagebuilder.AwsManagedComponent.awsCliV2(this, 'AwsCli', {
212+
platform: imagebuilder.Platform.LINUX
213+
});
214+
215+
// Update the operating system
216+
const updateComponent = imagebuilder.AwsManagedComponent.updateOS(this, 'UpdateOS', {
217+
platform: imagebuilder.Platform.LINUX
218+
});
219+
220+
// Reference any AWS-managed component by name
221+
const customAwsComponent = imagebuilder.AwsManagedComponent.fromAwsManagedComponentName(
222+
this,
223+
'CloudWatchAgent',
224+
'amazon-cloudwatch-agent-linux'
225+
);
226+
```
227+
228+
#### AWS Marketplace Components
229+
230+
You can reference AWS Marketplace components using the marketplace component name and its product ID:
231+
232+
```ts
233+
const marketplaceComponent = imagebuilder.AwsMarketplaceComponent.fromAwsMarketplaceComponentAttributes(
234+
this,
235+
'MarketplaceComponent',
236+
{
237+
componentName: 'my-marketplace-component',
238+
marketplaceProductId: 'prod-1234567890abcdef0',
239+
}
240+
);
241+
```
242+
39243
### Infrastructure Configuration
40244

41245
Infrastructure configuration defines the compute resources and environment settings used during the image building

0 commit comments

Comments
 (0)