AWS Instance Schedulerを使ってEC2インスタンスを自動起動・自動停止する

# はじめに
AWS Instance Schedulerは、Amazon Elastic Compute Cloud (Amazon EC2) と Amazon Relational Database Service (Amazon RDS) のインスタンスの開始と停止を自動化するためのアーキテクチャです。

本記事では、実際にInstance SchedulerをCloudFormationテンプレートから払い出して、最もシンプルな形でのEC2インスタンスの自動起動・自動停止を実践してみます。


# Instance Scheduler アーキテクチャ
AWSの公式からアナウンスされているInstance Schedulerのフル機能は、下記のようなアーキテクチャ図になります。

![instance-scheduler-on-aws.6a76bdccb7ff3610934f86dba7d1d4678a0b9e4b.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/eb8ba119-30c5-8dad-bd57-dd2630144947.jpeg)
↓
↓　今回利用する機能だけに絞ったアーキテクチャ図はこんな感じ。
↓
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/3d9b3468-9f27-3ec7-7562-47b0215adf91.png)

かなりシンプルな図になりましたね。
流れとしては、以下のようになります。

①CloudWatchが定義した間隔で、Lambda関数が呼び出される。
②呼び出されたLambda関数は、DynamoDBに保存されているスケジュール定義を読み込む。
③読み込んだスケジュール定義とEC2に付与されている「Schedule」タグを照合して、
　Lambda関数がインスタンスの起動停止をコントロールする。


# Instance Scheduler ハンズオン
実際にInstance SchedulerをCloudFormationから払い出してみましょう。

ざっくり手順
1.　CloudFormationテンプレートからInstance Schedulerを払い出す。
2.　DynamoDBに保存されているスケジュール定義を変更して、
　　独自のスケジュールを作成する。
3.　インスタンスに、Lambda関数が参照するタグを付与する。
4.　インスタンスが自動で停止・起動していることを確認する。

それではやっていきます。

### 1.　CloudFormationテンプレートからInstance Schedulerを払い出す。
・まずは下記のURLから、[AWSコンソールで起動する]を選択して、
　AWSコンソールとCloudFormationを起動させる。
【URL】https://aws.amazon.com/jp/solutions/implementations/instance-scheduler-on-aws/

![aaa240427_005.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/a0a16068-8b8d-96e9-ee4e-a4a2ce70d961.jpeg)

:::note warn
画面遷移後、**ログイン先のアカウント** と **払い出し先のリージョン**が
想定通りであることを確認する。
:::

<br/>

**・スタックの作成**
　全部デフォルトで[次へ]

<details><summary>画面キャプチャ</summary>

![240428_001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/f2027ba4-fc46-fb23-49ba-e4e1bad3ee45.jpeg)

</details>

<br/>

**・スタックの詳細を指定**
　下記の設定を変更して[次へ]

| パラメータ | 値 |
| ---- | ---- |
| スタック名 | InstanceScheduler |
| Default time zone | Asia/Tokyo |
| Enable CloudWatch Metrics | Yes |

<details><summary>画面キャプチャ</summary>

![240428_002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/15c61694-7167-f3ff-bf61-5c4ccc541a5a.jpeg)

![240428_003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/f2601e41-395e-0cf4-faf9-b28b1c27e059.jpeg)

![240428_015.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/b73da877-d9cb-0397-07eb-842e2bc26d18.jpeg)

![240428_005.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/944c90e6-a526-7554-b0ed-8b8832b3a450.jpeg)

</details>

<br/>

**・スタックオプションの設定**
　全部デフォルトで[次へ]

<details><summary>画面キャプチャ</summary>

![240428_006.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/6a6f609d-d0f5-56c1-aa55-6dcfccdd0e19.jpeg)

![240428_007.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/d5515a55-acbf-594a-55cf-ec7ba3c8de42.jpeg)

</details>

<br/>

**・確認して作成**
　画面最下部の下記にチェックを入れて[送信]
- [x] AWS CloudFormationによってIAMリソースが作成される場合があることを承認します。 

<details><summary>画面キャプチャ</summary>

![240428_008.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/1e608eec-5e45-a84d-16db-c1009673fe1f.jpeg)

![240428_009.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/910c9f7c-f776-3e82-7e23-6fa79f2f51a7.jpeg)

![240428_010.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/9cac9a63-c438-19f8-9f53-3c8221c87212.jpeg)

</details>

<br/>

スタックのステータスが[CREATE_COMPLETE]になったら完了です。

![240428_014.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/583c2172-6eee-d3bf-0431-e087bdab23f1.jpeg)

<br/>

