カミナシ エンジニアブログ

株式会社カミナシのエンジニアが色々書くブログです

もし、今からAWSのエミュレーターを選ぶならどれにする?

はじめに

カミナシでエンジニアリングマネージャーをしてます、すずけん(@szk3)です。

唐突ですが、皆さん AWSのエミュレーター使ってますか?

自チームのプロダクトはS3、DynamoDB、STS、IAM あたりの AWS サービスに依存していて、ローカル開発やテストではこれらのエミュレーターを使っています。ただ、歴史的な背景からリポジトリには LocalStack、RustFS、Moto の 3 種が混在していて、用途ごとに考えることが地味に増えてしまった状態でした。

この記事では、その 3 種を Moto に統一した経緯と、検討した他の候補、そして移行から少し経った今でも次の選択肢を検討し続けているよ、という話をシェアします。

統合前の構成

ローカル開発とテスト環境では、目的ごとに違うエミュレーターを利用していました。

エミュレーター 用途 対象 AWS サービス
LocalStack ローカル開発 (docker-compose) + E2E テスト S3, DynamoDB, STS, IAM
RustFS シナリオテスト (testcontainers) S3
Moto 単体テスト (testcontainers) S3, STS

歴史的には、当初ローカル開発とE2EはLocalStackで進めていました。そこに、シナリオテストを軽くするために、RustFSを導入しました。また、単体テストでは、署名付きPOST URLのPOSTポリシーのテストを実装する際にRustFSでは対応できなかったため、そこにはMotoを採用しました。

こうして用途ごとに段階的に継ぎ足ししていった結果、気づいたらこの状態になっていました。

当時の一つ一つの判断は妥当だったとは思えるものの、3種になると流石にマインドシェアが分散すると感じたのと、LocalStackがコミュニティ版と商用版を統合することが発表されたのをきっかけに、統一を検討しはじめました。

なぜ Moto を選んだか

統一先の案として3つ検討しました。

LocalStackに統一

まずは、LocalStackです。ローカルと E2E で動いていて、もっとも実績がある選択肢。機能面でも対応サービスの幅と深さでも、エミュレーターとしては今も強力です。一方で2026年3月にコミュニティ版と商用版が統合され、利用にLOCALSTACK_AUTH_TOKENが必須化されるという告知が 2025年12月に出ました。アカウントベースの無料プランは個人・OSS 用途で引き続き利用できるものの、これまでの匿名で使える無償運用は終わる方向です。商用版に移行する費用対効果(コミュニティ版を商用 SaaS の開発で使い続けるのはライセンス的にも難しく、Base 以上のプランへの切り替えが前提になる)と、LocalStackが提供する多様な機能が今の利用状況で必要かどうか、という疑問が残ったため、別の選択肢に揃えるほうが自然と判断しました。

The Road Ahead for LocalStack: Upcoming Changes to the Delivery of Our AWS Cloud Emulators

専用エミュレーターを組み合わせる

次は、S3はRustFS、DynamoDBはAWS公式のDynamoDB Local、というように単機能のエミュレーターを束ねる案です。各エミュレーターがそのサービスに特化していて、本番挙動との一致度は一番期待できそうだと思いましたが、自分たちのテスト要件に必要なSTS/IAMをカバーするエミュレーターが見当たらず、POSTポリシーの発行にAssumeRoleが必要なので、ここが埋まらない以上、この案は不採用になりました。また各種エミュレーターを組み合わせるのであれば、当初の感じたマインドシェアが分散してしまう課題を払拭することはできません。

Moto に統一

docs.getmoto.org

ひょっとしたらあまり馴染みがないかもしれませんが、かなり昔から存在するOSSです。Python 製でAWS SDK互換のサービス数は100超えています。既に自プロダクトの単体テストで動いていて、自チームのユースケース(S3、DynamoDB、STS、IAM)は検証済み。OSS として活発ですし、商用化フォークの動きも観測しておりません。一方で、MotoはPython製なのでRust製である RustFSと比べると遅くなりそうな予測をしていましたが、ローカル環境で実験したところ、テスト時間に致命的な影響は出ない見込みになりました。

最終的に Moto を選んだ決め手

