AWS Emulator がリリースされたので試してみた

AWS Emulator がリリースされたので試してみた

AWS が公開したローカル用エミュレータ AWS Emulator を Docker で起動し、S3・SQS・DynamoDB・Lambda の基本操作を試しました。起動にかかった時間は約0.26秒、アイドル時のメモリ使用量は約174MiB でした。
2026.11.12

はじめに

AWS は2026年11月11日に、ローカル用のエミュレータ AWS Emulator の提供開始を発表しました。

https://aws.amazon.com/about-aws/whats-new/2026/11/aws-emulator-now-available/

この記事では、AWS Emulator v1.0.322 を Docker で起動し、AWS SDK や AWS CLI の呼び出し先をローカルの AWS Emulator のエンドポイントに切り替えて、S3・SQS・DynamoDB・Lambda の基本操作を実行しました。

あわせて、起動時間、メモリ使用量、イメージサイズを、OSS のローカルエミュレーターである Floci 2.4.0 と比較しました。

起動と接続

イメージのビルド

Docker 用のビルド済みイメージはなく、User Guide の Dockerfile からビルドします。今回は aarch64 のホストで試したため、ADD 行の RPM だけを aarch64 用に変えています。

https://docs.aws.amazon.com/emulator/latest/userguide/getting-started-docker.html

Dockerfile という名前で次の内容を保存します。

Dockerfile(aarch64 用)
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"]

この Dockerfile は aarch64 用です。x86_64 のホストでは、User Guide に掲載されている Dockerfile をそのままご利用ください。

Dockerfile のあるディレクトリを指定してビルドします。

docker build -t aws-emulator:verify <Dockerfile のあるディレクトリ>

コンテナの起動

マウントするのは専用のディレクトリです。ホストの ~/.aws 配下は使いません。

SHARE="$PWD/aws-emulator-share"
mkdir -p "$SHARE"
docker run -d --rm --name aws-emulator-verify --memory=2g --memory-swap=2g \
  -p 127.0.0.1:9297:9297 --user "$(id -u):$(id -g)" \
  -e EMULATOR_TELEMETRY=off \
  -v "$SHARE:/home/emulator/.aws/emulator" \
  aws-emulator:verify -p 9297

起動直後は接続できないため、/__admin/health が HTTP 200 を返すまで次のループで待ちます。

for i in $(seq 30); do
  curl -sf --cacert "$SHARE/9297/ca.pem" https://127.0.0.1:9297/__admin/health && break
  sleep 1
done

AWS CLI の向け先

向け先は環境変数で切り替えます。次の内容を env-emulator.sh として保存します。このスクリプトは変数 SHARE を参照するため、前の手順で SHARE を設定したシェルで読み込みます。

env-emulator.sh
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_PROFILE
_S="$SHARE/9297"
export AWS_ENDPOINT_URL=https://127.0.0.1:9297
export AWS_SHARED_CREDENTIALS_FILE="$_S/emulator_credentials"
export AWS_CONFIG_FILE="$_S/config"
export AWS_CA_BUNDLE="$_S/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

読み込んでから、呼び出しがエミュレータに届いていることを確認します。

source env-emulator.sh
aws sts get-caller-identity
{
    "Account": "000000000000",
    "Arn": "arn:aws:iam::000000000000:user/emulator"
}

000000000000 はエミュレータの固定アカウント ID です。

動作確認

以降のコマンドは、環境変数を読み込んだシェルで実行しました。

S3

バケットの作成、標準入力からのアップロード、一覧の取得、ダウンロードは、いずれも通常の aws s3 コマンドで実行できました。data0.json の中身は {"hello":"world"} です。

aws s3 mb s3://my-bucket
cat data0.json | aws s3 cp - s3://my-bucket/data.json
aws s3 ls s3://my-bucket
aws s3 cp s3://my-bucket/data.json ./downloaded.json && cat downloaded.json
make_bucket: my-bucket
2026-11-12 10:52:34         18 data.json
{"hello":"world"}

次に、バージョニングを有効にしました。そのうえで、内容が {"hello":"world","version":2} の data2.json を同じキーに上書きし、バージョン一覧を取得しました。

aws s3api put-bucket-versioning --bucket my-bucket --versioning-configuration Status=Enabled
aws s3 cp data2.json s3://my-bucket/data.json
aws s3api list-object-versions --bucket my-bucket
        {
            "Size": 30,
            "Key": "data.json",
            "VersionId": "<version-id>",
            "IsLatest": true
        },
        {
            "Size": 18,
            "Key": "data.json",
            "VersionId": "null",
            "IsLatest": false
        }

