一句話結論:AWS Emulator 是 AWS 官方在 2026 年 11 月 11 日發布的本機 AWS API 模擬器,CC0 釋出、不用 AWS 帳號、安裝後一行 aws-emulator 就在 127.0.0.1:9297 起一個 HTTPS 端點,把 SDK 的 AWS_ENDPOINT_URL 指過去就能跑測試;它不評估 IAM、只支援單一 Region,資料全在記憶體,關掉就清空。
對每天要跑整合測試的人來說,這個組合很香:不用註冊、不用 auth token、不用為 CI 買訂閱。但它同時也是 AWS 第一次把「測試環境」這件事當成自家產品來做,背後的故事比工具本身更有意思——整份程式碼沒有任何一行是人寫的。
為什麼現在特別值得看:LocalStack 改制後的真空
長年以來,本機跑 AWS 的預設答案是 LocalStack。但它在 2026 年 3 月 23 日改成單一鏡像:Community 與 Pro 合併,現行版本需要 LocalStack 帳號與 auth token(CI 也一樣),免費 Hobby 方案限非商業用途、涵蓋約 30 個服務,開源社群版原始碼則停止在 v4.14.0。第三方整理的價目(2026-10 查證)是 Base 方案年繳每月 39 美元、Ultimate 每月 89 美元;實際價格與條款以 LocalStack 官方頁面為準。
同一時間,另一個常見選擇 moto 仍是 Apache 2.0 的 Python 函式庫,主要用法是在同一個 Python 程序裡 mock boto3 呼叫(也能以 server 模式跑在 5000 埠)。
AWS Emulator 切入的正是這個缺口:免費、不需帳號、不綁語言,而且它自己就是官方 API model 的產物。
| 工具 | 授權與費用 | 需要帳號/token | 定位 |
|---|---|---|---|
| AWS Emulator | CC0-1.0(vendor/ 為 Apache-2.0) | 不需要 | 獨立 HTTPS 伺服器,任何 SDK/CLI 改 endpoint 即可 |
| LocalStack | 現行版本需訂閱;Hobby 免費但限非商業 | 需要帳號與 auth token(含 CI) | 獨立伺服器,服務數依方案分級 |
| moto | Apache 2.0 | 不需要 | Python 函式庫(可另跑 server 模式) |
一表看懂:這個東西有多大
以下數字是本次實測時以 GitHub API 與官方 release 取得(2026-11-11):
| 項目 | 內容 |
|---|---|
| 最新版本 | v1.0.322(release 2026-11-11 00:32 UTC,aws-emulator -v 顯示 release date 2026.11.10、commit 7753983c) |
| 授權 | CC0-1.0(vendor/ 目錄為 Apache-2.0) |
| 語言 | Rust,repo 於 2026-09-11 建立 |
| 社群熱度 | 611 stars、11 forks、2 個 open issue(上線首日,數字僅供參考) |
| 程式規模 | services/ 下有 437 個 crate,整份檔案樹 44,143+ 個檔案(API 回傳已截斷,實際更多) |
| 服務覆蓋 | 官方稱 400+ 個 API model、200+ 個 AWS 服務 |
| 已知缺口 | issues/things-that-do-not-work/ 6,545 筆、已修 things-that-now-work/ 12,709 筆 |
| 套件大小 | Debian 套件 164 MB,解開後 928 MB |
| 執行方式 | 本機 HTTPS 127.0.0.1:9297(自簽憑證)、Docker 容器、或 Rust 測試內嵌模式 |
| 實測延遲 | list_buckets 20 次中位數 1.52 ms(min 1.32/max 4.5) |
| 實測記憶體 | 啟動後閒置 RSS 281 MiB(官方文件稱約 160 MiB) |
那個 release note 值得點開看:v1.0.322 一次列了 215 條 fix:,內容從 cognito-idp、iam、bedrock-agent 到 dynamodb 的錯誤訊息措辭都有。官方文件寫「更新一天多次」,這個 commit 頻率是真的。
它是怎麼被做出來的(這段比工具本身更值得讀)
AWS 的 Sr. Principal Engineer Matt Goldberg 在官方文章裡描述流程:
- AWS 的公開 API model(Smithy 格式)就是規格書,真實 AWS 就是參考實作。
- 代理先寫「保真度測試(fidelity test)」——一段用 SDK 跑工作流程、斷言 AWS 行為(含錯誤碼與訊息)的程式,反覆修正到「在真實 AWS 上通過」,這樣測試就記錄了 AWS 的真實行為。
- 代理再改模擬器,讓它通過同一批測試。沒過的測試就是缺口,被寫成 issue 進 repo。
- 每個變更都要過 merge gate:多個安全代理從不同攻擊角度做對抗式審查,加上確定性檢查阻止代理改動不該改的檔案。
他從 SQS 開始,給 Kiro 一段提示,約 15 分鐘就生出一個可用的 SQS 模擬器;內部版一個週末成形、一個月內開始被採用。Werner Vogels 在部落格補了前傳:2004 年他和 Al Vermeulen 用 JVM 模擬 Alf 鎖服務的環境,把封包丟失、故障注入都做進同一個程式裡,因為「併發 bug 只在特定事件順序出現」。二十年後,同一件事變成 200 多個服務、每個都要有測試環境,手寫不可能,於是把「造環境」也交給代理。
理解這條脈絡,就能理解它的能力邊界:它逼近的是「API 的線上行為」,不是「AWS 的治理模型」。所以 IAM 政策不評估、跨 Region 不隔離,這些不是偷懶,而是保真度測試目前主要覆蓋控制平面(control plane)API 的結果。
三種跑法,先選一種
| 方式 | 適用 | 取得方式 |
|---|---|---|
| Linux 原生套件 | Ubuntu/Debian/RHEL 系,測試機或開發機 | RPM 或 Debian 套件 |
| Docker 容器 | macOS、Windows、不想動系統的 Linux | 官方提供 Dockerfile,自己 build(沒有預載映像) |
| Rust 內嵌模式 | 用 AWS SDK for Rust 寫測試 | 加成 dev-dependency,一個測試一個實例 |
Linux 套件(官方指令原文)
Debian/Ubuntu(amd64):
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 -v
RHEL/Amazon Linux(x86_64;ARM 換 aarch64):
sudo dnf install -y https://downloads.aws.com/aws-emulator/packages/aws-emulator/LTS/latest/aws-emulator-x86_64.rpm
套件會裝到 /opt/aws-emulator/,並把 aws-emulator 放進 /usr/bin/。官方也提供 GnuPG 簽章驗證(金鑰指紋 98BC F336 A3BE 53B7 34E9 67C5 2E5B F49B D940 F624),在受管環境值得做。
本次實測沒有把套件裝進系統,而是用 dpkg-deb -x 解到暫存目錄直接執行——這在不能改動系統套件、或想同時留著舊版對照的情境很好用:
curl -fsSL -o /tmp/aws-emulator.deb https://downloads.aws.com/aws-emulator/packages/aws-emulator/LTS/latest/aws-emulator_amd64.deb
dpkg-deb -x /tmp/aws-emulator.deb /tmp/emudir
/tmp/emudir/opt/aws-emulator/bin/aws-emulator -v
實測輸出:
Version: 1.0.322
Release date: 2026.11.10
Commit: 7753983c6e495ec3612695b1336bf4936fc7b7fd
Docker(macOS、Windows 用這條)
官方不發布預載映像,要在空目錄自己建一個 Dockerfile:
FROM public.ecr.aws/amazonlinux/amazonlinux:2023-minimal
ADD https://downloads.aws.com/aws-emulator/packages/aws-emulator/LTS/latest/aws-emulator-x86_64.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"]
Apple silicon 或 Arm 機器要把 aws-emulator-x86_64.rpm 換成 aws-emulator-aarch64.rpm。跑起來時有兩個容易忽略的細節:
- 一定要寫
-p 127.0.0.1:9297:9297,不要寫-p 9297:9297——後者等於開放給整個網段。 - 必須把
~/.aws/emulator掛進容器,否則 SDK 讀不到模擬器產生的憑證與憑證檔。
把 SDK 指過去
模擬器啟動時會產生一組只用於這次執行的 access key/secret,並把設定檔、憑證與 CA 憑證寫到 ~/.aws/emulator/<port>/:
ca.pem # 自簽 CA
config # SDK 設定(含 endpoint_url、ca_bundle)
emulator_credentials # 本次執行專用的假金鑰
truststore.p12 # 給 Java 用
把這些環境變數設好,程式碼完全不用改:
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
那行 unset 別省。環境變數的優先序高於憑證檔,留著真的金鑰會讓 SDK 用真帳號簽章,模擬器會直接拒收(這是好事,但錯誤訊息不好懂)。健康檢查:
curl --cacert ~/.aws/emulator/9297/ca.pem https://127.0.0.1:9297/__admin/health
# ok
實測:S3、DynamoDB、SQS 一輪跑通
用 boto3 1.44.0 打模擬器,程式碼一個字都沒改(只吃環境變數):
| 測試 | 結果 |
|---|---|
s3.create_bucket | HTTP 200,首呼叫約 38 ms |
s3.list_buckets | 回 ['most-tw-test-bucket'] |
s3.put_object / get_object | 內容正確取回 |
dynamodb.create_table(名稱 2 字元) | ValidationException,訊息與 AWS 逐字相同:「Member must have length greater than or equal to 3」 |
dynamodb.create_table(正常) | 第一次 describe 回 CREATING,第二次回 ACTIVE |
dynamodb.put_item / get_item / scan | 200、資料正確、Count: 1 |
sqs.create_queue / send_message / receive_message | 收到訊息;立刻第二次 receive 回 0 筆(visibility timeout 行為與真 AWS 一致) |
lambda.list_functions | 回空陣列 [](已實作、無函式) |
延遲(20 次 list_buckets) | 中位數 1.52 ms、最快 1.32 ms、最慢 4.5 ms |
那個 CREATING → ACTIVE 的狀態機是刻意做的。第一次建表後馬上 put_item,會拿到 ResourceNotFoundException: Requested resource not found——跟真 AWS 一樣,表格還沒 ACTIVE 就不能寫。反過來說,這也代表測試裡該有的 waiter 一個都不能省,模擬器不會幫你把狀態直接設成可寫。
延遲這一項是本機工具的真正價值:同一個 list_buckets 打到真實 AWS,光 TLS 握手加跨區往返就是 100 ms 等級;在模擬器上是 1.5 ms。整合測試如果一次跑幾百個呼叫,差距會出現在 CI 的總時長上。
實測踩到的坑
1. 閒置記憶體比文件寫的高。官方文件說閒置約 160 MiB,本次在 Ubuntu 24.04/x86_64 上剛啟動、只做過健康檢查,ps 量到的 RSS 是 281 MiB;跑完 S3/DynamoDB/SQS 一輪後是 315 MB。差距可能來自版本、配置或量測方式,但規劃 CI 記憶體時建議以 300–500 MiB 起算,別照文件抓 160。
2. 設定檔自帶 endpoint_url,會蓋掉你的預期。~/.aws/emulator/9297/config 內容是:
[default]
region = us-east-1
endpoint_url = https://127.0.0.1:9297
ca_bundle = /root/.aws/emulator/9297/ca.pem
s3 =
signature_version = s3v4
因為 AWS_CONFIG_FILE 指向它,就算把 AWS_ENDPOINT_URL unset 掉,SDK 還是會打到模擬器。要驗證「真的打到雲端」得連 AWS_CONFIG_FILE 一起清掉,否則會得到「看起來成功、其實在打本機」的假綠燈。
3. 憑證每次啟動都換。金鑰只對這一次執行有效,重啟後舊的在背景執行的測試會全部 401。CI 裡的順序必須是「先起模擬器、再匯出變數、最後跑測試」。
4. 資料只在記憶體,關掉就沒了。這是設計,不是 bug:Ctrl+C 之後 ~/.aws/emulator/<port>/ 會被刪除,資源全部消失。好處是每個測試乾淨、壞處是不能拿它當「本機 dev 的持久環境」。
5. 一個 Region、一個帳號。它接受任何 Region 與 account ID,但不分開保存資源。要測多 Region 就多起幾個實例(-p 9300、-p 9301…),每個實例有自己的目錄與狀態。
6. 遙測預設是開的。它會上報匿名使用量與錯誤(不含請求內容、程式碼、憑證)。要關掉有三種方式:啟動參數 --telemetry off、環境變數 EMULATOR_TELEMETRY=off、或寫進 ~/.aws/emulator/config.toml:
[telemetry]
enabled = false
在受管環境或 CI 裡,建議一開始就關——不是因為它收集了什麼敏感東西,而是預設開的東西遲早要寫進資安政策文件。
它明確不能做的事
官方文件自己列得相當清楚,這段值得原文照抄進團隊的評估文件:
| 限制 | 實務意義 |
|---|---|
| 不評估 IAM 政策 | 不能拿它測權限。想驗「這個角色能不能讀那個 bucket」,測了也不算 |
| 只有單一 Region 與帳號 | 跨區複寫、跨帳號存取的邏輯測不出來 |
| 保真度依服務而異 | 控制平面(建立/描述/列表)最接近 AWS,資料平面與 IaC 工具支援度不一 |
| 只對 us-west-2 驗證(全域服務用 us-east-1) | 其他 Region 的服務差異不會反映 |
未實作的操作回 HTTP 501 NotImplemented | 測試會立刻失敗,不會靜默通過——這點是好的 |
| 未針對長時間執行與壓測驗證 | 建議一個測試生命週期起停一次,或用 --idle-timeout 自動收 |
| 資源佔用你的機器記憶體 | 需要限額可用 systemd-run 或 Docker 的 --memory |
那個「未實作回 501」的設計比聽起來重要。多數 mock 工具的失敗模式是「回一個看起來合理的空結果」,測試因此假性通過;501 會讓測試直接紅,你才會知道該換方法。
CI 怎麼接
官方推薦的形狀很單純:起模擬器 → 等健康檢查 → 跑測試 → 停。等待迴圈官方文件直接給了:
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
放到 GitHub Actions 大概是這樣(步驟順序是重點,不是語法):
- name: Install AWS Emulator
run: |
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
- name: Start emulator
run: |
EMULATOR_TELEMETRY=off aws-emulator > /tmp/emulator.log 2>&1 &
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
- name: Run integration tests
run: pytest tests/integration
env:
AWS_ENDPOINT_URL: https://127.0.0.1:9297
AWS_SHARED_CREDENTIALS_FILE: /home/runner/.aws/emulator/9297/emulator_credentials
AWS_CONFIG_FILE: /home/runner/.aws/emulator/9297/config
AWS_CA_BUNDLE: /home/runner/.aws/emulator/9297/ca.pem
AWS_EC2_METADATA_DISABLED: "true"
AWS_DISABLE_HOST_PREFIX_INJECTION: "true"
AWS_REGION: us-east-1
要加速可以把它包成 Docker 映像推到自己的 registry(官方不提供預載映像),或把 928 MB 的執行檔用 CI 快取存起來。
誰適合,誰不需要
適合:有 boto3/AWS SDK 整合測試要跑、不想為 CI 付訂閱、不想讓測試帳號碰到真雲端、想讓 AI 編碼代理在本地自我驗證(官方甚至提供了 aws emulator 的 agent skill:aws agent-toolkit add-skill --skill-name aws-emulator)。
不需要:要驗 IAM/SCP/資源政策的(工具做不到)、要測跨 Region 行為的、要一個「本機持久 development 環境」的、或已經有穩定 LocalStack 付費流程且不想搬的。對最後一種,AWS Emulator 目前最大的價值是「第二意見」——同一個測試跑兩個模擬器,找出哪些行為其實是自己假設出來的。
它上線第一天有 611 顆星與兩個 open issue,數字還很年輕;但 CC0、官方 API model、一天多次更新的組合,是這個類別裡過去看不到的。對絕大多數「只想讓測試跑起來」的情境,這已經足夠。
站內延伸閱讀
- Docker Compose 完整教學 2026:compose.yaml 到 AI models
- GitHub Actions 完整教學 2026
- 自架 S3 物件儲存完整教學:Garage、SeaweedFS、RustFS 比較
(利益揭露:本文無聯盟連結。文中版本號、星數、issue 數與 release 內容為 2026-11-11 以 GitHub API 與官方頁面查得;延遲與記憶體為同一日在 Ubuntu 24.04/x86_64、2 vCPU 環境的單機實測,數字會隨硬體與版本變動。)
