How to Automate EC2 Instance Scheduling with EventBridge Scheduler
Introduction
Many AWS users frequently rely on EC2 instances for their daily tasks. However, once these instances are started, they incur costs until explicitly stopped.
Using EventBridge Scheduler, you can automate the starting and stopping of EC2 instances without writing any application code.
Another advantage is that EventBridge Scheduler comes at no additional cost for up to 14,000,000 invocations per month.
This post demonstrates how to use EventBridge Scheduler with an example.
Starting an EC2 Instance
To start an EC2 instance for testing, replace <SECURITY_GROUP_IDS>
and <SUBNET_ID>
with actual values and execute 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
Use the following CloudFormation template to provision the required resources for scheduling:
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-*
To deploy the CloudFormation stack, replace <INSTANCE_ID>
with the actual instance ID(s) and run:
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 automatically start EC2 instances at 7:00 AM and stop them at 10:00 PM.
If you need to modify the schedule, update the ScheduleStartExpression
and ScheduleStopExpression
parameters when deploying the CloudFormation stack.
Verify that the instances are started and stopped as expected by monitoring your EC2 dashboard or using AWS CLI commands.
Cleaning Up
To avoid unnecessary charges, clean up the provisioned resources by running:
aws ec2 terminate-instances --instance-ids <INSTANCE_IDS>
aws cloudformation delete-stack --stack-name ec2-scheduler
Conclusion
EventBridge Scheduler is an efficient tool for automating EC2 instance management, particularly for development and testing environments, where instances are not required 24/7.
Additionally, you can extend its use to other AWS services to automate recurring tasks such as backups, data processing, or scheduled maintenance.
By implementing this cost-saving automation, you can better manage your AWS resources and reduce operational overhead.
Happy Coding! 🚀