💸

【AWSコスト最適化】開発環境の不使用時間帯シャットダウン

2024/04/02に公開

こんにちは。シンプルフォーム株式会社 にてインフラエンジニアをしています、山岸です。

前回、AWS コスト最適化の取り組みの1つとして ECR コンテナイメージの定期削除 に関する記事を投稿しました。今回は、同じくコスト最適化に関する小ネタ其の2になります。

概要

  • 当社では、プロダクトの機能強化や開発環境の増加に伴い、AWS 利用にかかるコストの増加が目立つようになってきていました。そこで、開発組織全体でコスト削減施策に関する議論を行い、コストインパクトの大きいものについて集中的に施策を実行してきました。
  • 本記事では、施策の一つである「開発環境の不使用時間帯シャットダウン」についてご紹介します。当社では、プロダクト開発において本番環境以外にも複数の開発環境を運用しています。これらの開発環境について、使用していない時間帯は停止させておく仕組みを整備したので、その実装や運用についてご紹介します。

背景

当社ではプロダクト開発において、顧客向けに提供するサービスが稼働する「本番環境」の他に、「ステージング環境」および複数の「統合環境」を用意しています。

各環境の説明は以下の通りです。

  • 本番環境 (Production, PROD) ... 前述の通り、顧客向けに提供するサービスが稼働する環境です。GitHub リポジトリにおいてリリースタグを切ることで、変更がデプロイされます。
  • ステージング環境 (Staging, STG) ... GitHub リポジトリにおける main ブランチを反映した環境です。主にリグレッションテストや負荷試験などに利用されます。
  • 統合環境 (Integration, ITGx) ... 開発中の機能ブランチをデプロイし、動作確認を行うための環境です。GitHub Actions の workflow_dispatch を使用してユーザーストーリー毎にデプロイされるような使われ方が多いです。現在は 2 環境を用意しています。

各環境には RDS/Aurora データベースや、ECS サービスなどが存在しており、稼働中は固定費として利用料金がかかってきます。本番環境やステージング環境はともかくとして、統合環境は利用されていない時間も多く、常に稼働させておく必要はありません。

上記を踏まえ、「統合環境については不使用時間帯はなるべく停止させておく」というのを基本方針として、その仕組みや運用について検討することにしました。

Before

まず、施策実施前がどのような状況だったかを確認しておきます。

以下は、AWS Organizations 組織の管理アカウント (Payer アカウント) にて、2023年8月 ~ 2024年1月の期間の統合環境にかかる AWS サービス利用料を、Cost Explorer で月次表示したものです。

2023年12月は一時的な検証のため外れ値的に増加していますが、2 つの統合環境を合計して大体 $6,000 ~ $7,000 /月 で推移しています。全体の何割かを削減できるだけでもそれなりの効果を見込めそうです。

施策検討・実施

実装

Cost Explorer でさらにドリルダウンしてみると、以下の AWS サービスが特にコストがかかっていることが分かりました。

  • RDS データベース
  • ECS サービス
  • Neptune クラスター

次点で OpenSearch Service ドメインがありましたが、上記 3 つに比べてそこまで大きくないのと、そもそも OpenSearch Service は一時的な停止をサポートしていないため検討対象外としました。ということで、上記 3 つについて起動・停止の仕組みを作っていきます。

全体停止・起動ワークフロー

統合環境を停止・起動するためのワークフローを AWS Step Functions (SFN) で実装しました。

以下に示すワークフローグラフのように、RDS や ECS などのサービス毎に停止・起動の SFN ステートマシンをそれぞれ作成し、それらを全体停止・起動の SFN ステートマシンからネストで呼び出す構成にしています。

全体停止ワークフロー

全体起動ワークフロー

後述の通り、これらのワークフローは EventBridge ルールによるスケジュール実行、または開発者によるオンデマンド実行の両方を想定しています。全自動ではなく、一部開発メンバーにも操作が発生する仕組みであるため、なるべく簡単な操作になるよう SFN ステートマシン実行開始時の JSON 入力は不要(空 JSON {})で済むような実装にしました。(コスト削減のためとはいえ、開発者に一定の不便を強いるものなので、この辺りのストレスは極力減らしておきます)

