AWS EC2をある決まった時間に自動で起動し、決まった時間で停止する方法を紹介します。
EC2の起動時間が短くなればコスト削減につながるので業務時間以外は停止させておきたいということはよくあると思います。
以前はAWS Lambdaで起動・停止用のスクリプトを組んで定期実行していましたが、現在はAWS Systems Managerを利用することで簡単に設定できるので、手軽にコスト削減を実現させるのにちょうどよい方法です。
15分程度で設定できるのでサクッとやってしまいましょう。
設定のおおまかな流れ
EC2の自動起動・停止はSystems Managerによって行うため、対象のEC2にSSM Agentがインストールされている必要があります。
また、自動起動・停止の実行用IAMロールの作成も必要です。
そのため、おおまかな流れとしては以下のようになります。
- EC2にSSM Agentをインストールする
- 起動・停止実行用のIAMロールを作成する
- CloudWatch Eventsで起動・停止の定期実行を設定する
EC2にSSM Agentをインストールする
まずは対象のEC2にSSM Agentをインストールしていきます。
(対象のEC2にすでにSSM Agentがインストールされている場合は本章をスキップして構いません。)
AWS Systems Managerコンソール画面を開き、「高速セットアップ」タブを開きます。

(クリックすると画像が拡大されます。)
これまで高速セットアップを使用したことがなければ、リストに履歴が表示されません。
その場合は以下の高速セットアップを使用したSSM Agentのインストールを参照してください。
以前に高速セットアップしたことがある場合は、リストに履歴が残っています。
その場合は以下の高速セットアップの設定変更を参照してください。
高速セットアップを使用したSSM Agentのインストール
AWS Systems Managerコンソール画面の「高速セットアップ」タブで「Create」をクリックします。

(クリックすると画像が拡大されます。)
次に「Host Management」を選択し、「Next」をクリックします。

(クリックすると画像が拡大されます。)
次に「Choose how you want to target instances」で「Manual」を選択し、リストから対象のEC2インスタンスを選択して「Create」をクリックします。

(クリックすると画像が拡大されます。)
高速セットアップは4つSuccessになっていれば後続の作業を始めて問題ありません。
セットアップの進みが遅ければ、対象EC2を再起動するとスムーズに進む場合があります。
この後の手順は「起動・停止実行用のIAMロールを作成する」に進みます。

(クリックすると画像が拡大されます。)
高速セットアップの設定変更
すでに高速セットアップを実行したことがある場合は、本章の手順で高速セットアップの対象EC2を追加します。
AWS Systems Managerコンソール画面の「高速セットアップ」タブで既存の実行履歴を選択し、「View details」をクリックします。

(クリックすると画像が拡大されます。)
「Configuration details」で既存の実行履歴を選択し、右上の「Action」から「Edit configuration option」をクリックします。

(クリックすると画像が拡大されます。)
高速セットアップの設定画面が表示されたら、新しい対象EC2にチェックをつけ「Update」をクリックします。

(クリックすると画像が拡大されます。)
既存の実行履歴が「Running」となれば対象EC2に対してインストールを開始しています。
高速セットアップは4つSuccessになっていれば後続の作業を始めて問題ありません。
セットアップの進みが遅ければ、対象EC2を再起動するとスムーズに進む場合があります。

(クリックすると画像が拡大されます。)
SSM AgentがインストールされているEC2の確認
SSM Agentがインストールされたか以下から確認できます。
AWS Systems Managerコンソール画面の「フリートマネージャ」タブで「マネージドインスタンス」に対象のEC2が存在するか確認します。

(クリックすると画像が拡大されます。)
起動・停止実行用のIAMロールを作成する
次に起動・停止実行用のIAMロールを作成する必要があります。
次章の「CloudWatch Eventsで起動・停止の定期実行を設定する」の中で設定中に「IAMロールを新規作成」してくれるのですが、現状だと以下のようなエラーが出てしまうので自分でIAMロールを作るのがお勧めです。

IAMコンソール画面を開き「ロール」タブから「ロールを作成」をクリックします。

