EC2 SchedulerでEC2を平日だけ稼働させてコスト削減する

# 背景
EC２の中には平日だけ使うので休日は停止してコスト削減したい、という例はあるかと思います。今回対象してしているEC２はt2.largeのwindowsサーバとなりますが、この場合のコストが`$0.1208 / 1時間`なので、月額720h（30日）で計算すると、休日2日（48時間）を停止させると、日本円で**約2650円**(1USD / 106JPY)ほど削減することが可能です。

- Amazon EC2 料金表  
https://aws.amazon.com/jp/ec2/pricing/on-demand/

# 概要
AWSにて、EC2の起動/停止をスケジュールする仕組みをEC2Schedulerとしてcloudformationにして提供しています。
内容は、CloudWatch Eventsで指定したcron形式の日時でLambdaが実行され、起動/停止の時間を記載したタグをつけたEC2を探してlambdaが起動/停止するというものです。

参考にしたのはこちらの手順です。
https://dev.classmethod.jp/articles/aws-answers-try-ec2-scheduler/

# 手順
1. AWS公式の以下URLからCloudFormationテンプレートのスタックを起動させます。  
https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/new?stackName=ec2-scheduler&templateURL=https://s3.amazonaws.com/solutions-reference/ec2-scheduler/latest/ec2-scheduler.template

2. CloudFormationスタックに名前をつけ、タグやcloudwatch Eventのパラメータ設定を行います。デフォルトでは５分起動となっています。何も変更しなくても作成は可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252317/4e597041-5d9a-d21d-2e77-a7536bd39d22.png)

3. IAMロールが作成されることを確認し、承認にチェックをして作成してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252317/03d09851-26ed-5c7e-0e7b-2a6c6c873461.png)

4. 作成後数分で、作成する各種サービスが「CREATE COMPLETE」となることを確認してください。  
 - lambda
 - DynamoDB
 - 各種サービスに対するパーミッション
 - IAM  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252317/1d5e3f4f-2b2b-a8a5-3a18-1f0687f95769.png)

5. lambdaに2つの関数が完成していることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252317/d5460d79-f243-0b3d-37ef-d084476543be.png)

6. DynamoDBが作成され、指定したパラメータの値が入っていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252317/46e0d9af-fac2-30c1-ddb3-5f404575ce2e.png)

7. CloudWatchではこのような形でcron形式のルールが作成され、指定した間隔でlambdaを呼び出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252317/a6b5a59f-a495-04e7-a5a1-cbe856ced904.png)

8. EC2に起動や停止時間を指定するタグをつけます。
時間はUTCで指定する必要があり、私の場合は日本時間の土曜の朝８時に停止し、月曜日の朝８時に起動する設定とするために以下のタグをつけています。
起動と停止でタグを２つに分けているのは、同じ時間（UTC標準23時）だと稼働しないからです。停止している時しか起動のタグ指定は稼働せず、逆に起動している時しか停止のタグは稼働しません。

| キー   |値    |
|:--|:--|
| scheduler:ec2-startstop:start| 2300;none;utc;sun|
| scheduler:ec2-startstop:stop|none;2300;utc;fri 

以下の例の通り、起動時間が停止時間より早ければ同じタグ内で表記可能です。

| タグ値の例 | 説明 |
|:--|:--|
| 0800;1800;utc;all | インスタンスは08:00に開始し、18:00にすべての曜日に停止します。 |
| 1000;1700;utc;weekdays | インスタンスは10:00から開始し、月曜日から金曜日の17:00に停止します。 |
| 1030;1700;utc;mon,tue,fri | インスタンスは10:30に開始し、月曜日、火曜日、金曜日にのみ17:00に停止します。 |
| 0815;1745;utc;wed,thu | インスタンスは8:15に開始し、水曜日と木曜日のみ17:45に停止します。 |
| none;1800;utc;weekdays | インスタンスは、月曜日から金曜日の18:00に停止します。インスタンスは手動で起動する必要があります。 |
| 0800;none;utc;weekdays | インスタンスは月曜日から金曜日の08:00に開始します。インスタンスを手動で停止する必要があります。 |
| none;none;utc;weekdays | インスタンスは手動で開始および停止する必要があります（自動アクションは実行されません）。 |
| 0800 | インスタンスは8:00に開始され、Amazon DynamoDBテーブルに格納されているデフォルトのアクティブ日にデフォルトの停止で停止します。 |
| 0800;1800 | インスタンスは、Amazon DynamoDBテーブルに格納されているデフォルトの有効日数で、08:00に開始し、18:00に停止します。 |
| 0800;1800;utc | インスタンスは、Amazon DynamoDBテーブルに格納されているデフォルトの有効日数で、08:00に開始し、18:00に停止します。 |
| default | インスタンスは、デフォルトのスケジュールで開始および停止します。 |
| True | インスタンスは、デフォルトのスケジュールで開始および停止します。 |
| EMPTY | インスタンスに対して実行されるアクションはありません。 |
| Random String | インスタンスに対して実行されるアクションはありません。 |


# 結果
CloudWatch logのイベントから、対象のタグがついたEC2が指定した時間帯に停止/起動されていることが分かります。　　

- 停止時  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252317/a50beedc-b413-64ac-5047-bcdd61d1200c.png)
- 起動時  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252317/700826b5-9327-f9a9-2936-de00e688fad6.png)