Vagrant Ansible Provisioning


In this video we are going to get started provisioning our brand new Vagrant box by making use of Ansible.

This will involve installing Ansible, so if you haven't done so already, please do so by either following the instructions on the Ansible docs, or using my abridged version here.

To make our lives a little easier, we are going to make use of the Vagrantfile created by Jeff Gerling, making only two changes - the box in use, and the amount of RAM.

# /your/project/vagrant/Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.ssh.insert_key = false

  config.vm.provider :virtualbox do |v|
    v.name = "lamp"
    v.memory = 1024
    v.cpus = 2
    v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
    v.customize ["modifyvm", :id, "--ioapic", "on"]
  end

  config.vm.hostname = "lamp"
  config.vm.network :private_network, ip: "192.168.33.33"

  # Set the name of the VM. See: http://stackoverflow.com/a/17864388/100134
  config.vm.define :lamp do |lamp|
  end

  # Ansible provisioner.
  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "provisioning/playbook.yml"
    ansible.inventory_path = "provisioning/inventory"
    ansible.sudo = true
  end

end

(full credit to Jeff Gerling for this, and other Vagrant with Ansible examples)

We are going to make use of the ubuntu/trusty64 box. As mentioned in the previous video's show notes, if you are sharing your project with the wider world, using a 32bit box may make your project more accessible.

It's important to bump up the RAM - v.memory = 1024 - as Composer in particular throws a bit of a fit if it runs out of RAM. And as we are PHP-ists we will be using Composer quite a lot :) Feel free to bump this value as high as you require.

In anything but a fresh Symfony install, I find v.memory = 2048 makes things 'just work'.

Vagrant Ansible Provisioning

There are a few things we need to do now.

If we were to go ahead and run vagrant up at this stage, our provisioning process would fail as our playbook and inventory_path do not yet exist.

To fix this, let's create those files:

cd /your/project/vagrant
mkdir -p provisioning/roles
cd provisioning
touch playbook.yml
touch inventory

Then, assuming we have installed Ansible by now, we can make use of the ansible-galaxy command to create ourselves a skeleton Role. This saves us from having to manually create the files and folder structure that makes up an Ansible Role. A time saver, but not essential. Feel free to do this by hand if you are so inclined.

cd /your/project/vagrant/provisioning/roles
ansible-galaxy init example
cd example

This will then create us the example role, with the full Role directory structure.

We want to specify a very basic role to begin with. We will move on to a more complex role structure in the next video.

For now, we want to install one thing - htop. Feel free to install anything you like.

Setting up this Role is very straightforward. If you would like to know more about setting up custom roles then please watch the tutorial series on Ansible.

# /your/project/vagrant/provisioning/roles/example/tasks/main.yml
---
- name: Installing something
  apt: pkg={{ item }} state=installed update_cache=true
  with_items:
    - htop
    # - any other valid package

Note, this assumes you are installing to an Ubuntu server (ubuntu/trusty64). If you have used a different flavour of Linux, you will likely need to change the apt line for your chosen Linux variant equivalent.

That's as much as we need for our simple example role.

Next, we must create the Ansible Playbook which specifies which hosts to run (or install) a given list of roles against.

# /your/project/vagrant/provisioning/playbook.yml
---
- hosts: lamp # or whatever you called your machine in your Vagrantfile
  sudo: true
  gather_facts: true

  roles:
    - example
    # - any other roles you want

Again, very basic here. In fairness, most playbooks look similar to this.

Lastly, we need to update our Inventory, so Ansible knows about our new server.

# /your/project/vagrant/provisioning/inventory
lamp ansible_ssh_host=192.168.33.33 ansible_ssh_port=22

Update any of these values if you have changed anything along the way.

With these three pieces in place, we can go ahead and provision our server with our new config.

cd /your/project/vagrant
vagrant provision

This will reboot the machine and apply the new build script.

After the process completes, and assuming everything went swimmingly, you should be able to do the following:

vagrant ssh
htop

And as if by magic, now you have htop installed.

The beauty of this is, anyone else who is sharing your project only needs to do the vagrant provision step and they too will find their machine identical to yours.

Be sure to commit your Vagrantfile into your git repo!

This process is identical regardless of how complex your Ansible provisioning process becomes.

Episodes

# Title Duration
1 Beginners Guide to Vagrant 07:58
2 Vagrant Ansible Provisioning 14:35
3 Vagrant Housekeeping 03:12
4 Vagrant and Symfony2 13:50