diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/RepositoryEncryption.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/RepositoryEncryption.assets.json new file mode 100644 index 0000000000000..41edf05bdd534 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/RepositoryEncryption.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "768c42cfd03f86c9416c69488b08f5ab428f042e921c8019c371f9a3353af94f": { + "source": { + "path": "RepositoryEncryption.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "768c42cfd03f86c9416c69488b08f5ab428f042e921c8019c371f9a3353af94f.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/RepositoryEncryption.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/RepositoryEncryption.template.json new file mode 100644 index 0000000000000..70000edd5b374 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/RepositoryEncryption.template.json @@ -0,0 +1,85 @@ +{ + "Resources": { + "MyKey6AB29FA6": { + "Type": "AWS::KMS::Key", + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "MyCodecommitRepository26DB372B": { + "Type": "AWS::CodeCommit::Repository", + "Properties": { + "KmsKeyId": { + "Fn::GetAtt": [ + "MyKey6AB29FA6", + "Arn" + ] + }, + "RepositoryName": "my-test-repository" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/RepositoryEncryptionTestDefaultTestDeployAssert819A2226.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/RepositoryEncryptionTestDefaultTestDeployAssert819A2226.assets.json new file mode 100644 index 0000000000000..a4d3e749e8183 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/RepositoryEncryptionTestDefaultTestDeployAssert819A2226.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "RepositoryEncryptionTestDefaultTestDeployAssert819A2226.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/RepositoryEncryptionTestDefaultTestDeployAssert819A2226.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/RepositoryEncryptionTestDefaultTestDeployAssert819A2226.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/RepositoryEncryptionTestDefaultTestDeployAssert819A2226.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/integ.json new file mode 100644 index 0000000000000..68e446d719272 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "RepositoryEncryptionTest/DefaultTest": { + "stacks": [ + "RepositoryEncryption" + ], + "assertionStack": "RepositoryEncryptionTest/DefaultTest/DeployAssert", + "assertionStackName": "RepositoryEncryptionTestDefaultTestDeployAssert819A2226" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/manifest.json new file mode 100644 index 0000000000000..eed4f1834e466 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/manifest.json @@ -0,0 +1,119 @@ +{ + "version": "36.0.0", + "artifacts": { + "RepositoryEncryption.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "RepositoryEncryption.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "RepositoryEncryption": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "RepositoryEncryption.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/768c42cfd03f86c9416c69488b08f5ab428f042e921c8019c371f9a3353af94f.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "RepositoryEncryption.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "RepositoryEncryption.assets" + ], + "metadata": { + "/RepositoryEncryption/MyKey/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyKey6AB29FA6" + } + ], + "/RepositoryEncryption/MyCodecommitRepository/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyCodecommitRepository26DB372B" + } + ], + "/RepositoryEncryption/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/RepositoryEncryption/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "RepositoryEncryption" + }, + "RepositoryEncryptionTestDefaultTestDeployAssert819A2226.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "RepositoryEncryptionTestDefaultTestDeployAssert819A2226.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "RepositoryEncryptionTestDefaultTestDeployAssert819A2226": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "RepositoryEncryptionTestDefaultTestDeployAssert819A2226.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "RepositoryEncryptionTestDefaultTestDeployAssert819A2226.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "RepositoryEncryptionTestDefaultTestDeployAssert819A2226.assets" + ], + "metadata": { + "/RepositoryEncryptionTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/RepositoryEncryptionTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "RepositoryEncryptionTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/tree.json new file mode 100644 index 0000000000000..7a6079bad0b51 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.js.snapshot/tree.json @@ -0,0 +1,182 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "RepositoryEncryption": { + "id": "RepositoryEncryption", + "path": "RepositoryEncryption", + "children": { + "MyKey": { + "id": "MyKey", + "path": "RepositoryEncryption/MyKey", + "children": { + "Resource": { + "id": "Resource", + "path": "RepositoryEncryption/MyKey/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::KMS::Key", + "aws:cdk:cloudformation:props": { + "keyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_kms.CfnKey", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_kms.Key", + "version": "0.0.0" + } + }, + "MyCodecommitRepository": { + "id": "MyCodecommitRepository", + "path": "RepositoryEncryption/MyCodecommitRepository", + "children": { + "Resource": { + "id": "Resource", + "path": "RepositoryEncryption/MyCodecommitRepository/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CodeCommit::Repository", + "aws:cdk:cloudformation:props": { + "kmsKeyId": { + "Fn::GetAtt": [ + "MyKey6AB29FA6", + "Arn" + ] + }, + "repositoryName": "my-test-repository" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codecommit.CfnRepository", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codecommit.Repository", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "RepositoryEncryption/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "RepositoryEncryption/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "RepositoryEncryptionTest": { + "id": "RepositoryEncryptionTest", + "path": "RepositoryEncryptionTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "RepositoryEncryptionTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "RepositoryEncryptionTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "RepositoryEncryptionTest/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "RepositoryEncryptionTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "RepositoryEncryptionTest/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.ts new file mode 100644 index 0000000000000..49ee3fced5dbc --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codecommit/test/integ.repository-encryption.ts @@ -0,0 +1,19 @@ +#!/usr/bin/env node +import * as cdk from 'aws-cdk-lib'; +import * as codecommit from 'aws-cdk-lib/aws-codecommit'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as kms from 'aws-cdk-lib/aws-kms'; + +const app = new cdk.App(); + +const stack = new cdk.Stack(app, 'RepositoryEncryption'); + +const kmsKey = new kms.Key(stack, 'MyKey'); +new codecommit.Repository(stack, 'MyCodecommitRepository', { + repositoryName: 'my-test-repository', + kmsKey, +}); + +new integ.IntegTest(app, 'RepositoryEncryptionTest', { + testCases: [stack], +}); diff --git a/packages/aws-cdk-lib/aws-codecommit/README.md b/packages/aws-cdk-lib/aws-codecommit/README.md index 302b47cee79df..6aab93ba71abe 100644 --- a/packages/aws-cdk-lib/aws-codecommit/README.md +++ b/packages/aws-cdk-lib/aws-codecommit/README.md @@ -41,6 +41,25 @@ const repo = new codecommit.Repository(this, 'Repository', { }); ``` +## Use a customer managed key + +CodeCommit repositories are automatically encrypted with an AWS managed key. To use +a customer managed key, specify the `kmsKey` property. + +For more information, see +[AWS Key Management Service and encryption for AWS CodeCommit repositories](https://docs.aws.amazon.com/cdk/latest/guide/reference.html#versioning). + +```ts +import * as kms from 'aws-cdk-lib/aws-kms'; + +declare const kmsKey: kms.IKey; + +const repo = new codecommit.Repository(this, 'Repository', { + repositoryName: 'MyRepositoryName', + kmsKey, +}); +``` + ## Events CodeCommit repositories emit Amazon CloudWatch events for certain activities. diff --git a/packages/aws-cdk-lib/aws-codecommit/lib/repository.ts b/packages/aws-cdk-lib/aws-codecommit/lib/repository.ts index 873f32e719aaa..a8518c2662e6d 100644 --- a/packages/aws-cdk-lib/aws-codecommit/lib/repository.ts +++ b/packages/aws-cdk-lib/aws-codecommit/lib/repository.ts @@ -4,6 +4,7 @@ import { CfnRepository } from './codecommit.generated'; import * as notifications from '../../aws-codestarnotifications'; import * as events from '../../aws-events'; import * as iam from '../../aws-iam'; +import * as kms from '../../aws-kms'; import { ArnFormat, IResource, Lazy, Resource, Stack } from '../../core'; /** @@ -496,6 +497,13 @@ export interface RepositoryProps { * @default - No initialization (create empty repo) */ readonly code?: Code; + + /** + * The customer managed key used to encrypt and decrypt the data in repository. + * + * @default - Use an AWS managed key + */ + readonly kmsKey?: kms.IKey; } /** @@ -561,6 +569,7 @@ export class Repository extends RepositoryBase { repositoryDescription: props.description, triggers: Lazy.any({ produce: () => this.triggers }, { omitEmptyArray: true }), code: (props.code?.bind(this))?.code, + kmsKeyId: props.kmsKey?.keyArn, }); this.repositoryName = this.getResourceNameAttribute(repository.attrName); diff --git a/packages/aws-cdk-lib/aws-codecommit/test/codecommit.test.ts b/packages/aws-cdk-lib/aws-codecommit/test/codecommit.test.ts index 99d1676660404..c9ac2714507cd 100644 --- a/packages/aws-cdk-lib/aws-codecommit/test/codecommit.test.ts +++ b/packages/aws-cdk-lib/aws-codecommit/test/codecommit.test.ts @@ -2,6 +2,7 @@ import * as fs from 'fs'; import { join, resolve } from 'path'; import { Template } from '../../assertions'; import { Role, ServicePrincipal } from '../../aws-iam'; +import * as kms from '../../aws-kms'; import { Asset } from '../../aws-s3-assets'; import { App, Stack } from '../../core'; import { Code, Repository, RepositoryProps } from '../lib'; @@ -310,5 +311,20 @@ describe('codecommit', () => { }); }); + + test('specify a kms key', () => { + const stack = new Stack(); + + const key = new kms.Key(stack, 'Key'); + new Repository(stack, 'Repository', { + repositoryName: 'my-repo', + kmsKey: key, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CodeCommit::Repository', { + RepositoryName: 'my-repo', + KmsKeyId: { 'Fn::GetAtt': ['Key961B73FD', 'Arn'] }, + }); + }); }); });