サービス別停止・起動ワークフロー

サービス別停止・起動ワークフローについて、RDS データベース の例を示しておきます。

RDS データベース停止ワークフロー

RDS データベース起動ワークフロー

この辺りの実装は AWS サービス毎に異なってくると思いますが、例えば RDS の場合、まず RDS クラスターのリストを取得し、後続の Map ステートで各クラスターの停止・起動処理を実行しています。

停止ワークフローのみ、Skip タグによる分岐処理を実装しています。これについては次項で解説します。

Skip タグによる停止処理のスキップ

特定のリリソースのみ停止させたくない、といったユースケースに応えられるよう、「Skip タグ」という仕様を用意しました。例えば、開発都合によりグラフ機能開発のため Neptune クラスターとグラフ API が稼働する ECS サービスのみ停止させたくない、といったケースです。

Skip タグという名の通り、リソースタグをベースに制御する方法を採りました。RDS や Neptune であれば各 DB クラスター、ECS であれば各 ECS サービスのリソースタグに、特定のキー名を持つ Skip タグを設定しておき、その値に応じて停止処理を行うか Choice ステートで制御します。

当社の場合、SkipStopAutomation というタグに設定されている値が (1) true であれば停止をスキップしてその旨を通知、(2) false であれば停止、(3) それ以外の値が設定されている、または設定されていない場合は失敗を Slack 通知、という実装にしました。

通知

全体停止・起動ワークフロー実行後の Slack 通知を設定しました。停止・起動処理が完了すると、以下のような通知が飛んでくるようにしています。ワークフロー実行の開始者が、EventBridge ルールなのか開発者個人なのかを確認できるよう、Initiator の部分に埋め込むようにしています。(この情報は CloudTrail の LookupEvents API を利用して取得できます)

また、Skip タグが true に変更されたまま戻すのを忘れられないよう、スキップされた場合には全体ワークフロー実行結果とは別に通知を設定しています。

運用方法

運用方法は以下のようにしました。

  • 毎日定刻 (22:00) に全体停止ワークフロー StopALL をトリガーする EventBridge ルールを設定しておき、日次で自動停止する。
  • 日次起動の EventBridge ルールは設定せず、統合環境を使用したい人がオンデマンドで全体開始ワークフロー StartALL を実行する。使い終わったらコスト節約のため、なるべく StopALL ワークフローを実行して環境稼働を停止する。
  • 開発の都合上、日次停止したくない特定のリソースがある場合は、該当のリソースに付与されている Skip タグを true に変更する。開発が完了し、停止ワークフローをスキップする必要性がなくなったら false に戻す。
  • サービス全体を停止したくない場合は、日次停止用の EventBridge ルールを無効化する。自動停止をスキップする必要性がなくなったら EventBridge ルールを再度有効化する。

運用方法について開発メンバーに周知する際、仕組みの目的や仕様・手順など、最低限の情報についてまとめたドキュメントを用意しておくと、QA にかかるお互いのコミュニケーションコストを抑えられるので、併せて整備しておくと良いと思います。

After

2024年3月初旬から運用を開始してみて、一ヶ月ほど経過を確認してみた結果がこちらです。

2024年4月以降どう推移するかは未知数ですが、2024年3月に関しては合計 $3,400 /月 弱に着地したので、施策実施前と比較して $2,500 ~ $3,000 /月 ほどの削減効果になっていそうです。
(RDS クラスターを使用していない時間帯は手動で一時停止するという運用を 2024年2月頃から始めていたので、2月から一部効果が見え始めています)

ということで金額的に比較的大きなコスト削減に成功しました!

さいごに

前回の記事 に引き続き、AWS コスト削減に関するネタについて書いてみました。いかがでしたでしょうか。

今回の施策に関しては、検討当初 $1,500 /月程の削減効果と試算していたので、想定よりも減ったなという感覚でした。見込める効果の試算ももちろん大事ではありますが、不確定要素の多いものでもとりあえず実行してみるのは良いかもしれません。

最後まで読んで頂き、ありがとうございました。

SimpleForm Tech Blog

Discussion