Vagrant – A complete beginner’s guide
Introduction
This article is a complete beginner’s guide to Vagrant. Vagrant is an open-source free tool for building and managing virtual machine environments in a single workflow. Once you install Vagrant, it provides a command line client tool “vagrant” to quickly set up virtual machines using virtual machine providers like Oracle VM Virtual Box, Hyper-V, Docker and any other providers including cloud providers like AWS.
While Vagrant itself is not a provider, it works on top of providers and helps quickly set up environments.
Vagrant ships out of the box with support for Oracle VM Virtual Box, Hyper-V, Docker. You can make it work with any other provider by using custom providers. For example, you can make it work with AWS using vagrant-aws plugin.
Why use Vagrant?
If you are an Software Developer or Operations engineer or DevOps engineer or Security engineer, Vagrant is a tool that helps you set up a fully automated disposable environment for developing and testing application code or infrastructure management scripts or security scripts or performing various Proof Of Concepts.
Vagrant helps you create repeatable environments with simple commands. With vagrantfile, which helps you define configuration of virtual machines, you create and maintain your infrastructure as code.
Lets Get Started
This tutorial will walk you through your first Vagrant project, highlighting major features of Vagrant.
To get started with Vagrant, you will need to install Vagrant and a Virtual Machine Provider. We will use Oracle Virtual Box as provider which is free to download.
Prerequisites
The installations of prerequisites are pretty straightforward:
- Install Vagrant
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.
The installer will automatically addvagrant
to your system path so that it is available in terminals. If it is not found, please try logging out and logging back in to your system (this is particularly necessary sometimes for Windows). - Install Oracle Virtual Machine
Download the installer from https://www.virtualbox.org/ and follow the installers default instructions to install the Virtual Box.
Quick VM set up
In order to feel the power of Vagrant, we will first quickly spin up a VM on Virtual Box.
After you run the following two commands, you will have a fully running virtual machine in VirtualBox running Ubuntu 18.04 LTS 64-bit. Yes! It’s that easy.
First initialise Vagrant using init
command
$ vagrant init hashicorp/bionic64
Start the virtual machine using up
command
$ vagrant up
That’s it! You have just created your first virtual environment with Vagrant.
Now you can SSH into this machine with below command and explore your environment
$ $ vagrant ssh
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-58-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Tue Jun 16 21:57:57 UTC 2020
System load: 0.44 Processes: 91
Usage of /: 2.5% of 61.80GB Users logged in: 0
Memory usage: 11% IP address for eth0: 10.0.2.15
Swap usage: 0%
* MicroK8s gets a native Windows installer and command-line integration.
https://ubuntu.com/blog/microk8s-installers-windows-and-macos
0 packages can be updated.
0 updates are security updates.
vagrant@vagrant:~$
Terminate the SSH session with CTRL+D
, or by logging out.
vagrant@vagrant:~$ logout
Connection to 127.0.0.1 closed.
When you are done exploring terminate the virtual machine with destroy
command as follows and confirm when the CLI prompts you by typing yes
.
$ vagrant destroy
Now imagine every project you’ve ever worked on being this easy to set up! With Vagrant, vagrant up
is all you need to work on any project, to install every dependency that project needs, and to set up any networking or synced folders, so you can continue working from the comfort of your own machine.
The rest of these tutorials will walk you through setting up a more complete project.
Getting started with Vagrant project
Now let’s start with a complete project in which we will use Vagrant to spin up a VM using Ubuntu 18.04 LTS 64-bit and also install apache web server using shell
provisioner.
The first step to create a project with Vagrant is to create a Vagrantfile
. A Vagrantfile is generated on running vagrant init
command with boilerplate code.
The Vagrantfile allows you to:
- Mark the root directory of your project. Many of the configuration options in Vagrant are relative to this root directory.
- Describe the kind of machine and resources you need to run your project, as well as what software to install and how you want to access it i.e. define the configuration of your machine as code.
Now let’s start setting up Vagrant project Step by Step.
Create Vagrant root directory
If you are using Linux/Unix or Mac then open terminal or if using Windows open cmd prompt and create directory as follows:
$ mkdir vagrant_first_project
Move into new directory
$ cd vagrant_first_project
Initialise the directory
Now we will initialise our directory using init
command. This will generate a pre-populated Vagrantfile with some examples and documentation to understand the code.
The init command will take box name as argument like hashicorp/bionic64
. Boxes are the package format for Vagrant environments. The easiest way to use a box is to add a box from the publicly available catalog of Vagrant boxes.
Now we will initialise the directory and specify the hashicorp/bionic64
box
$ vagrant init hashicorp/bionic64
Now we have a Vagrantfile
in current directory which we will modify in our tutorial.
The Vagrantfile is meant to be committed to version control with your project, if you use version control. This way, every person working with that project can benefit from Vagrant without any upfront work.
You have now initialised your first project directory. To set up Vagrant for an existing project you would run vagrant init
in a pre-existing directory for example, root directory of a code repository. This will generate Vagrantfile which you can modify according to your project.
Now we can bring up the virtual machine to test if it works.
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
## ... Output truncated ...
Now we can ssh into the machine.
$ vagrant ssh
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-58-generic x86_64)
## ... Output truncated ...
Local and Guest Files Synchronization
Before moving on to learning shell provisioner, we will learn about sharing files between hosts and guests machines.
Vagrant automatically syncs files to and from the guest machine. This way you can edit files locally and run them in your virtual development environment.
By default, Vagrant shares your project directory (the one containing the Vagrantfile) to the /vagrant
directory in your guest machine.
If not already logged in, SSH into your virtual machine to see the synched file.
$ vagrant ssh
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-58-generic x86_64)
## ... Output truncated ...
On the virtual machine, list the files in the vagrant directory.
vagrant@vagrant:~$ ls /vagrant
Vagrantfile
This Vagrantfile that you see inside the virtual machine is actually the same Vagrantfile that is on your actual host machine.
To see the files sync between the guest machine and yours add a new folder in your virtual machine’s vagrant directory.
vagrant@vagrant:~$ touch /vagrant/test
End your SSH session.
vagrant@vagrant:~$ exit
logout
Connection to 127.0.0.1 closed.
Now list the contents of your local vagrant directory, and notice that the new directory you created on your virtual machine is reflected there.
$ ls
Vagrantfile test
The folder “test” is now on your host machine; Vagrant kept the folders in sync.
Provision a Virtual Machine using shell provisioner
Now we will edit the same Vagrantfile that we used above and learn to use shell provisioner to install and run an apache web server.
If we opt to just install apache by ssh into VM then we have to do this every time if we destroy the virtual machine. Hence we automate provisioning using shell provisioner.
Create an HTML file
Before doing that we will create a directory html
inside project directory vagrant_first_project and create a simple html file index.html
inside new directory.
The content of html file index.html
would look like this.
<html>
<body>
<h1>Getting started with Vagrant!</h1>
</body>
</html>
Create provisioning script
Now is the time to install Apache using shell provisioner. For that we need to create a script and call it lets just say bootstrap.sh
and save it in the same directory as Vagrantfile.
#!/usr/bin/env bash
apt-get update
apt-get install -y apache2
if ! [ -L /var/www ]; then
rm -rf /var/www
ln -fs /vagrant /var/www
fi
This script will download and start Apache, and crate a symlink between your synced files directory and the location where Apache will look for content to serve.
Modify Vagrantfile
Edit the Vagrantfile as follows
Vagrant.configure("2") do |config|
config.vm.box = "hashicorp/bionic64"
config.vm.provision :shell, path: "bootstrap.sh"
end
The provision
line tells Vagrant to use the shell
provisioner to setup the machine, with the bootstrap.sh
file. The file path is relative to the location of the project root (where the Vagrantfile is).
Provision the webserver
If you never ran vagrant up
before, then running it now will create machine and install Apache for us.
If machine is already created, we can run reload
to reload configuration from Vagrantfile.
$ vagrant reload --provision
==> default: Attempting graceful shutdown of VM...
==> default: Checking if box 'hashicorp/bionic64' version '1.0.282' is up to date...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
## ... Output truncated ...
After Vagrant completes running, the web server will be up and running. You cannot see the website from your own browser (yet), but you can verify that the provisioning works by loading a file from within the machine.
$ vagrant ssh
Now get the HTML file that was created during provisioning.
vagrant@vagrant:~$ wget -qO- 127.0.0.1
<html>
<body>
<h1>Getting started with Vagrant!</h1>
</body>
</html>
This works because in the shell script above you installed Apache and setup the default DocumentRoot
of Apache to point to your /vagrant
directory, which is the default synced folder setup by Vagrant.
Network Configuration
We will use Vagrant’s networking features to provide access to the guest machine from our host machine.
Port forwarding
Port forwarding allows you to specify ports on the guest machine to share via a port on the host machine. This allows you to access a port on your own machine, but actually have all the network traffic forwarded to a specific port on the guest machine.
Set up a forwarded port so you can access Apache in your guest, by adding it to the Vagrantfile under the line you added to run your bootstrap script.
Vagrant.configure("2") do |config|
config.vm.box = "hashicorp/bionic64"
config.vm.provision :shell, path: "bootstrap.sh"
config.vm.network :forwarded_port, guest: 80, host: 4567
end
Reload so that these changes can take effect.
$ vagrant reload
Access Apache from local browser
Once the machine is running again, load http://
127.0.0.1
:4567
in your browser, where you will find a web page that is being served from the guest virtual machine.
We have successfully configured networking for your virtual machine using Vagrant.
Share a Vagrant Environment
Vagrant Share is a plugin that lets you share your Vagrant environment to anyone around the world with an Internet connection. It will give you a URL that will route directly to your Vagrant environment from any device in the world that is connected to the Internet.
The person you are sharing the URL do not need to have vagrant installed.
Prerequisite
For vagrant share to work, we need to install ngrok
. Ngrok exposes local servers behind NATs and firewalls to the public internet over secure tunnels.
It can be downloaded and installed from https://ngrok.com/download
Install the plugin
Install the vagrant-share
plugin as follows:
$ vagrant plugin install vagrant-share
Installing the 'vagrant-share' plugin. This can take a few minutes...
Fetching vagrant-share-1.1.10.gem
Installed the plugin 'vagrant-share (1.1.10)'!
Share the environment
Now run vagrant share
to share the environment
$ vagrant share
##... output truncated ...
==> default: Creating Vagrant Share session...
==> default: HTTP URL: http://a2fc4f8e.ngrok.io
##... output truncated ...
Open a web browser and visit the URL from your output. It should load the Apache page we setup earlier.
If you modify the files in your shared folder and refresh the URL, you will see your update. The URL is routing directly into your Vagrant environment, and works from any device in the world that is connected to the internet.
End the sharing session.
$ ^C
==> default: Halting Vagrant share!
Suspend,Halt,Destroy or Rebuild Vagrant machines
Vagrant provides various options on how you want to stop or restart your work on Vagrant machines. We will explore these options now
Suspend the machine
Suspending the virtual machine will stop it and save its current running state.
$ vagrant suspend
==> default: Saving VM state and suspending execution...
When you begin working again bring the machine back up and its state resumes from where you left off.
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'hashicorp/bionic64' version '1.0.282' is up to date...
==> default: Resuming suspended VM...
##... output truncated ...
Suspending your machine is intended for stopping and starting work quickly.
The downside is that the virtual machine will still use disk space while suspended, and requires additional disk space to store the state of the virtual machine RAM.
Halt the machine
Halting the virtual machine will gracefully shut down the guest operating system and power down the guest machine.
$ vagrant halt
==> default: Attempting graceful shutdown of VM...
Halting your machine will cleanly shut it down, preserving the contents of disk and allowing you to cleanly start it again.
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'hashicorp/bionic64' version '1.0.282' is up to date...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
##... output truncated ...
A halted guest machine will take more time to start from a cold boot and will still consume disk space.
Destroy the machine
Destroying the virtual machine will remove all traces of the guest machine from your system. It’ll stop the guest machine, power it down, and reclaim its disk space and RAM. Destroy the machine now, and confirm with a yes
when prompted.
$ vagrant destroy
default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Forcing shutdown of VM...
==> default: Destroying VM and associated drives...
Again, when you are ready to work again, just issue a vagrant up
.
Rebuild the machine
Even if you have destroyed your machine. You still have files stored in shared file local. You can opt to checkin the project folder along with all the shared files and Vagrantfile. Now whenever you are ready to work on your project anytime which could be days or weeks or months or whenever you want to, all you need to do is run vagrant up
command.
$ vagrant up
And now you have rebuilt the environment with same configuration as before with just one command. Once Vagrantfile is completely configured, project can be shared with team members and they can set up environments with same configuration as you.
Conclusion
I am pretty sure by now you have realized how Vagrant can make your life much easier. It is a must have tool in your toolkit. Other provisioners which can be used with Vagrant are ansible , docker, chef, CFEngine and Salt.
Now go ahead and try to set up your project using Vagrant. You can refer Vagrant documentation at https://www.vagrantup.com/docs/index