Skip to content

Commit

Permalink
feat(dynamodb): allow setting TableClass for a Table (#18719)
Browse files Browse the repository at this point in the history
Support already exists in CloudFormation, but hasn't been implemented in CDK.

Closes #18718

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
arjanschaaf authored Feb 1, 2022
1 parent 9380885 commit 73a889e
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
17 changes: 17 additions & 0 deletions packages/@aws-cdk/aws-dynamodb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,23 @@ const table = new dynamodb.Table(this, 'Table', {
Further reading:
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.

## Table Class

DynamoDB supports two table classes:

* STANDARD - the default mode, and is recommended for the vast majority of workloads.
* STANDARD_INFREQUENT_ACCESS - optimized for tables where storage is the dominant cost.

```ts
const table = new dynamodb.Table(this, 'Table', {
partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
tableClass: dynamodb.TableClass.STANDARD_INFREQUENT_ACCESS,
});
```

Further reading:
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.TableClasses.html

## Configure AutoScaling for your table

You can have DynamoDB automatically raise and lower the read and write capacities
Expand Down
20 changes: 20 additions & 0 deletions packages/@aws-cdk/aws-dynamodb/lib/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,12 @@ export interface TableOptions extends SchemaOptions {
*/
readonly serverSideEncryption?: boolean;

/**
* Specify the table class.
* @default STANDARD
*/
readonly tableClass?: TableClass;

/**
* Whether server-side encryption with an AWS managed customer master key is enabled.
*
Expand Down Expand Up @@ -1182,6 +1188,7 @@ export class Table extends TableBase {
},
sseSpecification,
streamSpecification,
tableClass: props.tableClass,
timeToLiveSpecification: props.timeToLiveAttribute ? { attributeName: props.timeToLiveAttribute, enabled: true } : undefined,
contributorInsightsSpecification: props.contributorInsightsEnabled !== undefined ? { enabled: props.contributorInsightsEnabled } : undefined,
kinesisStreamSpecification: props.kinesisStream ? { streamArn: props.kinesisStream.streamArn } : undefined,
Expand Down Expand Up @@ -1773,6 +1780,19 @@ export enum StreamViewType {
KEYS_ONLY = 'KEYS_ONLY'
}

/**
* DynamoDB's table class.
*
* @see https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.TableClasses.html
*/
export enum TableClass {
/** Default table class for DynamoDB. */
STANDARD = 'STANDARD',

/** Table class for DynamoDB that reduces storage costs compared to existing DynamoDB Standard tables. */
STANDARD_INFREQUENT_ACCESS = 'STANDARD_INFREQUENT_ACCESS',
}

/**
* Just a convenient way to keep track of both attributes
*/
Expand Down
42 changes: 42 additions & 0 deletions packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
ProjectionType,
StreamViewType,
Table,
TableClass,
TableEncryption,
Operation,
CfnTable,
Expand Down Expand Up @@ -719,6 +720,47 @@ test('if an encryption key is included, encrypt/decrypt permissions are added to
});
});

test('when specifying STANDARD_INFREQUENT_ACCESS table class', () => {
const stack = new Stack();
new Table(stack, CONSTRUCT_NAME, {
partitionKey: TABLE_PARTITION_KEY,
tableClass: TableClass.STANDARD_INFREQUENT_ACCESS,
});

Template.fromStack(stack).hasResourceProperties('AWS::DynamoDB::Table',
{
TableClass: 'STANDARD_INFREQUENT_ACCESS',
},
);
});

test('when specifying STANDARD table class', () => {
const stack = new Stack();
new Table(stack, CONSTRUCT_NAME, {
partitionKey: TABLE_PARTITION_KEY,
tableClass: TableClass.STANDARD,
});

Template.fromStack(stack).hasResourceProperties('AWS::DynamoDB::Table',
{
TableClass: 'STANDARD',
},
);
});

test('when specifying no table class', () => {
const stack = new Stack();
new Table(stack, CONSTRUCT_NAME, {
partitionKey: TABLE_PARTITION_KEY,
});

Template.fromStack(stack).hasResourceProperties('AWS::DynamoDB::Table',
{
TableClass: Match.absent(),
},
);
});

test('when specifying PAY_PER_REQUEST billing mode', () => {
const stack = new Stack();
new Table(stack, CONSTRUCT_NAME, {
Expand Down

0 comments on commit 73a889e

Please sign in to comment.