AWS Emulatorは、AWSが2026年11月11日に発表した公式のローカルエミュレータで、AWSアカウントなし・無料でAWSのAPIを手元に再現します。LocalStackは2026年3月から認証トークンが必須になり、仕事で使うには有料プランが要ります。その代わりになるのでしょうか?
Apple siliconのMacとDockerでv1.0.322を動かすと、S3・DynamoDB・SQS・Lambdaを使うコードはそのまま流れ、TerraformとCDKも通りました。これらのサービスの基本操作を使うテストを回す用途なら、代わりになります。IAMの権限設計を確かめる用途には向きません。
AWS Emulatorを手元のDockerで立ち上げるには?
ビルド済みのイメージは配られていない
LinuxはRPMかDebのパッケージで入りますが、macOSとWindowsは公式ドキュメントのDockerfileから自分でイメージを作ります。ビルドは33秒、イメージは1.16GBでした。
# IntelのMacは aarch64 を x86_64 に替える
cat > Dockerfile <<'EOF'
FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal
ADD https://downloads.aws.com/aws-emulator/packages/aws-emulator/LTS/latest/aws-emulator-aarch64.rpm /tmp/aws-emulator.rpm
RUN rpm -i /tmp/aws-emulator.rpm && rm /tmp/aws-emulator.rpm \
&& mkdir -p /home/emulator && chown 1000 /home/emulator
USER 1000
ENV HOME=/home/emulator
EXPOSE 9297
ENTRYPOINT ["aws-emulator", "-b", "0.0.0.0"]
EOF
docker build -t aws-emulator .
mkdir -p ~/.aws/emulator
docker run --rm --memory=2g --memory-swap=2g -p 127.0.0.1:9297:9297 \
-e HOME="$HOME" -v "$HOME/.aws/emulator:$HOME/.aws/emulator" \
aws-emulator -p 9297 --telemetry off起動は1秒足らず、テレメトリは自分で切る
エミュレータは起動のたびに、そのとき限りのアクセスキー・設定ファイル・証明書を~/.aws/emulator/9297/に作ります。-vは、コンテナが作ったこれらのファイルを手元のCLIやSDKから読めるようにする指定です。-e HOMEでコンテナの中のホームを手元と同じパスにそろえると、設定ファイルに書かれるパスが手元でもそのまま通ります。-p 127.0.0.1:9297:9297は自分のマシンにだけポートを開く指定、--memory=2gは使うメモリの上限で、超えるとコンテナが止まって作ったリソースも消えます。
何も指定しないと、匿名の利用状況とエラーのデータをAWSに送る設定(テレメトリ)が有効なまま起動するので、--telemetry offで止めました。docker runから、ヘルスチェックcurl --cacert ~/.aws/emulator/9297/ca.pem https://127.0.0.1:9297/__admin/healthがokを返すまで0.56秒です。
普段のAWS CLIとboto3のコードは、環境変数だけでAWS Emulatorに向く
宛先と鍵の置き場を、環境変数8個で手元に向ける
AWS CLIやSDKはリージョンから送り先を決めていて、それをAWS_ENDPOINT_URLで手元に書き換えるのがendpoint URLの差し替えです。エミュレータは署名のない要求を断り、通信もHTTPSなので、鍵と証明書の場所も渡します。
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_PROFILEAWS_EC2_METADATA_DISABLEDはEC2上で本物の認証情報を拾わないため、AWS_DISABLE_HOST_PREFIX_INJECTIONはSDKが一部の操作でホスト名に接頭辞を足すのを止めるためです。AWS_CONFIG_FILEを差し替えるので、このシェルでは普段のprofileの設定は効きません。
S3とDynamoDBは、条件付き書き込みの失敗まで通った
試したのはAWS CLI 2.40.1とboto3 1.44.1です。aws sts get-caller-identityはAccount 000000000000を返し、S3はバケット作成から読み出しまでの4コマンドが1.7秒で通って、アップロードした中身hello-emulatorが返りました。
DynamoDBもboto3でテーブル作成とput・getが通り、条件付き書き込みの失敗はConditionalCheckFailedExceptionで返りました。どちらも、コードにはエンドポイントも鍵も書いていません。
SQSからLambdaまで、AWS EmulatorはDockerソケットなしでつながった
Lambdaの関数は、Dockerを渡さなくても実行された
LocalStackはLambdaの実行にDockerを使うので、コンテナにDockerソケットを渡す設定が要ります。AWS Emulatorでpython3.12の関数をzipで作って呼ぶと、その設定なしで0.53秒で返り、動いていたプロセスはaws-emulatorの1つだけでした。試したランタイムはPythonです。
イベントソースマッピングは、ロールの権限不足で一度断られた
ロールにSQSの権限を付けずにSQSとLambdaをつなぐと、InvalidParameterValueException(ReceiveMessageを呼ぶ権限がない)で止まりました。エミュレータが見たのは、つなぐときにロールが必要な権限を持っているかという1か所です。公式は、IAMポリシー全般は本物どおりに評価しないと明言しているので、権限の設計を確かめるテストには使えません。
AWSLambdaSQSQueueExecutionRoleを付けて作り直すと、溜まっていた2件が1秒以内に処理され、ログに2件の中身が出ました。
次は、同じ経路をTerraformとCDKで作ってみます。
TerraformとCDKは、AWS Emulatorにそのまま流せるか?
AWS provider 6系では、S3バケットだけがエラーで止まった
S3・DynamoDB・SQS・IAMロール・ポリシーの付与・Lambda・SQSとLambdaのつなぎの7個を、環境変数を設定したままterraform applyしました。AWS provider 6.73.0では6個が作れ、S3バケットだけがタグの読み出しでlookup 000000000000.127.0.0.1: no such hostと失敗しました。
タグの読み出しで呼ばれていたのは、S3 Controlという別のAPIです。S3 Controlの要求はSDKがホスト名にアカウントIDを付け、これはAWS_DISABLE_HOST_PREFIX_INJECTIONでも止められないので届かない、と公式ドキュメントにあります。
providerを5系に下げると、7個すべて作れた
terraform {
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
}
# 接続先は環境変数 AWS_ENDPOINT_URL などで AWS Emulator に向けている
provider "aws" {}5.100.0ではApply complete! Resources: 7 addedとなり、作ったキューに送るとLambdaまで届きました。6系のまま避ける方法は見つけていないので、5系に固定しています。
CDKはbootstrapからdeployまで通った
cdk bootstrapのあとcdk deployでS3・DynamoDB・SQS・Lambdaのスタックを作ると、9/9がCREATE_COMPLETEで7.59秒でした。普段のcdkコマンドのままで、Node.jsにはNODE_EXTRA_CA_CERTS=$HOME/.aws/emulator/9297/ca.pemで証明書を渡します。
CDKが使うCloudFormationは、本物との一致率を示す点数が19%しかないのに、です。この点数はどう読めばいいのでしょうか?
fidelity scoreで、使うサービスの再現度を先に見る
AWSは、本物のAWSで確かめた挙動を書いた短いテストを公開しています。エミュレータがそれを通った割合をサービスごとに出したものがfidelity scoreで、ステータスコードや作られたリソースまで本物と一致して、はじめて通過と数えます。
v1.0.322のリリースに添付されたscores.json.gzでは、全体の通過が56.5%でした。S3は63%、DynamoDBとSQSは68%、Lambdaは52%、CloudFormationは19%です。
自分のスタックが使うサービスは何%でしょうか?このファイルはGitHubのReleasesページで、各版のAssetsに付いています。中身はテスト1件ごとの記録なので、使う版のファイルを落として、たとえばS3なら次のように数えます。結果は1763 pass、1035 fail、16 skippedでした。
gunzip -c scores.json.gz \
| jq -r '.units[] | select(any(.services[]; test("^com.amazonaws.s3#"))) | .outcome' \
| sort | uniq -c点数が低いサービスほど、自分のスタックで試して確かめる
1つのテストが複数のサービスをまたぐこともあり、点数はそのサービスが出てくるテスト全体の率です。自分が使う操作だけの率ではありません。CloudFormationが19%でも、基本的なリソースを作るだけの今回のCDKスタックは通りました。
未実装の操作はHTTP 501のNotImplementedで止まるので見つけやすい一方、実装済みの操作が本物と同じ結果を返すかは、自分のスタックを流して確かめます。
LocalStackの代わりに使う前に、確かめておくこと
LocalStackの最新版は、認証トークンなしでは起動しない
LocalStackの最新版(2026.10.7)は、トークンなしだとLicense activation failed!で止まりました。2026年3月にCommunity版のリポジトリがアーカイブされ、認証トークンが必須の1つのイメージになったためです。トークンは無料のHobbyプランでも得られますが、Hobbyは非商用向けです。AWS Emulatorは本体のライセンスがCC0(パブリックドメインに近い扱い)です。
比べる相手は、トークンなしで起動できる最後の4系の4.14です。
同じboto3スクリプトで分かれたのは、Lambdaと権限の確認
S3・DynamoDB・SQSの基本操作と、失敗したときの返り方は両方とも同じでした。いまLocalStackで回しているテストがLambdaを含むなら、Dockerソケットの設定が要らなくなる分、移す手間は減ります。
4.14のLambdaは、Dockerソケットを渡さない今回の構成で失敗しました(渡した構成は試していません)。つなぐときの権限の確認は、AWS Emulatorが止め、4.14は通しました。
AWS Emulatorで本物と同じにならない所
- IAMポリシーは本物どおりに評価されないので、セキュリティのテストには使わない(公式の明言)
- 1アカウント・1リージョンの前提で使う
- リソースはメモリにあり、止めると消える
- エンドポイントは
127.0.0.1のままにする。localhostだと一部のSDKがS3のバケット名をホスト名に入れる - 証明書は
127.0.0.1とlocalhost向けなので、別のコンテナからホスト名で呼ぶと証明書エラーになる
最後の点は、呼ぶ側のコンテナをエミュレータのネットワークに相乗りさせると避けられました。--network container:<エミュレータ>で起動し、~/.aws/emulatorを共有すれば127.0.0.1のまま呼べます。docker composeのnetwork_mode: "service:<名前>"と同じ形です。
まずは自分のスタックが使うサービスの点数を見て、手持ちのテストを1本、AWS Emulatorに流してみてください。








コメント
ログイン か 会員登録 するとコメントできます