概要
AWS Instance Schedulerは、EC2やRDSなどのインスタンスを自動で起動・停止する仕組みです。AWSが公開しているテンプレートをCloudFormation(CFn)として実行することで、必要なリソース一式が作成され、すぐに利用を開始できます。本日のWhat's Newにて、「EC2で容量不足エラーが発生した場合に、代替インスタンスタイプを使用して失敗した起動アクションを自動的に再試行できる」機能、いわゆるICE対応が追加されたとの発表がありました。
本記事では、まずInstance Schedulerの仕組みを整理し、その後に実際のインストール・設定手順、最後に上記のICE対応について確認していきます。
全体の流れ
公式ドキュメントにアーキテクチャ図がありますが、さまざまな処理がまとめて記載されており、少し分かりづらい印象でした。CFnで全リソースを作成した後の流れを整理すると、以下のようになります。
-
スケジュール・期間の登録(青線)
例として「月曜~金曜の09:00~17:00はEC2を起動しておく」といったスケジュールを、DynamoDBのConfigテーブルに保存します。登録はCFnのカスタムリソースを使用して行います。 -
EC2へのタグ付け(緑線)
起動・停止対象のEC2にタグを付与します。指定されたタグが付与されるとEventBridgeがこれを検知し、DynamoDBのRegistryテーブルに起動・停止対象リソースとして登録します。あわせて、EC2側にも管理対象であることを示すタグが付与されます。 -
起動・停止処理の実行(赤線)
定期的(デフォルトは5分ごと)にEventBridgeスケジューラが起動し、Orchestrator Lambdaを呼び出します。Orchestrator LambdaはConfigテーブルおよびRegistryテーブルからスケジュールと対象リソースを取得し、個別にScheduler Lambdaを起動します。 -
起動・停止処理の実行(紫線)
Scheduler LambdaがRegistryテーブルを参照し、該当するEC2の起動・停止を実行します。あわせてRegistryテーブルやEC2のタグ情報も更新されます。
手順
リソースの作成
こちらからinstance-scheduler-on-aws.templateをダウンロードします。AWSコンソールにログイン後、CloudFormationコンソールからスタック作成を行い、取得したテンプレートをアップロードします。
スタック名を入力します。
今回は以下のパラメータのみ変更しました。各パラメータの詳細はこちらに記載されています。
- Retain data and logs:Disabled(DynamoDBの削除保護を無効化)
- Default time zone:Asia/Tokyo
その他はデフォルトのまま進め、スタックを作成します。しばらくするとリソースが作成されます。
スケジュール・期間の登録
スケジュール登録はIaCを使用する方法とCLIを使用する方法の2種類がありますが、今回はIaCを使用します。こちらにサンプルがありますが、少しカスタマイズして以下のテンプレートを作成しました。
以下をsample-schedule.ymlとして保存します。月曜~金曜の09:00~17:00にEC2を起動するスケジュールのサンプルになります。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
ServiceInstanceScheduleServiceTokenARN:
Type: String
Description: (Required) service token arn taken from InstanceScheduler outputs
Metadata:
'AWS::CloudFormation::Designer': {}
Resources:
TokyoWorkingWeek:
Type: 'Custom::ServiceInstanceSchedule'
Properties:
NoStackPrefix: 'True'
Name: tokyo-working-hours
Description: run instances from 9am to 5pm in Tokyo on weekdays
ServiceToken: !Ref ServiceInstanceScheduleServiceTokenARN
Timezone: Asia/Tokyo
Periods:
- Description: 9am to 5pm on weekdays
BeginTime: '09:00'
EndTime: '17:00'
WeekDays: mon-fri
先ほどと同様に、こちらのファイルを使用してCFnのスタックを作成します。
その際、ServiceInstanceScheduleServiceTokenARNを指定する必要があります。こちらは最初に作成したスタックの「出力」タブから確認できます。その他はデフォルトのまま進め、スタックを作成します。
DynamoDB→「項目を探索」の順に進むとConfig-Tableを確認できます。※最初のスタック作成時に作成されています。
中を確認すると、sample-scheduleの実行によりスケジュールと期間の2つのレコードが作成されています。スケジュールの中で期間(tokyo-working-hours-period-0001)が指定されており、その期間レコードの中で具体的な起動・停止時間が定義されています。
EC2にタグ付け
適当なEC2を作成します。
EC2にタグを付与します。最初のスタック実行時にパラメータで設定変更を行っていなければ、タグキーはScheduleになります。値にはsample-schedule.ymlで指定したtokyo-working-hoursを設定します。
すると、EventBridgeルールにより下記条件(Scheduleタグの変更)でLambdaが実行されます。Lambda関数内でDynamoDBのRegistryテーブルへの登録と、EC2へのタグ追加が行われます。
{
"source": ["aws.tag"],
"detail": {
"changed-tag-keys": ["Schedule"]
}
}
DynamoDB→「項目を探索」の順に進み、Registry-Tableを確認すると、EC2が管理対象として追加されていることが分かります。
また、EC2自体にも、先ほど追加したScheduleタグとは別にIS-ManagedByというタグが自動的に追加されています。
起動・停止処理
このまま17:00まで待てばEC2は停止されますが、検証のためEndTimeを短縮します。下記の期間レコードのEndTimeを直近の時刻に変更します。
※検証時以外は設定不整合が発生するため、CFnから変更します。
しばらくすると、該当EC2が停止したことを確認できます。
EC2には、これまで存在しなかったIS-LastActionタグが付与されています。
また、Registry-Tableのstateもstoppedに更新されました。
EC2容量不足エラーの処理
EC2 容量不足エラーの処理に、設定方法および動作について記載があります。設定はIS-PreferredInstanceTypesタグを使用し、値としてインスタンスタイプをカンマ区切りで指定します。ICEを意図的に発生させるのは難しいため、IS-PreferredInstanceTypesタグを設定した状態で動作を確認してみます。
代替インスタンスタイプリストは優先順に提供され、最初のタイプが最も優先されます。Instance Scheduler が >EC2 インスタンスを起動しようとすると、次のようになります。
1.インスタンスが現在最も望ましいサイズでない場合、開始する前に最も望ましいサイズへの変更を試みます。
2.開始オペレーションが成功した場合、それ以上の代替操作は試行されません。
3.容量不足が原因で開始オペレーションが失敗した場合:
a.リスト内の次の代替インスタンスタイプにサイズ変更を試みます
b.開始オペレーションを再試行します
c.それでも失敗した場合、次の代替タイプを試行します
d.成功するか、すべての代替案が使い果たされるまで続行します
新規にEC2を1台作成し、停止状態にしておきます。
期間のBeginTime(開始時間)を13:50に変更します。現在時刻が14:30の場合、EC2起動時間は13:50~17:00の間となるため、EC2は起動する想定です。
EC2に以下のタグを付与して管理対象とします。
- Schedule:tokyo-working-hours
- IS-PreferredInstanceTypes:t3.micro,t3.small,t3.medium
EC2が起動しました。
なお、別のt3.microインスタンス起動後、IS-PreferredInstanceTypesにt3.microを含めていない場合は、EC2は起動しませんでした。
まとめ
AWS Instance Schedulerを使用してEC2の自動起動・停止環境を構築する方法について解説しました。
CloudFormationテンプレートを使用することで、必要なリソースを一括で作成でき、スケジュール設定もIaCで管理できます。ICE対策として実運用でどこまで活用できるかについては、もう少し検証が必要そうです。





















