開発時のDynamoDB環境としてDynamoDB Localを用いた際に行なったノウハウを公開します。

123件のシェア(ちょっぴり話題の記事)

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

好物はインフラとフロントエンドのかじわらゆたかです。 現在私が構築を行っているサービスでは、DynamoDBをデータストアとして用いています。

開発時に開発者各々に開発用のDynamoDBのテーブルを作成すると、 テーブル名の重複やコストの問題が発生してしまいます。 これらの問題を回避するため、開発時にはDynamoDB Localを用いて開発を進めました。 それらの手法についてお伝えします。

環境は以下の環境で実施しております。

  • Mac OS X High Sierra 10.13.4
  • java version "1.8.0_162"
  • curl 7.54.0
  • aws-cli 1.15.7
  • UnZip 6.00
  • Node.js v8.10.0

DynamoDBのテーブル定義を作成する

こちらはAWS CLIのスケルトンJSONを作成し、それを用いて作成します。

AWS CLIのパラメータをJSONファイルで記述する

$ aws dynamodb create-table --generate-cli-skeleton > skel_dynamodb_create-table.json

上記で作成されたjsonに対して、項目やテーブル名等を設定していきます。

今回の例としては以下の様なJSONを作成しました。

{
    "AttributeDefinitions": [
        {
            "AttributeName": "UserID",
            "AttributeType": "S"
        }
    ],
    "TableName": "user",
    "KeySchema": [
        {
            "AttributeName": "UserID",
            "KeyType": "HASH"
        }
    ],
    "ProvisionedThroughput": {
        "ReadCapacityUnits": 5,
        "WriteCapacityUnits": 5
    }
}

DynamoDB Localを立ち上げる

DynamoDB Localは開発環境としてAWSが提供している開発環境です。 Jarファイルとして提供されているため、開発時にインターネットへの接続が必要ありません。 そのため、ロビジョニングされたスループットやデータストレージ、データ転送料金を節約できることになります。

立ち上げるスクリプトとしては以下の様な内容を用いています。

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
mkdir ${SCRIPT_DIR}/_work
if [ ! -f ${SCRIPT_DIR}/_work/dynamodb_local_latest.zip ]; then
    curl  https://s3-ap-northeast-1.amazonaws.com/dynamodb-local-tokyo/dynamodb_local_latest.zip -o ${SCRIPT_DIR}/_work/dynamodb_local_latest.zip
    cd ${SCRIPT_DIR}/_work && unzip ./dynamodb_local_latest.zip
    cd ${SCRIPT_DIR}/_work && java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb
fi
cd ${SCRIPT_DIR}/_work && java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb

このスクリプトを動かすことでローカル環境の8000番ポートでDynamoDB Localが立ち上がります。

DynamoDB Localにテーブルを作成する

DynamoDB のDDLとして作成したJSONファイルを用いて、AWS CLIを用いてテーブルを作成します。 AWS CLIからDynamoDB Localを用いる場合は、--endpoint-url を用います。

aws dynamodb create-table --cli-input-json file://user.json  --endpoint-url http://localhost:8000

この時気をつける必要があるのは、--endpoint-urlのオプションの付与を必ず行うことです。 このオプションの付与を行わないと、ローカル環境のDynamoDB Localではなく、AWS環境上のDynamo DBに対してのテーブル作成を行うことになります。

実行結果は以下のようになります。

$ aws dynamodb create-table --cli-input-json file://user.json  --endpoint-url http://localhost:8000
{
    "TableDescription": {
        "AttributeDefinitions": [
            {
                "AttributeName": "UserID",
                "AttributeType": "S"
            }
        ],
        "TableName": "user",
        "KeySchema": [
            {
                "AttributeName": "UserID",
                "KeyType": "HASH"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": 1525686945.598,
        "ProvisionedThroughput": {
            "LastIncreaseDateTime": 0.0,
            "LastDecreaseDateTime": 0.0,
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 5,
            "WriteCapacityUnits": 5
        },
        "TableSizeBytes": 0,
        "ItemCount": 0,
        "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/user"
    }
}

TableArnがddblocal:000000000000となっており、DynamoDB Localを参照していることがわかります。

DynamoDB Localのテーブル情報を参照する管理画面を立ち上げる

DynamoDB Localはテーブル内のデータを参照するUIが存在しないため、別途用意する必要があります。 DynamoDB adminというツールを用いてテーブルのデータを参照します。

{
  "name": "dynamodb-local-admin",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "better-npm-run start",
    "pre-start": "npm install"
  },
  "betterScripts": {
    "start": {
      "command": "dynamodb-admin",
      "env": {
        "DYNAMO_ENDPOINT": "http://localhost:8000"
      }
    }
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "dynamodb-admin": "^1.12.0",
    "better-npm-run": "^0.1.0"
  }
}

上記のpackage.jsonを作成し、npm start で8001番ポートでDynamoDB Localを参照する管理画面が立ち上がります。

AWS SDK for Python (Boto3)を用いてDynamoDB Localへの操作を行う

PythonのAWS SDK実装であるBoto3を用いてDynamoDB Localへの操作を行います。 今回の方針としては、環境変数DYNAMODB_ENDPOINTに対して値が設定されている際は、設定されたエンドポイント(DynamoDB Local)を用い、設定されていない場合は、DynamoDBを用いることにします。 以下のコードではboto3がdefaultのprofileを参照するので、 項目自体は空で良いのでdefaultのprofileの作成を行なっておく必要があります。

import os
import uuid
import boto3
endpoint_url = os.getenv('DYNAMODB_ENDPOINT', None)
dynamodb = boto3.resource('dynamodb', endpoint_url=endpoint_url)
user_table = dynamodb.Table('user')
user = {
    "UserID": str(uuid.uuid4()),
    "UserName": "KAJIWARA YUTAKA"
}
user_table.put_item(Item=user)

上記のコードを実行した後に、先ほど構築したDynamoDB Adminで確認すると、DynamoDB Localに値が書き込まれていることがわかります。

VisualStudioCodeでPythonをデバッグする際の環境変数の設定

Pythonの実装はVisual Studio Codeを用いて行なっています。 Visual Studio Codeでは、デバッグ等を行うときの環境変数の設定を行うことが可能です。

デバッグ用の設定ファイル(launch.json)を作成した際に、envというキーでオブジェクトを作成し、その中に設定したい環境変数と値を設定します。 今回の例の場合はDYNAMODB_ENDPOINT という環境変数を作成したいので、以下のようになります。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "env": {
                "DYNAMODB_ENDPOINT": "http://localhost:8000"
            },
        }
    ]
}

まとめ

DynamoDB Localを用いての開発方法についてまとめました。
DynamoDB LocalとDynamoDB Adminを用いることでGUIで確認しながらDynamoDB を用いた実装を進めていくことが可能です。