はじめに
私はフルスタックエンジニアとして参画することが最近多いです。ただインフラ領域からキャリアを始めたため比較的知見があることもあり、これまで複数のプロジェクトで AWS・GCP のコスト最適化を経験してきました。
今の現場も参画から 1 年になりますが、AWS コスト削減施策を推進してきました。
私個人ではなく、メンバー数人で協力して地道に進めていったものになります。
施策の振り返りと、これまでのコスト削減推進経験で培った、大事だと思う姿勢みたいなものを共有していきたいと思います。
どなたかのご参考になると幸いです!
前提
フェーズ・規模感:
- 1 つの大きなサービスの中に複数機能があるマルチプロダクト系の Web サービス
- ユーザ数: 数万人規模
- サービス提供開始から 約 2 年後に自分が参画
- 0→1、1→10 フェーズは終わり現在は拡大フェーズに入っている
主な AWS サービス:
- Aurora Serverless v2
- ECS(Fargate)
- Redis(Redis OSS, Valkey 混在)
- EC2
- Lambda, SQS
- ネットワーク系もろもろ(ALB, NAT Gateway 等)
- 監視に CloudWatch 系と New Relic を併用
記事中の円換算は、すべて 1 USD = 150 円で計算しています。
主なコスト削減施策
1. Synthetics Canary の実行頻度を下げる
CloudWatch には Synthetics Canary(外形監視)の機能があります。
Synthetics Canary のコストは意外と高くなりがちなので注意です。
東京リージョンでは、1 回の実行につき 0.0019 USD かかります。
1 回あたりは小さく見えますが、1 分間隔で実行すると 1 ヶ月で 43,200 回実行されるので、Canary 1 本あたり約 82 USD / 月になります。
プロジェクトでは 4 環境 × 2 サービス = 計 8 本が 1 分間隔で動いていたため、約 670 USD / 月(1 時間あたり約 0.93 USD)かかっていました。
そこで以下の頻度に落としました。
- 本番環境: 5 分に 1 回
- 本番以外の環境: 1 時間に 1 回
本番の頻度も 5 分間隔に落としたのは、1 分以内に検知できてもそこまで迅速な反応・対応を人間側ができないからという考えからでした。
これはプロジェクトによりますが、当時のエンジニア人員や稼働率目標を加味して、そう判断しました。
これにより、月あたり約 554 USD(約 8.3 万円)、外形監視の料金を約 8 割削減できました。
2. 監視・ログ出力基盤を統一
当時は監視基盤として、New Relic を導入しているサービスとそうでないサービスがありました。
New Relic の利用をやめて CloudWatch に統一しました。
これにより New Relic メトリクス・ログ送信のコストも減ったし、CloudWatch に監視基盤を統一することで監視への IaC 導入や設定時の認知負荷も下げることができました。
New Relic / Datadog は高機能な監視を提供しており有用ですが、プロジェクトでは標準的な死活監視・リソース監視のみでうまく活用しきれていない状況だったため、CloudWatch に寄せるという判断になりました。
これは現場により判断が分かれる箇所です。
たとえば、
- CloudWatch にはない・または構築しづらい監視機能をすでに利用している場合(APM・コードレベルの性能分析など)
- マルチクラウド構成としている場合(AWS・GCP 両方利用など)
- エンジニア以外のメンバーもログや監視ダッシュボードを見る場合
といったケースでは、逆に New Relic / Datadog に監視・ログ出力を集約して、CloudWatch 側には不要なメトリクス・ログを出さないようにしてコスト削減という方向性も考えられます。
これにより、概算で以下のコストを削減できました。
- AWS 側: New Relic へのメトリクス送信を削除し 1 日あたり約 48.75 USD → 0 USD に。月あたり約 1,460 USD(約 21.9 万円)
- New Relic 側: 有料プランから無料プランへ切り替え、月あたり約 12.5 万円
合計すると、月あたり約 34 万円の削減になりました。
3. ECS Container Insights を必要な環境のみに絞る
ECS には Container Insights という機能があり、有効にするとクラスター・サービス・タスク単位の CPU/メモリ使用量やタスク数などを CloudWatch で確認できるようになります。
プロジェクトでは、環境によらずすべての ECS クラスターで有効になっていました。
Container Insights が収集するメトリクスは、CloudWatch のカスタムメトリクスとして課金されます。
ECS のコストとして分類されず気づきにくいため注意です。
東京リージョンでは 1 メトリクスあたり 0.30 USD / 月です。
サービスが 5 つほどあるクラスターだと 150 本近くのメトリクスが作られるため、クラスター 1 つあたり約 44 USD / 月かかる計算になります。
メトリクスの本数はタスク数にはほぼ比例せず、サービスやタスク定義の数で決まるので、タスクを少数しか動かしていない開発環境でも本番とほとんど同じ金額がかかっていました。
そこで以下のように変更しました。
- 本番環境: 有効のまま(強化モードのものは通常モードに変更)
- 本番以外の環境: 無効化
本番以外で無効にしても、サービス単位の CPU/メモリ使用率は ECS 標準のメトリクス(無料)で確認できるため、開発・ステージング環境では十分と判断しました。
もし負荷試験等により検証環境でタスク単位メトリクスが必要になれば、そのときに随時有効化することでチーム内で合意しました。
無効化するときの注意点としては、Container Insights のメトリクス(実行中のタスク数など)を CloudWatch Alarm で使っている場合は、無効化するとアラームが「データ不足」になるので、見直しが必要になります。
これにより、本番以外の約 10 クラスター(サービス約 30 個)を無効化し、月あたり約 440 USD(約 6.6 万円)を削減できました。
4. Aurora Serverless のリードレプリカで Writer のオートスケーリング追従を無効化
Aurora Serverless v2 では、負荷に応じて ACU(容量の単位)が自動で増減します。
リードレプリカ(Reader)は、フェイルオーバー時の昇格優先度(PromotionTier)が 0〜1 だと、自身の負荷に関係なく Writer と同じ ACU までスケールします。
これは、障害で Reader が Writer に切り替わったときに、すぐ同じ性能を出せるようにするための仕組みです。
プロジェクトではリードレプリカのあるクラスターでは、すべて PromotionTier 1 が設定されており、Reader は Writer に追従してスケールしていました。
しかし調査したところ、読み取りの負荷分散にはほとんど使っておらず、Reader の実態はフェイルオーバー用の待機要員でした。
つまり、Reader をほとんど使っていなくても、Writer と同じ ACU 分の料金がかかっていたことになります。
東京リージョンの Aurora Serverless v2(MySQL)は 1 ACU 時間あたり 0.15 USD で、対象の本番クラスターでは Aurora だけで月額数百 USD かかっていました。
そこで Reader の PromotionTier を 1 → 2 に変更し、Writer には追従せず、Reader 自身の読み取り負荷に応じてスケールするようにしました。
リスクとしては、フェイルオーバーで Reader が Writer に切り替わった直後は ACU が低い状態から始まるので、スケールアップが追いつくまで処理が遅くなる可能性があります。
Reader がフェイルオーバー先であることは変わらないので、切り替わり自体は従来どおり行われます。
この一時的な(数分の見込み)性能低下を許容することで合意したので、無効化に踏み切りました。
これにより、月あたり約 180 USD(約 2.7 万円)、対象クラスターの ACU 料金の約 2 割を削減できました。
5. EC2・ElastiCache のインスタンスタイプを最新世代にする
コスト面のインパクトは小さいですが、性能や安定性のために定期的にやりたい施策です。
プロジェクトでは、EC2(踏み台サーバ)や ElastiCache(Redis)で t2 や m4 といった旧世代のインスタンスタイプが残っていました。
旧世代は性能あたりの料金が割高なうえ、AWS 側の供給も縮小していくため、在庫不足でインスタンスの起動に失敗しやすくなります。(実際、1 度これに当たってリリースが中断したことがあります)
最近では以下のようなアップデートをしました。
- EC2(踏み台サーバ): t2.micro → t3.micro
- ElastiCache(本番): m4.large → m7g.large
- ElastiCache(本番以外): t2.micro → t4g.micro
ElastiCache はアプリケーションから CPU アーキテクチャを意識しないため、より安い ARM ベースの Graviton(t4g・m7g)に切り替えました。
EC2 は AMI やソフトウェアも ARM 対応が必要になるため、x86 のまま t3 を選んでいます。
これにより、本番の ElastiCache で月あたり約 35 USD(約 5,200 円)、本番以外で数 USD 程度コストが下がりました。
コスト削減を進める上で大事な姿勢
後半ですが、ここからがむしろ伝えたいことです。
複数現場でのコスト削減推進を通じて、大事だと思った姿勢について書きました。
1. AWS コンソールや Cost Explorer レポートを眺めてみる
これは、目的なくダラダラ AWS コンソールを眺めるだけでも効果はあると思ってます。
「意外とこのサービスのリソース数多いな/金かかってるな」「この時期からコスト跳ねてるけどなんだろう」みたいな発見があります。
気になるところを見つけたら、そこを起点に AI と壁打ちします。すると、ここ「コスト削れそう」というインスピレーションが湧いてきます。
また副次的に、経緯を追うことになるので現場理解が深まり、AWS 自体の勉強にもなるというメリットもあります。
また、定期的にプロジェクトのインフラのことを話す会を開催して、コンソールをみんなで眺めてみるのもおすすめです。
できればプロジェクト歴の長いプロパーや PM を会議に巻き込めると良いです。その場でプロジェクトの経緯を教えてもらえたり、場合によっては削減するか即判断できたりするので、スピード感を持った推進ができます。
PM 自身も気づいていなかった課題を認識できるので、Win-Win だと思います。
今の現場でも私がファシリとなり 3~4 人規模の「インフラ課題討議」を毎週開催していました。
これは、(コストに限らず)AWS まわりの課題・技術負債・お役立ちアイデア・アップデート情報をゆるく会話する会でした。
ちなみにここでは、知識レベルや立場によらず、対等に意見が出し合えるようファシリを意識しました。積極的な発言でメンバーのインフラ興味・知識レベル向上や、素朴な疑問から課題発見できることもあり、それらを期待してのことでした。
2. 根回ししておく
AWS コスト削減はインフラに手を入れるので、開発やサービス全体に影響が出る作業でもあります。
自分 1 人に閉じた作業ではないので、スムーズに進めるため根回しは必須です。
2-1. 関係性を作っておく
私は参画当初の信頼ゼロ状態から、いち早く「インフラできる人」と認識してもらえるよう意識して動いています。
今の現場では放置気味だった AWS 構成図・IaC の整備や CI/CD 改善などに手を挙げて、そこから実績を積み上げました。
もしくは、インパクトの少ない改善から提案して進めていくのもアリだと思います(いきなり影響が大きすぎると既存メンバーには抵抗があるため)
これにより、その後のコスト改善の提案も聞き入れてもらいやすくなりました。
2-2. 合意形成する・認識してもらう
まずこちらで調査しておきチームメンバーに説明して合意形成します。
コスト削減の概算(月額 ⚪︎ ドル削減見込み)と、発生する制約・デメリットを説明します。
規模の大きいプロジェクトだと、全員に合意をあらかじめとるのは現実的に難しいので、コアメンバーなど適宜絞っていいと思います。
ただし、認識は全員にしてもらってください。予期しない影響や不便が発生した際のトラブルを防ぐためです。影響範囲を完璧に把握しきれず予期しない影響が出るケースはどうしてもあるので、安全弁として必要です。
できれば Slack で @here で呼びかけるだけでなく、朝会などで簡単に口頭説明するといいです。
疑問を持ったメンバーがいればその場で質疑応答できますし、文面で伝えるよりも覚えてくれます。
万が一何かあっても「あれのことだな」となるので、不信感を持たれにくくなりトラブルが大きくならず進行できます。
3. 責任を持って判断・実行・経過観察する
コスト削減は基本的に何らかのトレードオフを加味して実行することになります。開発現場には多少なりとも制約を強いることになります。
判断に責任を持ち、やると決めたら責任を持ってやり切ってください。
「このコスト削減施策考えたから、あとやっといて」「削減したらその後は知らない」だと AI と一緒です。もはや人間がやる意味がないです。
まずデプロイ・リリースまでやり切って、その後も例えば CloudWatch Dashboard やログから、意図しないメトリクス変化・不穏なログが出ていないかを定期チェックしたり、朝会などでメンバーに不便が発生してないかをヒアリングするようにしましょう。
また、Cost Explorer も経過観察することで「実際にコスト ⚪︎ ドル削減できました」と言えるので、実績のアピールにもなります。
こういった信頼の積み重ねで、その後の提案(コスト削減に限らず)も通りやすくなり、自己効力感も上がります。
まとめ
この 1 年で取り組んだ AWS コスト削減施策と、進めるうえで大事にしている姿勢を紹介しました。
紹介した施策をすべて合わせると、月あたり約 52 万円(年間で約 620 万円)のコスト削減になりました(New Relic 側の削減分も含む)。
振り返ってみると、大きな構成変更をしたわけではなく「昔の設定のまま」や「最初は軽微だったが膨らんでいったコスト」を 1 つずつ見直していった結果だと思います。
どうしてもゼロイチフェーズでは「早く」作り上げたいので、中長期的なコスト感まで気が回らず適切な設定ができない事情があります。
これが見直されないまま残り続けると、気づかないうちに膨大なコストになってしまいます。
ポイントをまとめると、以下になります。
施策面
- 監視まわりは見落とされがちだが、意外とお金がかかる
- 本番と本番以外が同じ設定になっていないかを疑う。本番以外は大胆に落とせることが多い
- 「使っていないのに払っているもの」を探す
姿勢面
- コンソールや Cost Explorer を定期的に眺めて、違和感を見つける
- 削減額と制約をセットで説明して合意をとり、必ず全員に認識してもらう
- 判断に責任を持つ。実行して終わりにせず、経過観察までやりきる
要するに、地道に人間らしくやろうみたいなことですね。
この記事が、どなたかのコスト削減の参考になれば幸いです!