EventBridgeのスケジュール機能を使った自動起動/停止

# 1.はじめに
今回は業務で使っているEC2やDB（RDS、DocumentDB）といったリソースを使っていない時間帯は停止して、コスト削減をしたい！という目的でEventBridgeを初めて使う機会があったので、使い方や設定で詰まったところなどを共有できたらと思います。
本記事ではEventBridgeのスケジュール機能の紹介になるので、AWSアカウントの作成やDBなどのリソース構築については省略させていただきます。

# 2.前提
### 2-1.EventBridgeを使うに至った経緯
「はじめに」もある通り、私の参画しているプロジェクトでコスト削減を目的に、DBや踏み台に使っているEC2を操作しない時間帯（夜間）に停止できないかという施策の提案がありました。
ただ、リソースを平日毎日起動/停止するのは現実的ではない、、、
ということで、スケジュールベースで自動的にリソースの起動/停止をしてくれるサービスとしてEventBridgeを使ってみました。
### 2-2.やりたいこと
基本的には上記にあるとおりですが、イメージとしては次のようになります。
↓今までの曜日時間関係なく稼働し続けていたリソースのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/95a07efe-c389-66d3-48dc-5803f6660091.png)

↓作業しない時間帯はリソースを停止した場合のイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/fcb876f3-adb1-2d28-38f9-ab8f49e29456.png)


<dl>
  <dt>対象</dt>
  <dd>DB（Aurora・DocumentDB）、EC2</dd>
  <dt>スケジュール</dt>
  <dd>始業前に起動、平日夜間と休日に停止</dd>
  <dd>・自動起動：平日午前8時<dd>
  <dd>・自動停止：平日午後9時<dd>
</dl>
本記事では一例としてAuroraの自動起動/停止を取り上げます。

# 3.EventBridgeのスケジュール機能の説明
### 3-1.EventBridgeとは
そもそもEventBridgeとは、**イベントを通じて様々なアプリケーション同士を簡単に接続できるようにするサーバレスサービス**というものになっています。
ここでいうイベントの例を挙げると、「EC2が停止した」や「S3にオブジェクトが入った」などがあり、このイベントをトリガーにAWSサービスを動かしたりすることができるというものです。
いわゆる「イベント駆動型サービス」というものですね。

:::note
ちなみに
上記の説明にあるイベントの対象には、AWSサービスの他にもSaaSアプリケーションや自作アプリケーションも含まれるので使い方次第で色々できてしまう便利なサービスです。
:::

### 3-2.EventBridgeのスケジュール機能について
EventBridgeの機能のひとつに**EventBridge Scheduler**というものがあります。

https://docs.aws.amazon.com/ja_jp/scheduler/latest/UserGuide/what-is-scheduler.html

これが本記事のテーマとして挙げているEventBridgeのスケジュール機能になります。
EventBridge Schedulerは、タスクを作成・実行・管理ができます。
タスクの例として以下のようなものがあります。
* 毎日〇時に特定のLambda関数を実行
* 2024/4/1 12:00にEC2インスタンスを停止

このようなタスクを時間通りに実行してくれる機能になります。

:::note
スケジュール設定の仕方によっては繰り返しの定期実行ができるので今回の「リソースを平日毎日起動/停止」するという要望に応えることができます！
:::

# 4.EventBridge Schedulerを実際に設定してみる
では実際にEventBridge Schedulerを設定してみましょう。
今回はAuroraの自動停止のスケジュールの説明を行います。
### 4-1.IAMロールの作成
まずはEventBridgeにAuroraを起動/停止する権限を与えるためのIAMロールの作成を行います。
信頼ポリシーは以下の内容で設定します。
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "scheduler.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

