@ito_tetsushi

東京・神奈川のサーバーレス / Web / モバイルアプリエンジニア

AWS CDKでDynamoDBテーブルを構築する方法(TypeScript版)

概要

AWS CDK(Cloud Development Kit)は、AWS上のリソースをPython / Java / .NET / TypeScriptを使って構築することができるフレームワークです。 Amazon DynamoDBはAWS上にNoSQLデータベースを構築することができるマネージドサービスです。

動作確認

  • aws-cdk@1.6.1

AWS CDKのCLIをインストール

$ npm i -g aws-cdk

AWS CDKのプロジェクトを作成

# ディレクトリを作成
$ mkdir dynamodb

# ディレクトリに移動
$ cd dynamodb

# AWS CDKプロジェクトを作成
$ cdk init app --language=typescript

この時点でのディレクトリは以下のようになっています。

$ tree . -I node_modules
.
├── README.md
├── bin
│   └── dynamodb.ts
├── cdk.json
├── lib
│   └── dynamodb-stack.ts
├── package-lock.json
├── package.json
└── tsconfig.json

Amazon DynamoDBを構築するためのパッケージを追加する

AWS CDKでは、AWSの各リソースを構築するためのクラスはそれぞれ別パッケージとなっています。 次のコマンドでAmazon DynamoDBを構築するためのパッケージをインストールします。

$ npm i @aws-cdk/aws-dynamodb

Amazon DynamoDBを構築するコードを追加する

lib/dynamodb-stack.ts に以下のコードを追加します。

import cdk = require("@aws-cdk/core");

// 以下のコードを追加
import dynamodb = require("@aws-cdk/aws-dynamodb");

export class DynamodbStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 以下のコードを追加
    new dynamodb.Table(this, "PostTable", {
      partitionKey: {
        name: "id",
        type: dynamodb.AttributeType.STRING
      }
    });
  }
}

AWS CDKで構築したリソースをデプロイする

# TypeScriptをコンパイル
$ npx tsc

# リソースをデプロイ
$ cdk deploy

DynamodbStack: deploying...
DynamodbStack: creating CloudFormation changeset...
 0/3 | 21:18:55 | CREATE_IN_PROGRESS   | AWS::DynamoDB::Table | PostTable (PostTable197E3F68)
 0/3 | 21:18:55 | CREATE_IN_PROGRESS   | AWS::CDK::Metadata   | CDKMetadata
 0/3 | 21:18:55 | CREATE_IN_PROGRESS   | AWS::DynamoDB::Table | PostTable (PostTable197E3F68) Resource creation Initiated
 0/3 | 21:18:57 | CREATE_IN_PROGRESS   | AWS::CDK::Metadata   | CDKMetadata Resource creation Initiated
 1/3 | 21:18:57 | CREATE_COMPLETE      | AWS::CDK::Metadata   | CDKMetadata
 2/3 | 21:19:26 | CREATE_COMPLETE      | AWS::DynamoDB::Table | PostTable (PostTable197E3F68)
 3/3 | 21:19:27 | CREATE_COMPLETE      | AWS::CloudFormation::Stack | DynamodbStack

 ✅  DynamodbStack

マネジメントコンソールにてAmazon DynamoDBのテーブルIが出来上がっているのが確認できます。

f:id:ito_tetsushi:20190902212229p:plain

リソースを削除する

# リソースを削除する
$ npx cdk destroy

AWS CDKでAmazon DynamoDBのGSI(Global Secondary Index)を作成する

Amazon DynamoDBでは、Hash Key / Sort Keyとして定義した属性でしかアイテムを検索することができません。 GSI(Global Secondary Index)を使うことで、メインのテーブルとは別の属性でアイテムを検索できるようになります。

GSIを作成するには、lib/dynamodb-stack.ts を以下のように変更します。

import cdk = require("@aws-cdk/core");
import dynamodb = require("@aws-cdk/aws-dynamodb");

export class DynamodbStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const table = new dynamodb.Table(this, "PostTable", {
      partitionKey: {
        name: "id",
        type: dynamodb.AttributeType.STRING
      }
    });

    // Hash Key = name, Sort Key = createdAt のGSIを作成
    table.addGlobalSecondaryIndex({
      indexName: "name-createdAt_index",
      partitionKey: {
        name: "name",
        type: dynamodb.AttributeType.STRING
      },
      sortKey: {
        name: "createdAt",
        type: dynamodb.AttributeType.NUMBER
      }
    });
  }
}

Table クラスのインスタンスメソッドである addGlobalSecondaryIndex メソッドを使うことでGSIを作成することができます。 GSIはいつでも追加・削除することができます。

AWS CDKでAmazon DynamoDBのLSI(Local Secondary Index)を作成する

メインのテーブルと同じHash Keyを持ち、Sort Keyのみ異なるインデックスを作成したい場合はLSI(Local Secondary Index)を利用することができます。 LSIを作成するには、lib/dynamodb-stack.ts を以下のように変更します。

import cdk = require("@aws-cdk/core");
import dynamodb = require("@aws-cdk/aws-dynamodb");

export class DynamodbStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const table = new dynamodb.Table(this, "PostTable", {
      partitionKey: {
        name: "id",
        type: dynamodb.AttributeType.STRING
      }
    });

    // Hash Key = id, Sort Key = createdAt のLSIを作成
    table.addLocalSecondaryIndex({
      indexName: "createdAt_index",
      sortKey: {
        name: "createdAt",
        type: dynamodb.AttributeType.NUMBER
      }
    });
  }
}

Table クラスのインスタンスメソッドである addLocalSecondaryIndex メソッドを使うことでLSIを作成することができます。 LSIはテーブルの作成時にしか作成できないので、AWS CDKで管理するプロジェクトでLSIを作成・変更・削除するような変更をデプロイしようとするとDynamoDBテーブルの作り直しになってしまうのでご注意ください。

メインのテーブルと同じHash Keyを持つGSIを作ることも可能なので、一度作ってしまったテーブルに対してLSI的なインデックスを追加したい場合、GSIを使う選択肢もありかなと思います。

AWS CDKでAmazon DynamoDBのPITR(Point In Time Recovery)を設定する

Amazon DynamoDBでポイントインタイムリカバリ (PITR)を有効にすると、有効にした瞬間から最大 35日前までの任意の時点でのバックアップからそのテーブルを復元することができます。 AWS CDKを使ってPITRを有効化するには、lib/dynamodb-stack.ts を以下のように変更します。

import cdk = require("@aws-cdk/core");
import dynamodb = require("@aws-cdk/aws-dynamodb");

export class DynamodbStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    new dynamodb.Table(this, "PostTable", {
      partitionKey: {
        name: "id",
        type: dynamodb.AttributeType.STRING
      },
      pointInTimeRecovery: true // PITRを有効化
    });
  }
}