EC2 instances and how to prevent unexpected bills

by: John Keyes

EC2 instances and preventing unexpected bills. Image of tip jar.

The benefits of Cloud Computing and on-demand computing environments are pretty well known.

One such service is EC2 from Amazon, which allows business subscribers to run application programs in the computing environment. The EC2 serves as an almost unlimited set of virtual machines.

This is a great service for just a few dollars a day. However, sometimes due to a simple oversight we can be burdened with large unexpected bills by forgetting to shut down a virtual server.

Running an EC2 instance

As developers, we sometimes need to run an EC2 instance to run some temporary workloads. We do this because these workloads need more resources than what’s available on our developer machine. It’s generally for a process that needs a massive amount of RAM, like when testing data transformation for an in-memory database.

It’s amazing that we have such massive compute power on-demand for a few dollars a day. However, sometimes those few dollars a day, can become a headache at the end of the month.

We might need the big instance for four or five hours work. We complete the job, validate the results and congratulate ourselves on a job well done. But, we go home and forget to stop the instance.

This can result in the aforementioned unexpected bills.

Preventing unexpected bills with EC2

What would be the simplest way to resolve this without investing too much time and effort into it?

Could we launch a self-stopping instance?

A search led us to this Stack Overflow answer:

$ echo '#!/bin/sh' >
$ echo 'echo "halt" | at now + 1 hour' >>
$ echo 'echo per-boot: `date` >> /tmp/per-boot.txt' >>
$ chmod +x
$ sudo chown -R root
$ sudo mv -viu /var/lib/cloud/scripts/per-boot

This introduced us to Cloud-Init “the defacto multi-distribution package that handles early initialization of a cloud instance.”

An investigation into Cloud-Init and EC2 User-Data led us to our solution.  Use the following as the instance User-Data before launching the instance:

- [scripts-user, always]
- 'echo "per-boot start: `date`" >> /tmp/per-boot.txt'
- 'echo "sudo shutdown now" | at now + 1 hour'

The first runcmd runs every time the instance is booted and appends a timestamp to a simple log file. By inspecting this file, you’ll be able to see how many times the instance has been started, and you can easily see the last time it started too.

The second runcmd schedules the shutdown command to run in one hours time. We’re using the at command to schedule the call. This is a very versatile command and gives you plenty of scope to tailor how long you want your instance to run.

We have tested this User-Data on Ubuntu 16.10 and Amazon Linux 2 images. For it to work on Debian 9 you will need to have the `at` command installed so an additional `runcmd` is needed:

- 'apt-get install -y at'

Hopefully, this is straight-forward enough to save forgetful humans (like me) some money.

John Keyes

Server Side Developer

You May Also Like

We built a product in a lockdown

At the start of the lockdown, around March last year, I have to admit a case of the jitters. I was prospecting on five different projects. Some with existing clients, some with new clients. Our order book was good - but we always have to have an eye on up coming...

read more
The Rise of the Super App

The Rise of the Super App

Imagine being able to chat with your friend through instant messaging, then book dinner, a movie or a gig and pay for everything all from one single app. That’s the power of a super app.  Mobile users worldwide have dedicated apps for specific tasks. This is not...

read more


Submit a Comment

Your email address will not be published.