Docker-ComposeでDynamoDB-localとawscli-localのローカル環境セットアップ


## はじめに
こんにちは、今回は、Docker-Composeを使用してDynamoDBをローカル環境で構築する方法に焦点を当てていきます。

DynamoDB-localとawscli-localをDocker-composeを使用して一括で構築することで、環境構築の手間を大幅に削減できます。それではさっそく、手順を見ていきましょう。

## 前提条件
まずは、Dockerを使用してDynamoDBをローカル環境にセットアップします。そのためには、事前にDocker Desktopをインストールしておいてください。インストールがまだの方は、[公式サイト](https://www.docker.com/ja-jp/products/docker-desktop/)からダウンロードしてインストールを完了させておきましょう。

## DynamoDB と AWS CLI コンテナの稼働
#### Docker Compose で作成するDockerコンテナを定義
```yml:docker-compose.yml
version: '3.8'
services:
  dynamodb:
    # dynamodb-local イメージを使用する
    image: amazon/dynamodb-local:latest
    # DynamoDBLocal.jar: DynamoDB Localの実行JAR, -sharedDB: 共有DBを使用する, -dbPath: DBのパス, -optimizeDbBeforeStartup: DBを最適化する
    command: -jar DynamoDBLocal.jar -sharedDb -dbPath . -optimizeDbBeforeStartup
    container_name: dynamodb-local
    ports:
      - "8000:8000"
    volumes:
      - "./docker/dynamodb:/home/dynamodblocal/data"
    working_dir: /home/dynamodblocal
  
  awscli:
    # dynamodbが起動していることを確認してから起動
    depends_on:
     - dynamodb
    # awscli-local イメージを使用する
    image: amazon/aws-cli
    container_name: awscli-local
    ports:
      - "8080:8080"
    # entrypoint: エントリーポイントは空
    entrypoint: [""]
    # tty: true: ターミナルを使う
    tty: true
    # ACCESS_KEY_IDとSECRET_ACCESS_KEYはローカル接続なので適当
    environment:
      AWS_ACCESS_KEY_ID: 'DUMMY'
      AWS_SECRET_ACCESS_KEY: 'DUMMY'
    # シェルを実行
    command:
      - /bin/sh
```
#### dynamodb-local と awscli-local コンテナを作成する。

コンテナが構築できるかテスト
※エラーとなる場合 Docker Desktop が起動しているか確認
```:ターミナル
> docker-compose up -d
[+] Running 2/0
 ✔ Container dynamodb-local  Running
 ✔ Container awscli-local    Running  
```

#### コンテナが動作しているか確認
```:ターミナル
> docker ps -a     
CONTAINER ID   IMAGE                          COMMAND                   CREATED          STATUS         PORTS                    NAMES
870b7ec140c2   amazon/aws-cli                 "/bin/sh"                 5 minutes ago    Up 5 minutes   0.0.0.0:8080->8080/tcp   awscli-local
c3d4180311c2   amazon/dynamodb-local:latest   "java -jar DynamoDBL…"   10 minutes ago   Up 5 minutes   0.0.0.0:8000->8000/tcp   dynamodb-local
```

#### awscli-local コンテナに入る
```:ターミナル
> docker exec -it awscli-local /bin/bash
bash-4.2# 
```

#### DynamoDBが稼働しているか確認
まだテーブルを作成していない為、空のリストが返ってくる
```:ターミナル
aws dynamodb list-tables --region ap-northeast-1 --endpoint-url http://dynamodb-local:8000
}
    "TableNames": []
}
```

## DynamoDB 設定
#### Table定義シェルスクリプトファイル作成
```sh:create_dynamodb_table.sh
#!/bin/bash
aws dynamodb --region ap-northeast-1 --endpoint-url http://dynamodb-local:8000 \
  create-table \
  --table-name User \
  --attribute-definitions AttributeName=UserId,AttributeType=S AttributeName=SortKey,AttributeType=S \
  --key-schema AttributeName=UserId,KeyType=HASH AttributeName=SortKey,KeyType=RANGE \
  --billing-mode PAY_PER_REQUEST
```
- AttributeName=UserId,KeyType=HASH: UserIdをパーティションキー(HASHキー)として指定。
- AttributeName=SortKey,KeyType=RANGE: SortKeyをソートキー(RANGEキー)として指定。
- --billing-mode PAY_PER_REQUEST: 課金モードをオンデマンドモード指定(必須ではない)。

#### データ登録シェルスクリプトファイル作成
```sh:add_data_to_dynamodb.sh
#!/bin/bash

# DynamoDB LocalのエンドポイントURL
ENDPOINT_URL="http://dynamodb-local:8000"

# テーブルにデータを追加する関数
add_user() {
    aws dynamodb put-item \
        --table-name User \
        --region ap-northeast-1 \
        --endpoint-url $ENDPOINT_URL \
        --item '{
            "UserId": {"S": "'"$1"'"},
            "SortKey": {"S": "'"$2"'"},
            "Name": {"S": "'"$3"'"},
            "Email": {"S": "'"$4"'"}
        }'
}

# サンプルデータを追加
add_user "user1" "sort1" "John Doe" "john.doe@example.com"
add_user "user2" "sort2" "Jane Smith" "jane.smith@example.com"
add_user "user3" "sort3" "Alice Johnson" "alice.johnson@example.com"
```

#### DynamoDBにシェルスクリプトを実行
作成した2つのshファイルをawscli-local にコピーした後実行
```:ターミナル
> docker cp create_dynamodb_table.sh awscli-local:/usr/local/bin/create_dynamodb_table.sh
Successfully copied 2.05kB to awscli-local:/usr/local/bin/create_dynamodb_table.sh

> docker cp add_data_to_dynamodb.sh awscli-local:/usr/local/bin/add_data_to_dynamodb.sh
Successfully copied 2.56kB to awscli-local:/usr/local/bin/add_data_to_dynamodb.sh

> docker exec -it awscli-local /bin/bash
bash-4.2# chmod +777 /usr/local/bin/create_dynamodb_table.sh
bash-4.2# chmod +777 /usr/local/bin/add_data_to_dynamodb.sh

bash-4.2# /usr/local/bin/create_dynamodb_table.sh
bash-4.2# /usr/local/bin/add_data_to_dynamodb.sh
{/bin/add_data_to_dynamodb.sh
    "TableDescription": {
        "AttributeDefinitions": [
            {
                "AttributeName": "UserId",
                "AttributeType": "S"
            },
            {
                "AttributeName": "SortKey",
                "AttributeType": "S"
            }
        ],
        "TableName": "User",
        "KeySchema": [
            {
                "AttributeName": "UserId",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "SortKey",
                "KeyType": "RANGE"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": "2024-07-08T11:03:53.221000+00:00",
        "ProvisionedThroughput": {
            "LastIncreaseDateTime": "1970-01-01T00:00:00+00:00",
            "LastDecreaseDateTime": "1970-01-01T00:00:00+00:00",
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 0,
            "WriteCapacityUnits": 0
```
問題なく作成できました！！

#### 作成したコンテナとイメージを削除
最後に後片付けをしておきましょう。
```:ターミナル
> docker-compose down --rmi all
```

## まとめ
Docker-Composeを使用することで、複数のDockerイメージをまとめて簡単に定義できるのはとても便利ですね。特に、DynamoDB-localとawscli-localを使ったローカル環境の構築は、手軽で効率的であると感じました。

DynamoDBの設定やawscliの操作を一つの環境で完結させることで、開発やテストのスピードが格段に向上しました。これからもDockerを活用して、より効率的な開発環境を構築していきたいと思います。