DEV Community

Cover image for $ vagrant up
Adan Patience
Adan Patience

Posted on

$ vagrant up

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

Installation

Installing Vagrant is extremely easy. Head over to the Vagrant downloads page 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.

# -*- 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

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

vagrant status

To ssh to the host run vagrant ssh controller

vagrant ssh

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.

- 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.

# -*- 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

vagrant proof

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.

Top comments (2)

Collapse
 
rnjudas_za profile image
RNJudas

Would it at all be possible to do inline appending of the vagrantfile during the ansible run to streamline the entire process?

Collapse
 
__init__adan profile image
Adan Patience

If I'm understanding your question correctly, you could append the Vagrantfile with a provisioner and run vagrant up controller --provision . It will only execute the provision blocks, without destroying the VM