How to Automate EC2 Instance Scheduling with EventBridge Scheduler

How to Automate EC2 Instance Scheduling with EventBridge Scheduler

Takahiro Iwasa
Takahiro Iwasa
3 min read
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! 🚀

Takahiro Iwasa

Takahiro Iwasa

Software Developer at KAKEHASHI Inc.
Involved in the requirements definition, design, and development of cloud-native applications using AWS. Now, building a new prescription data collection platform at KAKEHASHI Inc. Japan AWS Top Engineers 2020-2023.