hashicorp / vagrant

Vagrant is a tool for building and distributing development environments.
https://www.vagrantup.com
Other
26.16k stars 4.43k forks source link

Generate ansible inventory based on hostname if present #11113

Open kindlehl opened 4 years ago

kindlehl commented 4 years ago

I was trying to run a multi-machine environment with two centos boxes. I wanted to test the firewall configuration on 'mono' by hitting it from 'testing'. The documentation wasn't clear on how inventory is generated, so I assumed that it was based on the hostname set in the Vagrantfile, which would make sense. to me It took me a while to figure out that the hostname is set based on the argument given to config.vm.define, since the Vagrantfile had worked before I added a second VM which forced me to specify the name argument for the VMs.

I think it'd make more sense to base the inventory hostnames on the hostname variable set, if is set; then default to the name of the VM given. Let me know what you think.

Here is my Vagrantfile

require 'yaml'

ansible_config = if File.exist?('vagrant_targets_local.yml')
                   ansible_config = YAML.load_file('vagrant_targets_local.yml')
                 else
                   {   
                     'groups' => { 'webservers' => ['vagrant-ansible.mydomain.com'] },
                     'tags' => []
                   }   
                 end 

Vagrant.configure(2) do |config|

  config.vm.box = "centos/7"

  # Disable the new default behavior introduced in Vagrant 1.7, to
  # ensure that all Vagrant machines will use the same SSH key pair.
  # See https://github.com/mitchellh/vagrant/issues/5005
  config.ssh.insert_key = false

  config.vm.define "mono", primary: true do |mono|

    mono.vm.network "private_network", ip: "10.0.10.3"

    mono.vm.hostname = "vagrant-ansible.mydomain.com"

    mono.vm.provider "virtualbox" do |v| 
      v.customize ["modifyvm", :id, "--audio", "none"]
      v.customize ["modifyvm", :id, "--memory", 2048]
    end 

    mono.vm.provision "ansible" do |ansible|
      ansible.compatibility_mode = "2.0"
      ansible.playbook = "site.yaml"
      ansible.limit = "all"
      ansible.extra_vars = ansible_config['extra_vars']
      ansible.groups     = ansible_config['groups']
      ansible.tags       = ansible_config['tags'] unless ansible_config['tags'].empty?
    end 
  end 

  config.vm.define "testing" do |testing|
    testing.vm.hostname = "testing.mydomain.com"
    testing.vm.network "private_network", ip: "10.0.10.4"
  end 
end
pommetjehorlepiep commented 3 years ago

@kindlehl, this is exactly the problem I bumped into as well. Your post gave me the bit I needed to fix my issue.

This doesn't work (why not!?):

    config.vm.hostname = "server2"
    config.vm.provision "ansible" do |ansible|
      ansible.groups = {
        "servers" => ["server1","server2"]
      }
      ansible.playbook = "ansible/site.yml"
    end

The generate inventory file looks like this:

# Generated by Vagrant

default ansible_host=127.0.0.1 ansible_port=2200 ansible_user='ansible' ansible_ssh_private_key_file='........'

[servers]

Why doesn't it just copy the groups in and use the hostname??

Even with vm.define the create inventory file will just contain the 'defined' name and not both mentioned servers...

I would've thought that this should be made clear in the documentation...