以下の内容はhttps://xp-cloud.jp/blog/2026/03/05/100000より取得しました。


SSM Automation×EventBridge Schedulerで実現する“夜間縮退・朝復帰”運用

はじめに

皆さんは定期的にEC2のスケールアップやスケールダウンをどのように実施していますでしょうか。

例えば、現場ではこのような思いはありませんか?

  • 夜は日中ほどのスペックは必要ないので、できればスケールダウンしてコストを下げたい
  • 繁忙期の前は事前にスケールアップして、万全な状態で繁忙期を迎えたい

今回は上記のような時に活用できる AWS Systems Manager AutomationとEventBridge Schedulerを組み合わせた、
自動で定期的にEC2インスタンスタイプを夜間はスケールダウンして縮退、朝はスケールアップして復帰する方法をご紹介します。

全体像

夜間は縮退、朝は復帰する想定とします。
さらに対象のインスタンスを絞るためにタグ判定も導入して対象のEC2(1台)を選定します。

  • 夜間想定(縮退):t3.medium → t3.small
  • 朝想定(復帰):t3.small → t3.medium

構成は以下です。

  • EC2:1台 (SSMマネージドインスタンス)
  • タグ:NightShrink=true
  • IAM ロール:2つ (Automation用=EC2操作 / Scheduler用=Runbook起動)
  • SSM Automation Runbook:タグ検索 → 停止 → instanceType変更 → 起動
  • EventBridge Scheduler: 2本(縮退用 / 復帰用)

※Scheduler が Runbook を起動し、Runbook が EC2 の停止・変更・起動を実行します。

検証①インスタンスにタグありでEventBridge Schedulerを起動する

STEP1:EC2にタグ付与 / IAMロール作成

  • EC2へのタグ付与
    インスタンスサイズを変更する対象のEC2にタグを付与します。

1.AWSコンソール画面 → 「対象のEC2を選択」 → 「タグ」 →「タグを管理」
2.Key: NightShrink,Value: trueを設定し保存

EC2のタグ欄からタグが付与されたことを確認します。

  • Automation用IAMロールを作成
    SSM Automation(Runbook)が タグ NightShrink=true の付いたEC2 1台に対して、
    停止 → インスタンスタイプ変更 → 起動 を実行するための権限を付与します。

1.IAM → 「ロール」 → 「ロールの作成」
2.信頼されたエンティティタイプ:AWSのサービス
3.ユースケース:Systems Managerを選択
4.許可を追加をスキップ → 任意の名前を入力して作成
5.作成されたロールをクリック → 「許可」 → 「許可を追加」 → 「インラインポリシーを作成」
6.JSON形式で以下のコードを入力 → 「次へ」
※▶をクリックするとJSONコードが開きます。

IAMポリシー(Automation用)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DescribeInstancesForTagResolve",
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeInstances",
        "ec2:DescribeInstanceStatus"
      ],
     "Resource": "*"
    },
    {
      "Sid": "StopStartModifyOnlyNightShrinkTagged",
      "Effect": "Allow",
      "Action": [
        "ec2:StopInstances",
        "ec2:StartInstances",
        "ec2:ModifyInstanceAttribute"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "ec2:ResourceTag/NightShrink": "true"
        }
      }
    }
  ]
}
7.任意のポリシー名を入力 → 「ポリシーの作成」

補足:
Conditionでec2:ResourceTag/NightShrink = trueのインスタンスに限定しているため、
タグの無いEC2には実行されません。

  • Scheduler用IAMロール作成を作成
    Automation用IAMロールと同じ手順でロールを作成後、インラインインラインポリシーに以下のJSONコードを入力して作成します。
    ※▶をクリックするとJSONコードが開きます。
    IAMポリシー(Scheduler用)
    {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Sid": "StartAutomation",
        "Effect": "Allow",
        "Action": "ssm:StartAutomationExecution",
        "Resource": "*"
      },
      {
        "Sid": "EC2ShrinkActions",
        "Effect": "Allow",
        "Action": [
          "ec2:DescribeInstances",
          "ec2:StopInstances",
          "ec2:StartInstances",
          "ec2:ModifyInstanceAttribute"
        ],
        "Resource": "*"
      }
    ]
    }

補足:
Scheduler経由実行で権限不足になりやすいため、今回は分かりやすくScheduler用ロールにもEC2操作権限を含めています。

STEP2:SSM Automation ドキュメント(Runbook)作成

ドキュメントを作成していきます。

1.AWS Systems Manager → 「ドキュメント」 → 「ドキュメントの作成」 → 「オートメーション」をクリックします。
2.任意のドキュメント名を入力します。
3.以下のコードを入力して「ランブックを作成」から作成します。

schemaVersion: '0.3'
description: NightShrink=true のEC2(1台)を停止→インスタンスタイプ変更→起動する
parameters:
  AutomationAssumeRole:
    type: String
    description: SSM Automation assume role ARN (作成したAutomation用IAMロール)
  NewInstanceType:
    type: String
    description: 変更後のインスタンスタイプ(夜:t3.small / 朝:t3.medium)
