EC2 インスタンスの起動と停止を自動化することは出来ますか?

2021.04.14

困っていた内容

1日のうち決まった時間帯のみ特定の EC2 インスタンスを起動させたい要件があります。毎回手動で行うのは手間なので、自動化させたいと考えています。

どうすればいいの?

Amazon Systems Manager のオートメーションと CloudWatch イベントを使用して自動起動、停止をスケジュールすることが可能です。

IAMロールを作成する

CloudWatch イベントの作成時に使用する IAM ロールを作成します。 CloudWatch Events には、提供された Automation ドキュメントとパラメータを使用して SSM Start Automation Execution を呼び出すための権限が必要です。

IAM コンソールよりロールを作成します。今回は event-ssm-automation-role という名前のロールを作成しました。IAM ロールには、下記のように AWS 管理ポリシーの AmazonSSMAutomationRole をアタッチします。

IAMロール

「信頼関係」タブを開き、「信頼関係の編集」より下記のように編集します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "events.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

IAMロール

CloudWatch イベントのルールを作成する

EC2 インスタンスを自動起動するための CloudWatch イベントのルールを作成します。CloudWatch コンソールのイベントから「ルールの作成」ボタンをクリックします。

イベント

下記画面でイベントソースを設定します。今回は、毎日特定の時間に EC2 インスタンスを起動するように設定したいため、cron 式で入力します。cron 式の書き方は下記ドキュメントをご参考ください。

参考ドキュメント: cron 式 - ルールのスケジュール式 - Amazon CloudWatch Events

今回は、「30 18 * * ? *」と入力しました。毎日 18:30 UTC にイベントが発生するような設定です。

イベント

次に、「ターゲットの追加」ボタンからターゲットを設定します。 ロールは「既存のロールを使用」に変更し、先ほど作成した IAM ロールを選択します。 全て設定出来たら「設定の詳細」ボタンをクリックします。

イベント

ルールの名前と説明を入力し、「ルールの作成」をクリックします。

イベント

ルールが作成されました。

イベント

同様の手順で EC2 インスタンスを自動停止させるための CloudWatch イベントルールを作成します。イベントソースにて「スケジュール」を選択し、Cron 式で「0 19 * * ? *」と入力しました。毎日 19:00 UTC にイベントが発生するような設定です。

ターゲットには、下記のように設定しました。SSM Automation の「ドキュメント」以外は先ほどの設定と同様です。全て設定出来たら「設定の詳細」ボタンをクリックします。

イベント

ルールの名前と説明を入力し、「ルールの作成」をクリックします。

イベント

ルール作成完了です。

イベント

実行確認

まずは、インスタンスの自動起動の確認です。指定のインスタンスを停止状態にしておきます。

ec2

設定した時間にインスタンスのステータスが「実行中」となりました。

ec2

Amazon Systems Manager コンソールの自動化でオートメーションの実行が成功していることを確認しました。

オートメーション

次に、インスタンスの自動停止の確認です。設定した時間にインスタンスのステータスが「停止済み」となりました。

ec2

Amazon Systems Manager コンソールの自動化でオートメーションの実行が成功していることを確認しました。

オートメーション

さらに、CloudTrail コンソールでイベント履歴を確認すると、StartInstance は想定通りでしたが、StopInstance は2回履歴が記録されていました。詳細を確認すると、2回目の StopInstance は "force": true と強制終了していました。

cloudtrail

"requestParameters": {
    "instancesSet": {
        "items": [
            {
                "instanceId": "i-*******"
            }
        ]
    },
    "force": true
},

SSM のドキュメント「AWS-StopInstance」の内容を確認してみると、通常の StopInstances の後に forceStopInstances するよう作成されていました。

オートメーション

インスタンス停止のタイミングで、基盤側の障害等と重る等、通常の StopInstances のみでは停止出来ない場合がある可能性があるため、強制停止で必ず停止出来るようになっているのだと思います。