AWS Instance SchedulerでEC2/RDSを夜間自動停止する方法

コストが気になるAWS。少しでも料金を安くするために夜間は止めてしまいましょう!今回はAWS Instance Schedulerを使った夜間自動停止の設定を記載します。対象のリソースにタブをつけるだけで大丈夫です!

前提

  • IAMロールに CloudFormation, DynamoDB, Lambda, EC2, RDS, EventBridge の権限があること
  • 停止対象には必ずタグ付けできること(後述の Tag key/value)※Value: nightly-stopで作成していきます。

CloudFormation で Instance Scheduler をデプロイ

CloudFormation コンソール を開く > スタックの作成から新しいリソースを使用(標準)を選択

既存のテンプレートを選択 > Amazon S3 URLを選択後、以下のURLを設定 > 次へ

https://s3.amazonaws.com/solutions-reference/instance-scheduler-on-aws/latest/instance-scheduler-on-aws.template

スタックの詳を設定する。各項目の詳細と設定例を下記に記載します。

パラメータ名入力例説明
Stack nameinstance-scheduler-nightly-stopスタックを識別する名前。英字で始まり、英数字とハイフンのみ使用。128文字以内。
Schedule tag keyScheduleリソースに付与するタグのキー。タグ値と DynamoDB の ScheduleName が紐づきます。
Scheduling interval (minutes)5Lambda がスケジュール定義をポーリングする間隔(分)。短いほど変更反映が速いが実行回数が増えます。
Default time zoneAsia/Tokyoスケジュール定義でタイムゾーン未指定時に使われる IANA タイムゾーン。JST 運用ならこちら。
Enable schedulingYes全サービス共通のスケジューリング機能を有効化。
Enable EC2 schedulingEnabledEC2 インスタンスの停止/起動を有効化。
Enable RDS instance schedulingEnabledRDS のシングル/Multi-AZ インスタンス停止/起動を有効化。
Enable RDS cluster schedulingEnabledAurora などの RDS クラスター停止/起動を有効化。
Enable Neptune cluster schedulingDisabledNeptune を利用しない場合は無効化。
Enable DocumentDB cluster schedulingDisabledDocumentDB を利用しない場合は無効化。
Enable AutoScaling Group schedulingDisabledASG のスケールアクションは対象外とする場合は無効化。
Start tagsInstanceScheduler-LastAction=Started By {scheduler} {year}-{month}-{day} {hour}:{minute} {timezone}インスタンス起動時に自動付与されるタグ(実行履歴として)。
Stop tagsInstanceScheduler-LastAction=Stopped By {scheduler} {year}-{month}-{day} {hour}:{minute} {timezone}インスタンス停止時に自動付与されるタグ(実行履歴として)。
Enable EC2 SSM Maintenance WindowsNoSSM メンテナンスウィンドウ連携が不要な場合は No。
Kms Key Arns for EC2(空欄)暗号化 EBS 両対応が不要なら空欄。必要なら * か特定の KMS ARN をカンマ区切りで指定。
Create RDS instance snapshots on stopNo停止前スナップショット不要なら No。
ASG scheduled tag keyscheduledASG スケジュール用タグキー(ASG 無効化時は影響なし)。
ASG action name prefixis-ASG 用 ScheduledAction 名のプレフィックス(ASG 無効化時は影響なし)。
Use AWS OrganizationsNoマルチアカウント運用しない場合は No。
Namespacedefault同一リージョン内で一意な識別子。複数展開しないならデフォルトでOK。
Organization ID/remote account IDs(空欄)Organizations 未使用なら空欄。
Region(s)(空欄)このリージョンのみなら空欄。マルチリージョン運用時は ap-northeast-1,us-west-2 など。
Enable hub account schedulingYesこのアカウント自体を Scheduler 対象とする。
Log retention period (days)30CloudWatch Logs の保持日数。運用に合わせて調整可。
Enable CloudWatch debug LogsNo本番運用では通常 No。デバッグ時のみ Yes に。
Operational MonitoringEnabledCloudWatch Dashboard や追加メトリクスをデプロイ。
SchedulingRequestHandler Memory size512メイン Lambda のメモリサイズ(MB)。大規模環境でタイムアウトする場合は増。
AsgHandler Memory size512ASG 用 Lambda のメモリサイズ(MB)。
Orchestrator Memory size512マルチリージョン/マルチアカウント用 Lambda のメモリサイズ(MB)。
Protect DynamoDB TablesEnabledDynamoDB テーブルを削除保護。誤削除防止のため有効化推奨。

※その他パラメータはほぼデフォルトで可。

スタックオプション は特に設定不要。タグ/Service role は空欄。

The following resource(s) require capabilities: [AWS::IAM::Role] の承認チェックを忘れずにチェックして次へ

送信 をクリックし、状態が CREATE_COMPLETEになるまで待機

スケジュール定義の登録

DynamoDB コンソール を開く

テーブル一覧から InstanceScheduler-Schedule(もしくはご自分で指定した Namespace プレフィックス+-Schedule)を選択。←一覧の中から名前に ConfigTable を含むテーブルを探す StateTable のすぐ上か下に並んでいるはずです。

instance-scheduler-nightly-stop-ConfigTable-XXXXXXXXXXXX

テーブル画面の上部 「テーブルアイテムの探索」 を選択

「項目を作成」→JSONビューで以下のように記載して右下の 「保存」 をクリック

type: {
S: "schedule"
},
name: {
S: "nightly-stop"
},
expression: {
S: "cron(0 2 * * ? *)"
},
timezone: {
S: "Asia/Tokyo"
},
description: {
S: "毎日夜間に停止のみ"
}
}

対象リソースにタグ付け

停止対象の EC2/RDS インスタンス(各インスタンス単位)に、以下のタグを付与します。

Key:   Schedule
Value: nightly-stop
リソース種別コンソール操作CLI 例
EC2EC2 コンソール → 対象インスタンス → 「タグ」タブ → タグの追加aws ec2 create-tags –resources i-0123abc –tags Key=Schedule,Value=nightly-stop
RDSRDS コンソール → DB インスタンス → 「タグ」 → タグの追加aws rds add-tags-to-resource –resource-name arn:…:db:mydb –tags Key=Schedule,Value=nightly-stop

動作確認

CloudWatch Logs

  • ロググループ /aws/lambda/SchedulingRequestHandler の最新ログを確認
  • 毎日 2:00AM 前後に “Stopping DB instance …” / “Stopping EC2 instance …” と出力される

EC2 / RDS コンソール

  • 毎朝 2:00AM〜2:10AM 頃に、タグ付きリソースのステータスが「停止中」「停止済み」に遷移していることを確認

再起動スケジュールの登録

もし夜間停止後に翌朝自動で起動したい場合は、DynamoDB 登録を以下のように追加します。

そしてリソースタグの値を nightly-start に一時的に切り替える必要はなく、同タグ名で停止/起動を両方定義しておけば自動的に「停止→起動」処理が動きます。

ScheduleNamePeriodTimezone
nightly-startcron(0 7 * * ? *)Asia/Tokyo

まとめ

以上で AWS Instance Scheduler を使った「毎日夜間に自動停止(+任意で朝の自動起動)」の設定が完了します。1日中起動していると結構なコストになってしまいますが、夜間や休日は停止することによって半額程度に抑えることが可能です。ぜひ試してみてください。