Skip to content

Latest commit

 

History

History
602 lines (427 loc) · 17 KB

File metadata and controls

602 lines (427 loc) · 17 KB
description Docs for the sst.Table construct in the @serverless-stack/resources package. This construct creates a DynamoDB table, and enable DynamoDB Streams and Kinesis Data Streams.

The Table construct is a higher level CDK construct that makes it easy to create a DynamoDB table. It uses the following defaults:

Initializer

new Table(scope: Construct, id: string, props: TableProps)

Parameters

Examples

Specifying just the primary index

import { Table, TableFieldType } from "@serverless-stack/resources";

new Table(this, "Notes", {
  fields: {
    userId: TableFieldType.STRING,
    noteId: TableFieldType.STRING,
  },
  primaryIndex: { partitionKey: "noteId", sortKey: "userId" },
});

Adding secondary indexes

new Table(this, "Notes", {
  fields: {
    userId: TableFieldType.STRING,
    noteId: TableFieldType.STRING,
    time: TableFieldType.NUMBER,
  },
  primaryIndex: { partitionKey: "noteId", sortKey: "userId" },
  secondaryIndexes: {
    userTimeIndex: { partitionKey: "userId", sortKey: "time" },
  },
});

Configuring the DynamoDB table

Configure the internally created CDK Table instance.

import { RemovalPolicy } from "@aws-cdk/core";

new Table(this, "Table", {
  fields: {
    userId: TableFieldType.STRING,
    noteId: TableFieldType.STRING,
  },
  primaryIndex: { partitionKey: "noteId", sortKey: "userId" },
  dynamodbTable: {
    removalPolicy: RemovalPolicy.DESTROY,
  },
});

Configuring an index

Configure the internally created CDK GlobalSecondaryIndex.

import { ProjectionType } from "@aws-cdk/aws-dynamodb";

new Table(this, "Table", {
  fields: {
    userId: TableFieldType.STRING,
    noteId: TableFieldType.STRING,
    time: TableFieldType.NUMBER,
  },
  primaryIndex: { partitionKey: "noteId", sortKey: "userId" },
  secondaryIndexes: {
    userTimeIndex: {
      partitionKey: "userId",
      sortKey: "time",
      indexProps: {
        projectionType: ProjectionType.KEYS_ONLY,
      },
    },
  },
});

Enabling DynamoDB Streams

Using the minimal config

Enable DynamoDB Streams and add consumers.

const table = new Table(this, "Notes", {
  fields: {
    noteId: TableFieldType.STRING,
  },
  primaryIndex: { partitionKey: "noteId" },
  stream: true,
  consumers: {
    consumer1: "src/consumer1.main",
    consumer2: "src/consumer2.main",
  },
});

Lazily adding consumers

Lazily add the consumers after the table has been defined.

const table = new Table(this, "Notes", {
  fields: {
    noteId: TableFieldType.STRING,
  },
  primaryIndex: { partitionKey: "noteId" },
  stream: true,
});

table.addConsumers(this, {
  consumer1: "src/consumer1.main",
  consumer2: "src/consumer2.main",
});

Specifying function props for all the consumers

You can extend the minimal config, to set some function props and have them apply to all the consumers.

new Table(this, "Notes", {
  defaultFunctionProps: {
    timeout: 20,
    environment: { topicName: topic.topicName },
    permissions: [topic],
  },
  stream: true,
  consumers: {
    consumer1: "src/consumer1.main",
    consumer2: "src/consumer2.main",
  }
});

Using the full config

If you wanted to configure each Lambda function separately, you can pass in the TableConsumerProps.

new Table(this, "Notes", {
  stream: true,
  consumers: {
    consumer1: {
      function: {
        handler: "src/consumer1.main",
        timeout: 10,
        environment: { topicName: topic.topicName },
        permissions: [topic],
      },
    }
  },
});

Note that, you can set the defaultFunctionProps while using the function per consumer. The function will just override the defaultFunctionProps. Except for the environment, the layers, and the permissions properties, that will be merged.

new Table(this, "Notes", {
  defaultFunctionProps: {
    timeout: 20,
    environment: { topicName: topic.topicName },
    permissions: [topic],
  },
  stream: true,
  consumers: {
    consumer1: {
      function: {
        handler: "src/consumer1.main",
        timeout: 10,
        environment: { bucketName: bucket.bucketName },
        permissions: [bucket],
      },
    },
    consumer2: "src/consumer2.main",
  },
});

So in the above example, the consumer1 function doesn't use the timeout that is set in the defaultFunctionProps. It'll instead use the one that is defined in the function definition (10 seconds). And the function will have both the topicName and the bucketName environment variables set; as well as permissions to both the topic and the bucket.

Giving the consumers permissions

Allow the consumer functions to access S3.