有効化前にアップロードしたオブジェクトの VersionId は、文字列の "null" でした。

presign URL は、パス形式の https URL で発行されました。認証情報と署名はマスクしています。

aws s3 presign s3://my-bucket/data.json --expires-in 3600
https://127.0.0.1:9297/my-bucket/data.json?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=<masked>&X-Amz-Date=20261112T015236Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=<masked>

curl の --cacert にエミュレータの ca.pem を渡してこの URL にアクセスすると、HTTP 200 で最新バージョンの内容が返りました。

URL=$(aws s3 presign s3://my-bucket/data.json --expires-in 3600)
curl -s -w "\nhttp_code=%{http_code}\n" --cacert "$SHARE/9297/ca.pem" "$URL"
{"hello":"world","version":2}

http_code=200

SQS

標準キューを作成すると、QueueUrl のホストは sqs.us-east-1.amazonaws.com でした。URL に含まれる 000000000000 も、エミュレータの固定アカウント ID です。

aws sqs create-queue --queue-name orders
{
    "QueueUrl": "https://sqs.us-east-1.amazonaws.com/000000000000/orders"
}

この URL をそのまま --queue-url に渡して、送信と受信ができました。受信の応答は、本文と受信回数の部分だけを抜粋しています。

aws sqs send-message \
  --queue-url https://sqs.us-east-1.amazonaws.com/000000000000/orders \
  --message-body '{"event":"order.placed","id":"abc123"}'
aws sqs receive-message \
  --queue-url https://sqs.us-east-1.amazonaws.com/000000000000/orders \
  --max-number-of-messages 10 \
  --attribute-names All
{
    "Messages": [
        {
            "Body": "{\"event\":\"order.placed\",\"id\":\"abc123\"}",
            "Attributes": {
                "ApproximateReceiveCount": "1"
            }
        }
    ]
}

FIFO キューも作成でき、一覧に含まれました。

aws sqs create-queue --queue-name orders.fifo --attributes FifoQueue=true
aws sqs list-queues
{
    "QueueUrls": [
        "https://sqs.us-east-1.amazonaws.com/000000000000/orders",
        "https://sqs.us-east-1.amazonaws.com/000000000000/orders.fifo"
    ]
}

DynamoDB

テーブルを作成し、応答からテーブルの状態(TableStatus)だけを取り出しました。

aws dynamodb create-table \
  --table-name Users \
  --attribute-definitions AttributeName=userId,AttributeType=S \
  --key-schema AttributeName=userId,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST \
  --query TableDescription.TableStatus \
  --output text
CREATING

状態が CREATING だったため、aws dynamodb wait table-exists で ACTIVE になるまで待ちました。待ち時間は、前後に date で時刻を出力して測っています。

date +%H:%M:%S.%N
aws dynamodb wait table-exists --table-name Users
echo "wait_exit=$?"
date +%H:%M:%S.%N
aws dynamodb describe-table --table-name Users --query Table.TableStatus --output text
11:06:37.290630503
wait_exit=0
11:06:40.244624834
ACTIVE

waiter は約3秒で戻りました。続けて、アイテムの登録、取得、scan を実行しました。

aws dynamodb put-item --table-name Users --item '{"userId":{"S":"u1"},"name":{"S":"Alice"},"age":{"N":"30"}}'
aws dynamodb put-item --table-name Users --item '{"userId":{"S":"u2"},"name":{"S":"Bob"},"age":{"N":"20"}}'
aws dynamodb get-item --table-name Users --key '{"userId":{"S":"u1"}}'
{
    "Item": {
        "name": {
            "S": "Alice"
        },
        "userId": {
            "S": "u1"
        },
        "age": {
            "N": "30"
        }
    }
}

age が25より大きいという条件で scan すると、ScannedCount が2件、Count が1件でした。

aws dynamodb scan \
  --table-name Users \
  --filter-expression 'age > :min' \
  --expression-attribute-values '{":min":{"N":"25"}}'
    "Count": 1,
    "ScannedCount": 2,

Lambda

IAM ロールは作成せず、ロールの ARN だけを指定して、ランタイムが nodejs22.x の関数を作成しました。関数コードの index.mjs は、この節の末尾に載せています。

zip function.zip index.mjs
aws lambda create-function \
  --function-name my-function \
  --runtime nodejs22.x \
  --role arn:aws:iam::000000000000:role/lambda-role \
  --handler index.handler \
  --zip-file fileb://function.zip \
  --query '{FunctionName:FunctionName,Runtime:Runtime,Handler:Handler,State:State}'
{
    "FunctionName": "my-function",
    "Runtime": "nodejs22.x",
    "Handler": "index.handler",
    "State": "Pending"
}

State が Pending だったため、aws lambda wait function-active-v2 で待ち、DynamoDB と同じく前後の時刻を出しました。

date +%H:%M:%S.%N
aws lambda wait function-active-v2 --function-name my-function
echo "wait_exit=$?"
date +%H:%M:%S.%N
aws lambda get-function-configuration --function-name my-function --query '{State:State,LastUpdateStatus:LastUpdateStatus}'
11:06:42.621728900
wait_exit=0
11:06:43.992666608
{
    "State": "Active",
    "LastUpdateStatus": "Successful"
}

waiter は約1.4秒で戻りました。

同期で Invoke すると、StatusCode 200 が返り、response.json に関数の戻り値が入っていました。

aws lambda invoke \
  --function-name my-function \
  --payload '{"key":"value"}' \
  --cli-binary-format raw-in-base64-out \
  response.json
cat response.json
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
{"statusCode":200,"body":"{\"hello\":\"world\",\"received\":{\"key\":\"value\"}}"}
index.mjs
export const handler = async (event) => {
  console.log("Event:", JSON.stringify(event));
  return { statusCode: 200, body: JSON.stringify({ hello: "world", received: event }) };
};

対応サービス数

AWS CLI 2.40.0 の aws help で確認できる435のサービスのうち、AWS Emulator v1.0.322 のモデルが無いのは importexport(AWS Import/Export)と sdb(Amazon SimpleDB)の2件だけでした。

リソース消費

計測条件

OSS 実装の AWS エミュレーター Floci と、リソース消費などを比較しました。

https://github.com/floci-io/floci

計測には、ほかのコンテナも動いている aarch64 の Linux 作業機を使いました。Docker のバージョンは 29.9.3 です。AWS Emulator と Floci のどちらにも --memory=2g --memory-swap=2g を指定し、ポートは 127.0.0.1 だけに公開しました。AWS Emulator は自分でビルドしたイメージ、Floci は floci/floci:2.4.0 のイメージを使っています。

起動時間は、docker run の開始から HTTP 200 が返るまでの時間です。AWS Emulator は /__admin/health、Floci は http://127.0.0.1:4566/ に問い合わせました。ポーリングは0.02秒間隔で、イメージのビルド時間は含みません。この値は別途計測したもので、「コンテナの起動」の1秒間隔のループでかかった時間ではありません。

アイドル時メモリは、起動から約10秒後(AWS Emulator)と約16秒後(Floci)に取得しました。S3 バケットを作成した後にも、同じ方法で取得しています。メモリは docker stats --no-stream の MEM USAGE 列、イメージサイズは docker image ls の DISK USAGE 列の値です。

docker stats --no-stream --format 'table {{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.CPUPerc}}\t{{.PIDs}}' aws-emulator-verify
docker image ls aws-emulator:verify

docker stats --no-stream --format 'table {{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.CPUPerc}}\t{{.PIDs}}' floci-verify
docker image ls floci/floci:2.4.0
Floci の起動コマンド
docker run -d --rm --name floci-verify --memory=2g --memory-swap=2g \
  -p 127.0.0.1:4566:4566 \
  --tmpfs /app/data \
  floci/floci:2.4.0

計測結果

各値は1回だけ測定した結果です。

指標 AWS Emulator v1.0.322 Floci 2.4.0
起動時間 0.257秒 0.431秒
アイドル時メモリ 173.9MiB 34.12MiB
S3 バケット作成後のメモリ 177.6MiB 37.62MiB
イメージサイズ(DISK USAGE) 1.62GB 367MB

まとめ

AWS Emulator の ARM 版を Docker 環境上で動かし、S3・SQS・DynamoDB・Lambda の基本操作を AWS CLI から実行できることを確認できました。

AWS サービスのローカルエミュレーターには、LocalStack やオープンソースプロジェクトの Floci があります。AWS Emulator が AWS 純正ツールとしてリリースされたことで、高い再現性や新機能への追従、サポートの向上にも期待できます。

https://dev.classmethod.jp/articles/floci-two-months-52-services-update/

https://dev.classmethod.jp/articles/floci-localstack-alternative-aws-emulator-try/

AWS Emulator v1.0.322 で提供されるモデルは433と充実していますが、IAM ポリシーとリソースベースのポリシーなど、実サービスと異なる仕様に留意しつつ、AWS サービスのローカル開発や CI などでご活用ください。

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事