My team and I lean heavily on AWS services for prototypes, demos, and training. The challenge that we’ve encountered is that it’s easy to forget about the resources you’ve spun up. So I wrote a quickly little utility that shuts down unnecessary EC2 instances at night.
import boto.ec2 import yaml config_file = '/etc/nightly_shutdown.yml' with open(config_file) as f: config = yaml.safe_load(f)
In that config file, we’ve got our region, access and secret keys, and a white list of instance IDs we’d like to opt-out of the nightly shutdown. This last bit is important if you have instances doing long-running jobs like repo syncing, for example.
--- region: us-east-1 access_key: eggseggseggseggs secret_key: spamspamspamspam whitelist: - i-abcdefgh - i-ijklmnop
Now we connect to the AWS API and get a list of reservations. This itself is interesting, as it gives us a little insight into the guts of EC2. As I understand it, a reservation must exist before an instance can be launched.
conn = boto.ec2.connect_to_region(config['region'], aws_access_key_id=config['access_key'], aws_secret_access_key=config['secret_key']) reservations = conn.get_all_reservations()
Now it’s simply a matter of iterating over those reservations, getting the instance IDs, and filtering out the white-listed IDs.
running_instances =  for r in reservations: for i in r.instances: if i.state == "running": if i.id not in config['whitelist']: running_instances.append(i.id)
Finally, we make the API call to stop the instances. Before doing so, we check to be sure there are any running, as this call will throw an exception if the instance ID list is empty.
if len(running_instances) > 0: conn.stop_instances(instance_ids=running_instances)
Now you just have to add this to your daily cronjobs and you’ll save a little budget.