Skip to content
Open
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
331 changes: 331 additions & 0 deletions packages/@aws-cdk/aws-imagebuilder-alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1074,3 +1074,334 @@ const testContainerWorkflow = imagebuilder.AwsManagedWorkflow.testContainer(this
// Distribution workflows
const distributeContainerWorkflow = imagebuilder.AwsManagedWorkflow.distributeContainer(this, 'DistributeContainer');
```

### Lifecycle Policy

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.

#### Lifecycle Policy Basic Usage

Create a lifecycle policy to automatically delete old AMI images after 30 days:

```ts
const lifecyclePolicy = new imagebuilder.LifecyclePolicy(this, 'MyLifecyclePolicy', {
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
details: [
{
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
ageFilter: { age: Duration.days(30) }
}
],
resourceSelection: {
tags: { Environment: 'development' }
}
});
```

Create a lifecycle policy to keep only the 10 most recent container images:

```ts
const containerLifecyclePolicy = new imagebuilder.LifecyclePolicy(this, 'ContainerLifecyclePolicy', {
resourceType: imagebuilder.LifecyclePolicyResourceType.CONTAINER_IMAGE,
details: [
{
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
countFilter: { count: 10 }
}
],
resourceSelection: {
tags: { Application: 'web-app' }
}
});
```

#### Lifecycle Policy Resource Selection

##### Tag-Based Resource Selection

Apply lifecycle policies to images with specific tags:

```ts
const tagBasedPolicy = new imagebuilder.LifecyclePolicy(this, 'TagBasedPolicy', {
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
details: [
{
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
ageFilter: { age: Duration.days(90) }
}
],
resourceSelection: {
tags: {
Environment: 'staging',
Team: 'backend'
}
}
});
```

##### Recipe-Based Resource Selection

Apply lifecycle policies to specific image or container recipes:

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

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

const recipeBasedPolicy = new imagebuilder.LifecyclePolicy(this, 'RecipeBasedPolicy', {
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
details: [
{
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
countFilter: { count: 5 }
}
],
resourceSelection: {
recipes: [imageRecipe, containerRecipe]
}
});
```

#### Lifecycle Policy Rules

##### Age-Based Rules

Delete images older than a specific time period:

```ts
const ageBasedPolicy = new imagebuilder.LifecyclePolicy(this, 'AgeBasedPolicy', {
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
details: [
{
action: {
type: imagebuilder.LifecyclePolicyActionType.DELETE,
includeAmis: true,
includeSnapshots: true
},
ageFilter: {
age: Duration.days(60),
retainAtLeast: 3 // Always keep at least 3 images
}
}
],
resourceSelection: {
tags: { Environment: 'testing' }
}
});
```

##### Count-Based Rules

Keep only a specific number of the most recent images:

```ts
const countBasedPolicy = new imagebuilder.LifecyclePolicy(this, 'CountBasedPolicy', {
resourceType: imagebuilder.LifecyclePolicyResourceType.CONTAINER_IMAGE,
details: [
{
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
countFilter: { count: 15 } // Keep only the 15 most recent images
}
],
resourceSelection: {
tags: { Application: 'microservice' }
}
});
```

##### Multiple Lifecycle Rules

Implement a graduated approach with multiple actions:

```ts
const graduatedPolicy = new imagebuilder.LifecyclePolicy(this, 'GraduatedPolicy', {
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
details: [
{
// First: Deprecate images after 30 days
action: {
type: imagebuilder.LifecyclePolicyActionType.DEPRECATE,
includeAmis: true
},
ageFilter: {
age: Duration.days(30),
retainAtLeast: 5
}
},
{
// Second: Disable images after 60 days
action: {
type: imagebuilder.LifecyclePolicyActionType.DISABLE,
includeAmis: true
},
ageFilter: {
age: Duration.days(60),
retainAtLeast: 3
}
},
{
// Finally: Delete images after 90 days
action: {
type: imagebuilder.LifecyclePolicyActionType.DELETE,
includeAmis: true,
includeSnapshots: true
},
ageFilter: {
age: Duration.days(90),
retainAtLeast: 1
}
}
],
resourceSelection: {
tags: { Environment: 'production' }
}
});
```

#### Lifecycle Policy Exclusion Rules

##### AMI Exclusion Rules

Exclude specific AMIs from lifecycle actions based on various criteria:

```ts
const excludeAmisPolicy = new imagebuilder.LifecyclePolicy(this, 'ExcludeAmisPolicy', {
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
details: [
{
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
ageFilter: { age: Duration.days(30) },
amiExclusionRules: {
isPublic: true, // Exclude public AMIs
lastLaunched: Duration.days(7), // Exclude AMIs launched in last 7 days
regions: ['us-west-2', 'eu-west-1'], // Exclude AMIs in specific regions
sharedAccounts: ['123456789012'], // Exclude AMIs shared with specific accounts
tags: {
Protected: 'true',
Environment: 'production'
}
}
}
],
resourceSelection: {
tags: { Team: 'infrastructure' }
}
});
```

##### Image Exclusion Rules

Exclude Image Builder images with protective tags:

```ts
const excludeImagesPolicy = new imagebuilder.LifecyclePolicy(this, 'ExcludeImagesPolicy', {
resourceType: imagebuilder.LifecyclePolicyResourceType.CONTAINER_IMAGE,
details: [
{
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
countFilter: { count: 20 },
imageExclusionRules: {
tags: {
DoNotDelete: 'true',
Critical: 'baseline'
}
}
}
],
resourceSelection: {
tags: { Application: 'frontend' }
}
});
```

#### Advanced Lifecycle Configuration

##### Custom Execution Roles

Provide your own IAM execution role with specific permissions:

```ts
const executionRole = new iam.Role(this, 'LifecycleExecutionRole', {
assumedBy: new iam.ServicePrincipal('imagebuilder.amazonaws.com'),
managedPolicies: [
iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/EC2ImageBuilderLifecycleExecutionPolicy')
]
});

const customRolePolicy = new imagebuilder.LifecyclePolicy(this, 'CustomRolePolicy', {
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
executionRole: executionRole,
details: [
{
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
ageFilter: { age: Duration.days(45) }
}
],
resourceSelection: {
tags: { Environment: 'development' }
}
});
```

##### Lifecycle Policy Status

Control whether the lifecycle policy is active:

```ts
const disabledPolicy = new imagebuilder.LifecyclePolicy(this, 'DisabledPolicy', {
lifecyclePolicyName: 'my-disabled-policy',
description: 'A lifecycle policy that is temporarily disabled',
status: imagebuilder.LifecyclePolicyStatus.DISABLED,
resourceType: imagebuilder.LifecyclePolicyResourceType.AMI_IMAGE,
details: [
{
action: { type: imagebuilder.LifecyclePolicyActionType.DELETE },
ageFilter: { age: Duration.days(30) }
}
],
resourceSelection: {
tags: { Environment: 'testing' }
},
tags: {
Owner: 'DevOps',
CostCenter: 'Engineering'
}
});
```

##### Importing Lifecycle Policies

Reference lifecycle policies created outside of CDK:

```ts
// Import by name
const importedByName = imagebuilder.LifecyclePolicy.fromLifecyclePolicyName(
this,
'ImportedByName',
'existing-lifecycle-policy'
);

// Import by ARN
const importedByArn = imagebuilder.LifecyclePolicy.fromLifecyclePolicyArn(
this,
'ImportedByArn',
'arn:aws:imagebuilder:us-east-1:123456789012:lifecycle-policy/my-policy'
);

// Grant permissions to imported policies
const role = new iam.Role(this, 'Role', {
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com')
});

importedByName.grantRead(role);
importedByArn.grant(role, 'imagebuilder:PutLifecyclePolicy');
```
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-imagebuilder-alpha/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './container-recipe';
export * from './distribution-configuration';
export * from './image-recipe';
export * from './infrastructure-configuration';
export * from './lifecycle-policy';
export * from './workflow';

export * from './base-image';
Expand Down
Loading
Loading