AWS EmulatorでDynamoDBをアカウントなしで試す方法

​​AWS Emulator​AWS CLI,DynamoDB

AWS Emulator を手元で起動すると、AWS のアカウントがなくても、AWS CLI から DynamoDB のテーブルを作って項目を読み書きできます。ローカル環境での開発やテストで、本物の AWS にリクエストを送らずに DynamoDB を試したいときの手順です。テーブルの作成から、項目の書き込み・読み出し・更新・削除、テーブルの削除までを、検証環境で実行したコマンドと出力のまま載せます。

補足

検証環境は Ubuntu 24.04(x86_64)、AWS Emulator 1.0.352(2026年11月13日リリース)、AWS CLI 2.40.3 です。AWS のアカウントと認証情報は使っていません。本物の AWS の DynamoDB での動き(応答の速さ、料金など)は、この環境では確かめていません。記事で触れるところは公式ドキュメントを出どころにしています。

AWS Emulator を入れて起動する

AWS Emulator は、AWS の API を手元で受け付けるエミュレーターです。公式ドキュメントによると、AWS のアカウントは要らず、AWS Emulator そのものに追加の料金はかかりません。リクエストは AWS には送られず、エミュレーターの中に作られたリソースを相手にします。

入れ方と接続先の設定は別の記事で詳しく扱うので、ここでは短くします。Ubuntu では、Linux 向けの手順にある Debian パッケージを使います。次のコマンドは公式の手順にあるものです。私はファイル名を aws-emulator_amd64.deb にし、root で(sudo を付けずに)実行しました。手順にある、gpg で署名を確かめる操作もしています。

bash
curl -fsSLo aws-emulator.deb https://downloads.aws.com/aws-emulator/packages/aws-emulator/LTS/latest/aws-emulator_amd64.deb
sudo apt-get install -y ./aws-emulator.deb

起動は aws-emulator だけです。エミュレーターは、既定で利用状況のデータ(テレメトリー)を AWS に送ります。私は -t off で切って起動しました。

bash
aws-emulator -t off

エミュレーターはその端末で動き続けます。起動すると、ログが何行か出ます。検証環境ではバックグラウンドで起動してログをファイルに書きましたが、その中に次の行がありました(ホームディレクトリのパスは ~ に置き換えています)。

text
{"timestamp":"2026-11-14T02:07:39.118231Z","level":"INFO","fields":{"message":"emulator server information","endpoint_url":"https://127.0.0.1:9297","health_check_url":"https://127.0.0.1:9297/__admin/health","config_file":"~/.aws/emulator/9297/config","ca_file":"~/.aws/emulator/9297/ca.pem","java_truststore_file":"~/.aws/emulator/9297/truststore.p12"},"target":"aws_emulator_server"}

https://127.0.0.1:9297 で待ち受けていて、~/.aws/emulator/9297/ に、AWS CLI 用の設定ファイル、証明書、この起動のときだけ使えるアクセスキーが書き出されます。

AWS CLI の接続先をエミュレーターに向ける

別の端末で、公式ドキュメントにある環境変数を設定します。リージョンの us-east-1 も、公式ドキュメントの例の値のままです。

bash
export AWS_ENDPOINT_URL=https://127.0.0.1:9297
export AWS_SHARED_CREDENTIALS_FILE=~/.aws/emulator/9297/emulator_credentials
export AWS_CONFIG_FILE=~/.aws/emulator/9297/config
export AWS_CA_BUNDLE=~/.aws/emulator/9297/ca.pem
export AWS_EC2_METADATA_DISABLED=true
export AWS_DISABLE_HOST_PREFIX_INJECTION=true
export AWS_REGION=us-east-1
export AWS_DEFAULT_REGION=us-east-1
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_PROFILE
注意

公式ドキュメントでは、AWS_ENDPOINT_URL が設定されていないシェルでコマンドを実行すると、見つかった認証情報を使って本物の AWS に送られると注意しています。本物の AWS の認証情報が入ったシェルでは、上の環境変数がすべて設定されていることを確かめてから実行してください。

接続先がエミュレーターになったかは、aws sts get-caller-identity で確かめられます。エミュレーターに繋がっていれば、ユーザー名が emulator になります(12桁のアカウントIDは置き換えています)。

text
$ aws sts get-caller-identity --query Arn --output text
arn:aws:iam::<12桁のアカウントID>:user/emulator

最初はテーブルが1つもありません。

