Save AWS costs by scheduled start and stop of EC2 instances

Most of the AWS resources are billed on per-hour basis which provides us an opportunity to save cost based on the usage pattern. Especially in case of Dev/Test environment, we need them only during the working days and working hours.

By using AWS Lambda function (python) in combination with EC2 instance tags, scheduled start or stop can be achieved with few lines of code.

Advantages of using AWS Lambda:

  • For 128MB memory we get 3,200,000 seconds free tier usage per month in AWS Lambda which will be more than enough for this function.
  • IAM role will be associated with the Lambda function which will be used to perform the required task and no separate keys need to be configured.

I used a tag with name as schedule & JSON string for tag value using which I could define the day and time when it needs to be started or stopped.

Sample tag value

One interesting scenario where this script is useful is to start the instance manually when required (not to start by schedule), but want to stop it in the evening by schedule. In this scenario just leave the value of start key as empty string and configure appropriate stop value for that instance.

This function will check whether the current day and hour match the start or stop value configured in the tag for the particular instance. By default it checks all the EC2 instances for the tag. For instance, if the tag with name “schedule” doesn’t exist, it will create the tag using the default schedule configured in the script.

If you want to exclude any instance from being tagged for schedule, there are two ways to do that. 1) By adding the instance id of the particular instance in the exclude variable inside the script. 2) Adding a tag with name as “ignore” to the instance which needs to be excluded. Value of this tag doesn’t matter.

Handing instance[s] behind ELB:
If the instance is behind ELB and once the instance has been stopped, ELB will stop checking the health of the instance. Hence when the instance gets powered on, it won’t be available via ELB automatically. This script checks whether the instance which got started as per schedule has been attached to any ELB. If it’s attached to an ELB, it will be de-registered and registered again.

Handling instance[s] in Auto Scaling Group:
When instances in auto scaling group get stopped, ASG health check will identify whether the particular instance is unhealthy and trigger the necessary corrective action to launch alternate instance. Therefore to prevent the auto scaling from triggering creation of new instances, certain processes need to be suspended.

Lambda function

Following are the list of privileges that should be enabled for the IAM role associated to the Lambda function.

Lambda configuration:
Configure timeout as 10 seconds.
Add scheduler as event source and configure it to run every hour.


Handle instance start/stop schedule in a better way than depending on that particular hour.


 Add your comment
  1. Gavin Connell-Otten

    Hey Prakash, the python above seems to have some issues – syntax problems and some odd behaviours once the syntax problems were fixed (see lines 62/63 for example of the problems – there are a few others)

    Once I fixed the few issues I found – it’s running OK, but it’s only dealing with instances in ASGs, not ‘standalone instances.

    Do you have a more up to date version? Is this perhaps an old one?

    Any help you could offer would be appreciated!


  2. Nice job, looking to borrow this for my staging environments this week. I’ll let you know how it goes, thank you!

Leave a Comment

Your email address will not be published.

2 Trackbacks

  1. AWS Week in Review – November 16, 2015 | SMACBUZZ (Pingback)
  2. AWS Week in Review – November 16, 2015 | wart1949 (Pingback)