A simple guide to provisioning Vagrant boxes with Ansible

Over the last couple of weeks, I’ve been working on some Red Hat JBoss BPM Suite workshop material. One part of the workshop is a four-hour lab that guides the attendees through the development of JBoss BPM Suite 6.x processes, rules and applications (note that this workshop is available to our customers, please contact your Red Hat account manager or local Red Hat sales representative for more information), but I’m going to be sharing part of the story with you today.

The lab-sessions require a pre-installed and pre-provisioned virtual machine, which contains all the material required to run the lab. This means that I need to create, install, provision and deploy a virtual machine that contains all the required tools and code to successfully run the lab sessions. Obviously this can done by hand, but what’s the fun in that?!

Manual work is error prone, hard to reproduce and definitely hard to version control. Hence, we want to have an automated solution in which we can (declaratively) define the layout and configuration of our virtual machine. Say hello to Vagrant and Ansible!

Vagrant

Vagrant is my tool of choice when it comes to creating and managing my virtual machine (VM) development boxes. It’s a lightweight toolset that allows to define and describe the layout and structure of a virtual machine in a single file, the Vagrantfile. We can describe what base-box we want to use for our virtual machine (a base-box is a minimal virtual machine with a minimal set of tools on which we use as a base on top of which we will build our own environment), the number of CPUs we want to assign to the VM, the amount of RAM, the network configuration, etc. Once configured we can start our VM by simply executing the command:

vagrant up

This will automatically configure a new virtual machine (in my case in VirtualBox), download the base-box (if it has not been downloaded already), and provision the virtual machine (more about provisioning later).

Once Vagrant has been run, the VM will be fully defined, configured, up-and-running and ready for use.  To stop the VM, we simply execute the command:

vagrant halt

One of the powers of Vagrant is that it allows you to store your entire VM definition in just a single file from which the same VM can be created and re-created over and over again. Instead of having to save a large, fully pre-defined, VM image, we simply checkin our Vagrantfile in our version control system. When we want to create a VM on another development environment, we simply run vagrant up to recreate the VM.

Ansible

Ansible is a radically simple IT automation engine that automates cloud provisioningconfiguration managementapplication deploymentintra-service orchestration, and many other IT needs. It uses no agents and no additional custom security infrastructure, so it’s easy to deploy – and most importantly, it uses a very simple language (YAML, in the form of Ansible Playbooks) that allow you to describe your automation jobs in a way that approaches plain English. 1

Ansible allows us to define and orchestrate the provisioning of our systems. It’s targeted at managing large IT deployments, allowing to easily provision and configure a vast array of machines and their configurations. However, being a very light-weight, agentless platform, it’s also very well suited to run on a simple laptop to provision and configure, for example, development VMs.

Ansible works with the concept of a Playbook. A Playbook is simply a text-file that defines which roles get assigned to which machines. The roles concept allows us to modularise the provisioning tasks, depending on the functionality that is provided. E.g. we can create a role for a “JBoss EAP” server, which will provision JBoss Enterprise Application Platform on the target machine. Or we can create a role “JBoss BPM Suite”, which depends on the role “JBoss EAP”, which will provision JBoss BPM Suite on top of JBoss EAP on the target machine. Using the roles concept, we have a modular approach to system provisioning, allowing us to re-use provisioning tasks, and define the layout of a system by simply applying the required role or set of roles.

Vagrant Provisioning

Let’s discuss the topic of provisioning. Provisioning is the concept of preparing and equipping a machine to allow it to provide (new) services to its users. 2 Vagrant provides a number of different provisioning modules. For example, it provides a file provisioning module, which allows to upload a file or directory from the host machine to guest machine (VM), and a shell provisioning module,  which allows to upload and execute a shells script on the guest machine.

Another provisioning module it provides is the Ansible Provisioner. This provisioner allows us to provision our guest machine (VM), using an Ansible Playbook, effectively combining the power of the 2 tools.

Setup and Configuration

