# Vagrant + Multiple Machines + Ansible

**URL:** <https://forum.ansible.com/t/vagrant-multiple-machines-ansible/17728>\
**Category:** Ansible Project\
**Created:** [March 12, 2015, 11:58am UTC](https://forum.ansible.com/t/vagrant-multiple-machines-ansible/17728 "2015-03-12T11:58:39Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ruben\_Ortiz](https://avatars.discourse-cdn.com/v4/letter/r/a9a28c/32.png) [@Ruben\_Ortiz](https://forum.ansible.com/u/Ruben_Ortiz)\
**Post date:** [March 12, 2015, 11:58am UTC](https://forum.ansible.com/t/vagrant-multiple-machines-ansible/17728/1 "2015-03-12T11:58:39Z")

</div>

Hi

I’m trying to write playbook to deploy automatically a Galera Cluster. I’ve been googling before ask help and I found some interesting info about Vagrantfile and multi machine scenario.

My main problem is until now I have never worked with vagrant multiple machines (3 nodes) and Ansible. I just want to deploy 3 nodes with Vagrant and then make the provision with Ansible. My current code does well the easies part of the work

- 3 nodes are deployed with Vagrantfile: [https://gist.github.com/rubendob/ed0d756bd1b3dc00dd2b](https://gist.github.com/rubendob/ed0d756bd1b3dc00dd2b)
- then I run playbook.yml to do some task, by now are just few: install percona key, update cache and install pxc into each node

the problem I have is I don’t know how set some variables into my.cnf.j2 jinja template

wsrep\_node\_address = {{ ansible\_eth1.ipv4.address }}

bind\_address = {{ galera\_conf[‘bind\_address’] }}

for example, I have no problem with this two variables, one is a fact and other I have it on defaults/main.yml but what about this one?

wsrep\_cluster\_address = gcomm://ip1,ip2,ip3

I just don’t know how to setup this parameter. Do I have to use groups of inventory file? Where I can find the values of my galera cluster nodes? From inventory? From Vagrantfile? And how I can make to ansible write it in a right way?

Thanks

---

<div class="post-metadata">

**Author:** ![jorginator74](https://avatars.discourse-cdn.com/v4/letter/j/f19dbf/32.png) [@jorginator74](https://forum.ansible.com/u/jorginator74)\
**Post date:** [March 12, 2015, 4:26pm UTC](https://forum.ansible.com/t/vagrant-multiple-machines-ansible/17728/2 "2015-03-12T16:26:15Z")

</div>

If you use a group in the inventory file, e.g. named 'cluster', then  
your template could contain something like this:

wsrep\_cluster\_address=gcomm://{% for host in groups['cluster'] %}{% if not loop.first %},{% endif %}{{ hostvars[host]['wsrep\_node\_address'] }}{% endfor %}

Hope this helps

---

<div class="post-metadata">

**Author:** ![James\_Martin1](https://avatars.discourse-cdn.com/v4/letter/j/0ea827/32.png) [@James\_Martin1](https://forum.ansible.com/u/James_Martin1)\
**Post date:** [March 12, 2015, 4:29pm UTC](https://forum.ansible.com/t/vagrant-multiple-machines-ansible/17728/3 "2015-03-12T16:29:52Z")

</div>

First, see the “Tips and Tricks” section here about using ansible with parallel execution in Vagrant: [http://docs.vagrantup.com/v2/provisioning/ansible.html](http://docs.vagrantup.com/v2/provisioning/ansible.html). You’ll need to do the provisioning this way to properly collect facts on all the machines.

Let’s say you had a group called “cluster” that contained servers 1, 2, and 3. To generate the variable for wsrep\_cluster\_address, you would have to do something like:

`  
{% set iface = ‘ansible\_eth1’ %}

wsrep\_cluster\_address = gcomm://{% for server in groups[“cluster”] %}{{ hostvars[server][iface].ipv4.address }}{% if not loop.last %},{% endif %}{% endfor %}  
`

The first line I’m setting a a jinja2 variable of the interface that holds the IP I want to use, just for convenience. The second line is the magic – I’m doing a for loop through my cluster inventory group, and for each host I’m printing the interface, separating each IP by a comma unless it’s the last host, then I don’t want to use a comma.

- James

---

<div class="post-metadata">

**Author:** ![Ruben\_Ortiz](https://avatars.discourse-cdn.com/v4/letter/r/a9a28c/32.png) [@Ruben\_Ortiz](https://forum.ansible.com/u/Ruben_Ortiz)\
**Post date:** [March 12, 2015, 4:44pm UTC](https://forum.ansible.com/t/vagrant-multiple-machines-ansible/17728/4 "2015-03-12T16:44:53Z")

</div>

Hi guys

thanks a lot, I’d never been able to reach this solution without help. I will try to put all this together to see if it works and update post as soon as possible!

Thanks again

---

<div class="post-metadata">

**Author:** ![Ruben\_Ortiz](https://avatars.discourse-cdn.com/v4/letter/r/a9a28c/32.png) [@Ruben\_Ortiz](https://forum.ansible.com/u/Ruben_Ortiz)\
**Post date:** [March 17, 2015, 3:22pm UTC](https://forum.ansible.com/t/vagrant-multiple-machines-ansible/17728/5 "2015-03-17T15:22:46Z")

</div>

Hi!

wow, I was reading about the subject of dynamic inventory. Actually it is my first time with a setup so complex. My Vagrantfile is (based on work of one guy, I don’t remember now the link of github, apologies):

_# -- mode: ruby --_  
_# vi: set ft=ruby :_

_# Vagrantfile API/syntax version. Don’t touch unless you know what you’re doing!_  
_VAGRANTFILE\_API\_VERSION = “2”_

_cluster = {_  
_“node1” =\> { :ip =\> “192.168.33.50”, :cpus =\> 1, :mem =\> 1024 },_  
_“node2” =\> { :ip =\> “192.168.33.51”, :cpus =\> 1, :mem =\> 1024 },_  
_“node3” =\> { :ip =\> “192.168.33.52”, :cpus =\> 1, :mem =\> 1024 },_  
_}_

_Vagrant.configure(VAGRANTFILE\_API\_VERSION) do |config|_  
_#config.vm.box = “nrel/CentOS-6.5-x86\_64”_  
_#config.vm.box = “ubuntu/precise64”_

_cluster.each\_with\_index do |(hostname, info), index|_  
_config.vm.define hostname do |cfg|_  
_cfg.vm.provider :virtualbox do |vb, override|_  
_config.vm.box = “ubuntu/precise64”_  
_override.vm.network :private\_network, ip: “#{info[:ip]}”_  
_override.vm.hostname = hostname_  
_vb.name = ‘pxc-’ + hostname_  
_vb.customize [“modifyvm”, :id, “–memory”, info[:mem], “–cpus”, info[:cpus], “–hwvirtex”, “on” ]_

_end # end provider_

_# provision nodes with ansible_  
_if index == cluster.size - 1_  
_cfg.vm.provision :ansible do |ansible|_  
_#ansible.verbose = “vvvv”_  
_ansible.extra\_vars = { ansible\_ssh\_user: ‘vagrant’ }_  
_ansible.inventory\_path = “./inventory”_  
_ansible.playbook = “playbook.yml”_  
_ansible.limit = “local”_  
_end # end provision_  
_end #end if_

_end # end config_

_end # end cluster_

_end # end vagrant_

I don’t know if it is the better way to do it, but at least it is the only one that worked for me. I run a loop to provision all machines and then I run playbook.yml.

Then in my inventory I have:

[local]  
node1 ansible\_ssh\_host=192.168.33.50  
node2 ansible\_ssh\_host=192.168.33.51  
node3 ansible\_ssh\_host=192.168.33.52

son in my template I finally wrote:

% set iface = ‘ansible\_eth1’ %}  
wsrep\_cluster\_address = gcomm://{% for server in groups[“local”] %}{{ hostvars[server][iface].ipv4.address }}{% if not loop.last %},{% endif %}{% endfor %}

And worked perfectly!

Thanks a lot guys!
