dynamodb-localをシードデータで初期化して起動する

## 概要

[amazon/dynamodb-local](https://hub.docker.com/r/amazon/dynamodb-local)のDockerをシードデータで初期化して起動したかったので作りました。
事前に用意したデータを取り込んでDynamoDBをDocker上で起動できます。

下記のレポジトリをクローンしてREADMEの手順で実行すれば使えます。

https://github.com/sasakitimaru/dynamo-local-init

# 使い方

READMEに書いてありますが解説も交えて手順書いときます。

### 1. リポジトリのクローン

```jsx
git clone https://github.com/sasakitimaru/dynamo-local-init.git
```

### 2. DynamoDBにマウントするボリュームのディレクトリ作成

```jsx
mkdir -p dynamodb-local
sudo chmod 777 ./dynamodb-local
```

書き込み権限を振っておかないとエラーになります。([参考](https://qiita.com/etnk/items/fff02e8fbf6901e013f9))

### 3. シードデータの準備

#### テーブルの作成

`./schema/tables.yml`がテーブルを定義しているファイルです。
設定したいテーブル定義に書き換えてください。
データはaws-cli ver2の`create-table —cli-input-yaml`で取り込まれます。
デフォルトのデータは下記です。[ドキュメント](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/dynamodb/create-table.html)を参考に書き換えてください。

```yaml
Tables:
  - TableName: Product
    AttributeDefinitions:
      - AttributeName: id
        AttributeType: S
      - AttributeName: name
        AttributeType: S
      - AttributeName: category
        AttributeType: S
      - AttributeName: price
        AttributeType: N 
    KeySchema:
      - AttributeName: id
        KeyType: HASH
    BillingMode: PAY_PER_REQUEST
    GlobalSecondaryIndexes:
      - IndexName: NameIndex
        KeySchema:
          - AttributeName: name
            KeyType: HASH
        Projection:
          ProjectionType: ALL
      - IndexName: CategoryIndex
        KeySchema:
          - AttributeName: category
            KeyType: HASH
        Projection:
          ProjectionType: ALL
      - IndexName: PriceIndex
        KeySchema:
          - AttributeName: category
            KeyType: HASH
          - AttributeName: price
            KeyType: RANGE
        Projection:
          ProjectionType: INCLUDE
          NonKeyAttributes: [ "name", "price" ] 
```

#### シードデータの定義

`./schema/seeds.yml`でテーブルと流し込むシードデータのファイルと紐づけます。

```yaml
- table: Product
  sources: [Product.json]
```

jsonファイルの名前は任意です。テーブル名と同じである必要はありません。

Product.jsonは下記のようになっています。

```json
[
  {
    "id": "product1",
    "name": "Laptop Pro 15",
    "category": "Electronics",
    "price": 1000
  },
  {
    "id": "product2",
    "name": "Smartphone X2",
    "category": "Electronics",
    "price": 700
  },
...
  }
]
```

`--cli-input-yml`で取り込める形式に内部でコンパイルされます。

リストやマップも対応しています。

参考：コンパイル前

```json
[
  {
    "id": "xxx",
    "name": "example",
    "data": {
      "price": 100,
      "category": "free",
    },
    "tag": ["new", "sample", "season"]
  }
]
```

参考：コンパイル後

```json
{
  "PutRequest": {
    "Item": {
      "id": {"S": "xxx"},
      "name": {"S": "example"},
      "data": {
        "M": {
          "price": {"N": "100"},
          "category": {"S": "free"}
        }
      },
      "tag": {
        "L": [{"S": "new"}, {"S": "sample"}, {"S": "season"}]
      }
    }
  }
}
```

### 4. 起動

```
docker-compose up
```

下記のdocker-compose.ymlを起動します。
dynamoadb-adminはlocalhost:8001にアクセスすれば使用できます。

```yaml
version: '3.8'
services:
  dynamodb-local:
    command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data"
    image: "amazon/dynamodb-local:1.17.0"
    container_name: dynamodb-local
    ports:
      - "8000:8000"
    working_dir: /home/dynamodblocal
    volumes:
      - "./dynamodb-local:/home/dynamodblocal/data"

  # 管理ページが不要な場合は削除してください
  dynamodb-admin:
    image: aaronshaf/dynamodb-admin:4.6.1
    container_name: dynamodb-admin
    environment:
      - DYNAMO_ENDPOINT=http://dynamodb-local:8000
    ports:
      - 8001:8001
    depends_on:
      - dynamodb-local

  dynamodb-migrator:
    image: "sasakitimaru/dynamodb-local:1.0.6"
    environment:
      - AWS_ACCESS_KEY_ID=dummy
      - AWS_SECRET_ACCESS_KEY=dummy
      - AWS_DEFAULT_REGION=ap-northeast-1
      - DYNAMODB_ENDPOINT=http://dynamodb-local:8000
    depends_on:
      - dynamodb-local
    volumes:
      - ./schema/:/home/dynamodblocal/schema/
```

dynamo-adminのコンテナを毎回起動するのが面倒な人は下記でglobalにインストールして必要な時だけ起動するのがおすすめです。
```
npm install -g dynamodb-admin

# For Windows:
set DYNAMO_ENDPOINT=http://localhost:8000
dynamodb-admin

# For Mac/Linux:
DYNAMO_ENDPOINT=http://localhost:8000 dynamodb-admin
```
### 5. 停止

```
docker-compose down
```

停止してもdynamodbのデータは残ります。

`./dynamodb-local/shared-local-instance.db`を削除すればデータも消えます。

データを消さずに再度`docker-compose up`を実行するとシードデータの取り込みはスキップされます。（すでにテーブルが存在する場合はスキップする）

シードデータを変更したりテーブルのスキーマを変えた場合は`./dynamodb-local/shared-local-instance.db`を削除してから起動してください。

## 作成したイメージ
https://hub.docker.com/r/sasakitimaru/dynamodb-local/tags

下記のリポジトリにソースコードがあります。

https://github.com/sasakitimaru/dynamo-local-migrator

不具合や要望とかあればコメントください。対応します。