Vagrant, Libvirt, and Ansible
April 3, 2021
I recently started to learn how to use Ansible, from Jeff Geerling's book Ansible for DevOps, which so far I highly recommend. A bit of a pain point has been using virtual machines created by vagrant as if they were remote servers — without using Ansible as a provisioner and just running Ansible commands like normal. I think I now have a good workflow that I thought might help others in this situation.
First, a couple notes on my setup: my OS is Debian Testing (which I just upgraded to last week from Buster, which was surprisingly simple and painless to do) and I'm using libvirt as the provider, but this should probably be applicable to other configurations. I'm not going to cover installation of these or vagrant or Ansible, though perhaps someday I'll edit that in.
Create the virtual machine with vagrant. If you haven't yet added the box you want to use, add it with
vagrant add box [user]/[box]. Let's say it's CentOS7, since that's what Geerling tends to use:
vagrant add box generic/centos7. (I haven't been using the boxes he made since they use VirtualBox rather than libvirt.) Then initialize it:
vagrant init generic/centos7. This creates the configuration file, Vagrantfile, in the current directory. If you'll be using some kind of web server on the virtual machine, open that file up and uncomment the line
config.vm.network "forwarded_port", guest: 80, host: 8080(putting in whatever host port you'll use in your browser to connect to it).
Start up the virtual machine:
Get the ip address of the vm:
vagrant ssh-config. Either use it directly or put it in an Ansible "inventory" file.
Add the ssh key of the vm to your SSH authentication agent. For libvirt vms, this is located at
.vagrant/machines/default/libvirt/private_keyfrom the vm directory (where the Vagrantfile is located), so run
ssh-add .vagrant/machines/default/libvirt/private_key. I imagine that if you use a different provider, it would just be a matter of substituting its name for the "libvirt" directory.
That should do it — you should now be able to use
ansible-playbook to connect to the virtual machine.
Note that if you set up multiple servers on the virtual machine and then run an Ansible command on them, you'll need to confirm the ssh fingerprint the first time. Since Ansible runs in parallel mode by default, you'll repeatedly get asked to confirm it, and it doesn't always seem to work. So I'll use one fork in this case by passing in
-f 1 to the command the first time.