😽

CloudFormationの定義からDynamoDB localのTableを作成する

2022/01/02に公開

はじめに

ServerlessFrameworkを使ってDynamoDBで開発をしているのですが、ローカルの開発環境を用意する際にServerless DynamoDB LocalがM1 Macだとうまく動作しなかったので、Docker Composeで公式のDocker Imageからローカルサーバーを構築しました。
ここでテーブルを作成する際に、Cloudformationの定義化からいい感じにTableを自動構築してほしいなと思い、Rubyでスクリプトを書いて自動化してみました。

ファイル構成

.
├── createLocalTables.rb
├── dynamodb.yml
└── tables

ファイル構成はこんな感じに、CloudFormationの定義がdynamodb.ymlに記載してあり、createLocalTables.rbを実行すると自動的にtables以下にJSONが生成され、それを使ってAWS CLIでTableを作成します。

ここでは、dynamodb.ymlの中身はこんな感じです。

dynamodb.yml
Resources:
  Users:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Users
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: 1
        WriteCapacityUnits: 1
  Wallets:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Wallets
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: 1
        WriteCapacityUnits: 1

スクリプト

定義に従ってAWS CLIが読み込める形式のJSONを生成するために次のようなコードを書きました。

createLocalTables.rb
require "yaml"
require "json"

data = open("dynamodb.yml", "r") {
  |file|
  YAML.load(file)
}
data["Resources"].each do |key, value|
  tableData = value["Properties"]
  File.write("./tables/#{key}.json", JSON.pretty_generate(tableData)).then {
    `aws dynamodb create-table --cli-input-json file://tables/#{key}.json --endpoint-url http://localhost:8000`
  }
end

Dynaml DB Localがhttp://localhost:8000で動いている場合なので、エンドポイントが違う場合は適宜変更してください。

このスクリプトをdynamodb.ymlがあるディレクトリで実行します。

$ ruby dynamodb.yml

すると、こんな感じにJSONが吐き出されると同時に、AWS CLIを介してTableが作成されます。

.
├── createLocalTables.rb
├── dynamodb.yml
└── tables
    ├── Users.json
    └── Wallets.json

dynamodb-adminを使って確認すると、正しくTableが作成されていることが確認できます。
dynamodb-admin
ちなみに、JSONの中身はこんな感じになっています。

User.json
{
  "TableName": "Users",
  "AttributeDefinitions": [
    {
      "AttributeName": "id",
      "AttributeType": "S"
    }
  ],
  "KeySchema": [
    {
      "AttributeName": "id",
      "KeyType": "HASH"
    }
  ],
  "ProvisionedThroughput": {
    "ReadCapacityUnits": 1,
    "WriteCapacityUnits": 1
  }
}

おわりに

普通にServerless FrameworkのServerless DynamoDB Localを使えば解決する話なのであまり使う機会があるとは思えませんが、何かの役に立てば幸いです。

参考

CloudFormationの定義からDynamoDB Localにテーブルを作成する - miyasakura’s diary

Discussion