ロールにアタッチするIAMポリシーは以下の内容です。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "rds:StartDBCluster",
                "rds:StopDBCluster"
            ],
            "Resource": "{DBのAmazon リソースネーム}"
            ]
        }
    ]
}
```
ここでActionにStart・StopDBClusterとしたのですがDBInstanceにするとAuroraのフェイルオーバー機能が働いてしまいうまく停止ができないと思われるのでDBClusterにします。
また、Resourceの{DBのAmazonリソースネーム}はAuroraの設定値に書いてあるのでコピペします。
↓Auroraのコンソール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/1a090b33-d285-61f8-d425-4ecae091badf.png)

### 4-2.EventBridge Schedulerの設定
続いて、EventBridge Schedulerを設定していきます。
コンソールのEventBridgeのページから、「スケジュール」をクリックします。
↓EventBridgeのページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/df74c5a3-b177-e3a5-ac28-e3a4b0c47168.png)

EventBridge Schedulerのページに移動後、「スケジュールを作成」をクリックします。
↓EventBridge Schedulerのページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/4f235d8a-a33a-d626-cae4-0d90fc5e8f57.png)

スケジュールを作成する画面に移動するとまず、スケジュール名やスケジュールのパターンなどを設定します。ここでは特に必須項目や注意点の説明を行います。
↓スケジュール設定画面の一部
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/500c53af-6ec7-c0b9-3a92-83742462025e.png)



**スケジュール名**
必須項目になります。作成後は変更できないので複数作る場合などは特に命名規則などに注意して設定します。

↓スケジュール設定画面の一部
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/6889aae6-3232-7dcb-27f9-0849b8c267fc.png)

**頻度**
「定期的なスケジュール」を選択

**タイムゾーン**
わかりやすく日本時間で設定したいので「(UTC+09:00) Asia/Tokyo」を設定
※デフォルトで設定してあると思います。

**スケジュールの種類**
「cronベースのスケジュール」を選択

**cron式**
cron式のリファレンスがあるので以下のページを参考に設定します。

https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-cron-expressions.html

今回は平日の21時ちょうどにAuroraを停止するスケジュールを設定したいため画像のような設定値になります。

:::note warn
cron式の下に「次の 10 個のトリガー日」が表示されるので、正しくcron式が設定できているか確認しましょう。
:::


**フレックスタイムウィンドウ**
フレックスタイムウィンドウとは、スケジューラは指定した時間枠内でスケジュールを呼び出しを行う機能です。上記の設定時間を起点にフレックスタイムウィンドウで指定した時間以内に実行されることになります。
ただし今回は21時ちょうどに停止させたかったので「オフ」に設定しました。

↓スケジュール設定画面の一部
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/cb92e3e9-acd2-6c41-2b1e-bb7f21eb30e3.png)

**時間枠**
今回は設定しなかったので省略します。

「次へ」ボタンをクリックします。

**ターゲットの選択**
今回はAuroraの起動を設定したいので以下のような流れで設定を行います。
↓ターゲットの選択画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/ba07a78e-1bb8-e2de-ebba-50205d12b102.png)
**【設定手順】**
**1\. ターゲットAPIは「すべてのAPI」を選択**
**2\. 検索バーに「RDS」と入力**
**3\. 検索結果から「Amazon RDS」をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/2d26a8be-f5af-c707-4d18-d584f37738fc.png)
**4\. 検索バーに「stop」と入力**
ここで、自動起動スケジュールの場合は「start」を入力します。

**5\. 検索結果から「StopDBCluster」をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/b11200fd-507c-603f-fd29-4d8f5c78acf1.png)

**6\. "MyData"の部分に目的のAuroraのDBクラスターIDを入力**
IAMポリシー作成時にAmazonリソースネームを参照したRDSの設定値のページにある「DBクラスターID」をコピペします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/5f43bfbf-ee93-af1e-10b8-9d9db1fb87af.png)
上記1～6の設定が完了したら「次へ」をクリックします。
次の設定画面へ移動後、以下の設定を行います。

**スケジュールの状態**
スケジュールを今すぐ有効化したい場合は有効化に設定します。
スケジュール作成後に任意のタイミングでスケジュールを有効化できます。

**スケジュール完了後のアクション**
「DELETE」を選択した場合、最後の呼び出しが完了し、今後ターゲットとなる呼び出しが予定されていないと、自動的にスケジュールを削除する機能です。
繰り返しの処理で期限を決めていないのでどちらでも大丈夫と思われますが、今回はNONE（削除しない）を選択します。

**再試行ポリシーとデッドレターキュー (DLQ)**
あまり気にしなくても（変更しなくても）良い設定で、デフォルトでも大丈夫だと思いますが、起動/停止が失敗した場合何度も実行されるとなんとなく不安なので再試行回数を1回にします。
↓設定画面の一部
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/a3ed73dd-0f24-9a72-0e0e-2cdde1fa56e0.png)

**暗号化**
チェックせずデフォルトで設定します。

**アクセス許可**
「既存のロールを使用」を選択し、先ほど作成したIAMロールを選択します。

最後に「次へ」をクリックします。
↓設定画面の一部
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622326/d90c0e55-0bb8-c1ce-d122-0318a4684af7.png)

画面移動後、スケジュールの確認と作成というページになるので設定値を確認して問題なければページ下部へスクロールし、「スケジュールを作成」をクリックします。
もし修正点がある場合は各ステップごとに編集ができるので「編集」をクリックします。

### 4-3.確認
スケジュールを作成した後は想定通りの挙動をしてくれるかしっかり確認します。
今回はAuroraの自動停止スケジュールを設定したのでAuroraのコンソールを開き、目的のAuroraが時間通り停止しているかステータスの確認を行います。
ステータスが**停止**になっていれば成功です！

### 4-4.ポイント
今回EventBridge Schedulerを設定していて感じた注意点や実際に詰まってしまったポイントを以下にまとめます。

**必ずテストをする**
スケジュール作成後にスケジュールの有効-無効を切り替えたり、スケジュールを変更することが可能です（コンソールでスケジュールを選択して「編集」をクリックすると編集画面へ移動できます）。
試験的にスケジュールを5分後などに設定して想定通りに動くか確認します。
当たり前のことですが、ぶっつけ本番で行わないで事前にテストをしましょう。

**DocumentDBのポリシーはAuroraとほぼ同じ**
これに関しては知っている人はそうだよねという感じだと思います。
ただ、自分が今回ポリシーの作成で詰まってしまったので共有させてください。
Auroraのポリシーについては手順で説明した内容になるのですが、ほぼ同じです。
唯一異なる点はResourceの部分のみ、、、
DocumentDBでも以下に示すようにRDSと同じポリシーが使えます。
ちなみに、EventBridge Schedulerの設定中に出てくるターゲットAPIの選択ではAuroraとDocumentDBは区別されるので注意ポイントです(´・ω・｀)
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "rds:StartDBCluster",
                "rds:StopDBCluster"
            ],
            "Resource": {DBのAmazonリソースネーム}
            ]
        }
    ]
}
```