const table = new Table(this, "Notes", {
  fields: {
    noteId: TableFieldType.STRING,
  },
  primaryIndex: { partitionKey: "noteId" },
  stream: true,
  consumers: {
    consumer1: "src/consumer1.main",
    consumer2: "src/consumer2.main",
  },
});

table.attachPermissions(["s3"]);

Giving a specific consumer permissions

Allow the first consumer function to access S3.

const table = new Table(this, "Notes", {
  fields: {
    noteId: TableFieldType.STRING,
  },
  primaryIndex: { partitionKey: "noteId" },
  stream: true,
  consumers: {
    consumer1: "src/consumer1.main",
    consumer2: "src/consumer2.main",
  },
});

table.attachPermissionsToConsumer("consumer1", ["s3"]);

Configuring the Stream content

Configure the information that will be written to the Stream.

import { StreamViewType } from "@aws-cdk/aws-dynamodb";

new Table(this, "Notes", {
  fields: {
    noteId: TableFieldType.STRING,
  },
  primaryIndex: { partitionKey: "noteId" },
  stream: StreamViewType.NEW_IMAGE,
  consumers: {
    consumer1: "src/consumer1.main",
    consumer2: "src/consumer2.main",
  },
});

Configuring a consumer

Configure the internally created CDK Event Source.

import { StartingPosition } from "@aws-cdk/aws-lambda";

new Table(this, "Notes", {
  fields: {
    noteId: TableFieldType.STRING,
  },
  primaryIndex: { partitionKey: "noteId" },
  stream: true,
  consumers: {
    consumer1: {
      function: "src/consumer1.main",
      consumerProps: {
        startingPosition: StartingPosition.TRIM_HORIZON,
      },
    },
  },
});

Enabling Kinesis Streams

import { KinesisStream } from "@serverless-stack/resources";

const stream = new KinesisStream(this, "Stream");

const table = new Table(this, "Notes", {
  fields: {
    noteId: TableFieldType.STRING,
  },
  primaryIndex: { partitionKey: "noteId" },
  kinesisStream: stream,
});

Note, you do not need to configure the stream and consumers fields when enabling the Kinesis Streams. The stream field is used to configure DynamoDB Streams, and the consumers are only triggered by DyanmoDB Streams.

You can read more about configuring consumers for the Kinesis Stream in the KinesisStream doc.

Importing an existing table

Override the internally created CDK Table instance.

import * as dynamodb from "@aws-cdk/aws-dynamodb";

new Table(this, "Table", {
  dynamodbTable: dynamodb.Table.fromTableArn(this, "ImportedTable", tableArn),
});

Upgrading to v0.21.0

The v0.21.0 release of the Table construct includes a small breaking change. You might be impacted by this change if:

  • You are currently using any version < v0.21.0
  • And using consumers with table Streams enabled

Using consumers

If you are configuring the consumers like so:

new Table(this, "Table", {
  consumers: [
    "src/consumerA.main",
    "src/consumerB.main",
  ],
});

Change it to:

import { StartingPosition } from "@aws-cdk/aws-lambda";

new Table(this, "Table", {
  consumers: {
    Consumer_0: {
      function: "src/consumerA.main",
      consumerProps: {
        startingPosition: StartingPosition.TRIM_HORIZON,
      },
    },
    Consumer_1: {
      function: "src/consumerB.main",
      consumerProps: {
        startingPosition: StartingPosition.TRIM_HORIZON,
      },
    }
  },
});

Note it is important to name the first consumer Consumer_0; the second consumer Consumer_1; and so on. This is to ensure CloudFormation recognizes them as the same consumers as before. Otherwise, CloudFormation will remove existing consumers and create new ones.

Also note the default starting position for the consumer has changed from TRIM_HORIZON to LATEST. Make sure to set the startingPosition in consumerProps if the default value was used before.

Using addConsumers

If you are making the addConsumers call like this:

table.addConsumers(this, [
  "src/consumer1.main",
  "src/consumer2.main",
]);

Change it to:

import * as cognito from "@aws-cdk/aws-cognito";

table.addConsumers(this, {
  Consumer_0: {
    function: "src/consumerA.main",
    consumerProps: {
      startingPosition: StartingPosition.TRIM_HORIZON,
    },
  },
  Consumer_1: {
    function: "src/consumerB.main",
    consumerProps: {
      startingPosition: StartingPosition.TRIM_HORIZON,
    },
  }
});

Read more about the TableConsumerProps.consumers below.

Properties

An instance of Table contains the following properties.

tableArn

Type: string

The ARN of the internally created CDK Table instance.

tableName

Type: string

The name of the internally created CDK Table instance.

dynamodbTable

Type : cdk.aws-dynamodb.Table

The internally created CDK Table instance.