mainSteps:
  - description: NightShrink=true のインスタンスを検索
    name: DescribeInstancesByTag
    action: aws:executeAwsApi
    nextStep: SelectSingleInstance
    isEnd: false
    inputs:
      Service: ec2
      Api: DescribeInstances
      Filters:
        - Name: tag:NightShrink
          Values:
            - 'true'
    outputs:
      - Name: InstanceIds
        Selector: $.Reservations..Instances..InstanceId
        Type: StringList
  - description: タグから対象インスタンスを特定(特定できない場合は失敗)
    name: SelectSingleInstance
    action: aws:executeScript
    nextStep: StopInstance
    isEnd: false
    inputs:
      Runtime: python3.11
      Handler: handler
      InputPayload:
        InstanceIds: '{{DescribeInstancesByTag.InstanceIds}}'
      Script: |
        def handler(event, context):
            ids = event.get("InstanceIds") or []
            if isinstance(ids, str):
                ids = [ids]
            return {"InstanceId": ids[0]}
    outputs:
      - Name: InstanceId
        Selector: $.Payload.InstanceId
        Type: String
  - description: インスタンスを停止
    name: StopInstance
    action: aws:executeAwsApi
    nextStep: WaitForStopped
    isEnd: false
    inputs:
      Service: ec2
      Api: StopInstances
      InstanceIds:
        - '{{SelectSingleInstance.InstanceId}}'
  - description: 停止完了を待機(最大5分)
    name: WaitForStopped
    action: aws:waitForAwsResourceProperty
    timeoutSeconds: 300
    nextStep: ModifyInstanceType
    isEnd: false
    inputs:
      Service: ec2
      Api: DescribeInstances
      InstanceIds:
        - '{{SelectSingleInstance.InstanceId}}'
      PropertySelector: $.Reservations[0].Instances[0].State.Name
      DesiredValues:
        - stopped
  - description: インスタンスタイプを変更
    name: ModifyInstanceType
    action: aws:executeAwsApi
    nextStep: StartInstance
    isEnd: false
    inputs:
      Service: ec2
      Api: ModifyInstanceAttribute
      InstanceId: '{{SelectSingleInstance.InstanceId}}'
      InstanceType:
        Value: '{{NewInstanceType}}'
  - description: インスタンスを起動
    name: StartInstance
    action: aws:executeAwsApi
    nextStep: WaitForRunning
    isEnd: false
    inputs:
      Service: ec2
      Api: StartInstances
      InstanceIds:
        - '{{SelectSingleInstance.InstanceId}}'
  - description: 起動完了を待機(最大5分)
    name: WaitForRunning
    action: aws:waitForAwsResourceProperty
    timeoutSeconds: 300
    isEnd: true
    inputs:
      Service: ec2
      Api: DescribeInstances
      InstanceIds:
        - '{{SelectSingleInstance.InstanceId}}'
      PropertySelector: $.Reservations[0].Instances[0].State.Name
      DesiredValues:
        - running

このドキュメントのparametersとmainStepsについて簡単に説明します。

  • parameters:

    AutomationAssumeRole:
    AutomationAssumeRoleで実行ロールを明示
    ※EventBridge Scheduler経由で起動する場合、
      Schedulerの実行ロール権限だけだとEC2操作ができず失敗することがあるため

    NewInstanceType:
    変更後のインスタンスタイプを指定

  • mainSteps:
    DescribeInstancesByTag
    対象インスタンスをタグで検索(NightShrink=true)

    SelectSingleInstance
    タグ一致の結果からインスタンスを選択する(今回は先頭1台)

    StopInstance
    対象インスタンスを停止

    WaitForStopped
    停止完了待ち(最大5分)

    ModifyInstanceType
    インスタンスタイプ変更

    StartInstance
    インスタンスを起動

    WaitForRunning
    起動完了待ち(最大5分)

ドキュメントが完成したら、ドキュメントの「オートメーションを実行する」ボタンから実行してみます。
[入力パラメータ]欄には以下を入力してください。

  • AutomationAssumeRole
    Automation用AssumeRoleのARN

  • NewInstanceType
    夜想定の場合:t3.small / 朝想定の場合:t3.medium

実行したら、オートメーションの実行ステータスを確認して全体が成功していれば正常終了しています。
実際にEC2のインスタンスタイプを見て、指定したサイズになっているはずなので確認してみてください。

STEP3:EventBridge Scheduler作成(定期的なスケジュール)

オートメーションで動作することが確認できたら、いよいよEventBridgeの登場です。
毎日決まった時間に起動していきましょう。
夜間想定(縮退)用、朝想定(復帰)用の2つのスケジュールを作成します。

まずは夜間想定(縮退)用を作成してみましょう。

1.Amazon EventBridge → 「スケジュール」 → 「スケジュールを作成」をクリックします。
2.任意のスケジュール名を入力します。
3.スケジュールのパターンでは以下を選択します。
※今回は分かりやすく、曜日判定はしていません。
  夜想定を10時に起動、朝想定を10時30分に起動設定しました。

頻度:定期的なスケジュール
タイムゾーン:(UTC+9:00) Asia/Tokyo
スケジュールの種類:cronベースのスケジュール
          起動したい日時をcron( )欄に記載します。