text
$ aws dynamodb list-tables
{
    "TableNames": []
}

テーブルを作る

id という文字列の属性をパーティションキーにした、Cats というテーブルを作ります。--billing-mode PAY_PER_REQUEST は、読み書きの回数で課金されるオンデマンドの指定です。出力は長いので、--query で一部だけを出しています。

text
$ aws dynamodb create-table --table-name Cats \
    --attribute-definitions AttributeName=id,AttributeType=S \
    --key-schema AttributeName=id,KeyType=HASH \
    --billing-mode PAY_PER_REQUEST \
    --query 'TableDescription.{TableName: TableName, TableStatus: TableStatus, KeySchema: KeySchema, BillingMode: BillingModeSummary.BillingMode}'
{
    "TableName": "Cats",
    "TableStatus": "CREATING",
    "KeySchema": [
        {
            "AttributeName": "id",
            "KeyType": "HASH"
        }
    ],
    "BillingMode": "PAY_PER_REQUEST"
}

作った直後の状態は CREATING でした。CreateTable の API リファレンスによると、本物の DynamoDB でも最初は CREATING が返り、読み書きできるのは ACTIVE になってからです。そこで、aws dynamodb wait table-exists で ACTIVE になるのを待ちます。検証環境では3秒ほどで戻りました。

text
$ aws dynamodb wait table-exists --table-name Cats
$ aws dynamodb describe-table --table-name Cats --query 'Table.{TableStatus: TableStatus, ItemCount: ItemCount}'
{
    "TableStatus": "ACTIVE",
    "ItemCount": 0
}

項目を書き込む

put-item で項目を書き込みます。値は {"S": "..."}(文字列)、{"N": "..."}(数値)のように、型を付けた JSON で渡します。成功しても何も出力されません。

bash
aws dynamodb put-item --table-name Cats \
    --item '{"id": {"S": "tama"}, "name": {"S": "タマ"}, "age": {"N": "3"}}'
aws dynamodb put-item --table-name Cats \
    --item '{"id": {"S": "mike"}, "name": {"S": "ミケ"}, "age": {"N": "5"}, "likes": {"SS": ["かつお", "ひなた"]}}'

put-item は、同じキーの項目があると上書きします。上書きしたくないときは、--condition-expression 'attribute_not_exists(id)' を付けます。条件式のドキュメントにあるとおり、同じキーの項目がすでにあると書き込みは断られます。エミュレーターでも、tama に上書きしようとするとエラーになり、終了コードは 254 でした。

text
$ aws dynamodb put-item --table-name Cats \
    --item '{"id": {"S": "tama"}, "name": {"S": "上書きのタマ"}}' \
    --condition-expression 'attribute_not_exists(id)'

aws: [ERROR]: An error occurred (ConditionalCheckFailedException) when calling the PutItem operation: The conditional request failed

項目を読み出す

キーを指定して1件読むときは get-item です。

text
$ aws dynamodb get-item --table-name Cats --key '{"id": {"S": "tama"}}'
{
    "Item": {
        "id": {
            "S": "tama"
        },
        "age": {
            "N": "3"
        },
        "name": {
            "S": "タマ"
        }
    }
}

さきほどの条件付きの put-item は断られたので、name は「タマ」のままです。

一部の属性だけを読むときは --projection-expression を使います。name は DynamoDB の予約語なので、#n のような別名を --expression-attribute-names で割り当てています。GetItem の API リファレンスによると、get-item は既定では結果整合性のある読み込みで、直前の書き込みを必ず反映させたいときは --consistent-read を付けます。

text
$ aws dynamodb get-item --table-name Cats --key '{"id": {"S": "mike"}}' \
    --projection-expression '#n, likes' --expression-attribute-names '{"#n": "name"}' --consistent-read
{
    "Item": {
        "name": {
            "S": "ミケ"
        },
        "likes": {
            "SS": [
                "かつお",
                "ひなた"
            ]
        }
    }
}

存在しない項目のキーを指定すると、エラーにはならず、何も出力されません(終了コードは 0)。API リファレンスにも、合う項目がなければ Item を返さないと書かれています。

text
$ aws dynamodb get-item --table-name Cats --key '{"id": {"S": "kuro"}}'

キーの条件で探す query と、テーブル全体を読む scan も使えました。--query は AWS CLI の側で出力を絞るオプションで、DynamoDB の query とは別のものです。

