Skip to content

Commit d8c324a

Browse files
authored
feat(imagebuilder-alpha): add support for Image Pipeline Construct (#36153)
### 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 ImagePipeline construct. ### Description of changes This change implements the ImagePipeline construct, which is a higher-level construct of [CfnImagePipeline](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_imagebuilder.CfnImagePipeline.html). #### Example ```ts const imagePipeline = new imagebuilder.ImagePipeline(this, 'ImagePipeline-AMI', { imagePipelineName: 'test-image-pipeline', description: 'this is an image pipeline description.', recipe: imageRecipe, infrastructureConfiguration, distributionConfiguration: amiDistributionConfiguration, enabled: true, executionRole, schedule: { expression: events.Schedule.expression('cron(0 7 ? * mon *)'), timezone: cdk.TimeZone.PST8PDT, startCondition: imagebuilder.ScheduleStartCondition.EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE, autoDisableFailureCount: 5, }, workflows: [{ workflow: imagebuilder.AwsManagedWorkflow.buildImage(this, 'BuildImage') }], imageLogGroup, imagePipelineLogGroup, enhancedImageMetadataEnabled: true, imageTestsEnabled: false, imageScanningEnabled: false, }); ``` ### 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 f9aa31d commit d8c324a

File tree

45 files changed

+9851
-3
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

+9851
-3
lines changed

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

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,256 @@ 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+
### Image Pipeline
40+
41+
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.
42+
43+
#### Image Pipeline Basic Usage
44+
45+
Create a simple AMI pipeline with just an image recipe:
46+
47+
```ts
48+
const imageRecipe = new imagebuilder.ImageRecipe(this, 'MyImageRecipe', {
49+
baseImage: imagebuilder.BaseImage.fromSsmParameterName(
50+
'/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
51+
)
52+
});
53+
54+
const imagePipeline = new imagebuilder.ImagePipeline(this, 'MyImagePipeline', {
55+
recipe: exampleImageRecipe
56+
});
57+
```
58+
59+
Create a simple container pipeline with just a container recipe:
60+
61+
```ts
62+
const containerRecipe = new imagebuilder.ContainerRecipe(this, 'MyContainerRecipe', {
63+
baseImage: imagebuilder.BaseContainerImage.fromDockerHub('amazonlinux', 'latest'),
64+
targetRepository: imagebuilder.Repository.fromEcr(
65+
ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
66+
)
67+
});
68+
69+
const containerPipeline = new imagebuilder.ImagePipeline(this, 'MyContainerPipeline', {
70+
recipe: exampleContainerRecipe
71+
});
72+
```
73+
74+
#### Image Pipeline Scheduling
75+
76+
##### Manual Pipeline Execution
77+
78+
Create a pipeline that runs only when manually triggered:
79+
80+
```ts
81+
const manualPipeline = new imagebuilder.ImagePipeline(this, 'ManualPipeline', {
82+
imagePipelineName: 'my-manual-pipeline',
83+
description: 'Pipeline triggered manually for production builds',
84+
recipe: exampleImageRecipe
85+
// No schedule property - manual execution only
86+
});
87+
88+
// Grant Lambda function permission to trigger the pipeline
89+
manualPipeline.grantStartExecution(role);
90+
```
91+
92+
##### Automated Pipeline Scheduling
93+
94+
Schedule a pipeline to run automatically using cron expressions:
95+
96+
```ts
97+
const weeklyPipeline = new imagebuilder.ImagePipeline(this, 'WeeklyPipeline', {
98+
imagePipelineName: 'weekly-build-pipeline',
99+
recipe: exampleImageRecipe,
100+
schedule: {
101+
expression: events.Schedule.cron({
102+
minute: '0',
103+
hour: '6',
104+
weekDay: 'MON'
105+
})
106+
}
107+
});
108+
```
109+
110+
Use rate expressions for regular intervals:
111+
112+
```ts
113+
const dailyPipeline = new imagebuilder.ImagePipeline(this, 'DailyPipeline', {
114+
recipe: exampleContainerRecipe,
115+
schedule: {
116+
expression: events.Schedule.rate(Duration.days(1))
117+
}
118+
});
119+
```
120+
121+
##### Pipeline Schedule Configuration
122+
123+
Configure advanced scheduling options:
124+
125+
```ts
126+
const advancedSchedulePipeline = new imagebuilder.ImagePipeline(this, 'AdvancedSchedulePipeline', {
127+
recipe: exampleImageRecipe,
128+
schedule: {
129+
expression: events.Schedule.rate(Duration.days(7)),
130+
// Only trigger when dependencies are updated (new base images, components, etc.)
131+
startCondition: imagebuilder.ScheduleStartCondition.EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE,
132+
// Automatically disable after 3 consecutive failures
133+
autoDisableFailureCount: 3
134+
},
135+
// Start enabled
136+
status: imagebuilder.ImagePipelineStatus.ENABLED
137+
});
138+
```
139+
140+
#### Image Pipeline Configuration
141+
142+
##### Infrastructure and Distribution
143+
144+
Configure custom infrastructure and distribution settings:
145+
146+
```ts
147+
const infrastructureConfiguration = new imagebuilder.InfrastructureConfiguration(this, 'Infrastructure', {
148+
infrastructureConfigurationName: 'production-infrastructure',
149+
instanceTypes: [
150+
ec2.InstanceType.of(ec2.InstanceClass.COMPUTE7_INTEL, ec2.InstanceSize.LARGE)
151+
],
152+
vpc: vpc,
153+
subnetSelection: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS }
154+
});
155+
156+
const distributionConfiguration = new imagebuilder.DistributionConfiguration(this, 'Distribution');
157+
distributionConfiguration.addAmiDistributions({
158+
amiName: 'production-ami-{{ imagebuilder:buildDate }}',
159+
amiTargetAccountIds: ['123456789012', '098765432109']
160+
});
161+
162+
const productionPipeline = new imagebuilder.ImagePipeline(this, 'ProductionPipeline', {
163+
recipe: exampleImageRecipe,
164+
infrastructureConfiguration: infrastructureConfiguration,
165+
distributionConfiguration: distributionConfiguration
166+
});
167+
```
168+
169+
##### Pipeline Logging Configuration
170+
171+
Configure custom CloudWatch log groups for pipeline and image logs:
172+
173+
```ts
174+
const pipelineLogGroup = new logs.LogGroup(this, 'PipelineLogGroup', {
175+
logGroupName: '/custom/imagebuilder/pipeline/logs',
176+
retention: logs.RetentionDays.ONE_MONTH
177+
});
178+
179+
const imageLogGroup = new logs.LogGroup(this, 'ImageLogGroup', {
180+
logGroupName: '/custom/imagebuilder/image/logs',
181+
retention: logs.RetentionDays.ONE_WEEK
182+
});
183+
184+
const loggedPipeline = new imagebuilder.ImagePipeline(this, 'LoggedPipeline', {
185+
recipe: exampleImageRecipe,
186+
imagePipelineLogGroup: pipelineLogGroup,
187+
imageLogGroup: imageLogGroup
188+
});
189+
```
190+
191+
##### Workflow Integration
192+
193+
Use AWS-managed workflows for common pipeline phases:
194+
195+
```ts
196+
const workflowPipeline = new imagebuilder.ImagePipeline(this, 'WorkflowPipeline', {
197+
recipe: exampleImageRecipe,
198+
workflows: [
199+
{ workflow: imagebuilder.AwsManagedWorkflow.buildImage(this, 'BuildWorkflow') },
200+
{ workflow: imagebuilder.AwsManagedWorkflow.testImage(this, 'TestWorkflow') }
201+
]
202+
});
203+
```
204+
205+
For container pipelines, use container-specific workflows:
206+
207+
```ts
208+
const containerWorkflowPipeline = new imagebuilder.ImagePipeline(this, 'ContainerWorkflowPipeline', {
209+
recipe: exampleContainerRecipe,
210+
workflows: [
211+
{ workflow: imagebuilder.AwsManagedWorkflow.buildContainer(this, 'BuildContainer') },
212+
{ workflow: imagebuilder.AwsManagedWorkflow.testContainer(this, 'TestContainer') },
213+
{ workflow: imagebuilder.AwsManagedWorkflow.distributeContainer(this, 'DistributeContainer') }
214+
]
215+
});
216+
```
217+
218+
##### Advanced Features
219+
220+
Configure image scanning for container pipelines:
221+
222+
```ts
223+
const scanningRepository = new ecr.Repository(this, 'ScanningRepo');
224+
225+
const scannedContainerPipeline = new imagebuilder.ImagePipeline(this, 'ScannedContainerPipeline', {
226+
recipe: exampleContainerRecipe,
227+
imageScanningEnabled: true,
228+
imageScanningEcrRepository: scanningRepository,
229+
imageScanningEcrTags: ['security-scan', 'latest']
230+
});
231+
```
232+
233+
Control metadata collection and testing:
234+
235+
```ts
236+
const controlledPipeline = new imagebuilder.ImagePipeline(this, 'ControlledPipeline', {
237+
recipe: exampleImageRecipe,
238+
enhancedImageMetadataEnabled: true, // Collect detailed OS and package info
239+
imageTestsEnabled: false // Skip testing phase for faster builds
240+
});
241+
```
242+
243+
#### Image Pipeline Events
244+
245+
##### Pipeline Event Handling
246+
247+
Handle specific pipeline events:
248+
249+
```ts
250+
// Monitor CVE detection
251+
examplePipeline.onCVEDetected('CVEAlert', {
252+
target: new targets.SnsTopic(topic)
253+
});
254+
255+
// Handle pipeline auto-disable events
256+
examplePipeline.onImagePipelineAutoDisabled('PipelineDisabledAlert', {
257+
target: new targets.LambdaFunction(lambdaFunction)
258+
});
259+
```
260+
261+
#### Importing Image Pipelines
262+
263+
Reference existing pipelines created outside CDK:
264+
265+
```ts
266+
// Import by name
267+
const existingPipelineByName = imagebuilder.ImagePipeline.fromImagePipelineName(
268+
this,
269+
'ExistingPipelineByName',
270+
'my-existing-pipeline'
271+
);
272+
273+
// Import by ARN
274+
const existingPipelineByArn = imagebuilder.ImagePipeline.fromImagePipelineArn(
275+
this,
276+
'ExistingPipelineByArn',
277+
'arn:aws:imagebuilder:us-east-1:123456789012:image-pipeline/imported-pipeline'
278+
);
279+
280+
// Grant permissions to imported pipelines
281+
const automationRole = new iam.Role(this, 'AutomationRole', {
282+
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com')
283+
});
284+
285+
existingPipelineByName.grantStartExecution(automationRole);
286+
existingPipelineByArn.grantRead(role);
287+
```
288+
39289
### Image Recipe
40290

41291
#### Image Recipe Basic Usage

0 commit comments

Comments
 (0)