Fusic Tech Blog

Fusion of Society, IT and Culture

AWSの各サービスをLocalStackやMinioでDocker Compose環境を構築、S3バケットやDynamoDBテーブルを自動作成する
2022/06/13

AWSの各サービスをLocalStackやMinioでDocker Compose環境を構築、S3バケットやDynamoDBテーブルを自動作成する

はじめに

AWSサービスと連携したアプリケーションを開発する場合、LocakStackやMinioなどのローカル環境でAWSサービスと同じ環境を再現できるツールを利用するとデバッグなどが効率よく行えます。

これらをDocker Composeで管理、起動できるようにして、起動時に各種サービス(S3のバケット作成、DynamoDBのテーブル作成、SQSキューの作成など)のセットアップを完了させることでさらに効率よく開発できます。

LocalStackではS3も利用できますが、Minioではダッシュボードが利用でき便利なため、今回はこちらを使います。

Docker Composeの準備

以下がdocker-compose.ymlになります。

version: '3.8'
services:
  localstack:
    image: localstack/localstack:latest
    ports:
      - '4566:4566'
    environment:
      - DATA_DIR=/tmp/localstack/data
      - DEBUG=1
      - LAMBDA_EXECUTOR=local
      - INIT_SCRIPTS_PATH=/entrypoint
    volumes:
      - 'localstack-data:/tmp/localstack'
      - '/var/run/docker.sock:/var/run/docker.sock'
      - './entrypoint:/entrypoint'
  minio:
    image: minio/minio:latest
    ports:
      - '9000:9000'
      - '9001:9001'
    entrypoint: sh
    command: >
      -c "mkdir -p /data/my-bucket &&
      mkdir -p /data/.minio.sys/buckets/my-bucket && 
      cp /policy.json /data/.minio.sys/buckets/my-bucket/policy.json && 
      minio server /data --console-address ':9001'
      "
    volumes:
      - 'minio-data:/data'
      - ./policy.json:/policy.json
  dynamodb-admin:
    image: aaronshaf/dynamodb-admin:latest
    environment:
      - DYNAMO_ENDPOINT=localstack:4566
      - AWS_REGION=ap-northeast-1
    ports:
      - '8001:8001'
    depends_on:
      - localstack

volumes:
  localstack-data:
  minio-data:

LocalStackのイメージを使い、INIT_SCRIPTS_PATH という環境変数を設定することでコンテナ起動時にスクリプト実行することができます。今回は/entrypoint というパスに置くことを想定して設定してます。

INIT_SCRIPTS_PATH を指定しなくても、デフォルトでは/docker-entrypoint-initaws.d に実行したいスクリプトファイルを置くことで起動時に実行されます。

MinioではLocakStackのようなエントリポイントを指定できるようなものはなかったようなので、サーバー起動前にバケットとポリシーを作成するようなコマンドを設定しています。

さらにdynamodb-admin を追加しました。これを利用するとDynamoDBのダッシュボード画面が見れて、テーブルの編集やデータの閲覧ができて便利です。

LocalStackのエントリポイント準備

先ほどdocker-compose.ymlで設定したLocalStackのエントリポイントを用意します。

docker-compose.ymlと同じ場所にentrypointという名前でディレクトリを作成、そこにsetup.shというファイルを用意します(.shであればなんでもOK)。

#!bin/bash

echo "Creating sns topic"
awslocal sns create-topic --name MyTopic --region ap-northeast-1

echo "Creating sqs queue"
awslocal sqs create-queue --queue-name MyQueue --region ap-northeast-1

echo "Subscribing to sns topic"
awslocal sns subscribe \ 
    --topic-arn arn:aws:sns:ap-northeast-1:000000000000:MyTopic \
    --protocol sqs \
    --notification-endpoint arn:aws:sqs:ap-northeast-1:000000000000:MyQueue \
    --region ap-northeast-1

echo "Creating dynamodb table"
awslocal dynamodb create-table \
    --table-name Music \
    --attribute-definitions \
        AttributeName=Artist,AttributeType=S \
        AttributeName=SongTitle,AttributeType=S \
    --key-schema \
        AttributeName=Artist,KeyType=HASH \
        AttributeName=SongTitle,KeyType=RANGE \
    --provisioned-throughput \
        ReadCapacityUnits=5,WriteCapacityUnits=5 \
    --table-class STANDARD \
    --region=ap-northeast-1

ポイントとしてはawsコマンドを使わず、そのラッパーであるawslocalを使用していることです。これを使うことによって、通常は--endpoint-url オプション指定しないといけないところを指定なしでローカル環境(デフォルトはポート4566)にあるサービスへ向けてawsコマンドを実行することができます。

Minioのバケットポリシー準備

最後にバケット作成時にあてるポリシーの準備を行います。

policy.jsonという名前でdocker-compose.ymlと同じ場所に用意します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": [
        "s3:GetBucketLocation",
        "s3:ListBucket",
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::*"
      ]
    }
  ]
}

ポリシーは要件に応じて適宜いい感じに設定してください。

起動

準備ができたので実行してみます。

$ docker-compose up -d

各コンテナが立ち上がったら、確認してみましょう。awslocalがインストールされている場合は以下コマンドを打ってみます。

$ awslocal sqs list-queues --region ap-northeast-1
{
    "QueueUrls": [
        "http://localhost:4566/000000000000/MyQueue"
    ]
}
$ awslocal sns list-topics --region ap-northeast-1
{
    "Topics": [
        {
            "TopicArn": "arn:aws:sns:ap-northeast-1:000000000000:MyTopic"
        }
    ]
}
$ awslocal sns list-subscriptions --region ap-northeast-1
{
    "Subscriptions": [
        {
            "SubscriptionArn": "arn:aws:sns:ap-northeast-1:000000000000:MyTopic:xxxxxx-xxxx-xxxx-xxxx-xxxxxxx",
            "Owner": "",
            "Protocol": "sqs",
            "Endpoint": "arn:aws:sqs:ap-northeast-1:000000000000:MyQueue",
            "TopicArn": "arn:aws:sns:ap-northeast-1:000000000000:MyTopic"
        }
    ]
}

これでSQSキューとSNSトピックが作成され、サブスクリプションも設定されていることが確認できました。

S3(Minio)はブラウザでlocalhost:9001へアクセス(ID: minioadmin/PW: minioadmin)してバケットが作られていることが確認できます。

DynamoDBはlocalhost:8001へアクセスしてテーブルが作られていることが確認できます。

おわりに

今回はLocalStackやMinioなどをDocker Composeで管理して、ローカル環境でAWSの各サービスを構築してみました。

これによって実際のAWS上で各サービスにアクセスせずにデバッグなどが進められるので、コスト的にもメリットがあるので試してみてはいかがでしょうか。

Daiki Urata

Daiki Urata

フロントエンド好きなエンジニアです。