Vagrant Introduction

What is Vagrant? Taken directly from the vendors website:

Vagrant provides easy to configure, reproducible, and portable work environments built on top of industry-standard technology and controlled by a single consistent workflow to help maximize the productivity and flexibility of you and your team.

For more details about how Vagrant can be beneficial, I strongly encourage you to read the vendors website at:
https://www.vagrantup.com/docs/why-vagrant

Vagrant can be somewhat difficult to understand without seeing it in action. But in summary, building test servers can take a long time. With vagrant, you can run your test servers with a few simple commands so you can begin performing the tests that you wanted to get done without the wait. The environments are portable, so its very easy to share with colleagues.

All Vagrant does is communicate with providers of your choice such as VirtualBox, AWS, Rackspace Cloud, etc, and spins up the boxes using the respective providers API’s.

Installation

Installing Vagrant with VirtualBox is simple and easy on most desktop OS’s running Windows, Mac OSX, and Linux. Simply use the links below to download and install both VirtualBox and Vargrant on your desktop:

Known working versions
https://www.virtualbox.org/wiki/Download_Old_Builds_5_0
https://releases.hashicorp.com/vagrant/1.8.4/ **

** Vagrant v1.8.5 currently has issues with CentOS. Therefore, use v1.8.4 for now. Once v1.8.6 comes out, the bug should be addressed.

Once you have Vagrant and VirtualBox installed on your desktop, you are ready to begin deploying your test servers.

Getting familiar with Vagrant

Some quick terms you need to know:
Vagrantfile: This is the main configuration file for your test server.
Provider: Which API are we using? AWS, Rackspace Cloud, VirtualBox, etc.
Vagrant Boxes: This is the Vagrant base image. Think of it as your golden template that is used to deploy your test servers.

To manage your individual environments or test servers, you simply create the directory on your desktop, and tell Vagrant to deploy the OS to that individual directory.

An example of some of the test environments on my workstation are:

/home/user/vagrant/centos6
/home/user/vagrant/ubuntu1404
/home/user/vagrant/centos6-lamp-environment

Most of the common distro’s used today have official boxes available. I included puppetlabs as they have images that are up to date with base images as well as boxes with Puppet Enterprise already installed:
https://atlas.hashicorp.com/centos
https://atlas.hashicorp.com/ubuntu
https://atlas.hashicorp.com/debian
https://atlas.hashicorp.com/freebsd
https://atlas.hashicorp.com/puppetlabs

Quick start to see Vagrant in action

This is just a quick way to see Vagrant in action. It is important to remember that all the vagrant commands apply to whatever directory you are in on your desktop!

First, create the directory on your desktop for your test server:

[user@workstation ~]# mkdir -p vagrant/centos6-test
[user@workstation ~]# cd vagrant/centos6-test

Now initialize a Vagrantfile, which tells Vagrant what image to use, and how to configure it:

[user@workstation ~]# vagrant init centos/6

Then startup the test server:

[user@workstation ~]# vagrant up

And thats it! You can now log into your test server and get to work by running:

[user@workstation ~]# vagrant ssh

Once your done with your testing, you can remove the test server by running:

[user@workstation ~]# vagrant destroy

Command commands

These commands are to be ran from inside the directory of your project.

To check the status of a single test server:

[user@workstation ~]# vagrant status

If you made changes to your Vagrantfile and need to reload your settings:

[user@workstation ~]# vagrant reload

If you want to shutdown a test server, but you don’t want to destroy it:

[user@workstation ~]# vagrant halt

To check the status of all your test servers:

[user@workstation ~]# vagrant global-status

How to customize your test server

What makes Vagrant powerful is the Vagrantfile that resides in each directory for your test servers. This file allows you to specify IP’s, set users and passwords, run bootstrap scripts, or even spin up multiple servers from one file. This greatly speeds up the provisioning time so you can focus on testing what you truly needed to test.

The examples below are full examples of the Vagrantfile you can copy in your projects directory to spin up test servers.

Here is an example for spinning up a Ubuntu 12.04 server, and having Apache already installed:

[user@workstation ~]# mkdir vagrant/ubuntu1204-test01
[user@workstation ~]# cd vagrant/ubuntu1204-test01
[user@workstation ~]# vim Vagrantfile
  config.vm.box = "hashicorp/precise32"
  config.vm.provision "shell", inline: <<-SHELL
    sudo apt-get update
    sudo apt-get install -y apache2
    SHELL
