Just moozing

Before you can check your notes, you must make them…

Vagrant and ansible

with one comment

I was suggested to look into Ansible as a substitution for puppet. It seems to be a good idea, this blog entry is about how to use ansible to do simple provisioning with vagrant.

My initial experiences with vagrant and libvirt is found here, so start there for the libvirt specifics.

To set up vagrant with provisioning, we will first create an appropriate Vagrantfile and then the ansible playbook.

 

Vagrantfile

The default file only includes an interface to the vagrant-libvirt NAT’ed network. This is a network the plugin creates automatically, if nothing else is written in the Vagrantfile.

Since this is a server installation, we must connect the virtual machine to a non-NAT’ed network to enable access from other hosts. The inner workings of the Libvirt plugin requires us to know the IP address of the administrative interface, which prohibits a non-local DHCP solution, see the docs for details.

The virtual machine will have 2 network interfaces – a management interface and a public interface.

$ cat Vagrantfile | grep -v ^#

ENV['DEFAULT_VAGRANT_PROVIDER'] = 'libvirt'

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # Every Vagrant virtual environment requires a box to build off of.
  config.vm.box = "deb8-base"

  config.vm.provider :libvirt do |libvirt|
    libvirt.host = ""
    libvirt.nested = false
    libvirt.management_network_name = "MGNT"
    libvirt.management_network_address = "192.168.97.0/24"
  end

  config.vm.hostname = "squidserver01"

  config.vm.network :public_network,
          :dev => "br020",
          :mode => "bridge",
          :type => "bridge"

  config.vm.synced_folder ".", "/vagrant", type: "9p"
end

Quick run-down:

  • The base box is a pre-installed box called “deb8-base”.
  • We connect to libvirtd running on localhost
  • We connect to a management network called “MGNT”, which is created manually beforehand.
  • The guest is “squidserver01”
  • The public interface is connected to a physical interface called br020. In my setup, it is a bridge to vlan 20 on the physical interface eth0.
  • /vagrant in the guest is mapped to the directory containing the Vagrantfile

I had an issue with the default gateway. I wanted to be the one from DHCP on eth1. The “use_dhcp_assigned_default_route” keyword was the solution. See here for details.

This is a basic non-provisioned Libvirt+Vagrant virtual machine setup.

 

Using Ansible

Using Ansible for provisioning resembles using puppet, as I have described before. Ansible uses playbooks, and using tasks, variables, roles and so on, the system gets rolled out with the defined configuration.

To get startet, you may find some examples here and the official Vagrant/Ansible documentation is here. The Ansible section in Vagrantfile is as follows

 # Ansible provisioner.
 config.vm.provision "ansible" do |ansible|
   ansible.playbook = "provisioning/playbook.yml"
   ansible.sudo = true
   ansible.groups = {
     "ungrouped" => ["default"]
   }
 end

The important lines are the playbook, which tells Ansible what to do. It is recommended to have a directory structure for this, so it resides in the provisioning directory.

Vagrant usually uses a vagrant user and passwordless sudo. That is the case in this example also.

The groups declaration is telling vagrant to autogenerate the inventory file. Default is the internal name of the virtual machine, squidserver01 is the hostname, which is used by the host and DNS/DHCP.

And a minimal playbook for completeness

$ cat provisioning/playbook.yml
# minimal default squid installation
- hosts: all
  gather_facts: yes

  tasks:
  - name: updating and installing packages
    apt: update_cache=yes cache_valid_time=3600
    apt: name=squid3 state=present

This will install the program squid3 using default configuration (which binds to the ipv6 interface). It will also update the apt cache at every run, if it is at least 3600 seconds since last time.

There are issues running commands using ansible-playbook, since the ssh authentication is different than the one used by vagrant. You will need do the provisioning, so you are able to do plain ssh to the host – this will probably include copying a public key.

 

Closing comments

  • I am using libvirt, and the vagrant libvirt plugin has some network requirements, which gives an extra network interface. It would be cool to vagrant serial instead of vagrant ssh to circumvent it, but this is not implemented yet.
  • I have a redundant dual-router Ansible setup in stock, that I want to be able to vagrant up 🙂
Advertisements

Written by moozing

July 19, 2015 at 12:00

Posted in Tech

Tagged with , ,

One Response

Subscribe to comments with RSS.

  1. […] have worked with VPSes at digital ocean using vagrant, and since vagrant supports ansible provisioning, it seems like a good […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: