はじめに
皆さんは定期的にEC2のスケールアップやスケールダウンをどのように実施していますでしょうか。
例えば、現場ではこのような思いはありませんか?
- 夜は日中ほどのスペックは必要ないので、できればスケールダウンしてコストを下げたい
- 繁忙期の前は事前にスケールアップして、万全な状態で繁忙期を迎えたい
今回は上記のような時に活用できる AWS Systems Manager AutomationとEventBridge Schedulerを組み合わせた、
自動で定期的にEC2インスタンスタイプを夜間はスケールダウンして縮退、朝はスケールアップして復帰する方法をご紹介します。
- はじめに
- 全体像
- 検証①インスタンスにタグありでEventBridge Schedulerを起動する
- 検証②インスタンスにタグなしでEventBridge Schedulerを起動する
- AWS Systems Manager AutomationとEventBridge Schedulerの運用方法
- まとめ
全体像
夜間は縮退、朝は復帰する想定とします。
さらに対象のインスタンスを絞るためにタグ判定も導入して対象の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"
}
}
}
]
}
補足:
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のARNNewInstanceType
夜想定の場合: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 を活用してみてください。