end

[user@workstation ~]# vagrant up

Below is an example for spinning up a CentOS 6 server with the private IP address of 172.16.0.2, accessible only to your workstation:

[user@workstation ~]# mkdir vagrant/ubuntu1204-test01
[user@workstation ~]# cd vagrant/ubuntu1204-test01
[user@workstation ~]# vim Vagrantfile
Vagrant.configure(2) do |config|
  config.vm.box = "centos/6"
  config.vm.network "private_network", ip: "172.16.0.2"
end

[user@workstation ~]# vagrant up

Below is an example for spinning up a CentOS 6 server with the public IP address of 123.123.123.123, accessible by anyone:

[user@workstation ~]# mkdir vagrant/ubuntu1204-test01
[user@workstation ~]# cd vagrant/ubuntu1204-test01
[user@workstation ~]# vim Vagrantfile
Vagrant.configure(2) do |config|
  config.vm.box = "centos/6"
  config.vm.network "public_network", ip: "123.123.123.123"
end

[user@workstation ~]# vagrant up

Below is an example for spinning up a CentOS 6 server with Puppet Enterprise, with the private IP address of 10.1.0.3, and adding a bootstrap.sh file that we'll use for automatically our build process to install and configure Nginx:

[user@workstation ~]# mkdir vagrant/centos6-puppet-server01
[user@workstation ~]# cd vagrant/centos6-puppet-server01
[user@workstation ~]# vim Vagrantfile
Vagrant.configure(2) do |config|
  config.vm.box = "puppetlabs/centos-6.6-64-puppet"
  config.vm.network "private_network", ip: "10.1.0.3"
  config.vm.network "forwarded_port", guest: 80, host: 80
  config.vm.provision :shell, path: "bootstrap.sh"
end

[user@workstation ~]# vim bootstrap.sh
#!/usr/bin/env bash

# Sanity checks
if [ ! `whoami` = root ]; then
        echo "This script must be ran by the user:  root"
        exit 1
fi

# CentOS specific tasks:
if [ -f /etc/redhat-release ]; then
	selinux=`getenforce`
	if [ $selinux = "Enforcing" ]; then
		setenforce 0
	fi
	
	if [ `cat /etc/redhat-release | grep "Linux release 7" | wc -l` = 1 ]; then
		yum -y install iptables-services
	fi
fi

# Install required Puppet modules from the forge
puppet module install puppetlabs-stdlib
puppet module install jfryman-nginx
puppet module install puppetlabs-firewall

# General default.pp for Puppet
cat << EOF > /root/default.pp

class { 'nginx': }

nginx::resource::vhost { 'example.com':
  www_root    => '/var/www/example.com',
}

package { 'git':
  ensure => present,
}

firewall { '000 accept all icmp':
  proto  => 'icmp',
  action => 'accept',
}

firewall { '100 allow SSH':
  port   => [22],
  proto  => tcp,
  action => accept,
}

firewall { '101 allow http over port 80':
  port   => [80],
  proto  => tcp,
  action => accept,
}

EOF

# Execute first run of default.pp
puppet apply /root/default.pp

[user@workstation ~]# vagrant up

Below is an example for spinning up 2x CentOS 6 server with private IP addresses, accessible only to your workstation, both with 1G of memory, and installing MySQL on the db server, and Apache/PHP on the web server:

Vagrant.configure(2) do |config|
  config.vm.define "db01" do |db01|
    db01.vm.box = "centos/6"
    db01.vm.hostname = "web01.example.com"
    db01.vm.network "private_network", ip: "192.168.33.100"
    db01.vm.provision "shell", inline: <<-SHELL
        sudo yum update
        sudo yum install -y mysql
    SHELL
    db01.vm.provider "virtualbox" do |vb|
      vb.gui = false
      vb.memory = "1024"
    end
  end
  config.vm.define "web01" do |web01|
    web01.vm.box = "centos/6"
    web01.vm.hostname = "web02.example.com"
    web01.vm.network "private_network", ip: "192.168.33.101"
    web01.vm.provider "virtualbox" do |vb|
      vb.gui = false
      vb.memory = "1024"
    end
   web01.vm.provision "shell", inline: <<-SHELL
      sudo yum update
      sudo yum install -y httpd php
   SHELL
  end
end

[user@workstation ~]# vagrant up