AWS EmulatorをUbuntuに入れて使い始める方法

​​AWS Emulator​AWS CLI,Boto3,Python,Ubuntu

AWS Emulator を Ubuntu に入れて起動し、環境変数をいくつか設定すると、AWS CLI や AWS SDK のリクエストが本物の AWS ではなく手元のエミュレーターに届くようになります。ローカル環境での開発やテスト、CI で、AWS のアカウントを使わずに S3 や DynamoDB などの API を呼びたいときの準備の手順です。入れ方、起動と停止、AWS CLI と Python(Boto3)を向ける設定、テレメトリーの切り方を、検証環境で実行したコマンドと出力のまま載せます。

補足

検証環境は Ubuntu 24.04(x86_64、glibc 2.39)、AWS Emulator 1.0.353(2026年11月14日リリース)、AWS CLI 2.40.3、Python 3.11 と Boto3 1.44.3 です。私は root で作業したので実際には sudo を付けていませんが、記事では一般のユーザー向けに sudo を付けて書いています。AWS のアカウントと認証情報は使っていません。本物の AWS での動きや料金は確かめておらず、記事で触れるところは公式ドキュメントを出どころにしています。Docker で動かす方法と、RPM のパッケージは試していません。

AWS Emulator は何をする道具か

AWS Emulator は、AWS の API を手元で受け付けるエミュレーターです。公式ドキュメントによると、AWS のアカウントは要らず、AWS Emulator そのものに追加の料金はかかりません。リクエストは AWS に送られず、エミュレーターの中に作られたリソースを相手にします。画面はなく、コマンドで起動して、AWS CLI や SDK の接続先を環境変数でエミュレーターに向けて使います。

Linux では RPM か Debian のパッケージ(x86_64 と aarch64)を入れて動かします。macOS と Windows では Docker で動かすと案内されています。Linux で動かすときの条件は、事前の確認のページによると、64ビットの Linux で glibc 2.17 以降です。glibc のバージョンは ldd --version で確かめられます。

text
$ ldd --version | head -1
ldd (Ubuntu GLIBC 2.39-0ubuntu8.9) 2.39

Debian パッケージを入れる

Linux 向けの手順には、パッケージをダウンロードして apt-get install で入れるコマンドが載っています。手順には、入れる前に gpg で署名を確かめる方法もあります。私はこちらで入れました。x86_64 の Ubuntu なので、ファイル名は aws-emulator_amd64.deb です(Arm なら aws-emulator_arm64.deb)。

bash
PACKAGE_FILE=aws-emulator_amd64.deb
curl -fsSLO https://downloads.aws.com/aws-emulator/packages/aws-emulator/LTS/latest/$PACKAGE_FILE
curl -fsSLO https://downloads.aws.com/aws-emulator/packages/aws-emulator/LTS/latest/$PACKAGE_FILE.sig
curl -fsSLo aws-publishing.asc https://downloads.aws.com/keys/gpg/current.asc
gpg --import aws-publishing.asc

取り込んだ鍵の指紋を gpg --fingerprint で表示し、公式の手順に書かれている 98BC F336 A3BE 53B7 34E9 67C5 2E5B F49B D940 F624 と同じかを確かめます。公式の手順では鍵に付いたメールアドレスで指定していますが、鍵のIDで指定しても同じ指紋が出ます(メールアドレスの入った uid の行は省略しています)。

text
$ gpg --fingerprint 2E5BF49BD940F624
pub   rsa4096 2026-07-20 [SC]
      98BC F336 A3BE 53B7 34E9  67C5 2E5B F49B D940 F624

指紋が同じなら、署名を確かめます。公開鍵のメールアドレスは伏せています。

text
$ gpg --verify $PACKAGE_FILE.sig $PACKAGE_FILE
gpg: Signature made Sat Nov 14 02:09:55 2026 UTC
gpg:                using RSA key 98BCF336A3BE53B734E967C52E5BF49BD940F624
gpg: Good signature from "SSM Publishing <(公開鍵のメールアドレス)>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 98BC F336 A3BE 53B7 34E9  67C5 2E5B F49B D940 F624

Good signature が出れば大丈夫です。その下の WARNING は、公式の手順によると、指紋を確かめていれば気にしなくてよいものです。BAD signature と出たときは、2つのファイルを消して、入れないようにと書かれています。

確かめたファイルを入れます。

text
$ sudo apt-get install -y ./$PACKAGE_FILE
(途中は省略)
Unpacking aws-emulator (1.0.353-1) ...
Setting up aws-emulator (1.0.353-1) ...

本体は /opt/aws-emulator/ に入り、/usr/bin/aws-emulator から呼べるようになります。aws-emulator -v でバージョンを確かめます。