### 2.　DynamoDBに保存されているスケジュール定義を変更して、独自のスケジュールを作成する。
DynamoDBのレコードと、インスタンスの自動停止・起動のスケジューリングは、
以下のように紐づけされています。
ピリオド定義、スケジュール定義、インスタンスに付与するタグをカスタマイズしていきます。
![IMG_1666758004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/508be825-7b35-c3a8-31ca-fe0e9d8a208d.png)

**・DynamoDBにアクセスして、レコードを確認**
　DynamoDBの中に、[InstanceScheduler-ConfigTable-*******]テーブルが
　あることを確認して、左ペインの[項目を探索]から上記テーブルの内容を参照する。

<details><summary>画面キャプチャ</summary>

![240428_023.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/b9d8d6e2-b5fa-57d3-a245-a9d98f8588c9.jpeg)

</details>

　それぞれのtypeと定義は下の表のように対応しています。
| type | 対応する定義 |
| ---- | ---- |
| Config | InstanceSchedulerのコンフィグ情報（変更不可） |
| period | ピリオド定義 |
| schedule | スケジュール定義 |

<br/>

**・新しい「ピリオド定義」(period)を作成**
　typeがperiodのレコードを、どれでもいいので[項目の複製]から複製後、
　インスタンスの起動停止時刻を指定する。
 
<details><summary>画面キャプチャ</summary>

 ![240428_033.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/b1b6033b-87c8-a847-bec1-039bbf2e8d68.jpeg)

![240428_044.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/b7c81be3-f047-6557-55bf-b0351ea60c7c.jpeg)

</details>

　今回は下記のように定義しました。
　土日のお昼頃に検証してただけなので、
　定義した時間に深い意味はありません。

| 属性名 | 値 |
| ---- | ---- |
| name | InstanceSchedulerTest |
| begintime | 11:10 |
| endtime | 11:20 |
| weekdays | sat-sun |

図にすると今こんな感じ。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/a8c376f3-f320-2678-4c4a-ece49626d0ab.png)

<br/>

**・新しい「スケジュール定義」(schedule)を作成**
　ピリオド定義と同じように、typeがscheduleのレコードを、
　どれでもいいので[項目の複製]から複製後、
　インスタンスに付与するタグ名とtimezoneを指定する。

<details><summary>画面キャプチャ</summary>

![240428_027.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/51382f76-c034-ed66-4823-4c1db47d90be.jpeg)

</details>
 
　下記のように定義しました。

| 属性名 | 値 |
| ---- | ---- |
| name | InstanceSchedulerTestSchedule |
| periods | InstanceSchedulerTest |
| time zone | Asia/Tokyo |

図にすると今こんな感じ。
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/2d27f672-59f3-dbcb-214e-bdef5dec9c8d.png)

これでDynamoDB内の操作は完了です。

<br/>

### 3.　インスタンスに、Lambda関数が参照するタグを付与する。
　インスタンスに、先ほどDynamoDBで指定した[Schedule]タグを付与します。
　インスタンスは前もって作成しておいたテスト用のインスタンスを使います。

<details><summary>画面キャプチャ</summary>
 
![240428_028.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/62807978-175f-e75f-09c3-177143182922.jpeg)

![240428_029.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/a9e3e27d-a960-ee2f-32ca-62d13765ecf6.jpeg)

![240428_030.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/457c7a76-8827-e4a9-7f37-01f5fb8ebc6b.jpeg)

</details>

図にすると今こんな感じ。完成です。
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/d7793470-d94e-7145-258b-f41498ce0237.png)

<br/>

### 4.　インスタンスが自動で停止・起動していることを確認する。
　定義した時刻にインスタンスが起動され、
　その後定義した時刻に終了していることが確認できます。

　インスタンスには起動・停止時に[InstanceScheduler-LastAction]タグが付与されます。
 ![240428_040.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/1c408c45-b0b2-c486-b569-22dc9585217e.jpeg)
![240428_041.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778694/56f7c48a-79ed-90e4-72c1-235d54477a28.jpeg)


# 所感
今回は最もシンプルな形での起動・停止でしたが、
CloudFormationテンプレートを変更することで機能拡張することも可能です。
必要ない機能を削ってもいいですし、機能を追加してもいいですし、
IaCはこうして容易に再現・拡張できるところがやはり大きなメリットですね。

# 引用元

[1]AWS での Instance Scheduler
https://aws.amazon.com/jp/solutions/implementations/instance-scheduler-on-aws/

[2]AWS での Instance Scheduler実装ガイド
https://d1.awsstatic.com/Solutions/ja_JP/instance-scheduler-on-aws.pdf

[3]InstanceScheduler on AWS Workshop ( Japanese )
https://catalog.us-east-1.prod.workshops.aws/workshops/7afe32b1-9ffa-4372-9a12-5905de89b593/ja-JP