Skip to content

Commit

Permalink
feat(dynamodb): add tagging support to TableV2 (#27649)
Browse files Browse the repository at this point in the history
This change adds the ability to tag GlobalTable replicas created using the TableV2 construct. The top level "tags" will apply tags to the primary table while tags for each replica can be specified in the respective replica definition.

Closes #27146.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
mikevec23 authored Oct 26, 2023
1 parent 1433ff2 commit d46b535
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,13 @@
}
},
"Region": "us-east-2",
"TableClass": "STANDARD_INFREQUENT_ACCESS"
"TableClass": "STANDARD_INFREQUENT_ACCESS",
"Tags": [
{
"Key": "USE2ReplicaTagKey",
"Value": "USE2ReplicaTagValue"
}
]
},
{
"ContributorInsightsSpecification": {
Expand Down Expand Up @@ -173,7 +179,13 @@
"ReadCapacityUnits": 10
},
"Region": "us-west-2",
"TableClass": "STANDARD"
"TableClass": "STANDARD",
"Tags": [
{
"Key": "USW2ReplicaTagKey",
"Value": "USW2ReplicaTagValue"
}
]
},
{
"ContributorInsightsSpecification": {
Expand Down Expand Up @@ -214,7 +226,13 @@
"ReadCapacityUnits": 10
},
"Region": "us-east-1",
"TableClass": "STANDARD_INFREQUENT_ACCESS"
"TableClass": "STANDARD_INFREQUENT_ACCESS",
"Tags": [
{
"Key": "primaryTableTagKey",
"Value": "primaryTableTagValue"
}
]
}
],
"SSESpecification": {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class TestStack extends Stack {
contributorInsights: false,
},
},
tags: [{ key: 'USE2ReplicaTagKey', value: 'USE2ReplicaTagValue' }],
},
{
region: 'us-west-2',
Expand All @@ -62,8 +63,10 @@ class TestStack extends Stack {
readCapacity: Capacity.fixed(15),
},
},
tags: [{ key: 'USW2ReplicaTagKey', value: 'USW2ReplicaTagValue' }],
},
],
tags: [{ key: 'primaryTableTagKey', value: 'primaryTableTagValue' }],
});
}
}
Expand Down
25 changes: 25 additions & 0 deletions packages/aws-cdk-lib/aws-dynamodb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,31 @@ const table = new dynamodb.TableV2(this, 'Table', {
Further reading:
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.TableClasses.html

## Tags

You can add tags to a `TableV2` in several ways. By adding the tags to the construct itself it will apply the tags to the
primary table.
```ts
const table = new dynamodb.TableV2(this, 'Table', {
partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
tags: [{key: 'primaryTableTagKey', value: 'primaryTableTagValue'}],
});
```

You can also add tags to replica tables by specifying them within the replica table properties.

```ts
const table = new dynamodb.TableV2(this, 'Table', {
partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
replicas: [
{
region: 'us-west-1',
tags: [{key: 'replicaTableTagKey', value: 'replicaTableTagValue'}]
}
]
});
```

## Referencing Existing Global Tables

To reference an existing DynamoDB table in your CDK application, use the `TableV2.fromTableName`, `TableV2.fromTableArn`, or `TableV2.fromTableAttributes`
Expand Down
11 changes: 10 additions & 1 deletion packages/aws-cdk-lib/aws-dynamodb/lib/table-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { TableBaseV2, ITableV2 } from './table-v2-base';
import { IStream } from '../../aws-kinesis';
import { IKey, Key } from '../../aws-kms';
import { ArnFormat, Lazy, PhysicalName, RemovalPolicy, Stack, Token } from '../../core';
import { ArnFormat, CfnTag, Lazy, PhysicalName, RemovalPolicy, Stack, Token } from '../../core';

const HASH_KEY_TYPE = 'HASH';
const RANGE_KEY_TYPE = 'RANGE';
Expand Down Expand Up @@ -114,6 +114,13 @@ export interface TableOptionsV2 {
* @default - no Kinesis Data Stream
*/
readonly kinesisStream?: IStream;

/**
* Tags to be applied to the table or replica table
*
* @default - no tags
*/
readonly tags?: CfnTag[];
}

/**
Expand Down Expand Up @@ -612,6 +619,7 @@ export class TableV2 extends TableBaseV2 {
readProvisionedThroughputSettings: props.readCapacity
? props.readCapacity._renderReadCapacity()
: this.readProvisioning,
tags: props.tags,
};
}

Expand Down Expand Up @@ -716,6 +724,7 @@ export class TableV2 extends TableBaseV2 {
replicaTables.push(this.configureReplicaTable({
region: this.stack.region,
kinesisStream: this.tableOptions.kinesisStream,
tags: this.tableOptions.tags,
}));

return replicaTables;
Expand Down
58 changes: 58 additions & 0 deletions packages/aws-cdk-lib/aws-dynamodb/test/table-v2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,31 @@ describe('table', () => {
});
});

test('with tags', () => {
// GIVEN
const stack = new Stack(undefined, 'Stack', { env: { region: 'us-east-1' } });

// WHEN
new TableV2(stack, 'Table', {
partitionKey: { name: 'pk', type: AttributeType.STRING },
replicas: [{ region: 'us-west-1' }],
tags: [{ key: 'tagKey', value: 'tagValue' }],
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::DynamoDB::GlobalTable', {
Replicas: [
{
Region: 'us-west-1',
},
{
Region: 'us-east-1',
Tags: [{ Key: 'tagKey', Value: 'tagValue' }],
},
],
});
});

test('with all properties configured', () => {
// GIVEN
const stack = new Stack(undefined, 'Stack', { env: { region: 'us-west-2' } });
Expand Down Expand Up @@ -605,6 +630,7 @@ describe('table', () => {
contributorInsights: false,
},
},
tags: [{ key: 'USE1Key', value: 'USE1Value' }],
},
{
region: 'us-east-2',
Expand All @@ -615,8 +641,10 @@ describe('table', () => {
readCapacity: Capacity.fixed(15),
},
},
tags: [{ key: 'USE2Key', value: 'USE2Value' }],
},
],
tags: [{ key: 'USW2Key', value: 'USW2Value' }],
});

// THEN
Expand Down Expand Up @@ -748,6 +776,7 @@ describe('table', () => {
KMSMasterKeyId: 'arn:aws:kms:us-east-1:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6',
},
TableClass: 'STANDARD_INFREQUENT_ACCESS',
Tags: [{ Key: 'USE1Key', Value: 'USE1Value' }],
},
{
ContributorInsightsSpecification: {
Expand Down Expand Up @@ -783,6 +812,7 @@ describe('table', () => {
KMSMasterKeyId: 'arn:aws:kms:us-east-2:123456789012:key/g24efbna-az9b-42ro-m3bp-cq249l94fca6',
},
TableClass: 'STANDARD',
Tags: [{ Key: 'USE2Key', Value: 'USE2Value' }],
},
{
ContributorInsightsSpecification: {
Expand Down Expand Up @@ -833,6 +863,7 @@ describe('table', () => {
},
},
TableClass: 'STANDARD_INFREQUENT_ACCESS',
Tags: [{ Key: 'USW2Key', Value: 'USW2Value' }],
},
],
SSESpecification: {
Expand Down Expand Up @@ -1079,6 +1110,33 @@ describe('replica tables', () => {
});
});

test('with tags', () => {
// GIVEN
const stack = new Stack(undefined, 'Stack', { env: { region: 'us-east-1' } });

// WHEN
new TableV2(stack, 'Table', {
partitionKey: { name: 'pk', type: AttributeType.STRING },
replicas: [{
region: 'us-west-1',
tags: [{ key: 'tagKey', value: 'tagValue' }],
}],
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::DynamoDB::GlobalTable', {
Replicas: [
{
Region: 'us-west-1',
Tags: [{ Key: 'tagKey', Value: 'tagValue' }],
},
{
Region: 'us-east-1',
},
],
});
});

test('with per-replica kinesis stream', () => {
// GIVEN
const stack = new Stack(undefined, 'Stack', { env: { region: 'us-west-2' } });
Expand Down

0 comments on commit d46b535

Please sign in to comment.