Skip to content

Instantly share code, notes, and snippets.

@tknerr
Last active January 23, 2024 16:42
Show Gist options
  • Star 91 You must be signed in to star a gist
  • Fork 15 You must be signed in to fork a gist
  • Save tknerr/291b765df23845e56a29 to your computer and use it in GitHub Desktop.
Save tknerr/291b765df23845e56a29 to your computer and use it in GitHub Desktop.
Vagrant with Ansible Provisioner on Windows

Vagrant with Ansible Provisioner on Windows

Long story short, ansible does not work on a Windows control machine, so you basically have to:

  • either run ansible --connection=local ... in the target vm
  • set up a separate control vm where ansible is installed via shell provisioner

Below are Vagrantfile examples for both approaches

Within the Target VM

This requires the vagrant-guest_ansible plugin to be installed (v0.0.2.dev, see this pull request).

Vagrantfile:

Vagrant.configure("2") do |config|
  config.vm.box = "hansode/centos-6.5-x86_64"

  provisioner = Vagrant::Util::Platform.windows? ? :guest_ansible : :ansible

  config.vm.define "web" do |web|
    web.vm.network :private_network, ip: "192.168.33.13"
    web.vm.hostname = "web"
    web.vm.provision provisioner do |ansible|
      ansible.playbook = "provisioning/playbook.yml"
    end
  end

  config.vm.define "db" do |db|
    db.vm.network :private_network, ip: "192.168.33.14"
    db.vm.hostname = "db"
    db.vm.provision provisioner do |ansible|
      ansible.playbook = "provisioning/playbook.yml"
    end
  end

end

From a Separate Control VM

This does not require any additional plugins, but needs a shell script to install ansible in the control VM:

Vagrantfile:

Vagrant.configure("2") do |config|
  config.vm.box = "hansode/centos-6.5-x86_64"

  config.vm.define "web" do |web|
    web.vm.network :private_network, ip: "192.168.33.13"
    web.vm.hostname = "web"
    web.vm.synced_folder ".", "/vagrant", disabled: true
  end

  config.vm.define "db" do |db|
    db.vm.network :private_network, ip: "192.168.33.14"
    db.vm.hostname = "db"
    db.vm.synced_folder ".", "/vagrant", disabled: true
  end

  #
  # this is our ansible controller VM which provisions the other VMs
  #
  config.vm.define "controller" do |controller|
    controller.vm.network :private_network, ip: "192.168.33.15"
    controller.vm.hostname = "controller"
    # install ansible
    controller.vm.provision "shell", privileged: false, path: "install_ansible.sh"
    # run ansible
    controller.vm.provision "shell", privileged: false, inline: <<-EOF
      if [ ! -f /home/vagrant/.ssh/id_rsa ]; then
        wget --no-check-certificate https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant -O /home/vagrant/.ssh/id_rsa
        wget --no-check-certificate https://raw.githubusercontent.com/hashicorp/vagrant/master/keys/vagrant.pub -O /home/vagrant/.ssh/id_rsa.pub
        chmod 600 /home/vagrant/.ssh/id_*
      fi
      rm -rf /tmp/provisioning
      cp -r /vagrant/provisioning /tmp/provisioning
      cd /tmp/provisioning
      chmod -x hosts
      export ANSIBLE_HOST_KEY_CHECKING=False
      ansible-playbook playbook.yml --inventory-file=hosts
    EOF
  end

end
@dmytro-y-dev
Copy link

@tknerr Thanks for described solutions. Strange that it got so few starts ;/

@michaellihs
Copy link

Hi @tknerr - just stumbled over this and thought I'd say "Hello!" :)

@lakshmiNdevulapalli
Copy link

Thanks for the solution @tkneer. It worked for me! I was literally banging my head and tried 100 different workarounds, but finally your solution worked for me.

Cheers,
Bala

@brittmorris-kff
Copy link

This didn't work for me initially because the vagrant-guest_ansible plugin expects to have the /vagrant shared folder (which my installation didn't have; it had a different shared folder). It started working flawlessly when I added in the shared folder mapping db.vm.synced_folder ".", "/vagrant" (as is in the second example, but disabled). Thanks for providing this solution!

@brittmorris-kff
Copy link

Wish I had looked at the "see also" first, since this functionality (run Ansible within guest VM) has been part of Vagrant officially since 1.8: https://www.vagrantup.com/docs/provisioning/ansible_local.html

@gccpacman
Copy link

Actually now we can use Vagrant along with ansible in WSL quite easily, make sure you set up the variable export VAGRANT_WSL_ENABLE_WINDOWS_ACCESS="1" in WSL environment, see also: https://www.vagrantup.com/docs/other/wsl.html

@DaVince
Copy link

DaVince commented Apr 8, 2020

Nice stuff, thank you very much! It's still useful to do it this way for our use case.

Those wgets were a little confusing, so I changed the URL from mitchellh/vagrant to hashicorp/vagrant instead.

@tknerr
Copy link
Author

tknerr commented Apr 9, 2020

I just updated the wget URLs in the gist above, thanks @DaVince for the suggestion!

@m4ri0g
Copy link

m4ri0g commented Jun 1, 2020

how would you deploy a new vm using the controller vm?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment