If you have your physical or virtual environments configured with Ansible you can use this configuration code to provision and configure new cloud environments on AWS. The following solution shows how to:
- Create instances required on EC2 using Ansible.
- Target these instances with your existing configuration playbooks.
Please note that this solution is dependent on having followed Ansible’s excellent guidelines on organising and writing your playbooks, sites, and roles.
You can use Ansible’s Amazon cloud modules to create your new cloud site. I will only cover the
ec2 module here, but there are modules for creating your VPCs, subnets, and security groups etc allowing you to automate the creation of fully fledged environments.
Create a static inventory file to specify the instances that make up your environment ie provide the names of the hosts and their groups.
The following play will provision these instances. It runs for all hosts in the inventory but doesn’t connect to them as the
ec2 module runs locally on your Ansible master machine.
These instances need to be tagged so they can later integrate with your Ansible configuration roles and playbooks. In the above play you can see the
TAGS fact being populated with:
- All the groups the hosts belong to in the inventory (tags are key-value pairs so I have the constant/dummy value ‘yes’ though it is never used).
- Any extra tags specified a
GROUP_TAGSvariable in the
This fact is passed to the
ec2 task and used to tag the instance it creates.
As a result of running this playbook against the static inventory, you now have provisioned all the hosts in your environment. They are also tagged and ready to be configured by your existing Ansible configuration code.
In your configuration project, add a new site inventory folder (called ‘aws’ below).
In this folder put a copy of the Ansible’s EC2 dynamic inventory script and create a static inventory file. The dynamic inventory:
- Pulls all instances and their associated facts (incl. their ec2_tags) direct from EC2.
- Creates dynamic Ansible groups based on all the ec2_tags set on the instances.
The static inventory mirrors the hosts and groups of your existing site(s) inventory files. In addition you specify the dynamic ec2_groups which allows you to populate groups needed by the configuration playbooks from these dynamic groups.
This simple setup means that any previously written playbooks can run on the new AWS environment without any modification (assuming that your roles and plays are written correctly and any site specific information is retrieved from your site’s inventory and vars files!). You just point at the new site folder (as opposed to the specific inventory file) and Ansible will pick up both the dynamic and static inventory and merge them.
Mapping the facts is slightly more involved. As well as forming groups from them, any tags set during provisioning are retrieved as facts for the instance from the dynamic inventory.
Using the this play you can map these ‘ec2_tagged’ facts to facts needed by your roles and playbooks:
Just include this playbook in any playbooks configuring the new environment to ensure each new host has the facts required by your existing playbooks and roles.
You now have the ability to spin up new environments on EC2, using your existing Ansible roles and playbooks to configure these ephemeral instances. This reinforces what a good choice Ansible was for managing your infrastructure in the first place!
Here are a few things to remember:
- Use a static inventory with group_vars files for provisioning instances.
- Use ec2_tags to map groups.
- Use ec2_tags to map facts.
- Avoid using host_var files, allowing to remain as dynamic as possible.
- Don’t let any site specific info bleed out of the site folder.
A nice improvement would be to write a custom dynamic inventory script. This would take care of having the inventory in the exact format you need removing the need to:
- Merge static and dynamic inventory files.
- Map facts.