Improvements in Vagrant Provisioner: Request for Comments

Hi!

Salut Gilles,

Seems we have the beginning of a french Ansible User Group :wink:

Group 1 (mandatory):

  * --inventory-file: already available since vagrant 1.2.0
  * --limit: already available since vagrant 1.2.0
  * --sudo: already available since vagrant 1.2.0
  * --sudo-user: already available since vagrant 1.2.0
  * *--tags*: part of PR 1697. I vote for it!
  * *--start-at-task*: could make sense in a vagrant playground, anybody
    vote for it?
  * *--step*: could make sense in a vagrant playground, anybody vote for it?
  * *-v,-vv,-vvv: *'-v' is available in vagrant 1.2.0. PR 1697 proposes
    all verbosity levels. I vote for it!

I played all day long yesterday with Vagrant & Ansible and yes, tags and
verbose are definitively missing, especially when it comes to debug
playbooks.

I ended up runining long-winded ansible-playbook commands outside
vagrant. While it's not really a problem, it would be much more
convenient to have access to them in the Vagrantfile.

The other things that's missing I think it the ability to tell ansible
the host name to use. I didn't really check but it seems ansible
provisionner will use whatever IP it finds in the Vagrant config, or
127.0.0.1 if none.

This is not very convenient IMHO. I prefer to use names when possible in
inventories.

But may be I missed something though.

Thanks,

M

Salut Michel,

Thanks for your feedbacks. I’m not sure to understand well your question:

The other things that’s missing I think it the ability to tell ansible
the host name to use. I didn’t really check but it seems ansible
provisionner will use whatever IP it finds in the Vagrant config, or
127.0.0.1 if none.

Vagrant uses argument --inventory-file with “ansible.inventory_file”. You should check there…

This make me think on following: There is no “control” by Vagrant to run ansible-playbook against VMs configured in Vagrantfile! It could be nice to add some sanity check: Ideally, Vagrant should parse ansible.inventory_file, filter by ansible.limit and check if it maps with Vagrantfile host(s).

Salut Michel,

Thanks for your feedbacks. I'm not sure to understand well your question:

    The other things that's missing I think it the ability to tell ansible
    the host name to use. I didn't really check but it seems ansible
    provisionner will use whatever IP it finds in the Vagrant config, or
    127.0.0.1 if none.

Vagrant uses argument --inventory-file with "ansible.inventory_file".
You should check there...

Yes sorry, I wasn't very clear or awake :slight_smile:
What I'm looking for is to use hostnames in inventory file without
touching /etc/hosts or adding ansible_ssh_host in the inventory.

For instance (example trimmed down) :

Vagrant.configure("2") do |config|
  config.vm.define :webapp do |webapp|
    webapp.vm.hostname = "webapp.local"
    webapp.vm.network :private_network, ip: "192.168.123.2"
  end

  config.vm.provision :ansible do |ansible|
    ansible.inventory_file = "vagrant/hosts"
  end
end

with the following vagrant/hosts :

webapp.local

AFAIK, this can't be done unless inventory is :

webapp.local ansible_ssh_host=192.168.123.2

which leads to repetition (changing the IP or networking style involves
changing the inventory file).

It could be nice if hostname defined in webapp.vm.hostname to be mapped
automatically to host IP.

In previous vagrant versions, vagrant-hostmaster could do this but it's
not compatible with newer vagrant versions.

But there is an issue opened, and things are looking good and I don't
think it worth it to do something on the provisionner side (at first
sight it would be quite hairy to do).

However, the same apply to ansible_ssh_port if port 22 if forwarded in
the configuration.

May be an option to generate an inventory file with the proper
hostnames, ansible_ssh_host, ansible_ssh_port could be nice and would
solve all this for simple setups.

This make me think on following: There is no "control" by Vagrant to run
ansible-playbook against VMs configured in Vagrantfile! It could be nice
to add some sanity check: Ideally, Vagrant should parse
ansible.inventory_file, filter by ansible.limit and check if it maps
with Vagrantfile host(s).

This is probably an ansible provisionner's responsability more than a
Vagrant one no ?

May be checking that the output of `ansible-playbook --list-hosts
--limit "#{config.limit}"` and checking that union with Vagrantfile
host(s) isn't nil could be enough ?

M

does a vagrant inventory plugin make sense? it should dynamically set
ansible_ssh_host could even add new hosts as they become available.

Thanks Michel and Brian for updates!

I like these DRY wishes :slight_smile: I therefore started to work on a separate vagrant add-on request, with following idea:

Ability to auto-generate a temporary ansible inventory based on Vagrantfile definitions. My prototype works well, even for multi-machine mode. For each machine to be provisioned, the temporary inventory file would look like following:


[db]
127.0.0.1:2201

based on this template


[<%= group_name %>]
<%= ssh_host %>:<%= ssh_port %>

We also could organize the template to get following result:

[db]
db-hostname ansible_ssh_host=127.0.0.1 ansible_ssh_port=2201

But I don’t see any advantage for the second variant… did I miss something?

Notes / Open Questions:

  • ansible-playbook will thus ssh-connect via the same localhost-portmapping channel as vagrant ssh itself.
  • Trying to reduce total number of options for Ansible Provisioner in Vagrant, I think that following configuration logic is handy:
  • auto-generate ansible inventory file unless ansible.inventory_file is specified in Vagrantfile- About the choice for the [group name], I rely on the vagrant machine name, leading to following values:
  • ‘default’ in single-machine mode
  • machine name in multi-machine mode (e.g. ‘db’ if config.vm.define :db do |db| ...)- Optional Vagrant settings like vm.hostname (only used to set vm hostname, i guess) or additional private network interfaces vm.network :private_network, ip:... are not considered and won’t be used in “auto” mode.

What do you think? Thank you in advance for review. I’ll try to clean my prototype code in order to submit this request this week-end…

@Michel: I like ansible-playbook --list-hosts --limit "#{config.limit}" sanity check too, which makes sense when using an ‘unsafe’ ansible.inventory_file. All possible SSH connections should be thus checked (127.0.0.1:2200, 192.168.123.2:22, …)… I won’t include this point for now, but it could come in a next step… is there any vote on it? or overkill stuff?

Gilles

All these ideas sound great. I've just started playing with the
ansible provisioner for Vagrant. One feature I'd like to see (and
maybe it's there already and I can't figure it out) is the ability to
launch a playbook _after_ all of the hosts are up. That way you get
the benefit of parallel provisioning goodness of ansible and the
ability for the hosts to interact with each other during the playbook
runs. This happens frequently for me when dealing with clustered
systems.

- James

Add-on “auto-generated inventory_file from Vagrantfile” proposed in https://github.com/mitchellh/vagrant/pull/1723 (I finally drop the wrong idea define a ‘group’, but just create a single line with hostname and ssh connection data). hosts fields in playbooks must either be set to all or correspond to vagrant machine names (default in single-machine mode).

RE James:I think that (at the moment) ansible awesome parallel-provisioning does not fit with multi-machine mode in vagrant (vagrant makes a provisioner call for each managed machine). Your “after all” feature sounds like a possible general feature request to vagrant (that makes sense independently of the provisioner in use: ansible, chef, …). But I think you can do the trick quite easily with something like:

vagrant up && ansible-playbook --tags=after_all site.yml