コスト削減のために、業務時間内だけAmazon EC2インスタンスを起動したいことってありますよね。 9時-18時だけ起動したいとか、週末は停止しておきたいとか。
そんな要望を実現するために、ノンコーディングなAmazon EventBridge Schedulerを使ってEC2を定期起動・停止するAWS CloudFormationテンプレートを紹介します。
Amazon EventBridge Schedulerでコーディング不要なスケジュール実行
AWS上で定期実行したい場合、かつてはAmazon EventBridge rulesでスケジュール実行するのが鉄板でしたが、2022年末にもっと便利なAmazon EventBridge Schedulerがリリースされました。
EventBridge Schedulerを使用すると
- Lambdaなどのコーディング無しに270を超えるAWSサービス、6000以上のAPIを直接を呼び出せる(ユニバーサルターゲット)ため、だれでもメンテナンスできる
- タイムゾーンを指定できるため、時差やサマータイムを考慮せずにスケジュール設定できる
など、管理者に優しい機能が強化されています。
EC2の定期起動・停止設定をCloudFormation化
EventBridge Schedulerを使うと、次のブログのようにコンソールから画面をポチポチするだけで、簡単に設定できてしまいます。
EventBridgeスケジューラを使ってEC2の定期起動/停止を行う方法 | DevelopersIO
EC2の定期起動・停止のような定形作業をより楽をするために、この設定をCloudFormationのテンプレート化してみました。
スタック作成時に
- プルダウンで対象インスタンス
- 起動・停止のスケジュール
- タイムゾーン
を指定するだけです。
CloudFormationテンプレート
Lambdaなどのコードが存在しないため、テンプレートは非常にシンプルです。 設定を指定しているだけです。
scheduler-ec2-start-stop.yml
---
AWSTemplateFormatVersion: '2010-09-09'
Description: EventBridge Scheduler to start/stop EC2 instance
Parameters:
InstanceId:
Type: AWS::EC2::Instance::Id
ScheduleStartTime:
Type: String
Default: "cron(0 8 * * ? *)"
ScheduleStopTime:
Type: String
Default: "cron(0 19 * * ? *)"
ScheduleTimezone:
Type: String
Default: Japan
Resources:
ScheduleEC2Sart:
Type: AWS::Scheduler::Schedule
Properties:
Name: !Sub 'EC2-Start-${InstanceId}'
Description: Start EC2 Instance
ScheduleExpression: !Ref ScheduleStartTime
ScheduleExpressionTimezone: !Ref ScheduleTimezone
FlexibleTimeWindow:
Mode: "OFF"
State: ENABLED
Target:
Arn: arn:aws:scheduler:::aws-sdk:ec2:startInstances
Input: !Sub "{\"InstanceIds\": [\"${InstanceId}\"]}"
RoleArn:
Fn::GetAtt:
- SchedulerEC2StopStartRole
- Arn
ScheduleEC2Stop:
Type: AWS::Scheduler::Schedule
Properties:
Name: !Sub 'EC2-Stop-${InstanceId}'
Description: Stop EC2 Instance
ScheduleExpression: !Ref ScheduleStopTime
ScheduleExpressionTimezone: !Ref ScheduleTimezone
FlexibleTimeWindow:
Mode: "OFF"
State: ENABLED
Target:
Arn: arn:aws:scheduler:::aws-sdk:ec2:stopInstances
Input: !Sub |-
{
"InstanceIds": ["${InstanceId}"]
}
RoleArn:
Fn::GetAtt:
- SchedulerEC2StopStartRole
- Arn
SchedulerEC2StopStartRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- scheduler.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
Policies:
- PolicyName: EC2StopStart
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ec2:StartInstances
- ec2:StopInstances
Resource:
- "*"
作成されたリソースを確認
このCloudFormationテンプレートは以下のリソースを作成します。
- 起動用と停止用の2つのEventBridge Schedule
- 上記Schedule実行用のIAMロール
スタック作成完了後、コンソールの「Amazon EventBridge > スケジュール」に作成されたリソースを確認できます。
スケジュール通りに起動・停止できていることを確認してください。
CloudFormatationの改善ポイント
本記事では、EventBridge Schdulerのユニバーサルターゲットのサンプルとして、極力シンプルなCloudFormationテンプレートを用意しました。
より実用的にするための改善ポイントを紹介します。
複数のEC2インスタンスを対象にする
今回紹介したテンプレートはスケジュールと対象EC2インスタンスを1:1で作成しています。
ec2:StartInstances
APIec2:StopInstances
API
は複数のインスタンスIDを受け取れるため、CloudFormationパラメータのインスタンスID指定を List<AWS::EC2::Instance::Id>
にかえてターゲットの指定も合わせて調整すると、複数IDに対応できます。
CloudFormationではスケジュールだけを登録し、ターゲットのインスタンスIDリストを手動で管理するのも現実的です。
EC2インスタンス以外を対象にする
EventBridge SchedulerはEC2を含む270のAWSサービス、6000以上のAPIに対応しています。
そのため、RDS/Aurora の自動起動・停止などにも簡単に応用できます。
エラー検知を追加
定期実行を安定運用させるため、実行失敗を検知できるようにデッドレターキューを設定しましょう。
Amazon EventBridge Schedulerのデッドレターキュー(DLQ)を使ってみた | DevelopersIO