Over a million developers have joined DZone.

Vagrant and Ansible for Dev Machines

Using Vagrant and Ansible for setting up developer machines for coding, allowing for everything to be automated and repeatable.

· DevOps Zone

Download “The DevOps Journey - From Waterfall to Continuous Delivery” to learn learn about the importance of integrating automated testing into the DevOps workflow, brought to you in partnership with Sauce Labs.

With my new job came, of course, lots of new projects. They cover quite a wide range of system requirements and so I've been creating ansible-provisioned vagrant machines for each one to make it easy to set up on other platforms. I thought I'd share some examples of my setup, in case anyone is interested, but more importantly so I can swiftly look this up when I start the next new project!

Start With the Vagrantfile

Vagrant is configured with a Vagrantfile. Here I'm setting the simplest options - which box to use, a name for the box, any directories I want to mount, and then the instruction to use ansible for the rest. Here's that basic config:

 Vagrant.configure("2") do |config| config.vm.box = "ubuntu/xenial64" config.vm.network :private_network, ip: "192.168.121.8" config.vm.synced_folder '.', '/vagrant' config.vm.provider "virtualbox" do |vb| vb.name = "example-app" end # # Run Ansible from the Vagrant Host # config.vm.provision "ansible" do |ansible| ansible.playbook = "playbook.yml" ansible.host_vars = { "default" => { "ansible_python_interpreter" => "/usr/bin/python2.7" } } end end 

This will bring up a basic Ubuntu 16.04 box (my preferred distro although it shipped with Python 3 rather than 2 which is why I need the ansible_python_interpreter setting and why I need to set the box name as by default the early versions of this box had a hardcoded name which broke things when you used it as the basis of more than one VM) and then hand off to ansible to do everything else.

Ansible to Make Technology Dance

There are a few different tools that would fit here but I've picked ansible for my VMs and so far I have found it quite approachable. In particular its declarative approach makes it easy to iteratively build up a machine by adding to the ansible recipe and reprovisioning repeatedly rather than always having to destroy the machine and start completely from scratch to test changes.

In the Vagrantfile example above, we set the provisioner to be ansible and give the playbook parameter as playbook.yml. The playbook is the recipe for cooking up the virtual machine you desire: it can be used to install packages, restart services, run commands, or really anything else we need to do to get the platform we need.

Rather than using the commands we already know, and typing them all in turn though, ansible has neat wrappers for almost all the tasks we could want to do. You'll probably want to refer to the excellent documentation for more information on the various modules that are in these examples and for others you want to use yourself.

Here's a quick cheatsheet of some of the patterns from my playbook.yml:

First-few-lines boilerplate

 --- - hosts: all gather_facts: no tasks: - name: apt-get update raw: sudo apt-get update -qq - name: Install python 2.7 raw: sudo apt-get install -qq python2.7 - name: Fix hostname to allow sudo remote_user: root become: yes lineinfile: dest=/etc/hosts line='127.0.0.1 ubuntu-xenial' owner=root group=root mode=0644 

Some of this is specific to the box that I had some issues with - since Python 2.7 isn't installed by default, currently ansible requires this older version of Python and so I found I needed to disable the fact-gathering and then install the required python to get the process started. The second block teaches the vagrant box its name which prevents an annoying warning when sudoing things.

Install an apt package

 - name: Install git remote_user: root become: yes apt: pkg=git 

The syntax for setting which user to use changed between versions of ansible, this is the currently-correct syntax but you'll see lots of examples using the older ones too so if you're copying/pasting examples and having issues, check this. Also if my examples aren't working, check the comments for errata and updates - and if you don't find what you're looking for, add a comment yourself!

When installing apt packages, you can also give a comma-separated list:

 - name: Install Node + npm remote_user: root become: yes apt: pkg=nodejs,npm,nodejs-legacy 

Running arbitrary shell commands

We can use the shell module to run commands:

 - name: Install node worker dependencies remote_user: root become: yes shell: npm install args: chdir: /vagrant/src/worker/ 

For many tasks, there are ansible wrappers (check out the files modules for example) already available which are recommended and stop the command from being blindly repeated on every provision.

For example the following block is from a project where I'm compiling couchdb from scratch:

 - name: Compile CouchDB remote_user: root become: yes shell: ./configure --disable-docs && make args: chdir: /vagrant/couchdb creates: bin/couchjs 

By using the creates property, I can tell ansible how to tell if this tool has already been compiled - it stops it from repeating the compile every time.

Technology-specific package managers

There are wrappers for all the dependency managers as well, here are two examples where I'm installing dependencies for npm and for pip (because polyglot is cool!)

 - name: Install Grunt remote_user: root become: yes npm: name=grunt-cli global=yes - name: Install Requestbin dependencies pip: requirements=/vagrant/requestbin/requirements.txt 

Working with services

If you change configuration and need to restart your webserver or any other service, there's a command for that too

 - name: Restart RabbitMQ remote_user: root become: yes service: name=rabbitmq-server state=restarted 

These examples are my reference library for my next project — if they're helpful to you too, then I'm delighted :) Comments are welcome!

Discover how to optimize your DevOps workflows with our cloud-based automated testing infrastructure, brought to you in partnership with Sauce Labs

Topics:
ansible ,vagrant ,devops ,automation

Published at DZone with permission of Lorna Mitchell, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}