主に3つあります。

  1. OSSとしての継続性の実績。安定した更新が行われており、AWS SDKと歩調を合わせている
  2. 既に自チームで動作実績がある。単体テストで使っていたので移行のリスクを取りやすい
  3. 対応サービスの幅。将来 SES、SQS、EventBridge などを足す余地がある

上記に加え、シナリオテスト全体に占めるエミュレーター部分のテスト比率は意外に小さく、Moto が抱える Python 由来の遅さよりエミュレーター統一の効果のほうが大きいだろうと判断しました。

とはいえ、完璧ではない

署名付きPOST URLのPOSTポリシーの検証が緩い

Motoは、署名付きPOST URLのContent-Type 条件を実際には検証しません。POSTポリシーの starts-with 条件は素通しです。本物のS3では image/ プレフィックス制限などをきちんと検証するので、ここに依存する挙動はテストで担保できないという問題があります。

なので、その緩さを許容する代わりに、POSTポリシーのJSON構造そのものを検証するテストを追加しました。

policyJSON, err := base64.StdEncoding.DecodeString(result.Policy())
require.NoError(t, err)
assert.Contains(t, string(policyJSON), `"starts-with"`)
assert.Contains(t, string(policyJSON), string(tc.contentType))

実アップロード時の挙動は、開発環境以降で確認する前提で運用しています。

移行後に再選定する

Motoに統一後は、当初抱えていた課題もスッキリし新しい課題も顕在化していないのですが、一方でAWS エミュレーターの選定は引き続き行っており、現時点ではいくつか新興 OSS が出てきており動向を追っています。

移行当時は、タイミング的に候補にあげられなかったのですが、最近だとflociとkumoが移行先の有力検討候補だと考えており、flociについてはMotoに移行が完了した後日にローカルで少し検証してみました。

floci

floci.io

flociは、Javaで実装されたパブリッククラウド(AWS, Azure, GCP)のエミュレーターで、AWSのエミュレートでは、現時点で52サービスに対応しています。また、起動 30ms、メモリ 13MB と軽いフットプリントも特徴的で、LocalStackのコミュニティ版統合をきっかけに作られたという経緯があります。

自チームのバックエンドのinfra/gateway系単体テスト(S3操作中心)でMotoと比較計測しました。macOS、Docker Desktop、-count=1 を 3 回計測、コンテナ起動込みです。

go test 中央値 real 中央値 速度比
Moto 2.285s 3.01s 1.00x
floci 0.861s 1.57s 2.65x / 1.92x

シナリオテスト全体(DB、Smocker(認証認可サービスのAPIモックとして利用)、AWS エミュレーターの 3 コンテナ起動込み、5 回計測の中央値)でも比較しました。

go test 中央値 real 中央値 速度比
Moto 69.77s 77.70s 1.00x
floci 63.80s 72.31s 1.09x / 1.07x

S3中心の単体テストでは 2 倍以上速いですが、シナリオテスト全体だとDBやSmockerのオーバーヘッドが支配的になって、差が 7〜9% 程度に落ち着き、速度的な優位性はそこまでという感じです。

互換性に関しては、検証した範囲で全てのテストを通過したので問題はありませんでした。

署名付きPOST URLのPOSTポリシーの content-length-range を Moto が素通しするのに対し、flociは忠実に検証するという挙動差があり、flociがAWSの振る舞いをエミュレートする際の精度の高さを感じました。

kumo

github.com

Go製のAWS エミュレーターで単一バイナリで動作し、現時点で76サービスに対応しています。移行を検討したタイミングでは S3 の署名付きURLのPOSTポリシー周りの実装がなかったので、画像アップロードのテストが実現できず、候補になりませんでした。ですが、個人的にはいま一番熱いAWSエミュレーターだと考えており、開発が活発なのでとても期待しています。

今の判断

次の乗り換えを検討するなら、現時点ではflociが魅力的に見えますが、まだ乗り換える判断には至っていません。理由は次の 2 点です。

  • シナリオテスト全体での速度差が 7〜9% 程度に留まる。ローカル単体テストは速くなりますが、CI の主時間を占めるシナリオテストでは効果が薄い。
  • floci 自体がまだ若い(1.5.x、活発に開発中)。来年も同じ配布形態で動いている保証は現時点では弱いですし、対応サービスもMotoやkumoと比べて少なく、最近 hectorvent/floci から floci/floci に組織が移動するなどの変更も観測されています。

