From ae47336c5d415f2cd6337b7e43b4ecc0449ef610 Mon Sep 17 00:00:00 2001 From: Lee Hannigan Date: Tue, 15 Oct 2024 17:10:33 +0100 Subject: [PATCH 1/3] Adding kinesis timestamp precision --- .../aws-cdk-lib/aws-dynamodb/lib/shared.ts | 17 ++++++ .../aws-cdk-lib/aws-dynamodb/lib/table-v2.ts | 20 +++++-- .../aws-dynamodb/test/table-v2.test.ts | 54 +++++++++++++++++++ 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/packages/aws-cdk-lib/aws-dynamodb/lib/shared.ts b/packages/aws-cdk-lib/aws-dynamodb/lib/shared.ts index 1955ef7fccd35..eb88215a79502 100644 --- a/packages/aws-cdk-lib/aws-dynamodb/lib/shared.ts +++ b/packages/aws-cdk-lib/aws-dynamodb/lib/shared.ts @@ -218,6 +218,23 @@ export enum StreamViewType { KEYS_ONLY = 'KEYS_ONLY', } +/** + * The precision associated with the DynamoDB write timestamps that will be replicated to Kinesis. + * The default setting for record timestamp precision is microseconds. You can change this setting at any time. + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-table-kinesisstreamspecification.html#aws-properties-dynamodb-table-kinesisstreamspecification-properties + */ +export enum ApproximateCreationDateTimePrecision { + /** + * Millisecond precision + */ + MILLISECOND = 'MILLISECOND', + + /** + * Microsecond precision + */ + MICROSECOND = 'MICROSECOND', +} + /** * Properties for a secondary index */ diff --git a/packages/aws-cdk-lib/aws-dynamodb/lib/table-v2.ts b/packages/aws-cdk-lib/aws-dynamodb/lib/table-v2.ts index 65e3c588968e5..e47149441b348 100644 --- a/packages/aws-cdk-lib/aws-dynamodb/lib/table-v2.ts +++ b/packages/aws-cdk-lib/aws-dynamodb/lib/table-v2.ts @@ -4,7 +4,7 @@ import { Capacity } from './capacity'; import { CfnGlobalTable } from './dynamodb.generated'; import { TableEncryptionV2 } from './encryption'; import { - StreamViewType, + StreamViewType, ApproximateCreationDateTimePrecision, Attribute, TableClass, LocalSecondaryIndexProps, SecondaryIndexProps, BillingMode, ProjectionType, } from './shared'; @@ -143,6 +143,13 @@ export interface TableOptionsV2 { */ readonly kinesisStream?: IStream; + /** + * Kinesis Data Stream approximate creation timestamp prescision + * + * @default ApproximateCreationDateTimePrecision.MICROSECOND + */ + readonly kinesisPrecisionTimestamp?: ApproximateCreationDateTimePrecision; + /** * Tags to be applied to the table or replica table * @@ -665,6 +672,12 @@ export class TableV2 extends TableBaseV2 { const pointInTimeRecovery = props.pointInTimeRecovery ?? this.tableOptions.pointInTimeRecovery; const contributorInsights = props.contributorInsights ?? this.tableOptions.contributorInsights; const resourcePolicy = props.resourcePolicy ?? this.tableOptions.resourcePolicy; + const kinesisStreamSpecification = props.kinesisStream + ? { + streamArn: props.kinesisStream.streamArn, + ...(props.kinesisPrecisionTimestamp && { approximateCreationDateTimePrecision: props.kinesisPrecisionTimestamp }), + } + : undefined; return { region: props.region, @@ -672,9 +685,7 @@ export class TableV2 extends TableBaseV2 { deletionProtectionEnabled: props.deletionProtection ?? this.tableOptions.deletionProtection, tableClass: props.tableClass ?? this.tableOptions.tableClass, sseSpecification: this.encryption?._renderReplicaSseSpecification(this, props.region), - kinesisStreamSpecification: props.kinesisStream - ? { streamArn: props.kinesisStream.streamArn } - : undefined, + kinesisStreamSpecification: kinesisStreamSpecification, contributorInsightsSpecification: contributorInsights !== undefined ? { enabled: contributorInsights } : undefined, @@ -810,6 +821,7 @@ export class TableV2 extends TableBaseV2 { replicaTables.push(this.configureReplicaTable({ region: this.stack.region, kinesisStream: this.tableOptions.kinesisStream, + kinesisPrecisionTimestamp: this.tableOptions.kinesisPrecisionTimestamp, tags: this.tableOptions.tags, })); diff --git a/packages/aws-cdk-lib/aws-dynamodb/test/table-v2.test.ts b/packages/aws-cdk-lib/aws-dynamodb/test/table-v2.test.ts index 63bbf3319b73e..98c8ba0217ccf 100644 --- a/packages/aws-cdk-lib/aws-dynamodb/test/table-v2.test.ts +++ b/packages/aws-cdk-lib/aws-dynamodb/test/table-v2.test.ts @@ -6,6 +6,7 @@ import { CfnDeletionPolicy, Lazy, RemovalPolicy, Stack } from '../../core'; import { AttributeType, Billing, Capacity, GlobalSecondaryIndexPropsV2, TableV2, LocalSecondaryIndexProps, ProjectionType, StreamViewType, TableClass, TableEncryptionV2, + ApproximateCreationDateTimePrecision, } from '../lib'; describe('table', () => { @@ -1342,6 +1343,59 @@ describe('replica tables', () => { }); }); + test('with per-replica kinesis stream with precision creation timestamp', () => { + // GIVEN + const stack = new Stack(undefined, 'Stack', { env: { region: 'us-west-2' } }); + const kinesisStream1 = new Stream(stack, 'Stream1'); + const kinesisStream2 = Stream.fromStreamArn(stack, 'Stream2', 'arn:aws:kinesis:us-east-1:123456789012:stream/my-stream'); + + // WHEN + new TableV2(stack, 'GlobalTable', { + partitionKey: { name: 'pk', type: AttributeType.STRING }, + kinesisStream: kinesisStream1, + kinesisPrecisionTimestamp: ApproximateCreationDateTimePrecision.MICROSECOND, + replicas: [ + { + region: 'us-east-1', + kinesisStream: kinesisStream2, + kinesisPrecisionTimestamp: ApproximateCreationDateTimePrecision.MILLISECOND, + }, + { + region: 'us-east-2', + }, + ], + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::DynamoDB::GlobalTable', { + Replicas: [ + { + Region: 'us-east-1', + KinesisStreamSpecification: { + StreamArn: 'arn:aws:kinesis:us-east-1:123456789012:stream/my-stream', + ApproximateCreationDateTimePrecision: 'MILLISECOND', + }, + }, + { + Region: 'us-east-2', + KinesisStreamSpecification: Match.absent(), + }, + { + Region: 'us-west-2', + KinesisStreamSpecification: { + StreamArn: { + 'Fn::GetAtt': [ + 'Stream16C8F97AF', + 'Arn', + ], + }, + ApproximateCreationDateTimePrecision: 'MICROSECOND', + }, + }, + ], + }); + }); + test('with per-replica contributor insights on global secondary index', () => { // GIVEN const stack = new Stack(undefined, 'Stack', { env: { region: 'us-west-2' } }); From 3e52df9432571c27eec89faf99d6ddcd25dc74c0 Mon Sep 17 00:00:00 2001 From: Lee Hannigan Date: Wed, 23 Oct 2024 11:07:35 +0100 Subject: [PATCH 2/3] Add additional param for ApproximateCreationDateTimePrecision --- .../cdk.out | 1 + .../integ.json | 16 ++ ...sis-stream-precision-timestamp.assets.json | 20 ++ ...s-stream-precision-timestamp.template.json | 121 +++++++++++ ...efaultTestDeployAssert34E3FBF9.assets.json | 19 ++ ...aultTestDeployAssert34E3FBF9.template.json | 36 ++++ .../manifest.json | 127 +++++++++++ .../tree.json | 202 ++++++++++++++++++ .../test/integ.dynamodb-v2.kinesis.ts | 35 +++ packages/aws-cdk-lib/aws-dynamodb/README.md | 3 + 10 files changed, 580 insertions(+) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesis-stream-precision-timestamp.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesis-stream-precision-timestamp.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/cdk.out new file mode 100644 index 0000000000000..c6e612584e352 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/integ.json new file mode 100644 index 0000000000000..b51d774a15871 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/integ.json @@ -0,0 +1,16 @@ +{ + "version": "38.0.1", + "testCases": { + "kinesis-stream-precision-timestamp-test/DefaultTest": { + "stacks": [ + "kinesis-stream-precision-timestamp" + ], + "regions": [ + "eu-west-1" + ], + "stackUpdateWorkflow": false, + "assertionStack": "kinesis-stream-precision-timestamp-test/DefaultTest/DeployAssert", + "assertionStackName": "kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesis-stream-precision-timestamp.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesis-stream-precision-timestamp.assets.json new file mode 100644 index 0000000000000..664d62ccb0936 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesis-stream-precision-timestamp.assets.json @@ -0,0 +1,20 @@ +{ + "version": "38.0.1", + "files": { + "36d1d4e27cb0002240940701b024a4f9ecc146a5f51b30cb8b4813ac33a1f260": { + "source": { + "path": "kinesis-stream-precision-timestamp.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-eu-west-1": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-eu-west-1", + "objectKey": "36d1d4e27cb0002240940701b024a4f9ecc146a5f51b30cb8b4813ac33a1f260.json", + "region": "eu-west-1", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-eu-west-1" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesis-stream-precision-timestamp.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesis-stream-precision-timestamp.template.json new file mode 100644 index 0000000000000..d91a0a59339a1 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesis-stream-precision-timestamp.template.json @@ -0,0 +1,121 @@ +{ + "Resources": { + "Stream790BDEE4": { + "Type": "AWS::Kinesis::Stream", + "Properties": { + "RetentionPeriodHours": 24, + "ShardCount": 1, + "StreamEncryption": { + "Fn::If": [ + "AwsCdkKinesisEncryptedStreamsUnsupportedRegions", + { + "Ref": "AWS::NoValue" + }, + { + "EncryptionType": "KMS", + "KeyId": "alias/aws/kinesis" + } + ] + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "TableCD117FA1": { + "Type": "AWS::DynamoDB::GlobalTable", + "Properties": { + "AttributeDefinitions": [ + { + "AttributeName": "hashKey", + "AttributeType": "S" + } + ], + "BillingMode": "PAY_PER_REQUEST", + "KeySchema": [ + { + "AttributeName": "hashKey", + "KeyType": "HASH" + } + ], + "Replicas": [ + { + "Region": "eu-west-2" + }, + { + "KinesisStreamSpecification": { + "ApproximateCreationDateTimePrecision": "MILLISECOND", + "StreamArn": { + "Fn::GetAtt": [ + "Stream790BDEE4", + "Arn" + ] + } + }, + "Region": "eu-west-1" + } + ], + "StreamSpecification": { + "StreamViewType": "NEW_AND_OLD_IMAGES" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Conditions": { + "AwsCdkKinesisEncryptedStreamsUnsupportedRegions": { + "Fn::Or": [ + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "cn-north-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "cn-northwest-1" + ] + } + ] + } + }, + "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-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.assets.json new file mode 100644 index 0000000000000..0c0ae0ca41865 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.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-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.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-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/manifest.json new file mode 100644 index 0000000000000..a6a4302d1466e --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/manifest.json @@ -0,0 +1,127 @@ +{ + "version": "38.0.1", + "artifacts": { + "kinesis-stream-precision-timestamp.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "kinesis-stream-precision-timestamp.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "kinesis-stream-precision-timestamp": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/eu-west-1", + "properties": { + "templateFile": "kinesis-stream-precision-timestamp.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-eu-west-1", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-eu-west-1", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-eu-west-1/36d1d4e27cb0002240940701b024a4f9ecc146a5f51b30cb8b4813ac33a1f260.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "kinesis-stream-precision-timestamp.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-eu-west-1", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "kinesis-stream-precision-timestamp.assets" + ], + "metadata": { + "/kinesis-stream-precision-timestamp/Stream/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Stream790BDEE4" + } + ], + "/kinesis-stream-precision-timestamp/AwsCdkKinesisEncryptedStreamsUnsupportedRegions": [ + { + "type": "aws:cdk:logicalId", + "data": "AwsCdkKinesisEncryptedStreamsUnsupportedRegions" + } + ], + "/kinesis-stream-precision-timestamp/Table/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TableCD117FA1" + } + ], + "/kinesis-stream-precision-timestamp/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/kinesis-stream-precision-timestamp/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "kinesis-stream-precision-timestamp" + }, + "kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "notificationArns": [], + "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": [ + "kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.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": [ + "kinesisstreamprecisiontimestamptestDefaultTestDeployAssert34E3FBF9.assets" + ], + "metadata": { + "/kinesis-stream-precision-timestamp-test/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/kinesis-stream-precision-timestamp-test/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "kinesis-stream-precision-timestamp-test/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-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/tree.json new file mode 100644 index 0000000000000..5bad7717a5710 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.js.snapshot/tree.json @@ -0,0 +1,202 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "kinesis-stream-precision-timestamp": { + "id": "kinesis-stream-precision-timestamp", + "path": "kinesis-stream-precision-timestamp", + "children": { + "Stream": { + "id": "Stream", + "path": "kinesis-stream-precision-timestamp/Stream", + "children": { + "Resource": { + "id": "Resource", + "path": "kinesis-stream-precision-timestamp/Stream/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Kinesis::Stream", + "aws:cdk:cloudformation:props": { + "retentionPeriodHours": 24, + "shardCount": 1, + "streamEncryption": { + "Fn::If": [ + "AwsCdkKinesisEncryptedStreamsUnsupportedRegions", + { + "Ref": "AWS::NoValue" + }, + { + "EncryptionType": "KMS", + "KeyId": "alias/aws/kinesis" + } + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_kinesis.CfnStream", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_kinesis.Stream", + "version": "0.0.0" + } + }, + "AwsCdkKinesisEncryptedStreamsUnsupportedRegions": { + "id": "AwsCdkKinesisEncryptedStreamsUnsupportedRegions", + "path": "kinesis-stream-precision-timestamp/AwsCdkKinesisEncryptedStreamsUnsupportedRegions", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnCondition", + "version": "0.0.0" + } + }, + "Table": { + "id": "Table", + "path": "kinesis-stream-precision-timestamp/Table", + "children": { + "Resource": { + "id": "Resource", + "path": "kinesis-stream-precision-timestamp/Table/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::DynamoDB::GlobalTable", + "aws:cdk:cloudformation:props": { + "attributeDefinitions": [ + { + "attributeName": "hashKey", + "attributeType": "S" + } + ], + "billingMode": "PAY_PER_REQUEST", + "keySchema": [ + { + "attributeName": "hashKey", + "keyType": "HASH" + } + ], + "replicas": [ + { + "region": "eu-west-2" + }, + { + "region": "eu-west-1", + "kinesisStreamSpecification": { + "streamArn": { + "Fn::GetAtt": [ + "Stream790BDEE4", + "Arn" + ] + }, + "approximateCreationDateTimePrecision": "MILLISECOND" + } + } + ], + "streamSpecification": { + "streamViewType": "NEW_AND_OLD_IMAGES" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_dynamodb.CfnGlobalTable", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_dynamodb.TableBaseV2", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "kinesis-stream-precision-timestamp/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "kinesis-stream-precision-timestamp/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "kinesis-stream-precision-timestamp-test": { + "id": "kinesis-stream-precision-timestamp-test", + "path": "kinesis-stream-precision-timestamp-test", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "kinesis-stream-precision-timestamp-test/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "kinesis-stream-precision-timestamp-test/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "kinesis-stream-precision-timestamp-test/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "kinesis-stream-precision-timestamp-test/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "kinesis-stream-precision-timestamp-test/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-dynamodb/test/integ.dynamodb-v2.kinesis.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.ts new file mode 100644 index 0000000000000..f710619e31547 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.ts @@ -0,0 +1,35 @@ +import * as kinesis from 'aws-cdk-lib/aws-kinesis'; +import * as cdk from 'aws-cdk-lib'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import { App, Stack, StackProps } from 'aws-cdk-lib'; +import { ApproximateCreationDateTimePrecision, AttributeType, TableV2 } from 'aws-cdk-lib/aws-dynamodb'; +import { Construct } from 'constructs'; + + + +class TestStack extends Stack { + public constructor(scope: Construct, id: string, props: StackProps) { + super(scope, id, props); + + const stream = new kinesis.Stream(this, 'Stream'); + + new TableV2(this, 'Table', { + partitionKey: { name: 'hashKey', type: AttributeType.STRING }, + removalPolicy: cdk.RemovalPolicy.DESTROY, + kinesisStream: stream, + kinesisPrecisionTimestamp: ApproximateCreationDateTimePrecision.MILLISECOND, + replicas: [ + { + region: 'eu-west-2', + } + ] + }); + } +} + +const app = new App(); +new IntegTest(app, 'kinesis-stream-precision-timestamp-test', { + testCases: [new TestStack(app, 'kinesis-stream-precision-timestamp', { env: { region: 'eu-west-1' } })], + regions: ['eu-west-1'], + stackUpdateWorkflow: false, +}); \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-dynamodb/README.md b/packages/aws-cdk-lib/aws-dynamodb/README.md index 24e09c418b6ae..1adaecdca9760 100644 --- a/packages/aws-cdk-lib/aws-dynamodb/README.md +++ b/packages/aws-cdk-lib/aws-dynamodb/README.md @@ -479,6 +479,8 @@ https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html A `kinesisStream` can be configured as a `TableV2` property. Replica tables will not inherit the `kinesisStream` configured for the primary table and should added on a per-replica basis. +ou can optionally configure the `kinesisPrecisionTimestamp` parameter to specify the precision level of the approximate creation date and time. The allowed values are `MICROSECOND` and `MILLISECOND`. If this parameter is not specified, the default precision is set to `MICROSECOND`. + ```ts import * as cdk from 'aws-cdk-lib'; import * as kinesis from 'aws-cdk-lib/aws-kinesis'; @@ -492,6 +494,7 @@ const stream2 = kinesis.Stream.fromStreamArn(stack, 'Stream2', 'arn:aws:kinesis: const globalTable = new dynamodb.TableV2(this, 'GlobalTable', { partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, kinesisStream: stream1, // for table in us-west-2 + kinesisPrecisionTimestamp: dynamodb.ApproximateCreationDateTimePrecision.MILLISECOND, replicas: [ { region: 'us-east-1' }, // no kinesis data stream will be set for this replica { From 3f80e2ee0a88d1947dce76900b37450e1408f841 Mon Sep 17 00:00:00 2001 From: Lee Hannigan Date: Wed, 23 Oct 2024 13:07:53 +0100 Subject: [PATCH 3/3] Fix linting issue for integ test --- .../test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.ts index f710619e31547..6e570292c893d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-dynamodb/test/integ.dynamodb-v2.kinesis.ts @@ -5,8 +5,6 @@ import { App, Stack, StackProps } from 'aws-cdk-lib'; import { ApproximateCreationDateTimePrecision, AttributeType, TableV2 } from 'aws-cdk-lib/aws-dynamodb'; import { Construct } from 'constructs'; - - class TestStack extends Stack { public constructor(scope: Construct, id: string, props: StackProps) { super(scope, id, props); @@ -20,9 +18,9 @@ class TestStack extends Stack { kinesisPrecisionTimestamp: ApproximateCreationDateTimePrecision.MILLISECOND, replicas: [ { - region: 'eu-west-2', - } - ] + region: 'eu-west-2', + }, + ], }); } }