Update Ansible provisioner to only create a single inventory file

The Ansible provisioner will now only create a single inventory file named,
"vagrant_ansible_inventory". All defined Vagrant machines will be added to
this inventory file. Provisioning will now include a "--limit=#{machine}"
option to scope Ansible provisioning tasks to just the current machine. Setting
the Ansible provisioner's "limit" config option will override the new default
limit. Ansible provisioning scripts will now have access to all other defined
machines and what groups they reside in.
This commit is contained in:
Mark Aaron Shirley 2014-02-01 13:04:20 -08:00
parent bc55081e9f
commit 3bf5032d4b
2 changed files with 32 additions and 18 deletions

View File

@ -13,6 +13,14 @@ module VagrantPlugins
# Joker! Not (yet) supported arguments can be passed this way. # Joker! Not (yet) supported arguments can be passed this way.
options.concat(self.as_array(config.raw_arguments)) if config.raw_arguments options.concat(self.as_array(config.raw_arguments)) if config.raw_arguments
# By default we limit by the current machine. This can be
# overriden by the limit config option.
limit_option = if config.limit == nil
"--limit=#{@machine.name}"
elsif not config.limit.empty?
"--limit=#{as_list_argument(config.limit)}"
end
# Append Provisioner options (highest precedence): # Append Provisioner options (highest precedence):
options << "--inventory-file=#{self.setup_inventory_file}" options << "--inventory-file=#{self.setup_inventory_file}"
options << "--extra-vars=#{self.get_extra_vars_argument}" if config.extra_vars options << "--extra-vars=#{self.get_extra_vars_argument}" if config.extra_vars
@ -22,7 +30,7 @@ module VagrantPlugins
options << "--ask-sudo-pass" if config.ask_sudo_pass options << "--ask-sudo-pass" if config.ask_sudo_pass
options << "--tags=#{as_list_argument(config.tags)}" if config.tags options << "--tags=#{as_list_argument(config.tags)}" if config.tags
options << "--skip-tags=#{as_list_argument(config.skip_tags)}" if config.skip_tags options << "--skip-tags=#{as_list_argument(config.skip_tags)}" if config.skip_tags
options << "--limit=#{as_list_argument(config.limit)}" if config.limit options << limit_option if limit_option
options << "--start-at-task=#{config.start_at_task}" if config.start_at_task options << "--start-at-task=#{config.start_at_task}" if config.start_at_task
# Assemble the full ansible-playbook command # Assemble the full ansible-playbook command
@ -64,25 +72,31 @@ module VagrantPlugins
ssh = @machine.ssh_info ssh = @machine.ssh_info
generated_inventory_file = generated_inventory_file =
@machine.env.root_path.join("vagrant_ansible_inventory_#{machine.name}") @machine.env.root_path.join("vagrant_ansible_inventory")
generated_inventory_file.open('w') do |file| generated_inventory_file.open('w') do |file|
file.write("# Generated by Vagrant\n\n") file.write("# Generated by Vagrant\n\n")
file.write("#{machine.name} ansible_ssh_host=#{ssh[:host]} ansible_ssh_port=#{ssh[:port]}\n")
# Write out groups information. Only include current @machine.env.active_machines.each do |am|
# machine and its groups to avoid Ansible errors on m = @machine.env.machine(*am)
# provisioning. file.write("#{m.name} ansible_ssh_host=#{m.ssh_info[:host]} ansible_ssh_port=#{m.ssh_info[:port]}\n")
end
# Write out groups information. Only includes groups and
# machines which have been defined, otherwise Ansible will
# complain.
groups_of_groups = {} groups_of_groups = {}
included_groups = [] included_groups = []
config.groups.each_pair do |gname, gmembers| config.groups.each_pair do |gname, gmembers|
if gname.end_with?(":children") if gname.end_with?(":children")
groups_of_groups[gname] = gmembers groups_of_groups[gname] = gmembers
elsif gmembers.include?("#{machine.name}") else
included_groups << gname included_groups << gname
file.write("\n[#{gname}]\n") file.write("\n[#{gname}]\n")
file.write("#{machine.name}\n") gmembers.each do |gm|
file.write("#{gm}\n") if @machine.env.active_machines.map { |m| m[0] }.include?(gm.to_sym)
end
end end
end end

View File

@ -30,15 +30,15 @@ a single page of documentation.
When using Ansible, it needs to know on which machines a given playbook should run. It does When using Ansible, it needs to know on which machines a given playbook should run. It does
this by way of an inventory file which lists those machines. In the context of Vagrant, this by way of an inventory file which lists those machines. In the context of Vagrant,
there are two ways to approach working with inventory files. The first and simplest option there are two ways to approach working with inventory files. The first and simplest option
is to not provide one to Vagrant at all. Vagrant will generate inventory files for each is to not provide one to Vagrant at all. Vagrant will generate an inventory file encompassing
virtual machine it manages, and use them for provisioning machines. Generated inventory files all of the virtual machine it manages, and use it for provisioning machines. The generated
are created adjacent to your Vagrantfile, named using the machine names set in your Vagrantfile. inventory file is created adjacent to your Vagrantfile, named `vagrant_ansible_inventory`.
The second option is for situations where you'd like to have more than one virtual machine The second option is for situations where you'd like to have more control over the inventory file,
in a single inventory file, perhaps leveraging more complex playbooks or inventory grouping. perhaps leveraging more complex playbooks or inventory grouping. If you provide the
If you provide the `ansible.inventory_path` option referencing a specific inventory file `ansible.inventory_path` option referencing a specific inventory file dedicated to your Vagrant
dedicated to your Vagrant project, that one will be used instead of generating them. project, that one will be used instead of generating them. Such an inventory file for use with
Such an inventory file for use with Vagrant might look like: Vagrant might look like:
``` ```
[vagrant] [vagrant]
@ -153,8 +153,8 @@ by the sudo command.
ansible.groups = { ansible.groups = {
"group1" => ["machine1"], "group1" => ["machine1"],
"group2" => ["machine2", "machine3"], "group2" => ["machine2", "machine3"],
"all_groups:children" => ["group1", "group2"] "all_groups:children" => ["group1", "group2", "group3"]
} }
``` ```
Note that only the current machine and its related groups will be added to the inventory file. Note that undefined machines and groups are not added to the inventory. For example, `group3` in the above example would not be added to the inventory file.
* `ansible.host_key_checking` can be set to `false` which will disable host key checking and prevent `"FAILED: (25, 'Inappropriate ioctl for device')"` errors from being reported during provisioner runs. The default value is `true`, which matches the default behavior of Ansible 1.2.1 and later. * `ansible.host_key_checking` can be set to `false` which will disable host key checking and prevent `"FAILED: (25, 'Inappropriate ioctl for device')"` errors from being reported during provisioner runs. The default value is `true`, which matches the default behavior of Ansible 1.2.1 and later.