From 3bf5032d4ba4e9fced364cde42aa8952018bf0cb Mon Sep 17 00:00:00 2001 From: Mark Aaron Shirley Date: Sat, 1 Feb 2014 13:04:20 -0800 Subject: [PATCH] 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. --- plugins/provisioners/ansible/provisioner.rb | 30 ++++++++++++++----- .../source/v2/provisioning/ansible.html.md | 20 ++++++------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/plugins/provisioners/ansible/provisioner.rb b/plugins/provisioners/ansible/provisioner.rb index aae761f0a..9a27ae3ca 100644 --- a/plugins/provisioners/ansible/provisioner.rb +++ b/plugins/provisioners/ansible/provisioner.rb @@ -13,6 +13,14 @@ module VagrantPlugins # Joker! Not (yet) supported arguments can be passed this way. 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): options << "--inventory-file=#{self.setup_inventory_file}" 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 << "--tags=#{as_list_argument(config.tags)}" if config.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 # Assemble the full ansible-playbook command @@ -64,25 +72,31 @@ module VagrantPlugins ssh = @machine.ssh_info 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| 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 and its groups to avoid Ansible errors on - # provisioning. + @machine.env.active_machines.each do |am| + m = @machine.env.machine(*am) + 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 = {} included_groups = [] config.groups.each_pair do |gname, gmembers| if gname.end_with?(":children") groups_of_groups[gname] = gmembers - elsif gmembers.include?("#{machine.name}") + else included_groups << gname 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 diff --git a/website/docs/source/v2/provisioning/ansible.html.md b/website/docs/source/v2/provisioning/ansible.html.md index 9ad057116..f7fb36498 100644 --- a/website/docs/source/v2/provisioning/ansible.html.md +++ b/website/docs/source/v2/provisioning/ansible.html.md @@ -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 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 -is to not provide one to Vagrant at all. Vagrant will generate inventory files for each -virtual machine it manages, and use them for provisioning machines. Generated inventory files -are created adjacent to your Vagrantfile, named using the machine names set in your Vagrantfile. +is to not provide one to Vagrant at all. Vagrant will generate an inventory file encompassing +all of the virtual machine it manages, and use it for provisioning machines. The generated +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 -in a single inventory file, perhaps leveraging more complex playbooks or inventory grouping. -If you provide the `ansible.inventory_path` option referencing a specific inventory file -dedicated to your Vagrant project, that one will be used instead of generating them. -Such an inventory file for use with Vagrant might look like: +The second option is for situations where you'd like to have more control over the inventory file, +perhaps leveraging more complex playbooks or inventory grouping. If you provide the +`ansible.inventory_path` option referencing a specific inventory file dedicated to your Vagrant +project, that one will be used instead of generating them. Such an inventory file for use with +Vagrant might look like: ``` [vagrant] @@ -153,8 +153,8 @@ by the sudo command. ansible.groups = { "group1" => ["machine1"], "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.