text
$ aws-emulator -v
Version: 1.0.353
Release date: 2026.11.14
Commit: ca8a89dedfa8e4b5e67a3c90dc736f921ba409a1

AWS CLI がまだなければ、AWS CLI のインストール手順にある、zip を展開して ./aws/install を実行する方法で入れます。検証環境では aws-cli/2.40.3 が入りました。

起動して、待ち受けを確かめる

起動は aws-emulator です。オプションの -t off は、あとで説明するテレメトリーを切る指定です。

bash
aws-emulator -t off

エミュレーターはその端末で動き続けます。既定では 127.0.0.1:9297 で HTTPS を受け付けるので、届くのは同じマシンからだけです。検証環境では、起動の表示を確かめやすいように、標準出力と標準エラーを別のファイルに書き出してバックグラウンドで起動しました。標準出力には JSON の行が3つ出ました(ホームディレクトリのパスは ~ に置き換えています)。

text
{"timestamp":"2026-11-14T02:27:04.838003Z","level":"INFO","fields":{"message":"aws-emulator emulator starting"},"target":"aws_emulator"}
{"timestamp":"2026-11-14T02:27:04.921986Z","level":"INFO","fields":{"message":"request authentication enabled","credentials_file":"~/.aws/emulator/9297/emulator_credentials"},"target":"aws_emulator_server"}
{"timestamp":"2026-11-14T02:27:04.922102Z","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"}

emulator server information の行に、接続先の URL と、書き出したファイルの場所が出ています。コマンドリファレンスによると、スクリプトから読むときはこの行を使ってよく、ほかの行の形はリリースごとに変わることがあります。

起動が終わったかは、ヘルスチェックの URL で確かめられます。公式ドキュメントにある、1秒おきに最大30秒待つ書き方です。検証環境では1秒ほどで ok が返りました。

text
$ for i in $(seq 30); do curl -sf --cacert ~/.aws/emulator/9297/ca.pem https://127.0.0.1:9297/__admin/health && break; sleep 1; done; echo
ok

~/.aws/emulator/9297/ には4つのファイルができていました。どれも持ち主だけが読み書きできる権限(0600)です(持ち主の列は user に置き換えています)。

text
$ ls -l ~/.aws/emulator/9297/
total 16
-rw------- 1 user user 566 Nov 14 02:27 ca.pem
-rw------- 1 user user 143 Nov 14 02:27 config
-rw------- 1 user user 116 Nov 14 02:27 emulator_credentials
-rw------- 1 user user 551 Nov 14 02:27 truststore.p12

emulator_credentials はこの起動でだけ使えるアクセスキー、config は AWS CLI と SDK 向けの設定、ca.pem は HTTPS の証明書です。truststore.p12 は Java 向けに同じ証明書を入れたものです。config の中身は次のとおりでした(証明書のパスは ~ に置き換えています)。

text
[default]
region = us-east-1
endpoint_url = https://127.0.0.1:9297
ca_bundle = ~/.aws/emulator/9297/ca.pem
s3 =
  signature_version = s3v4

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

エミュレーターを動かしている端末とは別の端末で、公式ドキュメントにある環境変数を設定します。それぞれの変数が、さきほどのファイルを指します。

AWS_ENDPOINT_URL は 127.0.0.1:9297 を、AWS_SHARED_CREDENTIALS_FILE は emulator_credentials を、AWS_CONFIG_FILE は config を、AWS_CA_BUNDLE は ca.pem を指す
環境変数と、エミュレーターが書き出すファイルの対応
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_EC2_METADATA_DISABLED:EC2 の上でテストするときに、インスタンスメタデータから本物の認証情報を取りに行かないようにする
  • AWS_DISABLE_HOST_PREFIX_INJECTION:一部の API で、AWS CLI と Boto3 がホスト名の前に data- などを付けて、エミュレーターに届かなくなるのを止める。本物の AWS では逆にその API が失敗するので、エミュレーターを使うシェルだけで設定する
  • 最後の unset:アクセスキーの環境変数は認証情報ファイルより優先されるので、本物のキーが残っていると、それで署名されたリクエストをエミュレーターが断る

AWS_CONFIG_FILE を設定すると、そのシェルでは自分の ~/.aws/config の設定(リトライの設定など)が使われなくなる点にも触れられています。エミュレーターは起動のたびに config を書き直すので、設定を足したいときはコピーを作ってそちらを指すように、とのことです。

設定できたら、aws sts get-caller-identity で接続先を確かめます。エミュレーターに届いていれば、アカウントIDが0の12桁になり、ARN のユーザー名が emulator になります(下の出力では、0の並びを <12桁の0> と書いています)。

text
$ aws sts get-caller-identity
{
    "UserId": "AIDAH5I7GEMO7ADXNFAZU",
    "Account": "<12桁の0>",
    "Arn": "arn:aws:iam::<12桁の0>:user/emulator"
}

