カレンダーを使ってEC2の起動停止をしたい

2022.10.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。
ご機嫌いかがでしょうか。
"No human labor is no human error" が大好きな吉井 亮です。

EC2 の月額費用を極力抑えたいという要望があったとしたら、どのような解決案が思い浮かぶでしょうか?
最も単純で効果の出る策がスペックダウンではないでしょうか。スペック (インスタンスタイプ) を半分すればコンピュート費用もおおよそ半分になります。(詳しくは EC2 料金ページで試算ください)

使っていない時間はシャットダウンしておく、という策も効果的です。クラウドの利点とも言えます。
今回はこちらの策をカレンダーで実行する方法を試してみます。

仕組み

Systems Manager だけで構成しています。

  1. Maitenance Window から決まった時刻に EC2 起動 or 停止処理を実行
  2. Automation が Change Calendar を参照しにいき、稼働日であれば起動 or 停止処理を実行
  3. 予め指定されたタグが付与された EC2 起動 or 停止

なぜ Systems Manager なの?

この手の仕組みは、EventBridge & Lambda or StepFunctions が多いと体感では思います。
なぜ Systems Manager を選んだかの理由を書きます。

大きな理由はカレンダーを使いたかったということです。
祝日や社内業務カレンダーを反映したスケジュールを組みたいと考えており、Change Calendar が今回の要件にピッタリでした。

また、Lambda はとてもパワフルですが、ランタイムサポート期限を気にしなければいけないと思っています。
Lambda をバリバリ書けるエンジニアが社内に在籍していれば問題にならないと思いますが、そうでない企業の場合はそこまでケアする必要があり個人的な悩みどころです。

やってみた

それでは環境構築をしましょう!

Change Calendar の作成

最初はカレンダーの作成です。マネジメントコンソールで Change Calendar を開きます。

カレンダーを作成 をクリックします。

任意のカレンダー名を入力します。カレンダータイプは デフォルトで開く のままにして カレンダーを作成 をクリックします。

カレンダーが作成され、カレンダー画面が開いていると思います。
イベントを作成 をクリックします。

「予定されたイベントを作成」では以下図の通り入力します。

  • スケジュールされたイベントの名前 → 任意
  • イベント開始日 → 直近土曜日の 00:00:00
  • イベント終了日 → 直近土曜日の 23:59:59
  • タイムゾーンをスケジュール → (GMT+09:00) Asia/Tokyo
  • 繰り返し → チェックを入れる
    • Weekly
    • Every Week
    • Saturday と Sunday を選択
    • Repeat forever

土曜日・日曜日に予定が入った状態になることを確認します。

カレンダー画面に 説明 タブがあるのでそこをクリックします。
Calendar use の三角形をクリックして展開をします。
9行目あたりに「- arn」で始まる文字列があります。「arn」から行の最後までをコピー(メモ)します。後で使います。

Systems Manager リソースの作成

カレンダー作成が終わったら他リソースを作成します。
CloudFormation で作ります。テンプレートをダウンロードし、CloudFormation からスタック作成をします。
パラメーターをご希望の値に編集してください。

パラメーター 説明
ChangeCalendarARN 前の手順で作成したカレンダーの ARN。最後にコピー(メモ)した文字列です。
CronExpressionStart EC2 を起動する時間(JST)です。CRON 式で指定ください。
CronExpressionStop EC2 を停止する時間(JST)です。CRON 式で指定ください。
IAMRoleName Systems Manager 用の IAM ロールです。こだわりがなければデフォルトのまま。
ResourceGroupName 対象の EC2 をグルーピングする Resource Group です。こだわりがなければデフォルトのまま。
EC2TagKey タグキーとタグバリューの組み合わせで対象の EC2 を識別しています。こだわりがなければデフォルトのまま。
EC2TagValue タグキーとタグバリューの組み合わせで対象の EC2 を識別しています。こだわりがなければデフォルトのまま。
DocumentNameStart SSM ドキュメント名です。こだわりがなければデフォルトのまま。
DocumentNameStop SSM ドキュメント名です。こだわりがなければデフォルトのまま。

スタックが無事作成されると以下図のリソースが作成されます。
ご確認ください。

EC2 にタグを付与

起動停止の対象にしたい EC2 インスタンスにタグを付与します。
CloudFormation のパラメーター EC2TagKey、EC2TagValue に指定したタグを付与してください。
デフォルトのままであれば以下図のようになります。

残業したい

今日だけは決められた時間にシャットダウンされたくない、残業したいという際には、タグバリューを true 以外 に変更してください。スケジュールの対象外となるためシャットダウンされなくなります。 元の true に戻すことを忘れずに!

祝日や業務カレンダーの反映

日本の祝日や自社の業務カレンダーを反映したい需要はあると思います。
Change Calendar は ics 形式でイベントのインポートが可能です。
Google カレンダーの「日本の祝日」や、自社で使っているカレンダーアプリから ics をエクスポート&インポートしてみてください。
もちろん、マネジメントコンソールから地道に入力も可能です。

まとめ

Cron での定期実行ではなく、カレンダーを使いたいという気持ちから Change Calendar で頑張ってみました。
祝日や長期休暇を考慮したスケジュールを組みたい方の参考になれば幸いです。

参考

AWS Systems Manager Change Calendar ユーザーガイド
待望の機能!AWS Systems Manager Change Calendar でより柔軟な定期処理実行が可能に!!
AWS Systems Manager Change Calendarで祝日を設定したジョブ実行が可能になりました

以上、吉井 亮 がお届けしました。