Index ¦ Archives ¦ Atom

Automating Ansible groups with Vagrant

Vagrant is a great tool for creating development environments and testing deployment scripts, especially with Ansible. Testing an Ansible playbook is can be as simple as vagrant up.

The problem

Ansible uses an inventory file to define the SSH details for each server, what groups a server belongs to - which then allows you to run certain roles/playbooks on specific servers. However the two options with Vagrant in dealing with the inventory file are rather limited.

The first option is the auto generated inventory, Vagrant will create a fresh inventory file based on the servers listed in the Vagrantfile which are currently up and running. This inventory file gets populated with the correct SSH details, however it means it starts with an empty inventory file which is only populated by setting ansible.groups.

The second option is the static inventory, which Vagrant will use instead of creating a dynamic inventory file. The downside with this would be duplicating the existing hosts file just to edit the SSH details, as well as hardcoding the IP addresses of all your Vagrant virtual machines.

The solution

We can use the ansibler Ruby gem to read the hosts file to automatically populate ansible.groups.

Installation is easy, as Vagrant maintains plugins separately from other Ruby libraries:

$ vagrant plugin install ansibler
Installing the 'ansibler' plugin. This can take a few minutes...
Installed the plugin 'ansibler (0.2.2)'!

Now we need to update the Vagrantfile. First of all we're going to read the existing hosts file, and populate the ANSIBLE_GROUPS variable with a hash of all the groups:

inventory = Ansible::Inventory.read_file('hosts')

ANSIBLE_GROUPS = {}

inventory.groups.each do |group|
    ANSIBLE_GROUPS["#{group.name}"] = group.hosts.map{ |host| host.name }
end

Next up is updating the Ansible provisioner config:

config.vm.provision "ansible" do |ansible|
    # ...
    ansible.groups = ANSIBLE_GROUPS
end

And that's it!

Now that ansible.groups contains an exact copy of all the group config from your hosts file, every time Vagrant creates a new dynamic inventory file it'll be populated with all the group configuration from your main hosts file.

© Alex Tomkins.