AWS EventBridge Scheduler:スケジュールに沿ってEC2を起動・停止する

AWS EventBridge Scheduler:スケジュールに沿ってEC2を起動・停止する

Lambdaを介さずEventBridge SchedulerがEC2 APIを直接呼び出すことで、cronスケジュールに従ってEC2インスタンスを起動・停止します。

Takahiro Iwasa
3 min read

EventBridge Schedulerを使えば、間にLambda関数を挟むことなく、cronスケジュールに従ってEC2インスタンスを起動・停止できます。

構築

テスト用にEC2インスタンスを起動します。

Terminal window
aws ec2 run-instances \
--image-id ami-0f9fe1d9214628296 \
--count 1 \
--instance-type t2.micro \
--security-group-ids <SECURITY_GROUP_IDS> \
--subnet-id <SUBNET_ID>

11〜16行目のScheduleStartExpressionScheduleStopExpressionパラメータで、cron式を使ってスケジュールを定義します。

template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: EC2 scheduler
Parameters:
Prefix:
Type: String
Default: ec2-scheduler
InstanceIds:
Type: String
Description: '"i-1234567890abcdefg", "..."'
ScheduleStartExpression:
Type: String
Default: 'cron(0 7 * * ? *)'
ScheduleStopExpression:
Type: String
Default: 'cron(0 22 * * ? *)'
ScheduleTimezone:
Type: String
Description: IANA timezone identifier. For the full list, refer to https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
Default: UTC
AllowedValues:
- UTC
- Japan
Resources:
ScheduleStart:
Type: AWS::Scheduler::Schedule
Properties:
Name: !Sub ${Prefix}-schedule-start
ScheduleExpression: !Ref ScheduleStartExpression
ScheduleExpressionTimezone: !Ref ScheduleTimezone
FlexibleTimeWindow:
Mode: 'OFF'
State: ENABLED
Target:
Arn: arn:aws:scheduler:::aws-sdk:ec2:startInstances
Input: !Sub |-
{
"InstanceIds": [${InstanceIds}]
}
RoleArn: !GetAtt Role.Arn
ScheduleStop:
Type: AWS::Scheduler::Schedule
Properties:
Name: !Sub ${Prefix}-schedule-stop
ScheduleExpression: !Ref ScheduleStopExpression
ScheduleExpressionTimezone: !Ref ScheduleTimezone
FlexibleTimeWindow:
Mode: 'OFF'
State: ENABLED
Target:
Arn: arn:aws:scheduler:::aws-sdk:ec2:stopInstances
Input: !Sub |-
{
"InstanceIds": [${InstanceIds}]
}
RoleArn: !GetAtt Role.Arn
Role:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${Prefix}-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- scheduler.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: ec2
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- ec2:StartInstances
- ec2:StopInstances
Resource: !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:instance/i-*

次のコマンドでCloudFormationスタックをデプロイします。

Terminal window
aws cloudformation deploy \
--template-file ./template.yaml \
--stack-name ec2-scheduler \
--parameter-overrides InstanceIds='"<INSTANCE_ID1>", "<INSTANCE_ID2>"' \
--capabilities CAPABILITY_NAMED_IAM

テスト

プロビジョニングされたEventBridge Schedulerは、午前7時にEC2インスタンスを自動的に起動し、午後10時に停止します。

クリーンアップ

次のコマンドで、この例でプロビジョニングしたすべてのAWSリソースをクリーンアップします。

Terminal window
aws ec2 terminate-instances --instance-ids <INSTANCE_IDS>
aws cloudformation delete-stack --stack-name ec2-scheduler

まとめ

cron式を使った2つのEventBridge Scheduleを設定したことで、EC2インスタンスが午前7時に起動し、午後10時に自動的に停止するようになりました。この構成にLambda関数が一切登場しないのは、arn:aws:scheduler:::aws-sdk:ec2:startInstancesによってEC2 APIを直接ターゲットにしているためです。EventBridge SchedulerはAWS SDKを直接呼び出せるため、スケジュールとec2:StartInstances/ec2:StopInstancesを許可するIAMロールだけで解決策が完結します。コスト削減のためにこの仕組みに頼る前に確認しておくべき設定はScheduleExpressionTimezoneです。テンプレートではデフォルトがUTCになっているため、他のタイムゾーンの営業時間に合わせたいスケジュールでは明示的にこのパラメータを設定しないと、想定より数時間ずれてインスタンスが起動・停止してしまいます。

About the author

Takahiro Iwasa

Takahiro Iwasa

Software Developer

This blog shares technical notes from hands-on projects—architecture, implementation, and AWS service integrations.