Often we need to create local environments to test setting up new services. A great way to do it is by provisioning VMs with Vagrant.
What is Vagrant?
Vagrant is a cross-platform tool to automate the creation and management of VMs for development uses. You write the desired configuration for your VMs in a
Vagrantfile and then use the
vagrant command to start, stop and manage the VMs.
Vagrant only automates the management of VMs. The VMs themselves are hosted by a provider like VirtualBox, VMware, Docker or Hyper-V. For this tutorial we are going to use VirtualBox on Windows 10.
Vagrant requires a compatible version of VirtualBox. Download and install VirtualBox 6.1.16.
Download and install Vagrant 2.2.10. This version is compatible with the previously installed VirtualBox. Restart your machine.
Starting and provisioning a simple VM
First choose a working directory and then create a Vagrantfile by entering in a command line:
vagrant init bento/ubuntu-20.04
What we’ve done here is tell the
vagrant command to create a Vagrantfile using the
bento/ubuntu-20.04 box. VM images for Vagrant are called boxes, and you can find them here. I recommend to use the bento ones.
Let’s have a look at the Vagrantfile. Open it in an editor, I recommend to open the directory in Visual Studio Code:
The Vagrantfile is a description of how you want Vagrant to create your VMs. It’s written in Ruby, but you don’t need to know Ruby to edit it. The syntax is self-explanatory and has very good comments. If you removed all the comments this would be the entire file:
Vagrant.configure("2") do |config| config.vm.box = "bento/ubuntu-20.04" end
It simply telling Vagrant to create a VM using the
bento/ubuntu-20.04 box. It uses the Vagrant configuration format version “2” (the current one).
Let’s make it more interesting. Uncomment lines 66-69 by removing the leading hashes, they should look like this:
As the comments explain, this is telling Vagrant to run a script to install Apache in the VM. This provisioning script runs only the first time you start the VM. If you want to run provisioning in an already existing VM, you need to use the
vagrant provision command.
Let’s also uncomment line 31 to tell Vagrant to map the VM’s por 80 to port 8080 in our machine:
Now start the VM! In the same directory where the Vagrantfile was created, enter in the command line:
You will see some logs and wait while Vagrant downloads the box and starts the VM, maps some ports and runs the provisioning script to install Apache. When it’s done, you can enter
vagrant status to check that it was created correctly:
If you open VirtualBox you can also verify that your VM is running in VirtualBox:
Connecting to the Virtual Machine
Enter in the command line:
This uses ssh to connect to the VM. Now you are inside the VM in a Linux terminal:
Change directories to
/vagrant and create a new file:
cd /vagrant echo "Hello from Vagrant!" > hello.txt
Now open the file you created inside the VM in Visual Studio Code:
Vagrant by default enables file sharing between your host and the guest VM, synchronizing your working directory (the one where Vagrafile is) to the
/vagrant directory in the VM.
And if you point the browser in your host machine to http://localhost:8080/, you will see the welcome page from the Apache server that is running inside the guest VM. Great!
Stopping and deleting the VM
To disconnect from the VM, press
Ctrl + D or type
exit at the command line. Now enter the following to stop the VM:
If you want to delete the VM because you no longer need it or you want to start fresh:
vagrant destroy -f
If you didn’t provide the
-f argument, it would ask for confirmation before deleting the VM. There are many other commands which you can discover by typing
vagrant without arguments and by reading the documentation.
As you can see, Vagrant is a great tool for creating test environments in your machine. The real power comes from being able to share the Vagrantfile with other developers whom can then recreate the same environment in a Windows, Linux or Mac OS machine by just typing
In a next post we’ll explore a more advanced scenario involving several VMs connected via a virtual network.
One thought on “Creating and provisioning virtual machines with Vagrant”