$ vagrant up
Tags: devops, tutorial, beginners, linux
Published: 2019-10-04 10:55:00


Vagrant is a tool for building and managing virtual machine environments in a single workflow. Because Vagrant is geared so strongly toward automation, it lowers the time it takes to set up environments and as a result, improves production parity and consistency across all environments, making the "but it works on my local" an excuse of the past.
 
As a DevOps Engineer, I've found an interest in Vagrant because it enabled our team to provision disposable environments in a consistent manner. As a result, this allowed us to quickly test our infrastructure scripts and POC tools such as Chef, Puppet and Ansible. For further reading, visit [Vagrant](https://www.vagrantup.com/intro/index.html)

### Installation

Installing Vagrant is extremely easy. Head over to the [Vagrant downloads page](https://www.vagrantup.com/downloads.html) and get the appropriate installer or package for your platform. Install the package using standard procedures for your operating system.

### Getting Started


Once you have both the Vagrant CLI and VirtualBox installed, create a new working directory and run `vagrant init`. You'll notice that a file had been created. The Vagrantfile describes the type of VMs that are to be created in terms of the configuration and the method used to provision these VMs.

Next for the purpose of this tutorial, get your favorite editor handy and copy the sample below. I've added comments, in hope to demystify some of the Vagrantfile magic.

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

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version
Vagrant.configure("2") do |config|

   # Defining a VM named controller
	config.vm.define "controller" do |controller|

    # Every Vagrant development environment requires a box. You can search for
    # boxes at https://vagrantcloud.com/search.
    controller.vm.box = "minimal/xenial64"

    # Create a private network, which allows host-only access to the machine
    # using a specific IP.
    controller.vm.network "private_network", ip: "192.168.50.4"

    # Create a public network, which generally matched to bridged network.
    # Bridged networks make the machine appear as another physical device on
    # your network.
    controller.vm.network "public_network"

    # Provider-specific configuration so you can fine-tune various
    # backing providers for Vagrant. These expose provider-specific options.
    # Example for VirtualBox:
	controller.vm.provider :virtualbox do |vb|
	      vb.customize [
	    		"modifyvm", :id,
	    		"--cpuexecutioncap", "50",
	    		"--memory", "1024",
	      ]
	end
	end
end

```

Run `vagrant up controller`

The `vagrant up [name|id]` command creates and configures the VM according to your Vagrantfile in your current working directory.

![vagrant Up](https://i.imgur.com/8wYAABm.png)

Once up, run `vagrant status controller` to confirm that the VM had been created and is running.

![vagrant status](https://i.imgur.com/ZZDoPIe.png)

To ssh to the host run `vagrant ssh controller`

![vagrant ssh](https://i.imgur.com/0pCz0Eh.png)

Because we've configured the VM to belong to a private network in our Vagrantfile, we're able access the server using its private IP `192.168.50.4` 


### Provisioners

Provisioners in Vagrant allow us to automate the installation of software, as well as alter the system configuration as part of the `vagrant up` process.

Of course, all the installation and configuration can be done by hand using `vagrant ssh`. But by using the provisioning systems built-in to Vagrant, we can automate the process so that it is repeatable. Most importantly, it requires no human interaction, so we can `vagrant destroy` and `vagrant up` and have a fully ready-to-go work environment with a single command.

Vagrant supports a multitude of provisioners. For the purpose of this tutorial we'll make use of the Ansible provisioner. We'll write a playbook to create a new user and amend our Vagrant file to run the playbook during the `vagrant up` process. 

Get out your editor and create `main.yaml` in the current working directory and copy the sample code below.

```yaml
- name: Dev.to Vagrant with Ansible Demos
  hosts: all

  tasks:
    - name: Add the user ansible with a specific uid and a primary group of 'admin'
      user:
        name: ansible
        comment: ansible created
        uid: 1040
        group: root
      become: true
      become_user: root

```

Next, amend the Vagrant file.

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

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version
Vagrant.configure("2") do |config|

  # Defining a VM named controller
	config.vm.define "controller" do |controller|

    # Every Vagrant development environment requires a box. You can search for
    # boxes at https://vagrantcloud.com/search.
		controller.vm.box = "minimal/xenial64"

    # Create a private network, which allows host-only access to the machine
    # using a specific IP.
    controller.vm.network "private_network", ip: "192.168.50.4"

    # Create a public network, which generally matched to bridged network.
    # Bridged networks make the machine appear as another physical device on
    # your network.
    controller.vm.network "public_network"

    # Provider-specific configuration so you can fine-tune various
    # backing providers for Vagrant. These expose provider-specific options.
    # Example for VirtualBox:
		controller.vm.provider :virtualbox do |vb|
	  	vb.customize [
	    		"modifyvm", :id,
	    		"--cpuexecutioncap", "50",
	    		"--memory", "1024",
	  	]
	  end

    # Run Ansible from the Vagrant Host
    controller.vm.provision "ansible" do |ansible|
      ansible.playbook = "main.yaml"
    end

	end
end

```

Save and run `vagrant destroy controller` and then `vagrant up controller`. You'll see in the console output that the playbook is then executed as part of the `vagrant up` process. See output below and of course, I checked that the user had been created.


![vagrant ansible](https://i.imgur.com/dGmDIUR.png)

![vagrant proof](https://i.imgur.com/rRrAPnG.png)

Vagrant has been an essential to my development and my learning process. I hope I sparked some interest in this awesome tool. Vagrant has enabled me to learn both Puppet and Ansible and in general it improved my Sys Admin skill set. 

If there is an interest in wanting to learn more about Vagrant, I am definitely keen and showing you guys how to set up an entire Python web server stack using a Vagrantfile and Ansible. I hope you all enjoyed this read.