(クリックすると画像が拡大されます。)
エンティティの種類で「AWS サービス」を選択しサービスで「Systems Manager」を選択しユースケースで「Systems Manager」を選択します。

(クリックすると画像が拡大されます。)
次にポリシーのフィルタに「AmazonSSMAutomationRole」と入力し、AmazonSSMAutomationRoleにチェックをつけて「次のステップ:タグ」をクリックします。

(クリックすると画像が拡大されます。)
タグは特につける必要ないかと思いますのでそのまま「次のステップ:確認」をクリックします。

(クリックすると画像が拡大されます。)
確認画面ではロール名とロールの説明を適宜入力し「ロールの作成」をクリックします。

(クリックすると画像が拡大されます。)
IAMロールの作成はまだ完了していません。CloudWatch Eventsからアクセスできるように「信頼関係」を設定する必要があります。IAMコンソール画面の「ロール」から作成したIAMロールを検索し、リンクをクリックします。

(クリックすると画像が拡大されます。)
作成したIAMロールの詳細画面を開いたら、「信頼関係」タブの「信頼関係の編集」をクリックします。

(クリックすると画像が拡大されます。)
jsonで書かれた信頼ポリシーがあるので、Service項目に「“events.amazonaws.com”」を追加します。
追加後、「信頼ポリシーの更新」をクリックします。

(クリックすると画像が拡大されます。)
IAMロールの詳細画面の「信頼関係」タブで信頼されたエンティティにさきほどの追加したevents.amazon.comが追加されていればOKです。

(クリックすると画像が拡大されます。)
IAMロールの作成は以上で完了です。あとはCloudWatch Eventsで定期実行を設定するのみです。
CloudWatch Eventsで起動・停止の定期実行を設定する
CloudWatchコンソールを開き「イベント」の「ルール」タブから「ルールの作成」をクリックします。

(クリックすると画像が拡大されます。)
以下のようにイベントソースには「スケジュール」で「Cron式」を入力します。今回は毎日AM8時(JST)に起動するようにしたかったので「0 23 * * ? *」と入力しました。このCron式は毎日23時(GMT)に動作するという意味で日本時間に直すと毎日AM8時ということになります。
ターゲットには「SSM Automation」を選択し、ドキュメントを「AWS-StartEC2Instance」を選択してInstanceIDに対象EC2のインスタンスIDを入力します。またIAMロールは新規作成ではなく、先ほど作成したIAMロールを選択すればOKです。

(クリックすると画像が拡大されます。)
あとはルール名と説明を適当に入力し、「ルールの作成」をクリックします。

(クリックすると画像が拡大されます。)
以下のように「成功」と表示され、作成したルールがリストに追加されていればOKです。

(クリックすると画像が拡大されます。)
自動起動設定は以上で完了です。続いて、同様に停止用の設定をしていきます。
起動ルールとの変更点は「Cron式」とドキュメントの「AWS-StopEC2Instance」です。
停止ルールではPM20時に停止したかったのでCron式は「0 11 * * ? *」としています。このCron式は毎日11時(GMT)に動作するという意味で日本時間に直すと毎日PM20時ということになります。

(クリックすると画像が拡大されます。)
先ほどと同様にルール名と説明を適当に入力し、「ルールの作成」をクリックします。

(クリックすると画像が拡大されます。)
こちらも「成功」と表示され、自動起動用と自動停止用のルールが表示されていればOKです。

(クリックすると画像が拡大されます。)
設定は以上です。あとは、想定した時間に自動起動および自動停止していることを確認してください。
自動起動・停止を設定するとEC2のパブリックIPが毎回変わることに困ることがあります。
そんな時は以下を参考に、EC2に特定のドメイン名でアクセスできるようにするよよいでしょう。
AWS Elastic IPから卒業し、EC2のパブリックIPを名前解決する
起動するごとに毎回変わるEC2のパブリックIPアドレスを動的にDNSレコードを書き換えることで常に同じ名前でアクセスできるようにします。興味があればぜひご覧ください。