text
$ aws dynamodb query --table-name Cats \
    --key-condition-expression 'id = :id' \
    --expression-attribute-values '{":id": {"S": "mike"}}' \
    --query 'Items[].name.S'
[
    "ミケ"
]
$ aws dynamodb scan --table-name Cats --query '{Count: Count, Ids: Items[].id.S}'
{
    "Count": 2,
    "Ids": [
        "mike",
        "tama"
    ]
}

項目を更新する

update-item では、項目全体を書き直さずに一部の属性だけを変えられます。age に 1 を足し、変わった値を --return-values UPDATED_NEW で返させました。

text
$ aws dynamodb update-item --table-name Cats --key '{"id": {"S": "tama"}}' \
    --update-expression 'SET age = age + :one' \
    --expression-attribute-values '{":one": {"N": "1"}}' \
    --return-values UPDATED_NEW
{
    "Attributes": {
        "age": {
            "N": "4"
        }
    }
}

項目を削除する

delete-item に --return-values ALL_OLD を付けると、消した項目の中身が返ります。

text
$ aws dynamodb delete-item --table-name Cats --key '{"id": {"S": "tama"}}' --return-values ALL_OLD
{
    "Attributes": {
        "id": {
            "S": "tama"
        },
        "age": {
            "N": "4"
        },
        "name": {
            "S": "タマ"
        }
    }
}

もう一度 get-item で読むと何も出力されず、scan で数えると残りは mike の1件でした。

text
$ aws dynamodb get-item --table-name Cats --key '{"id": {"S": "tama"}}'
$ aws dynamodb scan --table-name Cats --query '{Count: Count, Ids: Items[].id.S}'
{
    "Count": 1,
    "Ids": [
        "mike"
    ]
}

テーブルを削除する

delete-table の直後の状態は DELETING でした。DeleteTable の API リファレンスにも、削除が終わるまでは DELETING になると書かれています。wait table-not-exists で消えるのを待ってから確かめました。

text
$ aws dynamodb delete-table --table-name Cats --query 'TableDescription.{TableName: TableName, TableStatus: TableStatus}'
{
    "TableName": "Cats",
    "TableStatus": "DELETING"
}
$ aws dynamodb wait table-not-exists --table-name Cats
$ aws dynamodb list-tables
{
    "TableNames": []
}
$ aws dynamodb describe-table --table-name Cats

aws: [ERROR]: An error occurred (ResourceNotFoundException) when calling the DescribeTable operation: Requested resource not found: Table: Cats not found

エミュレーターを止めると、テーブルも消える

エミュレーターは、作ったリソースをメモリーにだけ置いています。Linux 向けの手順のとおり、止めるには起動した端末で Ctrl+C を押すか、プロセスに SIGTERM を送ります。

検証環境で、テーブルを作り直してからエミュレーターに SIGTERM を送ると、~/.aws/emulator/9297/ の中のファイルは0個になりました。もう一度 aws-emulator -t off で起動して list-tables を実行すると、テーブルは残っていませんでした。

text
$ aws dynamodb list-tables
{
    "TableNames": []
}

公式ドキュメントでも、起動し直せばテストを空の状態から始められると案内しています。アクセスキーは起動のたびに作り直されますが、環境変数はファイルの場所を指しているだけです。同じポートで起動し直した検証環境では、環境変数を変えずにそのまま list-tables を実行できました。

本物の DynamoDB との違いと注意点

公式ドキュメントには、本物の AWS との違いや、使うときの注意として、次のことが書かれています。

  • 料金:エミュレーターに追加の料金はかかりません。本物の DynamoDB のオンデマンド(PAY_PER_REQUEST)は、オンデマンドモードの説明によると、読み書きのリクエストごとに課金されます。
  • 権限:エミュレーターは IAM のポリシーを AWS と同じようには判定しないため、セキュリティの確認には使わないよう書かれています。
  • 確かめているリージョン:AWS がエミュレーターの動きを本物と比べているのは、米国西部(オレゴン、us-west-2)リージョンだけで、グローバルなサービスは米国東部(バージニア北部、us-east-1)です。
  • 使いみち:開発とテストのためのもので、本番のワークロードには使わないよう書かれています。

どこまで本物と同じ動きをするかは、サービスや機能ごとに違います。詳しくは公式ドキュメントの「Fidelity」のページと、GitHub のリリースページにリリースごとに載っているスコアで確かめられます。

​Posted by 86