From fcf1bfaab173ee57bbf64d95be62bf10cbb1b851 Mon Sep 17 00:00:00 2001 From: Vinayak Kukreja <78971045+vinayak-kukreja@users.noreply.github.com> Date: Mon, 19 Dec 2022 16:07:55 -0800 Subject: [PATCH] fix(dynamodb): add kms permissions to grantStreamRead (#23400) Currently [combinedGrant](https://github.com/aws/aws-cdk/blob/dfcfb8da34a495987214e70713b0c61f368ce962/packages/%40aws-cdk/aws-dynamodb/lib/table.ts#L1025-L1061) method does nothing if an encryption key is provided with stream action(s) present for the table. This impacts `grantStreamRead` method and is not attaching relevant KMS permissions to the policy. Resolves https://github.com/aws/aws-cdk/issues/22796 ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) ### Adding new Construct Runtime Dependencies: * [ ] This PR adds new construct runtime dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-construct-runtime-dependencies) ### New Features * [x] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)? * [x] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-dynamodb/lib/table.ts | 6 +- .../aws-dynamodb/test/dynamodb.test.ts | 54 ++++ .../aws-cdk-dynamodb.assets.json | 6 +- .../aws-cdk-dynamodb.template.json | 137 +++++++++ .../test/integ.dynamodb.js.snapshot/cdk.out | 2 +- .../integ.dynamodb.js.snapshot/integ.json | 2 +- .../integ.dynamodb.js.snapshot/manifest.json | 40 ++- .../test/integ.dynamodb.js.snapshot/tree.json | 275 ++++++++++++++++-- .../aws-cdk-dynamodb.assets.json | 6 +- .../aws-cdk-dynamodb.template.json | 26 +- .../integ.dynamodb.sse.js.snapshot/cdk.out | 2 +- .../integ.dynamodb.sse.js.snapshot/integ.json | 2 +- .../manifest.json | 16 +- .../integ.dynamodb.sse.js.snapshot/tree.json | 88 ++++-- .../aws-dynamodb/test/integ.dynamodb.ts | 18 ++ 15 files changed, 587 insertions(+), 93 deletions(-) diff --git a/packages/@aws-cdk/aws-dynamodb/lib/table.ts b/packages/@aws-cdk/aws-dynamodb/lib/table.ts index 539761ba96032..122820039d038 100644 --- a/packages/@aws-cdk/aws-dynamodb/lib/table.ts +++ b/packages/@aws-cdk/aws-dynamodb/lib/table.ts @@ -1026,6 +1026,9 @@ abstract class TableBase extends Resource implements ITable { grantee: iam.IGrantable, opts: { keyActions?: string[], tableActions?: string[], streamActions?: string[] }, ): iam.Grant { + if (this.encryptionKey && opts.keyActions) { + this.encryptionKey.grant(grantee, ...opts.keyActions); + } if (opts.tableActions) { const resources = [this.tableArn, Lazy.string({ produce: () => this.hasIndex ? `${this.tableArn}/index/*` : Aws.NO_VALUE }), @@ -1039,9 +1042,6 @@ abstract class TableBase extends Resource implements ITable { resourceArns: resources, scope: this, }); - if (this.encryptionKey && opts.keyActions) { - this.encryptionKey.grant(grantee, ...opts.keyActions); - } return ret; } if (opts.streamActions) { diff --git a/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts b/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts index 35145edd0d57c..02ccd0b1540d6 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts @@ -2264,6 +2264,60 @@ describe('import', () => { }); }); + test('if an encryption key is included, encrypt/decrypt permissions are added to the principal for grantStreamRead', () => { + const stack = new Stack(); + + const tableName = 'MyTable'; + const tableStreamArn = 'arn:foo:bar:baz:TrustMeThisIsATableStream'; + const encryptionKey = new kms.Key(stack, 'Key', { + enableKeyRotation: true, + }); + + const table = Table.fromTableAttributes(stack, 'ImportedTable', { tableName, tableStreamArn, encryptionKey }); + + const role = new iam.Role(stack, 'NewRole', { + assumedBy: new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), + }); + + expect(table.grantStreamRead(role)).toBeDefined(); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + 'Action': 'dynamodb:ListStreams', + 'Effect': 'Allow', + 'Resource': '*', + }, + { + 'Action': [ + 'kms:Decrypt', + 'kms:DescribeKey', + ], + 'Effect': 'Allow', + 'Resource': { + 'Fn::GetAtt': [ + 'Key961B73FD', + 'Arn', + ], + }, + }, + { + 'Action': [ + 'dynamodb:DescribeStream', + 'dynamodb:GetRecords', + 'dynamodb:GetShardIterator', + ], + 'Effect': 'Allow', + 'Resource': 'arn:foo:bar:baz:TrustMeThisIsATableStream', + }, + ], + Version: '2012-10-17', + }, + Roles: [stack.resolve(role.roleName)], + }); + }); + test('creates the correct index grant if indexes have been provided when importing', () => { const stack = new Stack(); diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.assets.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.assets.json index aa3256624691c..8f13a49bbff39 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.assets.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "22.0.0", "files": { - "28f29dc1ca8be205ffc54093c72bcd51a45a56b3375537b6cfa7e2b132bbdc9e": { + "aaaac6e8f3f1ffa9992cbb900021f1d1b5ec67af132595b4b296680991a0d152": { "source": { "path": "aws-cdk-dynamodb.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "28f29dc1ca8be205ffc54093c72bcd51a45a56b3375537b6cfa7e2b132bbdc9e.json", + "objectKey": "aaaac6e8f3f1ffa9992cbb900021f1d1b5ec67af132595b4b296680991a0d152.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.template.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.template.json index b4c641169a41e..5c90ea1dde1a9 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.template.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/aws-cdk-dynamodb.template.json @@ -371,6 +371,143 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, + "Key961B73FD": { + "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" + }, + "EnableKeyRotation": true + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "TableWithCustomerManagedKeyD5C58807": { + "Type": "AWS::DynamoDB::Table", + "Properties": { + "KeySchema": [ + { + "AttributeName": "hashKey", + "KeyType": "HASH" + } + ], + "AttributeDefinitions": [ + { + "AttributeName": "hashKey", + "AttributeType": "S" + } + ], + "ProvisionedThroughput": { + "ReadCapacityUnits": 5, + "WriteCapacityUnits": 5 + }, + "SSESpecification": { + "KMSMasterKeyId": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + }, + "SSEEnabled": true, + "SSEType": "KMS" + }, + "StreamSpecification": { + "StreamViewType": "NEW_AND_OLD_IMAGES" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Role1ABCC5F0": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "sqs.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "RoleDefaultPolicy5FFB7DAB": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "dynamodb:ListStreams", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + } + }, + { + "Action": [ + "dynamodb:DescribeStream", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TableWithCustomerManagedKeyD5C58807", + "StreamArn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "RoleDefaultPolicy5FFB7DAB", + "Roles": [ + { + "Ref": "Role1ABCC5F0" + } + ] + } + }, "User00B015A1": { "Type": "AWS::IAM::User" }, diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/cdk.out b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/cdk.out index 588d7b269d34f..145739f539580 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"22.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/integ.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/integ.json index 6de1a0399c7a2..45afa8d3160a6 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "22.0.0", "testCases": { "integ.dynamodb": { "stacks": [ diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/manifest.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/manifest.json index 293f1e74490ca..5f09227f142a1 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "22.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-dynamodb.assets": { "type": "cdk:asset-manifest", "properties": { @@ -23,7 +17,7 @@ "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}/28f29dc1ca8be205ffc54093c72bcd51a45a56b3375537b6cfa7e2b132bbdc9e.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/aaaac6e8f3f1ffa9992cbb900021f1d1b5ec67af132595b4b296680991a0d152.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -63,6 +57,30 @@ "data": "TableWithLocalSecondaryIndex4DA3D08F" } ], + "/aws-cdk-dynamodb/Key/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Key961B73FD" + } + ], + "/aws-cdk-dynamodb/TableWithCustomerManagedKey/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TableWithCustomerManagedKeyD5C58807" + } + ], + "/aws-cdk-dynamodb/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Role1ABCC5F0" + } + ], + "/aws-cdk-dynamodb/Role/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "RoleDefaultPolicy5FFB7DAB" + } + ], "/aws-cdk-dynamodb/User/Resource": [ { "type": "aws:cdk:logicalId", @@ -89,6 +107,12 @@ ] }, "displayName": "aws-cdk-dynamodb" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/tree.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/tree.json index 202cabc0f7115..4db3749ed870a 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, "aws-cdk-dynamodb": { "id": "aws-cdk-dynamodb", "path": "aws-cdk-dynamodb", @@ -53,8 +45,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/Table/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -327,8 +319,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/TableWithGlobalAndLocalSecondaryIndex/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -396,8 +388,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/TableWithGlobalSecondaryIndex/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -473,8 +465,120 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/TableWithLocalSecondaryIndex/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-dynamodb.Table", + "version": "0.0.0" + } + }, + "Key": { + "id": "Key", + "path": "aws-cdk-dynamodb/Key", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-dynamodb/Key/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" + }, + "enableKeyRotation": true + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-kms.CfnKey", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-kms.Key", + "version": "0.0.0" + } + }, + "TableWithCustomerManagedKey": { + "id": "TableWithCustomerManagedKey", + "path": "aws-cdk-dynamodb/TableWithCustomerManagedKey", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-dynamodb/TableWithCustomerManagedKey/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::DynamoDB::Table", + "aws:cdk:cloudformation:props": { + "keySchema": [ + { + "attributeName": "hashKey", + "keyType": "HASH" + } + ], + "attributeDefinitions": [ + { + "attributeName": "hashKey", + "attributeType": "S" + } + ], + "provisionedThroughput": { + "readCapacityUnits": 5, + "writeCapacityUnits": 5 + }, + "sseSpecification": { + "sseEnabled": true, + "kmsMasterKeyId": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + }, + "sseType": "KMS" + }, + "streamSpecification": { + "streamViewType": "NEW_AND_OLD_IMAGES" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-dynamodb.CfnTable", + "version": "0.0.0" + } + }, + "ScalingRole": { + "id": "ScalingRole", + "path": "aws-cdk-dynamodb/TableWithCustomerManagedKey/ScalingRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -483,6 +587,115 @@ "version": "0.0.0" } }, + "Role": { + "id": "Role", + "path": "aws-cdk-dynamodb/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-dynamodb/Role/ImportRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-dynamodb/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "sqs.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-cdk-dynamodb/Role/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-dynamodb/Role/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "dynamodb:ListStreams", + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + } + }, + { + "Action": [ + "dynamodb:DescribeStream", + "dynamodb:GetRecords", + "dynamodb:GetShardIterator" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TableWithCustomerManagedKeyD5C58807", + "StreamArn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "RoleDefaultPolicy5FFB7DAB", + "roles": [ + { + "Ref": "Role1ABCC5F0" + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, "User": { "id": "User", "path": "aws-cdk-dynamodb/User", @@ -582,17 +795,41 @@ "fqn": "@aws-cdk/aws-iam.User", "version": "0.0.0" } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-dynamodb/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-dynamodb/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } } }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.189" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.assets.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.assets.json index 7f8b8258d7abc..90f3a7d2343f5 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.assets.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.assets.json @@ -1,7 +1,7 @@ { - "version": "20.0.0", + "version": "22.0.0", "files": { - "449ab31c53e48708bdc4d899497ed3129e2565e94bbdf22cd8704751fc73fcb5": { + "67bada7a8e782ac86bb16bf47c61bc2039c780e5e42eaae93c8bc65e9b3e7cbb": { "source": { "path": "aws-cdk-dynamodb.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "449ab31c53e48708bdc4d899497ed3129e2565e94bbdf22cd8704751fc73fcb5.json", + "objectKey": "67bada7a8e782ac86bb16bf47c61bc2039c780e5e42eaae93c8bc65e9b3e7cbb.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.template.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.template.json index fdcaf307d248c..6cd6ef9769f51 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.template.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/aws-cdk-dynamodb.template.json @@ -489,6 +489,19 @@ "Properties": { "PolicyDocument": { "Statement": [ + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TableKey25666F95", + "Arn" + ] + } + }, { "Action": [ "dynamodb:BatchGetItem", @@ -532,19 +545,6 @@ "Ref": "AWS::NoValue" } ] - }, - { - "Action": [ - "kms:Decrypt", - "kms:DescribeKey" - ], - "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "TableKey25666F95", - "Arn" - ] - } } ], "Version": "2012-10-17" diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/cdk.out b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/cdk.out index 588d7b269d34f..145739f539580 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/cdk.out +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/cdk.out @@ -1 +1 @@ -{"version":"20.0.0"} \ No newline at end of file +{"version":"22.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/integ.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/integ.json index 14c805d5166f4..85acd063c33d2 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/integ.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/integ.json @@ -1,5 +1,5 @@ { - "version": "20.0.0", + "version": "22.0.0", "testCases": { "integ.dynamodb.sse": { "stacks": [ diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/manifest.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/manifest.json index 8460159e46960..487bca37f7c43 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/manifest.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/manifest.json @@ -1,12 +1,6 @@ { - "version": "20.0.0", + "version": "22.0.0", "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - }, "aws-cdk-dynamodb.assets": { "type": "cdk:asset-manifest", "properties": { @@ -23,7 +17,7 @@ "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}/449ab31c53e48708bdc4d899497ed3129e2565e94bbdf22cd8704751fc73fcb5.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/67bada7a8e782ac86bb16bf47c61bc2039c780e5e42eaae93c8bc65e9b3e7cbb.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -101,6 +95,12 @@ ] }, "displayName": "aws-cdk-dynamodb" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/tree.json b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/tree.json index 4d9a73bb877d9..15241edf76fe3 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/tree.json +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.sse.js.snapshot/tree.json @@ -4,14 +4,6 @@ "id": "App", "path": "", "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" - } - }, "aws-cdk-dynamodb": { "id": "aws-cdk-dynamodb", "path": "aws-cdk-dynamodb", @@ -116,8 +108,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/Table/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -390,8 +382,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/TableWithGlobalAndLocalSecondaryIndex/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -521,8 +513,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/TableWithGlobalSecondaryIndex/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -601,8 +593,8 @@ "id": "ScalingRole", "path": "aws-cdk-dynamodb/TableWithLocalSecondaryIndex/ScalingRole", "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" } } }, @@ -615,6 +607,14 @@ "id": "Role", "path": "aws-cdk-dynamodb/Role", "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-dynamodb/Role/ImportRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, "Resource": { "id": "Resource", "path": "aws-cdk-dynamodb/Role/Resource", @@ -652,6 +652,19 @@ "aws:cdk:cloudformation:props": { "policyDocument": { "Statement": [ + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "TableKey25666F95", + "Arn" + ] + } + }, { "Action": [ "dynamodb:BatchGetItem", @@ -695,19 +708,6 @@ "Ref": "AWS::NoValue" } ] - }, - { - "Action": [ - "kms:Decrypt", - "kms:DescribeKey" - ], - "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "TableKey25666F95", - "Arn" - ] - } } ], "Version": "2012-10-17" @@ -736,17 +736,41 @@ "fqn": "@aws-cdk/aws-iam.Role", "version": "0.0.0" } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-dynamodb/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-dynamodb/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } } }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", "constructInfo": { "fqn": "constructs.Construct", - "version": "10.1.85" + "version": "10.1.189" } } }, "constructInfo": { - "fqn": "constructs.Construct", - "version": "10.1.85" + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts index f016561c441db..762e513df1cd1 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/integ.dynamodb.ts @@ -1,4 +1,5 @@ import * as iam from '@aws-cdk/aws-iam'; +import * as kms from '@aws-cdk/aws-kms'; import { App, RemovalPolicy, Stack, Tags } from '@aws-cdk/core'; import { Attribute, AttributeType, ProjectionType, StreamViewType, Table, TableEncryption } from '../lib'; @@ -7,6 +8,7 @@ const STACK_NAME = 'aws-cdk-dynamodb'; // DynamoDB table parameters const TABLE = 'Table'; +const TABLE_WITH_CMK = 'TableWithCustomerManagedKey'; const TABLE_WITH_GLOBAL_AND_LOCAL_SECONDARY_INDEX = 'TableWithGlobalAndLocalSecondaryIndex'; const TABLE_WITH_GLOBAL_SECONDARY_INDEX = 'TableWithGlobalSecondaryIndex'; const TABLE_WITH_LOCAL_SECONDARY_INDEX = 'TableWithLocalSecondaryIndex'; @@ -127,6 +129,22 @@ tableWithLocalSecondaryIndex.addLocalSecondaryIndex({ sortKey: LSI_SORT_KEY, }); +const encryptionKey = new kms.Key(stack, 'Key', { + enableKeyRotation: true, +}); + +const tableWithCMK = new Table(stack, TABLE_WITH_CMK, { + partitionKey: TABLE_PARTITION_KEY, + removalPolicy: RemovalPolicy.DESTROY, + stream: StreamViewType.NEW_AND_OLD_IMAGES, + encryptionKey: encryptionKey, +}); + +const role = new iam.Role(stack, 'Role', { + assumedBy: new iam.ServicePrincipal('sqs.amazonaws.com'), +}); +tableWithCMK.grantStreamRead(role); + const user = new iam.User(stack, 'User'); table.grantReadData(user); tableWithGlobalAndLocalSecondaryIndex.grantReadData(user);