AWS Instance Scheduler

<!-- AWS Instance Scheduler -->

![nixie_tube_clock.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486518/4938b4fa-830f-d445-efae-5af41cb60c4d.png)

* *2021/06/14 追記: 最新版では [Cross-Account instance scheduling](https://docs.aws.amazon.com/ja_jp/solutions/latest/instance-scheduler/components.html#cross-account-scheduling) がサポートされているようです。複数アカウントで利用したい場合は検討してみると良いでしょう*

----

EC2 インスタンスを任意のスケジュールで起動・停止させたいという需要は多いと思います。
自作の Lambda function でスケジューリングする方法も思い浮かびますが、面倒なのでツールの自作はしたくありません（笑）
なんかもっといいものが無いのでしょうか。
[調べたら](https://www.google.co.jp/search?&hl=en&q=ec2+instance+auto+on+off) 、  [ありました](https://aws.amazon.com/solutions/instance-scheduler/) 。AWS 純正ですね。もとは EC2 Scheduler と呼ばれていたものがリニューアルされたようです。この記事執筆時点では `Version 1.2 Last updated: 06/2019` となっています。
これは筋が良さそうですので早速試してみましょう。

## ドキュメントを読む

ふーん、こうなってるのですね
https://docs.aws.amazon.com/ja_jp/solutions/latest/instance-scheduler/architecture.html

公式を読むのが一番ですが、残念なことに 2019/09 現在、日本語版は整備されていないようです。仕方ありませんのでこのまま英語版を読み進めて行きましょう
CloudWatch, DyanmoDB, Lambda で実装されているようですね。これらを CloudFormation で展開してゆくようです

## Deployment

これに沿ってやっていきましょう
https://docs.aws.amazon.com/ja_jp/solutions/latest/instance-scheduler/deployment.html

### Step 1. Launch the Instance Scheduler Stack （インスタンス スケジューラ スタック の起動）

https://docs.aws.amazon.com/ja_jp/solutions/latest/instance-scheduler/deployment.html#step1

https://aws.amazon.com/solutions/instance-scheduler/ から `Launch solution in the AWS Console` というリンクをクリックしていきましょう
region / time zone に注意してください
ここではスタック名は `Instance-Scheduler` とします
遷移先では画面の案内に従って進みます
パラメータはドキュメントに説明がありますので参考に

### Step 2. Configure Periods （Periods の設定）

マネコンか [専用CLI](https://docs.aws.amazon.com/ja_jp/solutions/latest/instance-scheduler/appendix-a.html) から設定可能とのこと。ここでは CLI でいくことにします

#### Step 2-a scheduler-cli のインストール

https://docs.aws.amazon.com/ja_jp/solutions/latest/instance-scheduler/deployment.html#step2

Periods の設定そのものの前にこの CLI を開発環境（自分のマシン）にインストールします
実際にやることをスクリプトで示しますとこのようになります

```
#!/bin/bash
readonly workdir=`mktemp -d`
cd $workdir
wget https://s3.amazonaws.com/solutions-reference/aws-instance-scheduler/latest/scheduler-cli.zip
unzip scheduler-cli.zip
pwd
ls
python setup.py install
#confirmation
scheduler-cli --version
```

#### Step 2-b Periods の設定

ここからが `Step 2` の本番です。実行したコマンドと結果

```
stack='Instance-Scheduler'; aws_profile='sandbox'; name=office-hours; region=ap-northeast-1; scheduler-cli update-period --name $name --begintime 09:00 --endtime 23:00 --weekdays mon-fri --stack $stack --profile-name $aws_profile --region $region
{
   "Period": {
      "Name": "office-hours",
      "Endtime": "23:00",
      "Type": "period",
      "Begintime": "09:00",
      "Weekdays": [
         "mon-fri"
      ]
   }
}
```

`update-period` します。前提知識として `office-hours` は instance-scheduler 上、デフォルトで定義済みとなっております。時間だけを我々の事情にあわせ指定しなおしたいので、このように実行するわけです。
`--profile-name` に指定する値は `awscli` のそれと等価です。適宜 `aws configure` しておきましょう（ここでは `sandbox`）
見ての通りですが、日本時間毎週月~金 09:00 に起動し、23:00 に停止させよ、という定義です。

### Step 3. Configure Schedules （スケジュール の設定）

https://docs.aws.amazon.com/ja_jp/solutions/latest/instance-scheduler/deployment.html#step3

`scheduler-cli` は前の Step でインストール済みなので早速 `scheduler-cli create-schedule` を実行します
実行したコマンドと結果

```
% periods=office-hours; schedule=jp-office-hours; description='defined by user'; stack='Instance-Scheduler'; aws_profile='sandbox'; region='ap-northeast-1'; scheduler-cli create-schedule --stack $stack --name $schedule --periods $periods --description "$description" --timezone Asia/Tokyo --profile-name $aws_profile --region $region

{
   "Schedule": {
      "RetainRunning": false,
      "Enforced": false,
      "Hibernate": false,
      "Description": "defined by user",
      "UseMetrics": false,
      "StopNewInstances": true,
      "Periods": [
         "office-hours"
      ],
      "UseMaintenanceWindow": false,
      "Timezone": "Asia/Tokyo",
      "Type": "schedule",
      "Name": "jp-office-hours"
   }
}
```

`--name` で指定した文字列を控えておきましょう。次で使います（ここでは `jp-office-hours` を指定）

### Step 4. Tag Your Instances （インスタンスにタグ付け）

https://docs.aws.amazon.com/ja_jp/solutions/latest/instance-scheduler/deployment.html#step4

ここまでくればもう出来たも同然。
あとは目当てのインスタンスに次のタグをつけるだけの簡単なお仕事です。マネコンでも CLI でもよいですが、次のようにします

|key|value|
|---|---|
|Schedule|jp-office-hours|

* タグ名はデフォルトで `Schedule` です。 Step 1 でカスタム値を指定している場合はそれになります
* 値は前 Step で定義した値（ここでは `jp-office-hours`）となります

これで最低限の設定は完了

## 動作確認

あとはこのインスタンスが指定時間に期待したステートに遷移するのを確認しましょう

## まとめ

Instance Scheduler を使ってお手軽にインスタンスの起動・停止をスケジューリングすることができました。
ポイントは
* AWS ネイティブによる安心感
* Lambda, DynamoDB 等によるシンプルな構成
* 本ツールにおける Period と Schedule の概念を把握すること、
といったところでしょうか。
展開後、各リソースをマネコンから覗いてみると理解が深まるかと思います。

以上です。

<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#">
<meta property="og:type" content="artcle" />
<meta property="og:image" content="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486518/4938b4fa-830f-d445-efae-5af41cb60c4d.png" />
<meta property="og:description" content="EC2 インスタンスを任意のスケジュールで起動・停止させたいという需要は多いと思います。自作の Lambda function でスケジューリングする方法も思い浮かびますが、面倒なのでツールの自作はしたくありません（笑）なんかもっといいものが無いのでしょうか。" />
</head>