Vagrant is a nice tool for automating the set-up of development environments on virtual machines or containers.
Vagrant vs Terraform
While Vagrant and Terraform are both created by Hashicorp they are different tools. Vagrant is geared towards setting up virtual machines on a developers workstation so they can develop and test things out. It includes some higher level, nice to have features that are out of scope for Terraform ( Synced folders, HTTP tunnelling, automatic networking ). Terraform is more geared towards provisioning infrastructure across a large number of remote machines.
The following will create an Ubuntu VM in Virtual Box, start it up, ssh to it, and then destroy it.
vagrant init hashicorp/bionic64 # create config vagrant up # create/start VM vagrant ssh # SSH Connection exit # exit ... vagrant destroy # destroy
Download and Install Vagrant
Download an installer for your OS: Vagrant Downloads
Downloading from from the official Vagrant site is recommended over using your system’s package manager.
Setting Up A Project
You will generally create a directory to hold your Vagrantfile and any other files related to the project that the VM will be used for. By default, this project directory will be mounted on the VM at /vagrant to facilitate the sharing of files between the guest and host.
- marks the root of a project
- describes machine and resources
Create a Vagrantfile:
mkdir my-project cd my-project vagrant init hashicorp/bionic64
Boxes are base images that can be cloned. These are the images from which our VMs are built. They are pulled down automatically if they aren’t there already when you run “vagrant up” so you may not even need to worry about adding them or configuring them.
NOTE - Destroying a VM won’t remove the box that it was created from.
Add a box so it can be used:
vagrant box add hashicorp/bionic64 # Add a box vagrant box remove # Remove an actual box file vagrant box list # List installed boxes
Here is how a box is defined in your Vagrantfile:
Vagrant.configure("2") do |config| config.vm.box = "hashicorp/bionic64" end
Vagrant.configure("2") do |config| config.vm.box = "hashicorp/bionic64" config.vm.box_version = "1.1.0" end
Vagrant.configure("2") do |config| config.vm.box = "hashicorp/bionic64" config.vm.box_url = "https://vagrantcloud.com/hashicorp/bionic64" end
Vagrant Shared Dirs
- will be mounted on the VM and will contian your project
- don’t run “rm -rf /”
Optional, you can configure a custom shared folder. The source can be relative to the project root or it can be absolute.
Vagrant.configure("2") do |config| config.vm.synced_folder "src/", "/var/www" end
You can run a script when a VM is created.
Create a script, for example, this one taken form the official Vagrant site:
#!/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
Specify the script in the Vagrantfile:
Vagrant.configure("2") do |config| config.vm.box = "hashicorp/bionic64" config.vm.provision :shell, path: "my-setup.sh" end
This is executed when you run “vagrant up”. If it is already running, you can re-provision it with the following command which will also reboot your VM:
vagrant reload --provision
Setup Port Forwarding
You can easily setup port forwarding in your Vagrantfile.
Vagrant.configure("2") do |config| config.vm.box = "hashicorp/bionic64" config.vm.provision :shell, path: "my-setup.sh" config.vm.network :forwarded_port, guest: 80, host: 4567 end
Create the vm with “vagrant up” or if it is already running use “vagrant reload”:
Now the webserver will be reachable at: http://127.0.0.1:4567
Share your exposed web port to anyone with an internet connection. This will output a URL that can be shared.
Suspend the virtual machine saving RAM contents to disk. This is really fast and saves your VM’s state.
Halt the machine to shut it down gracefully so that it can be started back up later.
Destroying the VM will remove all traces of it. This will require more time if you want to bring it back up because you will need to re-provision it.
For more information see here: Vagrant Private Networks
Port forwarding can be configured like this:
config.vm.network "forwarded_port", guest: 80, host: 8080
YOu can do this with TCP and UDP:
config.vm.network "forwarded_port", guest: 2001, host: 12005, protocol: "tcp" config.vm.network "forwarded_port", guest: 2001, host: 12005, protocol: "udp"
Auto correct can be used in case you have a port collision with another VM. It will detect if a port is in use before letting you forward it.
config.vm.network "forwarded_port", guest: 80, host: 8080, auto_correct: true
Configure the port range that can be used for auto correct:
Vagrant.configure("2") do |config| config.vm.usable_port_range = 8000..8999 end
Private network with DHCP:
Vagrant.configure("2") do |config| config.vm.network "private_network", type: "dhcp" end
Private network with static IP:
Vagrant.configure("2") do |config| config.vm.network "private_network", ip: "192.168.50.4" end
If you just type vagrant you will be prompted with a list of commands and their description. You can find these in this table:
|box||manages boxes: installation, removal, etc.|
|cloud||manages everything related to Vagrant Cloud|
|destroy||stops and deletes all traces of the vagrant machine|
|global-status||outputs status Vagrant environments for this user|
|halt||stops the vagrant machine|
|help||shows the help for a subcommand|
|init||initializes a new Vagrant environment by creating a Vagrantfile|
|package||packages a running vagrant environment into a box|
|plugin||manages plugins: install, uninstall, update, etc.|
|port||displays information about guest port mappings|
|powershell||connects to machine via powershell remoting|
|provision||provisions the vagrant machine|
|push||deploys code in this environment to a configured destination|
|rdp||connects to machine via RDP|
|reload||restarts vagrant machine, loads new Vagrantfile configuration|
|resume||resume a suspended vagrant machine|
|snapshot||manages snapshots: saving, restoring, etc.|
|ssh||connects to machine via SSH|
|ssh-config||outputs OpenSSH valid configuration to connect to the machine|
|status||outputs status of the vagrant machine|
|suspend||suspends the machine|
|up||starts and provisions the vagrant environment|
|upload||upload to machine via communicator|
|validate||validates the Vagrantfile|
|version||prints current and latest Vagrant version|
|winrm||executes commands on a machine via WinRM|