Borislav Hadzhiev
Last updated: Apr 14, 2022
Check out my new book
In order to create a dynamodb table in AWS CDK, we have to instantiate the Table class.
Let's look at a simple example where we create a dynamodb table and add a local secondary index to it:
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as cdk from 'aws-cdk-lib'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // 👇 create Dynamodb table const table = new dynamodb.Table(this, id, { billingMode: dynamodb.BillingMode.PROVISIONED, readCapacity: 1, writeCapacity: 1, removalPolicy: cdk.RemovalPolicy.DESTROY, partitionKey: {name: 'id', type: dynamodb.AttributeType.STRING}, sortKey: {name: 'createdAt', type: dynamodb.AttributeType.NUMBER}, pointInTimeRecovery: true, }); console.log('table name 👉', table.tableName); console.log('table arn 👉', table.tableArn); // 👇 add local secondary index table.addLocalSecondaryIndex({ indexName: 'statusIndex', sortKey: {name: 'status', type: dynamodb.AttributeType.STRING}, projectionType: dynamodb.ProjectionType.ALL, }); } }
Let's go over what we did in the code snippet.
Table
class are:billingMode
- we set it as PROVISIONED
. The alternative is
PAY_PER_REQUEST
, where the table will automatically scale with the traffic.
readCapacity
and writeCapacity
- the provisioned throughput for the table
removalPolicy
- specify what should happen to the table if we delete the cdk
stack or the table resource itself.
The default removalPolicy
for stateful resources (databases, S3 buckets,
Cognito User Pools, etc) is RETAIN
, which means that the resource will
remain in an orphaned state in the account, even after the CDK stack is
deleted.
partitionKey
and sortKey
- the primary key for our dynamodb table
pointInTimeRecovery
- when set to true
- enables continuous backups for
our dynamodb table
Let's issue the deployment command:
npx aws-cdk deploy
If we take a look at the dynamodb management console, we can see that the table has been created:
In order to grant permissions on a dynamodb table in CDK, we have to use the
grant*
methods on an instance of the
Table
class, for example:
Let's look at an example of using grantReadData
:
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as cdk from 'aws-cdk-lib'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // ... rest // 👇 grant permissions on table table.grantReadData(new iam.AccountRootPrincipal()); } }
We allowed the AWS account, into which the stack was deployed, to execute read operations on the dynamodb table.
A very common scenario is to use the grant*
methods to grant permissions to a
lambda function. For example, this line grants permission to a lambda to execute
all read operations on the table:
table.grantReadData(lambda);
A more fine-grained approach would be to use the grant
method and specify the
action:
table.grant(lambda, ['dynamodb:Query']);
By using the grant
method, we can follow the IAM best practice of granting
only the permissions that are required to perform a task.
In order to configure auto scaling for a Dynamodb table in CDK, we have to use the autoScaleReadCapacity and autoScaleWriteCapacity methods on an instance of the Table class.
Let's look at an example where we configure auto scaling for the write capacity of our table.
import * as appautoscaling from 'aws-cdk-lib/aws-applicationautoscaling'; import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as cdk from 'aws-cdk-lib'; export class CdkStarterStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // ... rest // 👇 configure auto scaling on table const writeAutoScaling = table.autoScaleWriteCapacity({ minCapacity: 1, maxCapacity: 2, }); // 👇 scale up when write capacity hits 75% writeAutoScaling.scaleOnUtilization({ targetUtilizationPercent: 75, }); // 👇 scale up at 9 o'clock in the morning writeAutoScaling.scaleOnSchedule('scale-up', { schedule: appautoscaling.Schedule.cron({hour: '9', minute: '0'}), minCapacity: 2, }); // 👇 scale down in the afternoon writeAutoScaling.scaleOnSchedule('scale-down', { schedule: appautoscaling.Schedule.cron({hour: '14', minute: '0'}), maxCapacity: 2, }); } }
In the code snippet:
Let's deploy the changes:
npx aws-cdk deploy
If we take a look at the dynamodb management console, we can see that the write capacity auto scaling configuration of the table has been updated:
To delete the resources we've provisioned, issue the destroy
command:
npx aws-cdk destroy