hectorvent/floci - Docker Image

しかし、Moto の緩さに暗黙に依存しているテストを厳密にできることは魅力的であり、継続して動向を追っていきたいと思っています。flociが業界での採用事例が増えてきた段階で、kumoを含めもう一度評価する予定です。

今、ゼロから選ぶならどうするか

ここまで、自チームのケースをシェアしました。

では、今、新しいプロジェクトに使うAWSエミュレーターを選ぶならどう考えるか、ユースケース別に整理してみます。

まず、テストをエミュレーターで広めにカバーしたい場合。対応サービスの幅、OSS 継続性、運用実績でMotoが今の現実解になりえそうです。後発のエミュレーターと比較して対応サービスの幅は徐々に縮まってくるとは思うのですが、OSSとして継続してきた実績は選定する際の理由としては強いものになりそうです。

次に、機能の網羅性と本番挙動の一致を最優先にしたい場合。商用版のLocalStackが良いと思います。Snapshot 機能、CloudFormation 完全エミュレーション、IAM の細かい挙動など、Moto が追いついていない領域がいくつもありますし、商用版ならではのサポートも魅力です。チーム規模やプロダクトの段階によっては、ライセンスコストを払う価値が十分にあります。

性能を優先し、ローカル単体テストの速度を絶対値で短縮したい場合。flociの起動30msと軽量フットプリントは魅力的です。ただし若いプロジェクトなので、少しだけ様子を見てからでも遅くはないと考えます。

そもそもエミュレーターを使いたくない場合。テストやローカル開発からアクセスできるAWS環境が用意できれば最善かもしれません。ただ、AIコーディングエージェントを使って開発するのであれば情報漏洩・インフラ環境破壊など、ガードレール(権限制限、実行ログ、課金監視)の構築にはしっかりと投資する必要がありそうです。(想定外な費用も発生する可能性も否定できないですしね)

これらを踏まえ、現時点での個人的な意見でいうと、まったく新しい環境に導入するなら、無料で使える、ある程度のサービスの網羅性、起動の速さ、パフォーマンス、構成されるライブラリ依存の少なさを優先したいので、kumoを第一候補、flociを第二候補に選ぶと思います。

kumoを第一候補としているのは、対応サービスの多さ、Go実装による依存解決のシンプルさとサプライチェーンの見通しの良さへの期待からで、flociは逆にAWS特化というよりマルチクラウドを見据えているので、ややリッチすぎるという観点と、kumo, Motoと比較して対応サービスの少なさから次点にしています(あくまでも個人の主観であり、選定に正解はないです)

振り返り

AWSのエミュレーターとしてデファクトスタンダードといっても過言ではないであろうLocalStackは今も優れたプロダクトで、商用版を含めれば機能面・サポートの面では頭ひとつ抜けています。しかし、無償版のサポート方針が変わる告知が出たことで、自分たちのライブラリ依存戦略を見直す良いきっかけを与えてくれました。

自分たちのケースでは、候補のエミュレーターはどれも魅力的でしたが、最終的にはMotoに揃えることを選びました。すでに単体テストで動作実績があり、移行リスクが小さかったのが決め手です。実際にいまプロダクトで動いているものに揃えることを優先したのが、スムーズに移行できた一番大きな要因だと思います。

乗り換え自体のコストはAIのおかげで以前ほど高くなく、定期的に自分たちのスタックを見直しやすくなっています。flociやkumoのような新興OSSも今後出てくるはずです。Motoを選んだ時点で完結させず、いま取りうる選択肢の引き出しを増やす癖をつけておきたいですね。

エミュレーターの選定はサービス開発の本丸ではありません。ですが、ローカル開発体験とCI安定性に直結する地味に重要な基盤です。その基盤を、その時々で最適なものにし続けるのは、意外と投資効果があるのでは、と考えています。

Appendix

GitHubのリンクはこちらですー