S3 のバケットを作って一覧を出すと、作ったバケットが返りました。

text
$ aws s3api create-bucket --bucket example-bucket
{
    "Location": "/example-bucket",
    "BucketArn": "arn:aws:s3:::example-bucket"
}
$ aws s3api list-buckets --query 'Buckets[].Name'
[
    "example-bucket"
]
注意

公式ドキュメントでは、AWS_ENDPOINT_URL が設定されていないシェルでコマンドを実行すると、見つかった認証情報を使って本物の AWS に送られると注意しています。本物の認証情報があるマシンでは、テストを動かすスクリプトの中で環境変数を設定し、テストの環境に本物の認証情報を置かないようにと書かれています。

unset を忘れたときの様子も見ておきます。アクセスキーの環境変数にダミーの値を入れたまま実行すると、エミュレーターは断りました。エラーの名前はサービスによって違い、STS では InvalidClientTokenId、S3 ではエミュレーターの鍵で署名するようにというメッセージの AccessDenied でした。

text
$ AWS_ACCESS_KEY_ID=DUMMYACCESSKEY AWS_SECRET_ACCESS_KEY=dummysecret aws sts get-caller-identity

aws: [ERROR]: An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation: The security token included in the request is invalid.
$ AWS_ACCESS_KEY_ID=DUMMYACCESSKEY AWS_SECRET_ACCESS_KEY=dummysecret aws s3api list-buckets

aws: [ERROR]: An error occurred (AccessDenied) when calling the ListBuckets operation: Sign the request with the emulator credentials

Python(Boto3)から使う

SDK も、同じ環境変数を読みます。コードに接続先や認証情報を書く必要はありません。AWS CLI と Boto3 は AWS_CA_BUNDLE で証明書を読むので、追加の設定も要りません。仮想環境を作って Boto3 を入れます。

bash
python3 -m venv .venv
. .venv/bin/activate
pip install boto3

検証環境では仮想環境の python と pip をパスで指定して実行しましたが、ここでは仮想環境を有効にした形で書いています。次のスクリプトは、STS で接続先を確かめてから、さきほどのバケットにオブジェクトを書き込んで読み出します。

python
import boto3

# 接続先・認証情報・証明書は、環境変数から読まれる(コードには書かない)
sts = boto3.client("sts")
print("Arn:", sts.get_caller_identity()["Arn"])

s3 = boto3.client("s3")
s3.put_object(Bucket="example-bucket", Key="hello.txt", Body="にゃー".encode())
print("Buckets:", [b["Name"] for b in s3.list_buckets()["Buckets"]])
body = s3.get_object(Bucket="example-bucket", Key="hello.txt")["Body"].read()
print("hello.txt:", body.decode())

環境変数を設定したシェルで実行すると、エミュレーターに届きました。AWS CLI で作ったバケットも見えています。

text
$ python list_buckets.py
Arn: arn:aws:iam::<12桁の0>:user/emulator
Buckets: ['example-bucket']
hello.txt: にゃー

ほかの言語の SDK では、証明書の読ませ方が違います。公式ドキュメントの表では、AWS SDK for JavaScript v3(Node.js)は NODE_EXTRA_CA_CERTS に ca.pem のパスを、Java は truststore.p12 を使う設定を入れるよう案内されています。

止める、起動し直す

止めるときは、起動した端末で Ctrl+C を押すか、プロセスに SIGTERM を送ります。検証環境で Ctrl+C の代わりに SIGINT を送ったところ、ログに shutdown signal received; stopping emulator server が出て、終了コード 0 で止まりました。SIGTERM でも同じく 0 でした。

止めると、~/.aws/emulator/9297/ の中のファイルは消えます(フォルダーは残りました)。アクセスキーのファイルもなくなるので、環境変数をそのままにしたシェルで AWS CLI を実行すると、認証情報が見つからないというエラーになりました。

text
$ ls -A ~/.aws/emulator/9297/ | wc -l
0
$ aws s3api list-buckets

aws: [ERROR]: An error occurred (NoCredentials): Unable to locate credentials. You can configure credentials by running "aws login".

作ったリソースはメモリーにだけ置かれているので、止めると消えます。もう一度 aws-emulator -t off で起動すると、さきほどのバケットは残っていませんでした。アクセスキーと証明書は作り直されますが、環境変数はファイルの場所を指しているだけなので、設定し直さずにそのまま使えました。

text
$ aws s3api list-buckets --query 'Buckets[].Name'
[]

