diff --git a/packages/@aws-cdk/aws-dynamodb/README.md b/packages/@aws-cdk/aws-dynamodb/README.md index b79b1e0efe465..f006eb277d984 100644 --- a/packages/@aws-cdk/aws-dynamodb/README.md +++ b/packages/@aws-cdk/aws-dynamodb/README.md @@ -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 diff --git a/packages/@aws-cdk/aws-dynamodb/lib/table.ts b/packages/@aws-cdk/aws-dynamodb/lib/table.ts index b109558752ab7..bc4b6ce39c9f0 100644 --- a/packages/@aws-cdk/aws-dynamodb/lib/table.ts +++ b/packages/@aws-cdk/aws-dynamodb/lib/table.ts @@ -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. * @@ -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, @@ -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 */ diff --git a/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts b/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts index 448aa7119eee6..6ca8b3bd0cf65 100644 --- a/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts +++ b/packages/@aws-cdk/aws-dynamodb/test/dynamodb.test.ts @@ -17,6 +17,7 @@ import { ProjectionType, StreamViewType, Table, + TableClass, TableEncryption, Operation, CfnTable, @@ -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, {