有名テック企業の技術ブログを、ひとつのフィードで。
フィード
32件
はじめに カミナシでエンジニアリングマネージャーをしてます、すずけん(@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つあります。 OSSとしての継続性の実績。安定した更新が行われており、AWS SDKと歩調を合わせている 既に自チームで動作実績がある。単体テストで使っていたので移行のリスクを取りやすい 対応サービスの幅。将来 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のリンクはこちらですー GitHub - localstack/localstack: 💻 A fully functional local AWS cloud stack. Develop and test your cloud & Serverless apps offline · GitHub (public archive) GitHub - getmoto/moto: A library that allows you to easily mock out tests based on AWS infrastructure. · GitHub GitHub - floci-io/floci: Light, fluffy, and always free - The AWS
はじめに カミナシの共通ID管理基盤を開発しているmanaty(@manaty226)です。カミナシ ID管理基盤ではログストレージにCloudWatch Logsを使っていましたが、サービスの成長に伴いコストに悩んでいました。この記事では、私たちが実践したAmazon S3 Tables(以下、S3 Tables)を使ったログストレージの構築と移行、そのコスト最適化効果について書きます。 サービス成長に伴うCloudWatch Logsのコスト増大 Amazon CloudWatch Logs(以下、CloudWatch Logs)はAWSが提供するログの保管や分析のためのサービスです。多くの一般的な構成ではアプリケーションが出力するログをそのままCloudWatch Logsに保管し、何かあればCloudWatch Logs Insightsを利用してログをクエリしたり、特定のエラーログにもとづくアラート設定をCloudWatch Alermと連携して行っているかと思います。私たちのID管理基盤も同様に、ECSからログルーターを介してCloudWatch Logsへログを配信し、Amazon Managed Service for Grafana(以下Grafana)を使って日々の開発運用に役立てていました。 一方で、カミナシのサービスが成長するにつれて、全てのサービスの認証認可リクエストを捌くID管理基盤は、そのリクエスト数の増大や機能拡張に伴ってログコストも無視できないほど膨らんでいきました。週次で行うレビューにより不要なログを排除したりまとめることで地道に改善できた部分もありますが、そういった改善活動では大幅なコスト最適化は難しく、抜本的な対策を考え始めました。 コストが徐々に増加していく様子 通常運用するうえで発生するCloudWatch Logsのコストには大きく、ログの取り込み、保管、クエリの3つがあります。料金表からも分かるように、コストが膨らむ主要因はログの取り込みであるため、どれだけ保管期間などを最適化してもリクエスト数の増大に比例してログコストも大きくなっていくことが分かりました。 そこで、コストと運用の両面でバランスが取れそうなS3 Tablesへログを取り込み保管することを検討しました。 aws.amazon.com Amazon S3 Tablesへの移行 S3 Tablesとは S3 Tablesは、Apache Icebergというオープンなテーブルデータフォーマットを実装したAWSサービスです。下図に示すように、Icebergではデータの実体となるIceberg形式のファイルに対してメタデータを管理することで、Amazon AthenaやSparkといったクエリエンジンからテーブルデータとして読み書きすることができます。メタデータによってテーブル構造が抽象化されているため、パーティションやカラムなどのテーブルスキーマの変更に柔軟であったり、スナップショットして管理されているメタデータ変更履歴に基づき過去のデータを読み出せるタイムトラベル機能、他にも従来のデータレイクハウスで利用されてきたHiveフォーマットの課題を解決しています。詳細は公式ページや、「実践Apache Iceberg」や「Apache Iceberg活用入門」といった書籍を読むことをおすすめします。 CloudWatch Logsのようにスキーマの事前定義なくクエリ時に柔軟にデータを読み込むことはできないものの、S3 Tablesにより馴染みのあるSQL構文を使って検索できることや、S3の安価なストレージを利用することによるコストメリット、コンパクションのようなIcebergの日々の運用をマネージドサービスに委任できること、将来的なスキーマ進化によるログ構造の変化への追従性などを鑑みてS3 Tablesへ移行することにしました。 Apache Icebergのデータアーキテクチャ(公式ページ:https://iceberg.apache.org/spec/#overview) ログ配信パイプラインによる段階的な移行 事前にCloudWatch LogsからいくつかのログをサンプリングしてS3 Tablesに投入し検証を行ったものの、実際に運用の中でどこまで現実的に使えるか分からなかったので、以下のような手順で段階的に移行しました。 ECSから配信されたログをログルーターで受けた後、ログルーターからCloudWatch LogsとAmazon Data Firehose → S3 Tablesの両方にログを配信 監視ツールとして利用しているGrafanaのクエリ先をS3 Tablesに変更して日々の運用における使用感や課題を洗い出し S3 Tablesによる運用が問題ないと判断できた時点で、ログルーターの配信先をS3 Tablesへ変更(ただし、エラーログはアラートにも利用しているため引き続きCloudWatch Logsへ配信) これにより、仮にS3 Tablesが私たちの運用に利用することが難しいと判明しても、CloudWatch Logsに保管されるログは引き続き欠損することなくクエリできるので、安全に移行することができました。 移行の各ステップにおける構成概略図 S3 Tables移行後のコスト最適化効果 CloudWatch Logsへのエラーログ以外のログ配信を停止してから、すぐに大幅なコスト最適化効果が見られました。コストの主要因であったログの投入にかかるコストは8割以上削減され、クエリコストもCloudWatch InsightsからAthenaに変わったことで大幅に低減しました。 CloudWatch LogsからS3 Tablesへ移行したことによるコスト変化 S3 Tablesと周辺エコシステムにおける現在の技術制約 S3 Tablesのパーティション変更 S3 TablesのパーティションはAthenaから変更することができません。したがって、作成時に設定したパーティション設定から変更したい場合は、そのためにAWS Glueジョブを使ってSparkクエリを書いてパーティション変更を行ったり、その他IcebergクライアントからDDLを実行する必要があります。せっかくAthenaというマネージドクエリサービスがあるので、ここは改善してほしいと思っており今後に期待しています。 docs.aws.amazon.com repost.aws Intelligent Tieringの利用開始可能タイミング S3 TablesはCloudWatch Logsに比べるとストレージコストが低いものの、毎日ログが蓄積されていけばコストは日々増加します。S3 Tablesは2025年12月に発表されたIntelligent Tieringにより、規定の期間アクセスされていないファイルのストレージクラスを自動的に最適化される機能を持っています。適切なパーティションが存在すれば、例えばログについては多くの場合直近のログにアクセスパターンが偏るため、古いログのストレージクラスが変更されてさらなるコスト最適化効果が見込めます。 一方で、Intelligent Tieringはテーブル作成時しか設定できず、標準ストレージで作成されたテーブルを後から変更することはできません。殆どの場合はIntelligent Tieringで良いはずなので忘れずに設定しましょう。私たちは泣きながらテーブルを再作成しました。 aws.amazon.com Terraformによる構築時の注意事項 カミナシではAWSインフラ管理にTerraformを利用しています。hashicorp/terraform-provider-awsが提供するモジュールには大変お世話になっていますが、S3 Tables周辺のAPIパラメータはまだまだ対応していないものも少なくありません。例えば、前述したテーブル作成時のパーティション設定やIntelligent Tieringの設定についても、PRはオープンしているもののマージはされていません。以前私が出したAthenaのマネージドクエリリザルト対応のPRもマージまで3か月ほどかかったので、これらの機能を欲している皆様はPRに👍してメンテナにIcebergへの熱い思いを伝えましょう。 github.com github.com おわりに 今回はアプリケーションログストレージをCloudWatch LogsからS3 Tablesへ移行してコスト最適化した事例紹介をおこないました。CloudWatch Logsは非常に使いやすく始めやすいため、アプリケーション開発の初期には私も毎回必ずCloudWatch Logsを選択します。その一方で、アプリケーションの成長とともにログコストは肥大していきます。そんなときに、S3 Tablesをログストレージの選択肢のひとつとして考えてみてはどうでしょうか。 私は昨年Icebergの書籍を読んでから、そのメタデータアーキテクチャやコンパクション戦略を基に、IoTデータような小さなデータを逐次的に投入するユースケースから大量のデータをバッチ的に取り扱うユースケースまで幅広く対応しようとする仕様の面白さに感銘を受けています
「カミナシ レポート」の開発・運用をしている、AWS インフラが得意な Security Engineering の furuya です(属性過多)。妙に流行り物に乗っかるときがあるのですが、「超かぐや姫!」を見てきました。よかったです。それはさておき今回は「カミナシ レポート」の開発におけるセキュリティ向上施策のお話です。 カミナシでは開発チームに Security Engineer を派遣する取り組みがあります。 kaminashi-developer.hatenablog.jp 気がつけば、この記事の公開から1年が経過していました。ここでそれを振り返ってみたいと思います。 サービスにおけるコンテキストを把握する 派遣されるセキュリティエンジニアは基本的には最初の半年から1年程度は開発チームの1メンバーとして、ともに開発や運用を行います。ですので、障害対応やインシデント対応、お客様からの通常のお問い合わせなどのオンコール担当としても活動します。 この1年を通して「カミナシ レポート」の開発・運用に携わりました。私自身のキャリア的にコーディングから離れていたのでその点は AI の力も借りながらそこそこに、代わりに得意なインフラ・運用面で改善をしたり、オンコールに入ることでチームメンバーの負荷を軽減したりして貢献しました。およそ最初の半年くらいでチームには馴染めたと思っており、そこで得たコンテキストから残りの半年は重めのインフラ・セキュリティ改善に取り組むことが最優先であると判断し、チームとしても合意の上で対応を進めることができました。 施策のテスター その欠陥を修正することにより獲得したナレッジを他サービスチームに共有することができ、セキュリティ上の欠陥が埋め込まれるのを未然に防いだり改善することが狙いとしてあります。 欠陥の修正ではないのですが、全チーム対応しないといけないようなセキュリティ施策(AWS Security Hub CSPM の新しいコントロールへの対応など)をまず最初に「カミナシ レポート」の開発チームで実施し、対応するための手順や Terraform のコード、ハマりどころを公開して他のチームの工数を削減する、といった取り組みを行いました。サービスを運用する中での変更になるので特有のワークアラウンドが必要なこともあり、単純にマニュアル通りにいかないケースで役に立ったかと思います。 セキュリティナレッジの共有 また、セキュリティエンジニアが持っているナレッジや考え方などをサービスチーム内で共有することにより、エンジニアがセキュリティを意識しながら開発や運用を行えるようになることを目的としています。 私自身セキュリティを専門としたキャリアを歩んでいないのでナレッジの共有といっても手探りではあります。ただ、だからこそ「セキュリティどうしたらいいかわからない開発者」の気持ちにもなれます。やはり開発する身になってみると「セキュリティ、いつどこでどうしたらいいかわからない」というのが真っ先に思い浮かびます。 「いつどこで」がわからない、というのはセキュリティを気にするべきタイミング・ポイントに気付けなければ実施・対策しようがない、ということでもあります。何にせよまずは知識を得るところが大事なのではないか、と思っていたときにちょうど「開発者はどこまでセキュリティを気にすればいいのか」という問いをメンバーからもらいました。そのときの話をセキュリティエンジニアの西川さんがブログに書いてくれています。 kaminashi-developer.hatenablog.jp そういう気に掛けることができるかどうかというのがすごく大事で、そのような気付きがあったときに「一旦セキュリティエンジニアに聞いてみようかな」というマインドセットを持てるかどうかが重要だと思っています。 気付ける筋肉みたいなものがあると思っており、それはやはり知識と実践で養われていきます。気付けさえすれば自分で解決することもできますし、できなくてもセキュリティエンジニアに聞くというアクションがとれます。 前置きが長くなったのですがやっぱりまずは座学で知るところからが一番でしょう、ということで開発者が気にすべきセキュリティの勉強会を開催しています。 geminiに作ってもらったセキュリティ対策全体像 第1回は「設計で気付けるとよいポイント」ということで脅威モデリングのワークショップを、第2回は「普段の実装の中で気付けるポイント」として SAST(Static Application Security Testing。コードの脆弱性チェック)の紹介および運用に取り入れる方法について議論をしました。もっと自然にチームメンバーが「気付くことができる」ように、定期的に実施していきたいです。 想定外の効果 すべてのチームにセキュリティエンジニアが派遣できればよいのですが、人数も限られており実現はできていません。しかし、派遣されなかったチームにも心境の変化があったようです。具体的には、派遣されないならされないなりに自分たちでよりセキュリティを高めていくぞ、というオーナーシップの醸成に繋がったチームがありました。実際、(個人的に)悔しいながらそのチームが一番セキュリティが出来ていそうなので、副次的ではありますが他のチームにいい影響を与えることができたのではないかと思っています(ここから挽回していきたいです)。 これから この1年を通して開発・運用をしながらそのコンテキストを理解したうえでセキュリティ対策をしたり、セキュリティ文化の醸成に取り組んだりしてきました。まだやるべきことはたくさんあります。この1年でようやく土台が整ってきたところなので、ここから『「カミナシ レポート」の開発チームって息をするようにセキュリティできてるよね』と言われるようになりたいです。 「カミナシ レポート」はカミナシのフラッグシッププロダクトということもあり、昔から積み上がった課題が複数残っています。これらに対処しつつ、先程のSASTなどを「開発速度を落とさないように」運用にのせて一段上のセキュリティレベルを目指しつつ、チームメンバーがもっとセキュリティに「気付ける」ようにしていきたいと思っています。