Methods

An instance of Table contains the following methods.

getFunction

getFunction(consumerName: string): Function

Parameters

  • consumerName string

Returns

Get the instance of the internally created Function, for a given consumer. Where the consumerName is the name used to define a consumer.

addConsumers

addConsumers(scope: cdk.Construct, consumers: { [consumerName: string]: FunctionDefinition | TableConsumerProps })

Parameters

  • scope cdk.Construct
  • consumers { [consumerName: string]: FunctionDefinition | TableConsumerProps }

An associative array with the consumer name being a string and the value is either a FunctionDefinition or the TableConsumerProps.

attachPermissions

attachPermissions(permissions: Permissions)

Parameters

Attaches the given list of permissions to all the consumerFunctions. This allows the consumers to access other AWS resources.

Internally calls Function.attachPermissions.

attachPermissionsToConsumer

attachPermissions(consumerName: string, permissions: Permissions)

Parameters

Attaches the given list of permissions to a specific function in the list of consumerFunctions. This allows that consumer to access other AWS resources.

Internally calls Function.attachPermissions.

TableProps

fields

Type : { [key: string]: TableFieldType }

An associative array with the list of fields of the table. Where key is the name of the field and the value is one of TableFieldType.

primaryIndex

Type : TableIndexProps

Define the primary index for the table using the TableIndexProps type.

secondaryIndexes?

Type : { [key: string]: TableIndexProps }, defaults to {}

An associative array of a list of secondary indexes, where the key is the name of the secondary index and the value is using the TableIndexProps type.

stream?

Type : boolean | cdk.aws-dynamodb.StreamViewType, defaults to false

DynamoDB Streams for the table. Takes a boolean or a cdk.aws-dynamodb.StreamViewType.

If stream is set to true, the Stream is enabled with NEW_AND_OLD_IMAGES.

consumers?

Type : { [consumerName: string]: FunctionDefinition | TableConsumerProps }, defaults to {}

The consumers for this Stream. Takes an associative array, with the consumer name being a string and the value is either a FunctionDefinition or the TableConsumerProps.

:::caution You should not change the name of a consumer. :::

Note, if the consumerName is changed, CloudFormation will remove the existing consumer and create a new one. If the starting point is set to TRIM_HORIZON, all the historical records available in the Stream will be resent to the new consumer.

kinesisStream?

Type : KinesisStream, defaults to Kinesis Stream disabled

The Kinesis Stream for DynamoDB to Stream item-level changes in your table to.

dynamodbTable?

Type : cdk.aws-dynamodb.Table | TableCdkProps, defaults to undefined

Or optionally pass in a CDK cdk.aws-dynamodb.Table instance or TableCdkProps. This allows you to override the default settings this construct uses internally to create the table.

defaultFunctionProps?

Type : FunctionProps, defaults to {}

The default function props to be applied to all the Lambda functions in the Table. If the function is specified for a consumer, these default values are overridden. Except for the environment, the layers, and the permissions properties, that will be merged.

TableIndexProps

Used to define an index.

partitionKey

Type: string

The field that's to be used as a partition key for the index.

sortKey?

Type: string, defaults to undefined

The field that's to be used as the sort key for the index.

indexProps?

Type: TableCdkIndexProps, defaults to undefined

Or optionally pass in TableCdkIndexProps. This allows you to override the default settings this construct uses internally to create the index.

TableConsumerProps

function

Type : FunctionDefinition

A FunctionDefinition object that'll be used to create the consumer function for the table.

consumerProps?

Type : cdk.aws-lambda-event-sources.lambdaEventSources.DynamoEventSourceProps, defaults to DynamoEventSourceProps with starting point set to LATEST.

Or optionally pass in a CDK DynamoEventSourceProps. This allows you to override the default settings this construct uses internally to create the consumer.

TableCdkProps

TableCdkProps extends cdk.aws-dynamodb.TableProps with the exception that the partitionKey and sortKey fields are not accepted. The parition key and the sort key should be configured using the primaryIndex field.

You can use TableCdkProps to configure all the other table properties.

TableCdkIndexProps

TableCdkIndexProps extends cdk.aws-dynamodb.GlobalSecondaryIndexProps with the exception that the indexName, partitionKey, and the sortKey fields are not accepted. The index name, parition key, and the sort key should be configured using the secondaryIndexes field.

You can use TableCdkIndexProps to configure the other index properties.

TableFieldType

An enum with the following members representing the field types.

Member Description
BINARY Up to 400KB of binary data. Must be encoded as base64 before sending to DynamoDB.
NUMBER Numeric values with a maximum of 38 digits. Can be positive, negative, or zero.
STRING Up to 400KB of UTF-8 encoded text.

For example, to set a field as string, use sst.TableFieldType.STRING.