Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ecr): add imageTagMutability prop #10557

Merged
merged 11 commits into from
Mar 9, 2021
7 changes: 7 additions & 0 deletions packages/@aws-cdk/aws-ecr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ repository.onImageScanCompleted('ImageScanComplete')
.addTarget(...)
```

### Image tag immutability

You can set tag immutability on images in our repository using the `imageTagMutability` construct prop.

```ts
new ecr.Repository(stack, 'Repo', { imageTagMutability: ecr.TagMutability.IMMUTABLE });
```

### Automatically clean up repositories

Expand Down
25 changes: 25 additions & 0 deletions packages/@aws-cdk/aws-ecr/lib/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,13 @@ export interface RepositoryProps {
* @default false
*/
readonly imageScanOnPush?: boolean;

/**
* The tag mutability setting for the repository. If this parameter is omitted, the default setting of MUTABLE will be used which will allow image tags to be overwritten.
*
* @default TagMutability.MUTABLE
*/
readonly imageTagMutability?: TagMutability;
}

export interface RepositoryAttributes {
Expand Down Expand Up @@ -420,6 +427,7 @@ export class Repository extends RepositoryBase {
// It says "Text", but they actually mean "Object".
repositoryPolicyText: Lazy.anyValue({ produce: () => this.policyDocument }),
lifecyclePolicy: Lazy.anyValue({ produce: () => this.renderLifecyclePolicy() }),
imageTagMutability: props.imageTagMutability || undefined,
});

resource.applyRemovalPolicy(props.removalPolicy);
Expand All @@ -436,6 +444,7 @@ export class Repository extends RepositoryBase {
resourceName: this.physicalName,
});


// image scanOnPush
if (props.imageScanOnPush) {
new cr.AwsCustomResource(this, 'ImageScanOnPush', {
Expand Down Expand Up @@ -608,3 +617,19 @@ const enum CountType {
*/
SINCE_IMAGE_PUSHED = 'sinceImagePushed',
}

/**
* The tag mutability setting for your repository.
*/
export enum TagMutability {
/**
* allow image tags to be overwritten.
*/
MUTABLE = 'MUTABLE',

/**
* all image tags within the repository will be immutable which will prevent them from being overwritten.
*/
IMMUTABLE = 'IMMUTABLE',

}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-ecr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
"import:@aws-cdk/aws-ecr.Repository",
"construct-base-is-private:@aws-cdk/aws-ecr.RepositoryBase",
"docs-public-apis:@aws-cdk/aws-ecr.Repository.fromRepositoryArn",
"docs-public-apis:@aws-cdk/aws-ecr.Repository.imageTagMutability",
"docs-public-apis:@aws-cdk/aws-ecr.Repository.fromRepositoryName",
"props-default-doc:@aws-cdk/aws-ecr.LifecycleRule.maxImageAge",
"props-default-doc:@aws-cdk/aws-ecr.LifecycleRule.maxImageCount",
Expand Down
14 changes: 14 additions & 0 deletions packages/@aws-cdk/aws-ecr/test/test.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,20 @@ export = {
test.done();
},


'image tag mutability can be set'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
new ecr.Repository(stack, 'Repo', { imageTagMutability: ecr.TagMutability.IMMUTABLE });

// THEN
expect(stack).to(haveResource('AWS::ECR::Repository', {
ImageTagMutability: 'IMMUTABLE',
}));

test.done();
},

'add day-based lifecycle policy'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
Expand Down