# 5．おわりに
今回はAuroraの自動停止の設定のみだったのですが、各設定をちょっといじるだけで対象のサービスを変更できたり、起動にできたり、スケジュールの変更ができます。なので、EC2とAurora、DocumentDBといった他のサービスのスケジュール作成も簡単に作成できました！変更が容易にできるのでもしイレギュラーな時間帯に作業が必要になっても無効化やスケジュールを修正するだけで対応できちゃうので便利ですね！
今のところ安定して想定通りの動きをしてくれているの安心しています。
本記事執筆時点ではスケジュール設定からまだ日が浅いのでどれだけコストを削減できるか楽しみです、、、！

また、同じシステムでECSを使用しているので、ECSも同様に作業が発生しない夜間帯や休日にタスク数を減らしたかったのでできないかと[記事](https://dev.classmethod.jp/articles/eventbridge-scheduler-regularly-start-and-stop-ecs-tasks/)を参考にしたのですが、結果としてECSに関してはEventBridgeではなくCLIを使ってAutoScalingのスケジュール設定をしました。というのも、ECSのコンソール上で必要数を最小数最大数の範囲を外れた値で設定をしようとするとエラーが出てしまいますが、必要数が最小数最大数から外れた値をEventBridgeでは設定可能となり、どのような挙動をするか確証が得られず不安というところが理由になります。
※以下の記事を参考にしました。

https://qiita.com/tatematsu-k/items/0f75ff972f7ea5d32693

https://dev.classmethod.jp/articles/ecs-scheduled-autoscaling/

もし同じような機能を使ってコスト削減などを行う人の参考になれば幸いです。
読んでいただきありがとうございました！

# 6．参考
* [Amazon EventBridge スケジューラとは](https://docs.aws.amazon.com/ja_jp/scheduler/latest/UserGuide/what-is-scheduler.html)
* [スケジュールに従って実行する Amazon EventBridge ルールの作成](https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-create-rule-schedule.html)
* [【SSM・Lambda不要】Amazon EventBridge SchedulerでAuroraの自動停止を実装してみた](https://dev.classmethod.jp/articles/amazon-eventbridge-scheduler-aurora-stop/)
* [cron 式のリファレンス](https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-cron-expressions.html)
* [EventBridge Scheduler で ECS タスクの起動と停止を自動化してみた](https://dev.classmethod.jp/articles/eventbridge-scheduler-regularly-start-and-stop-ecs-tasks/)
* [ECSサービスを時間指定でスケーリングする](https://qiita.com/tatematsu-k/items/0f75ff972f7ea5d32693)
* [ECSをスケジュールベースでスケールさせる](https://dev.classmethod.jp/articles/ecs-scheduled-autoscaling/)