DynamoDB LocalとLocalStackへの接続方法
ローカルのDynamoDBが動いていて、コードはそれと問題なく通信できている。でも、
毎回scanスクリプトを書くのではなく、テーブルを_見たい_。クライアントをローカル
エンドポイントに接続するのは2つの変更だけです。正しいURLに向けて、使い捨ての
認証情報を渡す。以下の細部こそ、みんながつまずくところです。リージョンの
名前空間分け、英数字キーのルール、そして8000と4566のポートの違いです。
DynamoDB Local vs LocalStack:何に接続するのか
どちらもAWSアカウントなしでlocalhost上のDynamoDB APIを提供しますが、別物です。
- DynamoDB Localは単一プロセスのダウンロード可能なDynamoDBエンジンです。AWSは
これをJARとDockerイメージ
(
amazon/dynamodb-local)として 配布しています。DynamoDBそのものであり、それ以外はありません。デフォルトポートは 8000(AWSドキュメント)。 DockerでDynamoDB Localを動かすを参照してください。 - LocalStackは一群のAWSサービスを1つのエンドポイントの背後でエミュレートします。 そのDynamoDBは DynamoDB Localで動いていますが、 すべてがLocalStackの単一の エッジポート4566を 通ります。
ですから接続における唯一の実用的な違いはエンドポイントURLです。スタンドアロンの
DynamoDB Localには:8000、LocalStack経由のDynamoDBには:4566。それ以外 —
API、認証情報のトリック、GUIの設定 — はすべて同じです。
みんながつまずくエンドポイント+ダミー認証情報のセットアップ
AWS SDKとCLIは、ローカルエンドポイントと通信するときでもアクセスキーとリージョンを 要求します。ただしそれらの値は本物である必要はありません。AWS自身のドキュメントは、 これらの値は「ローカルで実行するために有効なAWSの値である必要はない」と述べています (AWSドキュメント)。
自明でない落とし穴が2つあります。
- リージョン/アクセスキーが、データをひそかに名前空間分けする。
-sharedDbフラグがないと、DynamoDB LocalはアクセスキーID+リージョンの組み合わせ ごとに別々のmyaccesskeyid_region.dbファイルを書き込みます — AWSの正確な命名です。 アプリが使ったのと_違う_キーやリージョンで接続すると、テーブルが消えたように 見えます。実は別のファイルにあるだけです。-sharedDb付きで実行する(すべての クライアントに対して1つのshared-local-instance.db)か、アプリが使うキー+ リージョンを正確に合わせましょう。 - アクセスキーIDは英数字でなければならない — DynamoDB Localでは記号は不可です。
AWSドキュメントは
AWS_ACCESS_KEY_IDがA–Z、a–z、0–9のみを含められると述べています。AWSは これをDynamoDB Local 2.0.0(および1.23.0以降)で導入したので、以前のイメージで 動いていた特殊文字入りのキーが今は失敗します (AWS re:Post)。 下記のエラーを参照してください。
LocalStackでは安全なデフォルトはtest / testです。LocalStackは
シークレットキーを完全に無視し、
シークレットの値を一切検証しません。本物らしいAKIA…/ASIA…キーは
安全策として拒否され、ダミーアカウント000000000000にフォールバックします —
testのような任意のキーが解決されるのと同じアカウントです。testのままに
しておきましょう。
AWS CLIで接続する(動作確認)
GUIを向ける前に、エンドポイントが生きていることをCLIから確認しましょう。CLIには
組み込みのデフォルトローカルエンドポイントがないので、
コマンドごとに--endpoint-urlを渡すか、
AWS_ENDPOINT_URL_DYNAMODB=http://localhost:8000を設定します(CLI v2.13以降)。
DynamoDB Local:
aws dynamodb list-tables --endpoint-url http://localhost:8000LocalStack(同じコマンド、違うポート):
aws dynamodb list-tables --endpoint-url http://localhost:4566(~/.aws/credentials内やAWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY経由の
ダミーであっても)何らかの認証情報が設定されていれば、これはテーブル一覧を
返します。エラーなしで空のリストが返る場合、エンドポイントは動いていますが、
別のキー/リージョンの名前空間を見ています。上記の落とし穴を参照してください。
DynamoDB Local GUI:DynoTableでローカルテーブルを参照・クエリする
CLIが動いたら、GUIには同じ3つの値が必要です。エンドポイント、リージョン、 そして何らかのダミー認証情報です。CLIは目で読むDynamoDB-JSONを返しますが、 GUIは同じデータを、ソート・フィルター・編集できるテーブルとしてレンダリングします。
DynoTableでは、接続を追加してカスタムエンドポイントを設定します。
- エンドポイント:
http://localhost:8000(DynamoDB Local)またはhttp://localhost:4566(LocalStack) - リージョン: アプリが使うもの — 例えば
us-east-1。ここではラベルであり、 本物のAWSリージョンではありませんが、同じデータ名前空間に着地するよう一致 させる必要があります。 - アクセスキー / シークレット: 何でも構いません(
test/testが慣例)。 DynamoDB Localでのアクセスキーは英数字のみ。
そこから項目を参照し、QueryやScanを実行し、CLIでJSONを手でする
代わりにビジュアルに行を編集します。フィクスチャを読み込むときは、
DynamoDB-JSONコンバーターがプレーンなJSONを
ワイヤーフォーマットに変換し、Query vs Scanがどちらの
読み込みを使うべきかをカバーします。
LocalStack DynamoDBビューアーでも手順は同じで、ポートが
4566に変わるだけです。
DynoTableはローカル専用のデスクトップソフトウェアなので、localhostに向ければ
フィクスチャは自分のマシン上に留まります。GUIの選択肢については、
DynamoDB GUI比較を参照してください。
よくあるエラー(リージョン不一致、ポート、認証情報)
- Connection refused。 ポートが間違っています —
8000はDynamoDB Local、4566はLocalStackです。コンテナが実際にポートを公開しているかも確認してください (docker run -p 8000:8000 amazon/dynamodb-local)。LocalStackの場合は、http://localhost:4566/_localstack/healthで サービスが起動しているか確認しましょう。 - DynamoDB Localでの
The Access Key ID or Security Token is Invalid。 2.0.0(および1.23.0以降)イメージ以降、アクセスキーIDは 英数字のみで なければなりません。以前のイメージで動いていた記号入りのキーは今は失敗します — 文字/数字(例:test)に置き換え、すべてのツールを合わせて更新しましょう。 - LocalStackに対する
The security token included in the request is invalid。 これはほぼ必ずエンドポイントの問題であって、認証情報の問題ではありません — SDKクライアントが--endpoint-url/endpoint_urlを落として本物のAWS エンドポイントにアクセスし、それがダミーキーを拒否したのです。クライアントが 実際にhttp://localhost:4566に向いているか確認してください。 - SDK/CLIからの認証情報エラー。 ローカルエンドポイントでも_何らかの_
認証情報が存在している必要があります。SDKの認証情報チェーンが解決できるよう、
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY(あるいはダミープロファイル)を 設定しましょう。 httpとhttps。 ローカルエンドポイントは素のhttpです。https://のURLは TLSハンドシェイクに失敗します。
DynamoDB Localは本物のAWSテーブルと同じデータ?
いいえ — ローカルとクラウドは完全に別々のストアです。DynamoDB Local(および LocalStackのDynamoDB)はデータをローカルファイルまたはメモリに保持します。あなたの AWSアカウントには一切触れず、 AWSのリージョン/アカウントはクライアントレベルではサポートされません。 それこそが狙いです。これは 開発とテストのための ものです。同じフィクスチャをあとでクラウドに持っていきたいなら、 AWSはローカルでは _有効らしい_キー/リージョン値を使い、移行時にエンドポイントだけを差し替えることを 提案しています。出荷前にそのスキーマをモデリングするには、 シングルテーブル設計と GSI vs LSIが、ローカルと本番で変わらない意思決定を カバーしています。
ローカルが節約するもの(と本番がなお課金するもの)
DynamoDB Local は何も計量しません — RCU も WCU も転送もありません。同じ GetItem を us-east-1 オンデマンドのマネージド DynamoDB に対して行うと、アイテム ≤ 4 KB なら結果整合性で 0.5 RCU、強い整合性で 1 RCU が課金されます。--endpoint-url を本物のエンドポイントに差し替えた瞬間から、閲覧もクエリも再び課金が始まります。そのジャンプは 料金計算機 でモデルし、代表アイテムは アイテムサイズ計算機 で測ってください。
よくある質問
本物のAWS認証情報は必要? いいえ。DynamoDB LocalもLocalStackもダミー値を 受け付けます。ただ_存在していて_、(DynamoDB Localでは)英数字で、ツール間で 一貫していればよいだけです。
ツールを切り替えるとテーブルが消えるのはなぜ? -sharedDbがないと、
DynamoDB Localはアクセスキー+リージョンごとにデータを別々の
myaccesskeyid_region.dbファイルに分割します。-sharedDbを使うか、それらの値を
どこでも同一に保ちましょう。
ポート8000と4566の違いは? 8000はスタンドアロンのDynamoDB Localの
デフォルト、4566はエミュレートされた全サービス(DynamoDBを含む)の前面に立つ
LocalStackの単一エッジポートです。
1つのGUIで両方に接続できる? できます — どちらも同じDynamoDB APIを話します。
変わるのはエンドポイントURLだけです(:8000と:4566)。
DynamoDB Localは無料? はい。AWSはDynamoDB LocalをJARと Dockerイメージとして無料で 配布しています — 「プロビジョンドスループット、データストレージ、データ転送の 費用はかからず」、 開発とテストのみを想定して おり、本番向けではありません。
ローカルテーブルに対してSQLを実行できる? ローカルのDynamoDBはクラウドと
同じAPIを話すので、同じアクセスパターンのルールが適用されます — そして同じ制限も。
DynamoDBの
PartiQL SELECT文法は
SELECT … FROM … WHERE … ORDER BYのみで、JOINもGROUP BYも、
COUNT/SUM/AVGのような
グループ化集計関数も
ありません(PartiQL vs SQLを参照)。DynoTableの
は、それらの分析クエリを、ローカルを含む任意の接続に
対して実行します。
DynoTableを試すと、localhost:8000またはlocalhost:4566に直接
つないで、ローカルテーブルをGUIで参照・クエリ・編集できます。