AWS は、長い時間動かし続ける使い方や負荷テストでは試していないとしており、テストのたびに起動して終わったら止めるよう案内しています。止め忘れが心配なら、--idle-timeout <秒> を付けると、API の呼び出しがその秒数ないときに自分で止まります。--idle-timeout 3 で起動して何も呼ばずにおくと、3秒ほどで終了コード 0 で止まり、ファイルも消えていました。

同じポートでエミュレーターが動いているときに、もう1つ起動すると、ポートが使われているというエラーで終了コード 1 になりました。

text
$ aws-emulator -t off
(起動の行とテレメトリーの行は省略)
emulator serve failed: server I/O error: Address already in use (os error 98)

別のポートで動かすときは -p で指定します。aws-emulator -t off -p 9300 で起動すると、接続先は https://127.0.0.1:9300 になり、~/.aws/emulator/9300/ のフォルダーができました。このときは、環境変数の 9297 をすべて 9300 に変えます。

テレメトリーで送るもの・送らないものと、切り方

AWS Emulator は、初期設定で使われ方のデータ(テレメトリー)を AWS に送ります。テレメトリーのページによると、送るのは次のようなデータで、値はどれもランダムな ID、数値、決まった選択肢の中の値です。

  • インストールごと・起動ごとのランダムな ID(アカウントやハードウェア、ネットワークからは作らない)
  • OS と CPU の種類、リクエストを送った SDK やツールの名前とバージョン、使ったリージョン、入れ方、オンにしている追加の機能、コンテナや CI の中で動いているか、エミュレーターを動かしている AI のコーディングアシスタントの種類
  • エミュレーターのバージョン
  • API の操作ごとの呼び出し回数と結果(成功、クライアントのエラーなど。エラーは種類だけ)、応答時間の最小・最大・合計
  • メモリー使用量の範囲や起動時間などの性能、クラッシュしたときの種類

送らないものとして、リクエストやレスポンスの中身、リソースの名前・ARN・キー・ファイルのパス、環境変数や設定ファイルの値、認証情報やコード、エラーメッセージ、アカウントIDや個人のデータが挙げられています。データは TLS で AWS の受け口に送られ、第三者には共有せず、最長90日保管すると書かれています。送るのは5分おきと、止めるときです。IP アドレスは、受け口を乱用から守るためにネットワークの入り口でだけ使い、テレメトリーの記録には入らないとされています。また、起動したときにテレメトリーのオン・オフを知らせる1行を出し、その行より前には何も送らないとあります。

公式ドキュメントには、Rust のテストに組み込んで使う場合を含めて4つの切り方があり、Linux で動かすときに使うのは次の3つです。どれか1つでも設定すればオフになります。

  1. 起動のオプションで切る:aws-emulator -t off(--telemetry off の短い形)。その起動だけに効きます。
  2. 環境変数で切る:export EMULATOR_TELEMETRY=off。そのシェルから起動するエミュレーターすべてに効きます。
  3. 設定ファイルで切る:~/.aws/emulator/config.toml に次の2行を書きます。そのマシンでのすべての起動に効きます。
toml
[telemetry]
enabled = false

検証環境で3つとも試したところ、標準エラーに出る知らせの行は、どれも disabled になっていました。括弧の中には切った設定が出ます。-t off のときは the embedding configuration と表示されました(設定ファイルのパスは ~ に置き換えています)。

text
This emulator collects usage and error telemetry: disabled (via the embedding configuration) — to turn it back on, remove every opt-out setting and restart
This emulator collects usage and error telemetry: disabled (via EMULATOR_TELEMETRY=off) — to turn it back on, remove every opt-out setting and restart
This emulator collects usage and error telemetry: disabled (via ~/.aws/emulator/config.toml) — to turn it back on, remove every opt-out setting and restart

公式ドキュメントによると、オフのときは何も送らず、インストールの ID と送る前にためたデータ(~/.aws/emulator/telemetry/ に置かれる)も消します。検証環境では、最初からオフで起動していたので、このフォルダーは作られていませんでした。

使わなくなったら外す

パッケージを外すのは apt-get remove です。エミュレーターが動いていれば、先に止めておきます。検証環境では、外したあと aws-emulator のコマンドはなくなりましたが、~/.aws/emulator/ にはポートごとのフォルダーと config.toml が残っていました。これも消すなら、公式の手順にある rm -rf ~/.aws/emulator を実行します。

bash
sudo apt-get remove -y aws-emulator
rm -rf ~/.aws/emulator

エミュレーターは開発とテストのためのもので、公式ドキュメントでは本番のワークロードに使わないよう書かれています。IAM のポリシーも AWS と同じようには判定しないので、セキュリティの確認に使わないようにとも書かれています。AWS とどこまで同じに動くかの考え方は公式ドキュメントの忠実度(Fidelity)のページにあり、サービスごとの結果は GitHub のリリースページにリリースのたびに載ります。

​Posted by 86