はじめに
こんにちは、NTTDATAのKojiです。
この度、2024 Japan AWS Jr. Championsのメンバーでブログリレーを行うことになりましたので、普段SREとして業務を行なっている中で得た知見を共有しようと思います。
内容としては、コスト最適化を目的にAWSリソース(EC2,RDS,AutoScalingGroup)の夜間停止を行おうと思っている方や、既に行なっている方向けに、その仕組みと運用する上での注意点を紹介しようと思います。
夜間停止の仕組みとその課題について
AWSリソースの夜間停止と聞いてまず真っ先に思いつくのがEventBridgeを利用することだと思います。
EventBridgeのEventBridge Schedulerという機能は、タスクを作成・実行・管理してくれるものなので、
- 毎日特定の時間にインスタンスを起動
- 毎日特定の時間にインスタンスを停止
は実現可能だと思います。
ただそれ自体は設定も導入も簡単なのですが、いざ運用するとなると以下のような課題が発生してくると思います。
- 各チームが日別に細かな起動・停止を行うことができない。
- 例えばアプリチームが普段停止している試験環境を夜間でも使いたい場合を考えます。この場合、EventBridgeの設定をIaC管理していて、そのコードをインフラチームが管理する運用になっていると、アプリチームはすぐにそのコードを修正することができないです。
- 上記によりアプリチームとインフラチーム間で作業依頼などやりとりが発生します。それにより余計なリードタイムが発生し開発スピードが低下したり、運用負荷が高まってしまったりします。
- インフラチームが突発的対応が必要になり稼働が取られてしまう。
- シンプルに別作業の妨げになりますし、管理しているレポジトリで修正を行い設定をapplyする、アプリチームの用事が終わったら元に戻すなど一連の作業がトイル化しています。
これらの課題はアプリチームとインフラチームの境目がないような比較的小さめのプロジェクトでは、コミュニケーションコストが低いことや権限の制限が特にないなどで発生しづらいと思います。(中長期的目線で組織やプロジェクトがスケールしてくると発生する可能性は十分あると思います。)
しかし私が所属するプロジェクトではアプリチームとインフラチーム間で使用可能なリソースが権限によって分離されていることや、複数のシステムを横断的に少数のインフラチームメンバが見ていることもあり、大きな課題となっていました。
解決策
これらの課題を解決するためにStep FunctionsとChange Calendarを利用した新しい仕組みを導入しました。
AWS Systems Manager Change CalendarはカレンダーにOPENかCLOSEの予定を設定できるサービスです。
詳しい実装は省きますが、この仕組みの概要は以下です。
- Step Functionsを用いて以下のワークフローAを作成する(Lambdaのコーディングは必要)
- カレンダーの情報取得
- カレンダー内のイベント確認
- イベントで起動設定がなされている(起動時刻の範囲内)場合、カレンダー名をtagに持つリソースを起動する
- そうでない場合、カレンダー名をtagに持つリソースを停止する。
- EventBridgeのルールでワークフローAを30分ごと(ここの時間は変えて良い)に実行するように設定する。
- Change Calendarのコンソールで
サービス名+環境名
のhoge_dev
などとカレンダー(デフォルトcloseの設定)を作成する。 - カレンダー内でイベントを作成し、起動設定を行う。
- 例: 9:00 - 21:00 10/15-11/15 まで等
- 起動停止を設定したいリソース(EC2,RDSなど)にカレンダー名と同じ名前のtagをつける。
この仕組みを導入することで、
- 開発環境は9:00-21:00で起動したい。
- 試験環境は普段はclose、安定性試験などで一時的に夜間、休日などにも利用したい。
といった要望も、一度リソースへのtagの設定とカレンダーの作成さえインフラチームがしてしまえば、アプリチームが柔軟かつスピーディーに対応可能となりました。
また、アプリチームとインフラチームのやり取り、コード修正などの作業が減り運用負荷軽減につなげることができました。
ASGについて
EC2ではなくEKSなどを使っていてAutoScalingGroupでノードを管理している場合は
アプリチーム側で起動するノードの台数を調整したいなどの要望もあるかと思います。
その場合はASGのtagに以下を設定し、tagの変更でノードの起動数を変更できるようにすると良いと思います。
- DesiredCapacity
- 停止時に設定されていた「希望する容量」の値が入ります。起動時にこのタグの値を参照、起動し自動でタグの削除が行われます。
- MinimumCapacity
- 停止時に設定されていた「最小キャパシティ」の値が入ります。起動時にこのタグの値を参照、起動し自動でタグの削除が行われます。
- MaximumCapacity
- 停止時に設定されていた「最大キャパシティ」の値が入ります。起動時にこのタグの値を参照、起動し自動でタグの削除が行われます。
終わりに
この課題を通じて、
- コスト最適化を行うことだけではなく、その後の中長期的な運用のことも考えて設計することの重要さ
- この仕組みを別プロジェクトに横展開することや、対象リソースを広げていくことで組織の全体最適に繋げることの重要さ
を学ぶことができました。
同じような課題を抱えている方の参考になりましたら幸いです。
参考
https://qiita.com/ys1/items/21744f39676286b2c321
https://qiita.com/h_hoga/items/15da0c2632542f7d8150