How do I start and stop EC2 instances automatically?

2021.05.26

What is the problem?

I have a requirement that specific EC2 instances need to be at start status only at certain times of the day. It is a pain to do it manually every time, so I want to automate it.

What should I do?

You can use Amazon Systems Manager Automation and CloudWatch Events to schedule automatic start and stop.

Create an IAM role

Create an IAM role for CloudWatch Events. CloudWatch Events needs permission to call SSM Start Automation Execution with your supplied Automation document and parameters.

Create a role from the IAM console. This time I created a role named 'event-ssm-automation-role'. Attach the AWS managed policy 'AmazonSSMAutomationRole' to the IAM role as shown below.

Select the 'Trust Relationships' tab and edit from 'Edit Trust Relationship' as shown below.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "events.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Create CloudWatch Events rules

Create a CloudWatch Events rule to start your EC2 instance automatically. Select the 'Create rule' on the CloudWatch Console.

Set the Event Source. I want to set the EC2 instance to start at a specific time every day, so I used a cron expression. Please refer to the following document on how to write a cron expression.

Reference: Cron Expressions - Amazon CloudWatch Events

This time, I entered '30 18 * *? *' in the Cron expression field. The event will occur every day at 18:30 UTC.

Next, create a target from the ’Add target’. Select 'SSM Automation' as the target. Fill out Document name and EC2 Instance name. Then, choose 'Use existing role' and select the IAM role just created. After setting everything, click the 'Configure details' button.

Fill in a name and description for the rule and click 'Create Rule'.

The rule for the auto-starting instance has been created.

Follow the same step to create another CloudWatch Events rule to stop your EC2 instance automatically. I selected 'Schedule' in the event source and entered '0 19 * *? *' in the Cron expression field. The event will occur every day at 19:00 UTC.

Except for the Document of SSM Automation, the settings are the same as before. After filling those fields, click the 'Configure details' button.

Fill in a name and description for the rule and click 'Create Rule'.

The rule for the auto-stopping instance has been created.

Execution confirmation

First, I want to confirm that the setting for the auto-starting instance is working. Leave your instance in a stopped state for now.

The status of the instance changed to 'Running' at the expected time.

Open Amazon Systems Manager Automation to confirm that the auto-starting instance execution worked successfully.

Next, I confirmed that the status of the instance changed to 'Stopped' at the setting time.

Open Amazon Systems Manager Automation to confirm that the auto-stopping instance execution worked successfully.

In addition, I checked the Event History using CloudTrail. Please see the screenshot below. StartInstance was as expected. However, StopInstance was recorded twice. I looked at the details, and the second StopInstance was a force stop.

"requestParameters": {
    "instancesSet": {
        "items": [
            {
                "instanceId": "i-*******"
            }
        ]
    },
    "force": true
},

Let's check the contents of the SSM document 'AWS-StopInstance'. It is created to perform 'forceStopInstances' after 'stopInstances'.

I think the reason is that there is a possibility that the underlying host computer has issues when your instances need to be stoped. Then your instances may not be stoped only with StopInstances and need to be forced to stop.