例:分[ 00 ] 時間[ 10 ] 日付[ * ] 月[ * ] 曜日[ ? ] 年[ * ]
フレックスタイムウィンドウ:オフ

※定期的なスケジュールを選択した場合は翌日からの起動になります。
 1回限りのスケジュールの場合は当日指定が可能です。次の検証②で手順をご紹介します。

4.時間枠は入力せず「次へ」
5.ターゲット API:「すべてのAPI」→ 「Systems Manager」を選択 → 検索欄に「StartAutomationExecution」を入力して選択 6:StartAutomationExecution欄にAPIに渡すパラメータをJSONコードで記載します。
以下を入力してください。
※▶をクリックするとJSONコードが開きます。

EventBridge Scheduler のペイロード(縮退:t3.small)
{
  "DocumentName": "作成したドキュメント名",
  "Parameters": {
    "NewInstanceType": ["t3.small"],
    "AutomationAssumeRole": ["作成したAutomation用ARN名"]
  }
}
以下のように入力できたら「次へ」をクリック

7.設定
スケジュールを有効化:有効化
スケジュール完了後のアクション:NONE
アクセス許可:「既存のロールを使用」にチェック → 既存の役割を選択では Scheduler用IAMロール を選択 →「次へ」をクリック
その他はデフォルト設定でOKです。
8.最後に設定内容を確認して「スケジュールを保存」をクリックします。

作成できたらスケジュールの一覧に戻り、ステータスが有効であることを確認します。

あとは、同じ手順で時間を変更して朝想定(復帰)用のスケジュールを作成してください。
StartAutomationExecutionのJSONコード内NewInstanceType欄は以下のように変更してください。
- "NewInstanceType": ["t3.medium"],

STEP4:実行の確認

設定された時刻になると、以下のようにオートメーションの実行履歴から起動されたことが確認できます。 実際にEC2のインスタンスタイプを確認すると、指定したサイズに変更されています。
同じように朝想定(復帰)用のスケジューラーも正常に起動し、オートメーションの実行履歴も正常に終了しました。

検証②インスタンスにタグなしでEventBridge Schedulerを起動する

インスタンスにタグを付与した場合、正しく起動することが分かりました。 次にインスタンスからタグを外して実行して挙動を見てみましょう。

STEP1:EC2のタグを削除

1.AWSコンソール画面 → 対象のEC2を選択 → 「タグ」 → 「タグを管理」
2.NightShrink , true → 「削除」→ 「保存」
タグを外しました。

STEP2:EventBridge Schedulerの作成(1回限りのスケジュール)

今回は夜間想定(縮退)用想定にて当日指定、1回限りのスケジュールを作成していきます。

1.Amazon EventBridge → 「スケジュール」 → 「スケジュールを作成」をクリックします。
2.任意のスケジュール名を入力します。
3.スケジュールのパターンでは以下を選択します。

頻度:1 回限りのスケジュール
日付と時刻:任意の時間
 ※タイムゾーンが(UTC+9:00) Asia/Tokyo であることを確認してください。
4.以降の設定は先ほど作成した夜間想定(縮退)用の定期的なスケジュールと同じ手順です。
 すべて設定できたら作成してください。

STEP3:実行の確認

では、実行結果を確認してみましょう。 失敗したことが確認できました。
エラーの内容は以下と出力されているので、タグなしではインスタンスが特定できず失敗した正しい挙動です。
- ステップの入力を検証して解決している段階で失敗。
- 入力 InstanceIds を StringList 型として解決できず、InstanceIds の値が特定できない。

実行されたステップを確認しても、SelectSingleInstance のステップで失敗していることが分かります。

インスタンスの状態もt3.mediumのままでした。
タグなしではインスタンスが変更されないことも確認することができました。

AWS Systems Manager AutomationとEventBridge Schedulerの運用方法

今回作ったEventBridge Schedulerを実運用で稼働させる場合は、 朝想定(復帰):t3.small → t3.mediumの起動が要になります。
起動が失敗していた場合に即座に気が付けるように、Runbookの作成時には前回のブログで紹介した 実践3: エラーハンドリングと通知も参考にしてみてください。

EventBridge Schedulerはスポットで有効化、無効化をすることもできます。

1.Amazon EventBridge → 「スケジュール」
2.有効化したいスケジュール名にチェック → 「有効化」ボタンをクリック

無効化されているスケジュールは「有効化」ボタンが表示され、有効化されているスケジュールは「無効化」ボタンが表示されます。 実際の運用方法に基づいて、利用してみてください。

まとめ

今回はAWS Systems Manager AutomationとEventBridge Schedulerを組み合わせて、 定期的にEC2のインスタンスタイプを変更し、夜間の縮退と朝の復帰を自動化する方法をご紹介しました。
Runbook の作り方次第では、曜日指定やエラーハンドリングなど、より柔軟な運用にも対応できます。
ぜひ本記事を参考に、AWS Systems Manager Automation と EventBridge Scheduler を活用してみてください。




以上の内容はhttps://xp-cloud.jp/blog/2026/03/05/100000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14