@aws-cdk/aws-imagebuilder-alpha 2.229.0-alpha.0 → 2.230.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +4184 -928
- package/.jsii.tabl.json.gz +0 -0
- package/.warnings.jsii.js +173 -1
- package/README.md +588 -0
- package/lib/base-image.js +3 -3
- package/lib/component.js +8 -8
- package/lib/container-recipe.js +4 -4
- package/lib/distribution-configuration.js +2 -2
- package/lib/image-pipeline.d.ts +465 -0
- package/lib/image-pipeline.js +469 -0
- package/lib/image-recipe.js +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +3 -1
- package/lib/infrastructure-configuration.d.ts +1 -1
- package/lib/infrastructure-configuration.js +2 -2
- package/lib/lifecycle-policy.d.ts +409 -0
- package/lib/lifecycle-policy.js +459 -0
- package/lib/os-version.js +1 -1
- package/lib/private/image-and-pipeline-props-helper.d.ts +25 -0
- package/lib/private/image-and-pipeline-props-helper.js +67 -0
- package/lib/private/policy-helper.d.ts +20 -0
- package/lib/private/policy-helper.js +420 -0
- package/lib/recipe-base.js +1 -1
- package/lib/workflow.d.ts +63 -0
- package/lib/workflow.js +51 -6
- package/package.json +6 -6
- package/rosetta/default.ts-fixture +37 -2
package/README.md
CHANGED
|
@@ -36,6 +36,256 @@ EC2 Image Builder supports AWS-managed components for common tasks, AWS Marketpl
|
|
|
36
36
|
that you create. Components run during specific workflow phases: build and validate phases during the build stage, and
|
|
37
37
|
test phase during the test stage.
|
|
38
38
|
|
|
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(lambdaRole);
|
|
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(lambdaRole);
|
|
287
|
+
```
|
|
288
|
+
|
|
39
289
|
### Image Recipe
|
|
40
290
|
|
|
41
291
|
#### Image Recipe Basic Usage
|
|
@@ -1074,3 +1324,341 @@ const testContainerWorkflow = imagebuilder.AwsManagedWorkflow.testContainer(this
|
|
|
1074
1324
|
// Distribution workflows
|
|
1075
1325
|
const distributeContainerWorkflow = imagebuilder.AwsManagedWorkflow.distributeContainer(this, 'DistributeContainer');
|
|
1076
1326
|
```
|
|
1327
|
+
|
|
1328
|
+
### Lifecycle Policy
|
|
1329
|
+
|
|
1330
|
+
Lifecycle policies help you manage the retention and cleanup of Image Builder resources automatically. These policies define rules for deprecating or deleting old image versions, managing AMI snapshots, and controlling resource costs by removing unused images based on age, count, or other criteria.
|
|
1331
|
+
|
|
1332
|
+
#### Lifecycle Policy Basic Usage
|
|
1333
|
+
|
|
1334
|
+
Create a lifecycle policy to automatically delete old AMI images after 30 days:
|
|
1335
|
+
|
|
1336
|
+
```ts
|
|
1337
|
+
const lifecyclePolicy = new imagebuilder.LifecyclePolicy(this, 'MyLifecyclePolicy', {
|
|
1338
|
+
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
|
|
1339
|
+
details: [
|
|
1340
|
+
{
|
|
1341
|
+
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
|
|
1342
|
+
filter: { ageFilter: { age: Duration.days(30) } }
|
|
1343
|
+
}
|
|
1344
|
+
],
|
|
1345
|
+
resourceSelection: {
|
|
1346
|
+
tags: { Environment: 'development' }
|
|
1347
|
+
}
|
|
1348
|
+
});
|
|
1349
|
+
```
|
|
1350
|
+
|
|
1351
|
+
Create a lifecycle policy to keep only the 10 most recent container images:
|
|
1352
|
+
|
|
1353
|
+
```ts
|
|
1354
|
+
const containerLifecyclePolicy = new imagebuilder.LifecyclePolicy(this, 'ContainerLifecyclePolicy', {
|
|
1355
|
+
resourceType: imagebuilder.LifecyclePolicyResourceType.CONTAINER_IMAGE,
|
|
1356
|
+
details: [
|
|
1357
|
+
{
|
|
1358
|
+
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
|
|
1359
|
+
filter: { countFilter: { count: 10 } }
|
|
1360
|
+
}
|
|
1361
|
+
],
|
|
1362
|
+
resourceSelection: {
|
|
1363
|
+
tags: { Application: 'web-app' }
|
|
1364
|
+
}
|
|
1365
|
+
});
|
|
1366
|
+
```
|
|
1367
|
+
|
|
1368
|
+
#### Lifecycle Policy Resource Selection
|
|
1369
|
+
|
|
1370
|
+
##### Tag-Based Resource Selection
|
|
1371
|
+
|
|
1372
|
+
Apply lifecycle policies to images with specific tags:
|
|
1373
|
+
|
|
1374
|
+
```ts
|
|
1375
|
+
const tagBasedPolicy = new imagebuilder.LifecyclePolicy(this, 'TagBasedPolicy', {
|
|
1376
|
+
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
|
|
1377
|
+
details: [
|
|
1378
|
+
{
|
|
1379
|
+
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
|
|
1380
|
+
filter: { ageFilter: { age: Duration.days(90) } }
|
|
1381
|
+
}
|
|
1382
|
+
],
|
|
1383
|
+
resourceSelection: {
|
|
1384
|
+
tags: {
|
|
1385
|
+
Environment: 'staging',
|
|
1386
|
+
Team: 'backend'
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
});
|
|
1390
|
+
```
|
|
1391
|
+
|
|
1392
|
+
##### Recipe-Based Resource Selection
|
|
1393
|
+
|
|
1394
|
+
Apply lifecycle policies to specific image or container recipes:
|
|
1395
|
+
|
|
1396
|
+
```ts
|
|
1397
|
+
const imageRecipe = new imagebuilder.ImageRecipe(this, 'MyImageRecipe', {
|
|
1398
|
+
baseImage: imagebuilder.BaseImage.fromSsmParameterName(
|
|
1399
|
+
'/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64'
|
|
1400
|
+
)
|
|
1401
|
+
});
|
|
1402
|
+
|
|
1403
|
+
const containerRecipe = new imagebuilder.ContainerRecipe(this, 'MyContainerRecipe', {
|
|
1404
|
+
baseImage: imagebuilder.BaseContainerImage.fromDockerHub('amazonlinux', 'latest'),
|
|
1405
|
+
targetRepository: imagebuilder.Repository.fromEcr(
|
|
1406
|
+
ecr.Repository.fromRepositoryName(this, 'Repository', 'my-container-repo')
|
|
1407
|
+
)
|
|
1408
|
+
});
|
|
1409
|
+
|
|
1410
|
+
const recipeBasedPolicy = new imagebuilder.LifecyclePolicy(this, 'RecipeBasedPolicy', {
|
|
1411
|
+
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
|
|
1412
|
+
details: [
|
|
1413
|
+
{
|
|
1414
|
+
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
|
|
1415
|
+
filter: { countFilter: { count: 5 } }
|
|
1416
|
+
}
|
|
1417
|
+
],
|
|
1418
|
+
resourceSelection: {
|
|
1419
|
+
recipes: [imageRecipe, containerRecipe]
|
|
1420
|
+
}
|
|
1421
|
+
});
|
|
1422
|
+
```
|
|
1423
|
+
|
|
1424
|
+
#### Lifecycle Policy Rules
|
|
1425
|
+
|
|
1426
|
+
##### Age-Based Rules
|
|
1427
|
+
|
|
1428
|
+
Delete images older than a specific time period:
|
|
1429
|
+
|
|
1430
|
+
```ts
|
|
1431
|
+
const ageBasedPolicy = new imagebuilder.LifecyclePolicy(this, 'AgeBasedPolicy', {
|
|
1432
|
+
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
|
|
1433
|
+
details: [
|
|
1434
|
+
{
|
|
1435
|
+
action: {
|
|
1436
|
+
type: imagebuilder.LifecyclePolicyActionType.DELETE,
|
|
1437
|
+
includeAmis: true,
|
|
1438
|
+
includeSnapshots: true
|
|
1439
|
+
},
|
|
1440
|
+
filter: {
|
|
1441
|
+
ageFilter: {
|
|
1442
|
+
age: Duration.days(60),
|
|
1443
|
+
retainAtLeast: 3 // Always keep at least 3 images
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
],
|
|
1448
|
+
resourceSelection: {
|
|
1449
|
+
tags: { Environment: 'testing' }
|
|
1450
|
+
}
|
|
1451
|
+
});
|
|
1452
|
+
```
|
|
1453
|
+
|
|
1454
|
+
##### Count-Based Rules
|
|
1455
|
+
|
|
1456
|
+
Keep only a specific number of the most recent images:
|
|
1457
|
+
|
|
1458
|
+
```ts
|
|
1459
|
+
const countBasedPolicy = new imagebuilder.LifecyclePolicy(this, 'CountBasedPolicy', {
|
|
1460
|
+
resourceType: imagebuilder.LifecyclePolicyResourceType.CONTAINER_IMAGE,
|
|
1461
|
+
details: [
|
|
1462
|
+
{
|
|
1463
|
+
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
|
|
1464
|
+
filter: { countFilter: { count: 15 } } // Keep only the 15 most recent images
|
|
1465
|
+
}
|
|
1466
|
+
],
|
|
1467
|
+
resourceSelection: {
|
|
1468
|
+
tags: { Application: 'microservice' }
|
|
1469
|
+
}
|
|
1470
|
+
});
|
|
1471
|
+
```
|
|
1472
|
+
|
|
1473
|
+
##### Multiple Lifecycle Rules
|
|
1474
|
+
|
|
1475
|
+
Implement a graduated approach with multiple actions:
|
|
1476
|
+
|
|
1477
|
+
```ts
|
|
1478
|
+
const graduatedPolicy = new imagebuilder.LifecyclePolicy(this, 'GraduatedPolicy', {
|
|
1479
|
+
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
|
|
1480
|
+
details: [
|
|
1481
|
+
{
|
|
1482
|
+
// First: Deprecate images after 30 days
|
|
1483
|
+
action: {
|
|
1484
|
+
type: imagebuilder.LifecyclePolicyActionType.DEPRECATE,
|
|
1485
|
+
includeAmis: true
|
|
1486
|
+
},
|
|
1487
|
+
filter: {
|
|
1488
|
+
ageFilter: {
|
|
1489
|
+
age: Duration.days(30),
|
|
1490
|
+
retainAtLeast: 5
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
},
|
|
1494
|
+
{
|
|
1495
|
+
// Second: Disable images after 60 days
|
|
1496
|
+
action: {
|
|
1497
|
+
type: imagebuilder.LifecyclePolicyActionType.DISABLE,
|
|
1498
|
+
includeAmis: true
|
|
1499
|
+
},
|
|
1500
|
+
filter: {
|
|
1501
|
+
ageFilter: {
|
|
1502
|
+
age: Duration.days(60),
|
|
1503
|
+
retainAtLeast: 3
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
},
|
|
1507
|
+
{
|
|
1508
|
+
// Finally: Delete images after 90 days
|
|
1509
|
+
action: {
|
|
1510
|
+
type: imagebuilder.LifecyclePolicyActionType.DELETE,
|
|
1511
|
+
includeAmis: true,
|
|
1512
|
+
includeSnapshots: true
|
|
1513
|
+
},
|
|
1514
|
+
filter: {
|
|
1515
|
+
ageFilter: {
|
|
1516
|
+
age: Duration.days(90),
|
|
1517
|
+
retainAtLeast: 1
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
],
|
|
1522
|
+
resourceSelection: {
|
|
1523
|
+
tags: { Environment: 'production' }
|
|
1524
|
+
}
|
|
1525
|
+
});
|
|
1526
|
+
```
|
|
1527
|
+
|
|
1528
|
+
#### Lifecycle Policy Exclusion Rules
|
|
1529
|
+
|
|
1530
|
+
##### AMI Exclusion Rules
|
|
1531
|
+
|
|
1532
|
+
Exclude specific AMIs from lifecycle actions based on various criteria:
|
|
1533
|
+
|
|
1534
|
+
```ts
|
|
1535
|
+
const excludeAmisPolicy = new imagebuilder.LifecyclePolicy(this, 'ExcludeAmisPolicy', {
|
|
1536
|
+
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
|
|
1537
|
+
details: [
|
|
1538
|
+
{
|
|
1539
|
+
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
|
|
1540
|
+
filter: { ageFilter: { age: Duration.days(30) } },
|
|
1541
|
+
exclusionRules: {
|
|
1542
|
+
amiExclusionRules: {
|
|
1543
|
+
isPublic: true, // Exclude public AMIs
|
|
1544
|
+
lastLaunched: Duration.days(7), // Exclude AMIs launched in last 7 days
|
|
1545
|
+
regions: ['us-west-2', 'eu-west-1'], // Exclude AMIs in specific regions
|
|
1546
|
+
sharedAccounts: ['123456789012'], // Exclude AMIs shared with specific accounts
|
|
1547
|
+
tags: {
|
|
1548
|
+
Protected: 'true',
|
|
1549
|
+
Environment: 'production'
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
],
|
|
1555
|
+
resourceSelection: {
|
|
1556
|
+
tags: { Team: 'infrastructure' }
|
|
1557
|
+
}
|
|
1558
|
+
});
|
|
1559
|
+
```
|
|
1560
|
+
|
|
1561
|
+
##### Image Exclusion Rules
|
|
1562
|
+
|
|
1563
|
+
Exclude Image Builder images with protective tags:
|
|
1564
|
+
|
|
1565
|
+
```ts
|
|
1566
|
+
const excludeImagesPolicy = new imagebuilder.LifecyclePolicy(this, 'ExcludeImagesPolicy', {
|
|
1567
|
+
resourceType: imagebuilder.LifecyclePolicyResourceType.CONTAINER_IMAGE,
|
|
1568
|
+
details: [
|
|
1569
|
+
{
|
|
1570
|
+
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
|
|
1571
|
+
filter: { countFilter: { count: 20 } },
|
|
1572
|
+
exclusionRules: {
|
|
1573
|
+
imageExclusionRules: {
|
|
1574
|
+
tags: {
|
|
1575
|
+
DoNotDelete: 'true',
|
|
1576
|
+
Critical: 'baseline'
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
],
|
|
1582
|
+
resourceSelection: {
|
|
1583
|
+
tags: { Application: 'frontend' }
|
|
1584
|
+
}
|
|
1585
|
+
});
|
|
1586
|
+
```
|
|
1587
|
+
|
|
1588
|
+
#### Advanced Lifecycle Configuration
|
|
1589
|
+
|
|
1590
|
+
##### Custom Execution Roles
|
|
1591
|
+
|
|
1592
|
+
Provide your own IAM execution role with specific permissions:
|
|
1593
|
+
|
|
1594
|
+
```ts
|
|
1595
|
+
const executionRole = new iam.Role(this, 'LifecycleExecutionRole', {
|
|
1596
|
+
assumedBy: new iam.ServicePrincipal('imagebuilder.amazonaws.com'),
|
|
1597
|
+
managedPolicies: [
|
|
1598
|
+
iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/EC2ImageBuilderLifecycleExecutionPolicy')
|
|
1599
|
+
]
|
|
1600
|
+
});
|
|
1601
|
+
|
|
1602
|
+
const customRolePolicy = new imagebuilder.LifecyclePolicy(this, 'CustomRolePolicy', {
|
|
1603
|
+
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
|
|
1604
|
+
executionRole: executionRole,
|
|
1605
|
+
details: [
|
|
1606
|
+
{
|
|
1607
|
+
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
|
|
1608
|
+
filter: { ageFilter: { age: Duration.days(45) } }
|
|
1609
|
+
}
|
|
1610
|
+
],
|
|
1611
|
+
resourceSelection: {
|
|
1612
|
+
tags: { Environment: 'development' }
|
|
1613
|
+
}
|
|
1614
|
+
});
|
|
1615
|
+
```
|
|
1616
|
+
|
|
1617
|
+
##### Lifecycle Policy Status
|
|
1618
|
+
|
|
1619
|
+
Control whether the lifecycle policy is active:
|
|
1620
|
+
|
|
1621
|
+
```ts
|
|
1622
|
+
const disabledPolicy = new imagebuilder.LifecyclePolicy(this, 'DisabledPolicy', {
|
|
1623
|
+
lifecyclePolicyName: 'my-disabled-policy',
|
|
1624
|
+
description: 'A lifecycle policy that is temporarily disabled',
|
|
1625
|
+
status: imagebuilder.LifecyclePolicyStatus.DISABLED,
|
|
1626
|
+
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
|
|
1627
|
+
details: [
|
|
1628
|
+
{
|
|
1629
|
+
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
|
|
1630
|
+
filter: { ageFilter: { age: Duration.days(30) } }
|
|
1631
|
+
}
|
|
1632
|
+
],
|
|
1633
|
+
resourceSelection: {
|
|
1634
|
+
tags: { Environment: 'testing' }
|
|
1635
|
+
},
|
|
1636
|
+
tags: {
|
|
1637
|
+
Owner: 'DevOps',
|
|
1638
|
+
CostCenter: 'Engineering'
|
|
1639
|
+
}
|
|
1640
|
+
});
|
|
1641
|
+
```
|
|
1642
|
+
|
|
1643
|
+
##### Importing Lifecycle Policies
|
|
1644
|
+
|
|
1645
|
+
Reference lifecycle policies created outside of CDK:
|
|
1646
|
+
|
|
1647
|
+
```ts
|
|
1648
|
+
// Import by name
|
|
1649
|
+
const importedByName = imagebuilder.LifecyclePolicy.fromLifecyclePolicyName(
|
|
1650
|
+
this,
|
|
1651
|
+
'ImportedByName',
|
|
1652
|
+
'existing-lifecycle-policy'
|
|
1653
|
+
);
|
|
1654
|
+
|
|
1655
|
+
// Import by ARN
|
|
1656
|
+
const importedByArn = imagebuilder.LifecyclePolicy.fromLifecyclePolicyArn(
|
|
1657
|
+
this,
|
|
1658
|
+
'ImportedByArn',
|
|
1659
|
+
'arn:aws:imagebuilder:us-east-1:123456789012:lifecycle-policy/my-policy'
|
|
1660
|
+
);
|
|
1661
|
+
|
|
1662
|
+
importedByName.grantRead(lambdaRole);
|
|
1663
|
+
importedByArn.grant(lambdaRole, 'imagebuilder:PutLifecyclePolicy');
|
|
1664
|
+
```
|
package/lib/base-image.js
CHANGED
|
@@ -6,7 +6,7 @@ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
|
6
6
|
* Represents a base image that is used to start from in EC2 Image Builder image builds
|
|
7
7
|
*/
|
|
8
8
|
class BaseImage {
|
|
9
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.BaseImage", version: "2.
|
|
9
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.BaseImage", version: "2.230.0-alpha.0" };
|
|
10
10
|
/**
|
|
11
11
|
* The AMI ID to use as a base image in an image recipe
|
|
12
12
|
*
|
|
@@ -61,7 +61,7 @@ exports.BaseImage = BaseImage;
|
|
|
61
61
|
* Represents a base image that is used to start from in EC2 Image Builder image builds
|
|
62
62
|
*/
|
|
63
63
|
class BaseContainerImage {
|
|
64
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.BaseContainerImage", version: "2.
|
|
64
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.BaseContainerImage", version: "2.230.0-alpha.0" };
|
|
65
65
|
/**
|
|
66
66
|
* The DockerHub image to use as the base image in a container recipe
|
|
67
67
|
*
|
|
@@ -113,7 +113,7 @@ exports.BaseContainerImage = BaseContainerImage;
|
|
|
113
113
|
* EC2 Image Builder container build.
|
|
114
114
|
*/
|
|
115
115
|
class ContainerInstanceImage {
|
|
116
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.ContainerInstanceImage", version: "2.
|
|
116
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.ContainerInstanceImage", version: "2.230.0-alpha.0" };
|
|
117
117
|
/**
|
|
118
118
|
* The AMI ID to use to launch the instance for building the container image
|
|
119
119
|
*
|
package/lib/component.js
CHANGED
|
@@ -51,7 +51,7 @@ const LATEST_VERSION = 'x.x.x';
|
|
|
51
51
|
* The value of a constant in a component document
|
|
52
52
|
*/
|
|
53
53
|
class ComponentConstantValue {
|
|
54
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.ComponentConstantValue", version: "2.
|
|
54
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.ComponentConstantValue", version: "2.230.0-alpha.0" };
|
|
55
55
|
/**
|
|
56
56
|
* Creates a string type constant in a component document
|
|
57
57
|
*
|
|
@@ -268,7 +268,7 @@ var ComponentSchemaVersion;
|
|
|
268
268
|
* Represents the inputs for a step in the component document
|
|
269
269
|
*/
|
|
270
270
|
class ComponentStepInputs {
|
|
271
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.ComponentStepInputs", version: "2.
|
|
271
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.ComponentStepInputs", version: "2.230.0-alpha.0" };
|
|
272
272
|
/**
|
|
273
273
|
* Creates the input value from an object, for the component step
|
|
274
274
|
*
|
|
@@ -298,7 +298,7 @@ exports.ComponentStepInputs = ComponentStepInputs;
|
|
|
298
298
|
* Represents an `if` condition in the component document
|
|
299
299
|
*/
|
|
300
300
|
class ComponentStepIfCondition {
|
|
301
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.ComponentStepIfCondition", version: "2.
|
|
301
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.ComponentStepIfCondition", version: "2.230.0-alpha.0" };
|
|
302
302
|
/**
|
|
303
303
|
* Creates the `if` value from an object, for the component step
|
|
304
304
|
*
|
|
@@ -320,7 +320,7 @@ exports.ComponentStepIfCondition = ComponentStepIfCondition;
|
|
|
320
320
|
* Helper class for referencing and uploading component data
|
|
321
321
|
*/
|
|
322
322
|
class ComponentData {
|
|
323
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.ComponentData", version: "2.
|
|
323
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.ComponentData", version: "2.230.0-alpha.0" };
|
|
324
324
|
/**
|
|
325
325
|
* Uploads component data from a local file to S3 to use as the component data
|
|
326
326
|
*
|
|
@@ -414,7 +414,7 @@ exports.ComponentData = ComponentData;
|
|
|
414
414
|
* Helper class for S3-based component data references, containing additional permission grant methods on the S3 object
|
|
415
415
|
*/
|
|
416
416
|
class S3ComponentData extends ComponentData {
|
|
417
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.S3ComponentData", version: "2.
|
|
417
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.S3ComponentData", version: "2.230.0-alpha.0" };
|
|
418
418
|
isS3Reference = true;
|
|
419
419
|
bucket;
|
|
420
420
|
key;
|
|
@@ -461,7 +461,7 @@ class S3ComponentDataFromAsset extends S3ComponentData {
|
|
|
461
461
|
* Helper class for working with AWS-managed components
|
|
462
462
|
*/
|
|
463
463
|
class AwsManagedComponent {
|
|
464
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.AwsManagedComponent", version: "2.
|
|
464
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.AwsManagedComponent", version: "2.230.0-alpha.0" };
|
|
465
465
|
/**
|
|
466
466
|
* Imports the AWS CLI v2 AWS-managed component
|
|
467
467
|
*
|
|
@@ -728,7 +728,7 @@ exports.AwsManagedComponent = AwsManagedComponent;
|
|
|
728
728
|
* Helper class for working with AWS Marketplace components
|
|
729
729
|
*/
|
|
730
730
|
class AwsMarketplaceComponent {
|
|
731
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.AwsMarketplaceComponent", version: "2.
|
|
731
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.AwsMarketplaceComponent", version: "2.230.0-alpha.0" };
|
|
732
732
|
/**
|
|
733
733
|
* Imports an AWS Marketplace component from its attributes
|
|
734
734
|
*
|
|
@@ -801,7 +801,7 @@ let Component = (() => {
|
|
|
801
801
|
Component = _classThis = _classDescriptor.value;
|
|
802
802
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
803
803
|
}
|
|
804
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.Component", version: "2.
|
|
804
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-imagebuilder-alpha.Component", version: "2.230.0-alpha.0" };
|
|
805
805
|
/** Uniquely identifies this class. */
|
|
806
806
|
static PROPERTY_INJECTION_ID = '@aws-cdk.aws-imagebuilder-alpha.Component';
|
|
807
807
|
/**
|