We’re now ready to setup and configure both Vagrant and Ansible and combine their powers.:

  1. First we need to install the following tools:
    1. VirtualBox: this is our virtualization platform on which we will run our VMs.
    2. Vagrant: the tool in which we will configure the layout, structure and configuration of our VM.
    3. Ansible: our IT automation engine that will automatically provision our VM.
  2. In an empty directory, create a Vagrantfile. This file defines the layout, structure and configuration of our VM. An example Vagrantfile can be found here. This is the file I use to provision my JBoss BPM Suite workshop virtual machines. Note that in this file we use a CentOS 7 base-box:
config.vm.box = "centos/7"
  1. Next, we create an Ansible Playbook in the same directory as our Vagrantfile. In this example we use the filename “bpms-workshop-playbook.yml”. My example file can be found here. In the Playbook we need to define which roles get assigned to which machines. By default, the name of the VM created by Vagrant is “default” (this can be changed in the Vagrantfile  if you want, but in this example we will use the default value). This means that we need to use the name “default” as the machine name in the hosts section of our playbook. This snippet of our playbook file shows how we assign the roles “centos”, “gnome” and “bpmsuite-workshop”  to our “default” machine. Due to dependencies defined in the “bpmsuite-workshop” role, this also automatically applies the roles “bpms-design”, “bpms-base”, “eap” and java” to our machine:
- hosts: default
  remote_user: vagrant
  become: true
  become_method: sudo
  become_user: root
  roles:
    - centos
    - gnome
    - bpmsuite-workshop
  tags:
    - centos
    - gnome
    - bpmsuite-workshop
  1. We now need to define the roles. The roles I use for my BPM Suite Workshop Lab VM can be found here (note that there are more roles defined in that directory than I actually use). We will not dive into Ansible roles in this article. For more information about roles, please refer to the Ansible documentation.
  2. Next, we need to configure the Vagrant Ansible provisioning module and point it to our Ansible playbook. This can be done in the Vagrantfile:
config.vm.provision "ansible" do |ansible|
  ansible.verbose = "v"
  ansible.playbook = "bpms-workshop-playbook.yml"
end
  1. Finally, we can run the “vagrant up” command to create, start and provision our VM. If we want to re-provision an existing VM, we can simply run the command “vagrant provision“.

We can see the Ansible provisioning at work when Vagrant runs its provisioning module:

vagrant-ansible-provisioning

Conclusion

Vagrant and Ansible are two very powerful tools on their own, but combined they form an almost unbeatable combination. The ease of use and configuration of both tools makes these tools accessible to, and usable for, virtually any developer and/or  system administrator.

In this post we’ve given a short introduction to both tools, which is the tip of the features-iceberg provided by these platforms. We have shown that Ansible is not only targeted at system administrators, but that it’s also an invaluable tool for developers, testers, etc. I encourage you to experiment with the simple basics provided in this article, and expand the functionality of your playbook gradually to create even more sophisticated provisioning scripts.

For more information on Vagrant  and Ansible, please refer to Vagrant and  Ansible websites:

  • https://www.vagrantup.com
  • https://www.ansible.com

Special thanks to Justin Holmes for providing the initial Ansible playbook and roles for the JBoss BPM Suite platform.

 

Duncan Doyle

About the author:

Duncan Doyle is the Technical Marketing Manager for the JBoss BRMS and BPM Suite platforms at Red Hat. With a background in Red Hat Consulting and Services, Duncan has worked extensively with large Red Hat customers to build advanced, open-source, business-rules and business process management solutions.

He has a strong background in technologies and concepts like Service Oriented Architecture, Continuous Integration & Delivery, rules engines and BPM platforms and is a subject matter expert (SME) on multiple JBoss Middleware technologies, including, but not limited to, JBoss EAP, HornetQ, Fuse, Data Grid, BRMS and BPM Suite. When he’s not working on open-source solutions and technology, he is building Lego with his son and daughter or jamming along some 90’s rock-music on his Fender Stratocaster.


Join the Red Hat Developer Program (it’s free) and get access to related cheat sheets, books, and product downloads.

Share