README.md
1 # Amazon DynamoDB Construct Library 2 <!--BEGIN STABILITY BANNER--> 3 4 --- 5 6  7 8  9 10 --- 11 12 <!--END STABILITY BANNER--> 13 14 Here is a minimal deployable DynamoDB table definition: 15 16 ```ts 17 const table = new dynamodb.Table(this, 'Table', { 18 partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, 19 }); 20 ``` 21 22 ## Importing existing tables 23 24 To import an existing table into your CDK application, use the `Table.fromTableName`, `Table.fromTableArn` or `Table.fromTableAttributes` 25 factory method. This method accepts table name or table ARN which describes the properties of an already 26 existing table: 27 28 ```ts 29 declare const user: iam.User; 30 const table = dynamodb.Table.fromTableArn(this, 'ImportedTable', 'arn:aws:dynamodb:us-east-1:111111111:table/my-table'); 31 // now you can just call methods on the table 32 table.grantReadWriteData(user); 33 ``` 34 35 If you intend to use the `tableStreamArn` (including indirectly, for example by creating an 36 `@aws-cdk/aws-lambda-event-source.DynamoEventSource` on the imported table), you *must* use the 37 `Table.fromTableAttributes` method and the `tableStreamArn` property *must* be populated. 38 39 ## Keys 40 41 When a table is defined, you must define it's schema using the `partitionKey` 42 (required) and `sortKey` (optional) properties. 43 44 ## Billing Mode 45 46 DynamoDB supports two billing modes: 47 48 * PROVISIONED - the default mode where the table and global secondary indexes have configured read and write capacity. 49 * PAY_PER_REQUEST - on-demand pricing and scaling. You only pay for what you use and there is no read and write capacity for the table or its global secondary indexes. 50 51 ```ts 52 const table = new dynamodb.Table(this, 'Table', { 53 partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, 54 billingMode: dynamodb.BillingMode.PAY_PER_REQUEST, 55 }); 56 ``` 57 58 Further reading: 59 https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode. 60 61 ## Configure AutoScaling for your table 62 63 You can have DynamoDB automatically raise and lower the read and write capacities 64 of your table by setting up autoscaling. You can use this to either keep your 65 tables at a desired utilization level, or by scaling up and down at pre-configured 66 times of the day: 67 68 Auto-scaling is only relevant for tables with the billing mode, PROVISIONED. 69 70 [Example of configuring autoscaling](test/integ.autoscaling.lit.ts) 71 72 Further reading: 73 https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AutoScaling.html 74 https://aws.amazon.com/blogs/database/how-to-use-aws-cloudformation-to-configure-auto-scaling-for-amazon-dynamodb-tables-and-indexes/ 75 76 ## Amazon DynamoDB Global Tables 77 78 You can create DynamoDB Global Tables by setting the `replicationRegions` property on a `Table`: 79 80 ```ts 81 const globalTable = new dynamodb.Table(this, 'Table', { 82 partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, 83 replicationRegions: ['us-east-1', 'us-east-2', 'us-west-2'], 84 }); 85 ``` 86 87 When doing so, a CloudFormation Custom Resource will be added to the stack in order to create the replica tables in the 88 selected regions. 89 90 The default billing mode for Global Tables is `PAY_PER_REQUEST`. 91 If you want to use `PROVISIONED`, 92 you have to make sure write auto-scaling is enabled for that Table: 93 94 ```ts 95 const globalTable = new dynamodb.Table(this, 'Table', { 96 partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, 97 replicationRegions: ['us-east-1', 'us-east-2', 'us-west-2'], 98 billingMode: dynamodb.BillingMode.PROVISIONED, 99 }); 100 101 globalTable.autoScaleWriteCapacity({ 102 minCapacity: 1, 103 maxCapacity: 10, 104 }).scaleOnUtilization({ targetUtilizationPercent: 75 }); 105 ``` 106 107 When adding a replica region for a large table, you might want to increase the 108 timeout for the replication operation: 109 110 ```ts 111 const globalTable = new dynamodb.Table(this, 'Table', { 112 partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, 113 replicationRegions: ['us-east-1', 'us-east-2', 'us-west-2'], 114 replicationTimeout: Duration.hours(2), // defaults to Duration.minutes(30) 115 }); 116 ``` 117 118 ## Encryption 119 120 All user data stored in Amazon DynamoDB is fully encrypted at rest. When creating a new table, you can choose to encrypt using the following customer master keys (CMK) to encrypt your table: 121 122 * AWS owned CMK - By default, all tables are encrypted under an AWS owned customer master key (CMK) in the DynamoDB service account (no additional charges apply). 123 * AWS managed CMK - AWS KMS keys (one per region) are created in your account, managed, and used on your behalf by AWS DynamoDB (AWS KMS charges apply). 124 * Customer managed CMK - You have full control over the KMS key used to encrypt the DynamoDB Table (AWS KMS charges apply). 125 126 Creating a Table encrypted with a customer managed CMK: 127 128 ```ts 129 const table = new dynamodb.Table(this, 'MyTable', { 130 partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, 131 encryption: dynamodb.TableEncryption.CUSTOMER_MANAGED, 132 }); 133 134 // You can access the CMK that was added to the stack on your behalf by the Table construct via: 135 const tableEncryptionKey = table.encryptionKey; 136 ``` 137 138 You can also supply your own key: 139 140 ```ts 141 import * as kms from '@aws-cdk/aws-kms'; 142 143 const encryptionKey = new kms.Key(this, 'Key', { 144 enableKeyRotation: true, 145 }); 146 const table = new dynamodb.Table(this, 'MyTable', { 147 partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, 148 encryption: dynamodb.TableEncryption.CUSTOMER_MANAGED, 149 encryptionKey, // This will be exposed as table.encryptionKey 150 }); 151 ``` 152 153 In order to use the AWS managed CMK instead, change the code to: 154 155 ```ts 156 const table = new dynamodb.Table(this, 'MyTable', { 157 partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, 158 encryption: dynamodb.TableEncryption.AWS_MANAGED, 159 }); 160 161 // In this case, the CMK _cannot_ be accessed through table.encryptionKey. 162 ``` 163 164 ## Get schema of table or secondary indexes 165 166 To get the partition key and sort key of the table or indexes you have configured: 167 168 ```ts 169 declare const table: dynamodb.Table; 170 const schema = table.schema(); 171 const partitionKey = schema.partitionKey; 172 const sortKey = schema.sortKey; 173 174 // In case you want to get schema details for any secondary index 175 // const { partitionKey, sortKey } = table.schema(INDEX_NAME); 176 ``` 177 178 ## Kinesis Stream 179 180 A Kinesis Data Stream can be configured on the DynamoDB table to capture item-level changes. 181 182 ```ts 183 import * as kinesis from '@aws-cdk/aws-kinesis'; 184 185 const stream = new kinesis.Stream(this, 'Stream'); 186 187 const table = new dynamodb.Table(this, 'Table', { 188 partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, 189 kinesisStream: stream, 190 }); 191 ```