Scheduling EC2 Start and Stop using EventBridge Scheduler
Many AWS users should use EC2 instances in their daily work. Once the EC2 instances have been started, you will incur costs until stopping them.
Using EventBridge Scheduler, you can automate the starting and stopping process with no application code.
In addition, you can use EventBridge Scheduler with no additional costs up to 14,000,000 invocations per month.
This post describes how to use it with an example.
Starting EC2 Instance
Replace <SECURITY_GROUP_IDS>
and <SUBNET_ID>
with the actual value and start an EC2 instance for testing with the following command.
aws ec2 run-instances \
--image-id ami-0f9fe1d9214628296 \
--count 1 \
--instance-type t2.micro \
--security-group-ids <SECURITY_GROUP_IDS> \
--subnet-id <SUBNET_ID>
Creating AWS Resources
Create a CloudFormation template with the following content.
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-*
Replace <INSTANCE_ID>
with the actual value and deploy the CloudFormation stack with the following command.
aws cloudformation deploy \
--template-file ./template.yaml \
--stack-name ec2-scheduler \
--parameter-overrides InstanceIds='"<INSTANCE_ID1>", "<INSTANCE_ID2>"' \
--capabilities CAPABILITY_NAMED_IAM
Testing
The provisioned EventBridge scheduler will start the EC2 instances at 7 a.m. and stop at 10 p.m.
If you want to change the scheduling time, specify ScheduleStartExpression
and ScheduleStopExpression
at the CloudFormation stack deployment.
Please confirm the EC2 instances are started and stopped as expected.
Cleaning Up
Clean up the provisioned AWS resources with the following command.
aws ec2 terminate-instances --instance-ids <INSTANCE_IDS>
aws cloudformation delete-stack --stack-name ec2-scheduler
Conclusion
If you are using EC2 instances for development purposes, EventBridge Scheduler offers a cost-saving solution.
Since EventBridge Scheduler can run actions of other services than EC2, you can utilize it to automate scheduled maintenance.
I hope you will find this post useful.