Is there an easy way to start and stop AWS EC2 instances at a given time each day? This could save me quite a lot of money for my development and test servers.
Is there an easy way to start and stop AWS EC2 instances at a given time each day? This could save me quite a lot of money for my development and test servers.
Update
AWS have released a tool called the "Instance Scheduler", including a full configuration guide which is linked from that page. It looks to be an enhancement of the EC2 Scheduler I describe below, with a few more features, but it's essentially the same thing.
The guide below will still work, but it's probably better to look at the instance scheduler for new installations.
Original Post
AWS have a tool called EC2 Scheduler that gives you very flexible control over starting and stopping EC2 instances.
The tool allows you to define default start and stop times when you set the tool up, which you can change later. You can choose which instances get controlled, you and you can specify different start and stop times for each instance using tags.
While it's a great tool the documentation is somewhat vague and confusing. It's like the documentation has been written by an engineer who wrote the tool and knows everything about it, rather than a technical writer.
Note : if you have feedback or corrections comments are appreciated. If you have a question based on this please start your own question.
What is EC2 Scheduler
This tool is a Lambda Function that works with Cloudwatch Events and DynamoDB. It's deployed using a Cloudformation template, which also sets up the necessary IAM roles and policies. You can read about the architecture here.
Deployment
Start by going to this page and clicking "launch solution". Right now the direct link is here, but it could change.
Select the region you want the resources deployed to at the top of the console. The script controls EC2 instances in any region, but it runs in one region.
Tagging EC2 Instances
This is covered in the documentation here, but it's not as simple as it could be.
You control which instances are started and stopped by tagging your instances.
The simplest case requires you to tag each EC2 instance you want to be started and stopped according to the schedule. To do this find your EC2 instance in the console, click tags, and create this tag
To enable copy and paste:
If you want to have specific instance started and stopped on a different schedule you append additional information to the tag key and value. For example if you want an instance to start at 1500 UTC and stop at 2400 UTC on Tuesday, Thursday and Friday you enter the following.
Key: scheduler:ec2-startstop:late Value: 1500;2400;utc;tue,thu,fri
Note that the word "late" can be any string, "late" has no special meaning.
You can convert UTC to your local time using this tool.
You can use the tag editor to bulk tag instances. That could more easily let you set up bulk tagging, which could be useful for having different settings for dev, test, and production. I doubt you'd use this on production though.
CloudFormation Parameters
When you run the CloudFormation template you have to enter a lot of parameters. Most you can leave at default. Here's some of the most important parameters
Permissions, Policies, and Roles
The Permissions / IAM role section of the CloudFormation template is a red herring - ie it's largely irrelevant. It specifies only the role used to run the CloudFormation script, it makes no difference to the resources created or the role used when the lambda function runs. In retrospect this is obvious, but it wasn't obvious to me when I started.
Whatever role you run this script as the same role and inline permissions are created within IAM. The Lambda function runs using an "ec2 scheduler role" that the script creates.
I've included my policies below in case they're helpful for anyone.
CloudWatch Events and Metrics
If you want to see logs from your Lambda Function go into Cloudwatch Events. The logging is quite good. There are metrics as well, so you can see when it runs, time it runs for, etc.
Additional
The code for the lambda function is available on Github.
Policies
These aren't generally necessary, but could be for someone so I'll include them.
Policy for IAM Role
Trust policy for IAM role
If you just want to start and stop instances, here's another take on this which also make use of the Lambda service. It assumes you want to control a specific instance id. You can control multiple instances by adding more ids separated by a comma. (ex: 'i-3453453','i-45656745'). You can find the id of your instance in the AWS console Instances section.
In the Lambda console
Code below
Code below
Remember to replace region and instance values with your own.
Code below
Schedule the functions
Here you will create a CloudWatch Event that will trigger your Lambda function at night
Note: Cron expressions are evaluated in UTC. Be sure to adjust the expression for your preferred time zone. Here is an example that will run the function every day at 08:00 GMT/UTC):
To restart your instances in the morning, repeat these steps and use your preferred start time. If you want to send a mail message whenever the functions fail, you can set up an SNS topic and configure the sending of that message under Debugging in the Lmbda Function Creation Window.
The source of all this can be found here: AWS documentation
An easier way to achieve the same goal is using AWS EventBridge rules.
Go to Amazon EventBridge > Rules
Create a new rule and select Rule type as Schedule.
Provide cron expression for instance shutdown schedule. For eg. cron(30 17 * * ? *)
For Target1, select:
Review the schedule and instance detail and finish creating the rule.
You can use the method mentioned above (using lambda) to start the same instance again.