AWS EC2インスタンスの起動・停止をスケジュール実行してみた

## はじめに
テスト環境など、常時起動しておく必要のないインスタンスは、コスト削減の観点などから、決まった時間に起動、停止するようにしたいと考える人は多いと思います。

以前は、λでコードを書いたりする必要があったりしましたが、最近では、CloudWatch Eventsの後継のEventBridgeとSystemsManagerのオートメーションドキュメントを利用する事で、簡単にEC2インスタンスのスケジュール実行ができるようになっているので、改めて確認してみました。

## IAMロールの作成
事前にIAMロールを作成しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/dc806c4c-d32c-ad71-b992-b458c89b7d1f.png)
EventBridgeには、オートメーションドキュメントとパラメータを使用して、SSM Start Automation Execution を呼び出すための権限が必要です。

:::note warn
EventBridgeで自動起動・停止設定をする際に、必要なロールを自動作成できるような選択肢がありますが、それだけではSystemsManagerのオートメーションが起動できずエラーになります。
:::
必要なロールを作成していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/2049f504-4bbb-793f-391e-99a133f81a30.png)
信頼されたエンティティを選択で、「カスタム信頼ポリシー」を選択し、エディターで以下のように編集します(Principalに`"Service": "events.amazonaws.com"`を追記)。
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "events.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```
編集後、「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/31480b35-4474-abb1-78fd-581a52d4c6b9.png)
許可を追加で、AWS管理ポリシー`AmazonSSMAutomationRole`を追加し、「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/cd2f913b-ff1c-a0f9-9cee-b0e4af27940b.png)
ロール名を入力(この例では「events-ssm-ec2-start-and-stop-role」)し、信頼されたエンティティ、追加する許可ポリシーを確認後、「ロールを作成」をクリックします。

## EC2インスタンスの自動起動設定
EventBridgeで、イベントルールを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/d4265c9c-9d5f-c893-276d-e5314c935715.png)
まず、インスタンスの起動ルールを作成していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/b02f373c-1f4f-35e7-a3dd-e432b937c374.png)
以下のように設定し、「次へ」をクリックします。
- 名前：「EC2-instance-Start」※任意
- イベントバス：default
- ルールタイプ：スケジュール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/f8f7eaa7-a022-6adb-25f0-5e915213d460.png)
スケジュールを定義していきます。

スケジュールパターンには、「特定の時刻(毎月第1月曜日の午前8時(PST)など)に実行されるきめ細かいスケジュール」を選択し、Cron式でスケジュールのCron式を定義します。

この例では、「2022年の8月、9月の月曜日から金曜日の日本時間10時」を指定しました。

※Cron式については、以下を参照してください。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/ScheduledEvents.html#CronExpressions

:::note info
Cron式の指定が正しい場合、以後10回のトリガー日に指定した日時が表示されます。何も表示されない場合、Cron式の指定が間違っているので、指定内容を見直してみてください。
:::

次に、イベント発生時に実行するターゲットを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/f166a8df-b1f0-5078-54b8-2c924b711c68.png)
ターゲットには、以下を設定します。
| 項目 | 設定値 |
|:-|:-|
| ターゲットタイプ | AWSのサービス |
| ターゲットを選択 | System Manager オートメーション |
| ドキュメント | AWS-StartEC2Instance |
| ドキュメントのバージョン | デフォルト |

続いて、パラメータの設定と実行ロールを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/666cda7e-ed68-1721-8e5e-3e21f541f1fe.png)
自動化パラメータを設定で、「定数」を選択し、InstanceIdに起動させたいインスタンスのインスタンスIDを指定します。

:::note info
複数のインスタンスIDを指定したい場合は、["i-XXXXXXXXXXXXXXXXX", "i-YYYYYYYYYYYYYYYYY"] のように指定します。
:::
実行ロールには、事前に作成しておいた既存のロール、「events-ssm-ec2-start-and-stop-role」を選択します。

全ての設定が終わったら、「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/46755efb-c466-564b-41a3-9330b7590444.png)
必要に応じてタグを設定します。

最後に、レビューと作成で設定内容を確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/b3623717-f63c-7009-16a0-31759046ddc9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/989d6d59-9f0c-a87f-7bf8-f6c654024d21.png)
ルールタイプおよびスケジュール設定、ターゲットの設定に問題が無ければ、ルールを作成します。

## EC2インスタンスの自動停止設定
インスタンスの起動ルールと同様に、停止ルールを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/ac6c6611-5871-ca75-ffd3-65233731554b.png)
以下のように設定し、「次へ」をクリックします。
- 名前：「EC2-instance-Stop」※任意
- イベントバス：default
- ルールタイプ：スケジュール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/598e577a-9c87-ca8a-db94-321a38a77bda.png)
スケジュールを定義します。
この例では、「2022年の8月、9月の月曜日から金曜日の日本時間22時」を指定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/a144d0ba-eac8-142a-9253-4b487d61a5bb.png)
ターゲットには、以下を設定します。

| 項目 | 設定値 |
|:-|:-|
| ターゲットタイプ | AWSのサービス |
| ターゲットを選択 | System Manager オートメーション |
| ドキュメント | AWS-StopEC2Instance |
| ドキュメントのバージョン | デフォルト |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/666cda7e-ed68-1721-8e5e-3e21f541f1fe.png)
自動化パラメータを設定で、「定数」を選択し、InstanceIdに停止させたいインスタンスのインスタンスIDを指定します。

:::note info
複数のインスタンスIDを指定したい場合は、["i-XXXXXXXXXXXXXXXXX", "i-YYYYYYYYYYYYYYYYY"] のように指定します。
:::
実行ロールには、事前に作成しておいた既存のロール、「events-ssm-ec2-start-and-stop-role」を選択します。

全ての設定が終わったら、「次へ」をクリックします。

必要に応じてタグを設定し、レビューと作成で設定内容を確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/1a513402-c699-9917-9ede-b9f36d4594d4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/5e653fc0-bc1d-a793-570a-21d508fb23f2.png)
設定内容に問題が無ければ、ルールを作成します。

## 動作確認
管理コンソールのEC2のインスタンス一覧で、ターゲットに指定したインスタンスが、指定した時間に起動、停止するかを確認します。

もしくは、Systems managerのオートメーションからも確認する事ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2554521/1b47c205-f4f1-9815-17de-f54272934041.png)
指定した時間にオートメーションドキュメントが実行され、ステータスが「成功」になっていれば、動作確認完了です。

## おわりに
EC2インスタンスの起動・停止をスケジュール実行してみました。

AWSのサービス改善により、以前より簡単に設定ができるようになっている事が確認できました。