Aws Instances in Ansible

If you’re implementing a dev-build-deploy cycle that uses EC2 instances in AWS, you’ll need an automated way to start, stop and terminate instances. It’s neither realistic nor scalable to go to the EC2 dashboard each time an instance’s state needs to be changed.

Some folks like to use Cloud Formation scripts, which is a reasonable approach if you only use AWS cloud services. The moment you need to manage non-AWS resources, CF isn’t an option.

Use Ansible

Using Ansible, you can manage instance state with a few very similar tasks. As long as you tagged the instances at creation with something meaningful, subsequent runs of your ansible playbook can manage all instances that possess that tag.

You first use the ec2_remote_facts module to gather facts of all the instances in the region you specify (using vars) that are then filtered on the tag name. In this case, instance_tag is the name we’ll pass to this playbook as an –extra-vars variable when it is run.

Beware of Greedy Pattern Matching

When I wrote this playbook, I thought I would combine all the state controls into a single task - start, stop and terminate are similar and so shouldn’t require separate tasks. While this is generally true, the pattern matching that you need in place to ensure that you aren’t sending a terminate command to an instance that you don’t intend to terminate must be rock-solid. I hit edge cases during development where I accidently term’d (junk) instances. I decided that I would rather use separate tasks than try to be more clever than the EC2 API.

To stop all instances in your region tagged with Name:subsystem_123_build, run this:

ansible-playbook aws.yml --tags "gather-ec2-facts,print-ec2-facts,stop-instance" --extra-vars "instance_tag=subsystem_123_build"


It isn’t necessary to run the print-ec2-facts task, but it does provide super clear console or log feedback about the instances that about to be changed.

Here’s the code.

Published by in Development and tagged ansible, aws, ec2 and snippets using 314 words.