In this Vagrant tutorial, we will learn about Vagrant, vagrant boxes, vagrantfile, provisioning tools, how to install vagrant on Linux operating systems and finally learn a few basic vagrant commands to create and manage virtual machines from command line.
1. Introduction to Vagrant
Vagrant is an open source software for building and maintaining virtual software development environments. It provides a clean, easy to configure, reproducible, and portable development environment. In other words, Vagrant allows us to easily and quickly deploy an universal software development environment that can be used anywhere. Vagrant simply eliminates the "works on my machine" excuse. Because, everyone is working on the same environment with same set of configuration. It doesn't matter what OS they are using.
Vagrant is often used to setup an identical and collaborative working environment for developers to work on a common project. It isolates all required dependencies and their configuration settings in a single, disposable environment. When the other developers create a development environment with the same configuration file, they will get the same environment with same settings.
Vagrant is a cross-platform application written in Ruby language. It supports GNU/Linux, Mac OS and Microsoft Windows. It is developed by Hashicorp and released under MIT license.
1.1. Vagrant boxes
The "box" is a format and an extension for Vagrant environments. The vagrant boxes are just the base images. They can be a Virtualbox image or VMware image or a cloud provider's image like Amazon Machine Image (AMI). We can copy the vagrant boxes to any other systems and setup an exact replica of the current development.
There are many pre-configured Vagrant boxes available for download in Vagrant Cloud public repository. If you don't want to use an pre-configured boxes, just create one as per your liking and distribute it to all via this repository.
The operating system and software requirements are defined in a configuration file named "vagrantfile". This file is distributed along with the Vagrant boxes. When you initialize a VM with Vagrant, it will read this file and setup your development environment accordingly. So, the actual purpose of a vagrantfile is to describe the type of the virtual machine and how to configure and provision the VMs.
The following details are defined in a typical vagrantfile:
- Operating system version E.g. Ubuntu bionic.
- Enable/disable automatic box update checking.
- Network configuration;
- port forwarding,
- configure a private network (host-only access to the machine),
- configure public network (bridged-network).
- Share folders to guest VM.
- Set preferred provider E.g. virtualbox, kvm.
- Define total amount of memory to VM.
- Enable provisioning withe shell script or configuration management tools like Ansible.
1.3. Provisioning tools
Vagrant is not a standalone virtualization platform like KVM or Virtualbox. It is just a wrapper and front-end that sits between a virtualization software and a virtual machine. Vagrant uses various service providers and provisioning tools to create and manage the development environments.
The virtual machines are built on top of popular virtualization applications such as VirtualBox, KVM, Docker, VMware etc., and cloud service providers such as AWS, Azure, GCE and a lot more. You can view the complete list of supported providers here. Vagrant ships out of the box with support for VirtualBox, Hyper-V, and Docker. VirtualBox is the default provider for Vagrant.
Once the Virtual machine is built, we can install the software on it using simple shell scripts and industry-standard configuration management tools such as Ansible, CFEngine, Chef, Docker, Podman, Puppet and Salt etc. The users can also customize the configuration of virtual environments as per their requirement using the provisioning tools.
In a nutshell, the providers (E.g. VirtualBox, AWS) are used to create a virtual environment and the provisioners (E.g. Ansible, Puppet) are used to customize the virtual environments.
2. Install Vagrant On Linux
Vagrant installation is incredibility easy and straight forward. Just download the latest version from the Vagrant download page and install using the standard procedure for your operating systems. To know how to install Vagrant on various Linux platforms, refer the following link.
3. Vagrant Tutorial - Basic Vagrant commands to create and manage virtual machines
Here, I have given examples for only the basic Vagrant commands which we require to setup and manage a virtualized development. To learn the complete Vagrant usage, refer the official documentation given at the end.
3.1. Create Vagrant project directory
First, we need to create a project directory.
I am going to create a directory called "myvagrants" for my virtual environment:
$ mkdir myvagrants
Cd into that directory to build and store virtual machines:
$ cd myvagrants
3.2. Initialize Vagrant environment
Initialize the Vagrant environment using the following command:
$ vagrant init hashicorp/bionic64
A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on `vagrantup.com` for more information on using Vagrant.
The above command intializes the current directory as default Vagrant environment and create base Vagrantfile.
You can view the content of the newly created vagrantfile using "cat" command and know the details of the virtual machine that you are going to build:
$ cat Vagrantfile | less
When you start the VM in the subsequent steps, it will download the Ubuntu bionic box published by HashiCorp. The Vagrant team also recommends to use the Bento boxes. They are open source and built for popular providers such as Virtualbox, VMWare, and Parallels. HashiCorp and Bento are the only two officially-recommended box sets.
3.3. Start Virtual machine
Now, create and start the virtual machine according to the vagrantfile (which we created in the earlier step) using command:
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider... ==> default: Box 'hashicorp/bionic64' could not be found. Attempting to find and install... default: Box Provider: virtualbox default: Box Version: >= 0 ==> default: Loading metadata for box 'hashicorp/bionic64' default: URL: https://vagrantcloud.com/hashicorp/bionic64 ==> default: Adding box 'hashicorp/bionic64' (v1.0.282) for provider: virtualbox default: Downloading: https://vagrantcloud.com/hashicorp/boxes/bionic64/versions/1.0.282/providers/virtualbox.box Download redirected to host: vagrantcloud-files-production.s3.amazonaws.com ==> default: Successfully added box 'hashicorp/bionic64' (v1.0.282) for 'virtualbox'! ==> default: Importing base box 'hashicorp/bionic64'... ==> default: Matching MAC address for NAT networking... ==> default: Checking if box 'hashicorp/bionic64' version '1.0.282' is up to date... ==> default: Setting the name of the VM: myvagrants_default_1597837509450_67666 Vagrant is currently configured to create VirtualBox synced folders with the `SharedFoldersEnableSymlinksCreate` option enabled. If the Vagrant guest is not trusted, you may want to disable this option. For more information on this option, please refer to the VirtualBox manual: https://www.virtualbox.org/manual/ch04.html#sharedfolders This option can be disabled globally with an environment variable: VAGRANT_DISABLE_VBOXSYMLINKCREATE=1 or on a per folder basis within the Vagrantfile: config.vm.synced_folder '/host/path', '/guest/path', SharedFoldersEnableSymlinksCreate: false ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==> default: Forwarding ports... default: 22 (guest) => 2222 (host) (adapter 1) ==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2222 default: SSH username: vagrant default: SSH auth method: private key default: Warning: Connection reset. Retrying... default: Warning: Remote connection disconnect. Retrying... default: Warning: Remote connection disconnect. Retrying... default: default: Vagrant insecure key detected. Vagrant will automatically replace default: this with a newly generated keypair for better security. default: default: Inserting generated public key within guest... default: Removing insecure key from the guest if it's present... default: Key inserted! Disconnecting and reconnecting using new SSH key... ==> default: Machine booted and ready! ==> default: Checking for guest additions in VM... default: The guest additions on this VM do not match the installed version of default: VirtualBox! In most cases this is fine, but in rare cases it can default: prevent things such as shared folders from working properly. If you see default: shared folder errors, please make sure the guest additions within the default: virtual machine match the version of VirtualBox you have installed on default: your host and reload your VM. default: default: Guest Additions Version: 6.0.10 default: VirtualBox Version: 6.1 ==> default: Mounting shared folders... default: /vagrant => /home/sk/myvagrants
The above command will download the Ubuntu bionic box from Vagrant cloud, create a new virtual machine named "myvagrants_default_1597837509450_67666", add it to the Virtualbox and start the VM automatically.
You will not see any notifications even though the VM is running. To verify if the VM is running, open the virtualization application and check. Since Vagrant uses Virtualbox as its default provider, I can see the running VM from the virtualbox manager.
As you can see, Ubuntu bionic VM is running in Virtualbox.
3.4. Access Virtual machines
You can connect and access the running VMs using SSH.
To SSH into the running Vagrant box using command, run:
$ 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 Wed Aug 24 11:56:42 UTC 2020 System load: 0.08 Processes: 88 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% * Are you ready for Kubernetes 1.19? It's nearly here! Try RC3 with sudo snap install microk8s --channel=1.19/candidate --classic https://microk8s.io/ has docs and details. 0 packages can be updated. 0 updates are security updates. [email protected]:~$
3.5. Synchronize local and guest Files
Vagrant support file synchronization out of the box. By default, Vagrant shares your project directory (the one containing the Vagrantfile. In my case, it is ~/myvagrants.) to the
/vagrant directory in your guest virtual machine.
You can verify it by listing the contents of /vagrant directory in your virtual machine:
[email protected]:~$ ls /vagrant/ Vagrantfile
Please note that the Vagrantfile that you see inside the virtual machine is actually the same Vagrantfile that is on your actual host machine.
To test if synchronize actually works, create a sample file in /vagrant directory in your guest machine:
[email protected]:~$ touch /vagrant/test.txt
Exit from your VM's SSH session:
[email protected]:~$ logout
Now, check your local project directory in your host system. You will see the same file is created on host machine as well.
[email protected]:~/myvagrants$ ls test.txt Vagrantfile
3.6. Display the status of Virtual machines
To display the state of a virtual machine in a virtual environment, run:
$ vagrant status
Current machine states: default running (virtualbox) The VM is running. To stop this VM, you can run `vagrant halt` to shut it down forcefully, or you can run `vagrant suspend` to simply suspend the virtual machine. In either case, to restart it again, simply run `vagrant up`.
As you see above, I have only one VM and it is running now.
If the VM is powered off, you will the following output:
Current machine states: default poweroff (virtualbox) The VM is powered off. To restart the VM, simply run `vagrant up`
3.7. Display status of all Virtual environments
We can display the information about all known virtual environments on our system using the following command:
$ vagrant global-status
id name provider state directory ------------------------------------------------------------------------- 2086482 default virtualbox poweroff /home/sk/myvagrants The above shows information about all known Vagrant environments on this machine. This data is cached and may not be completely up-to-date (use "vagrant global-status --prune" to prune invalid entries). To interact with any of the machines, you can go to that directory and run Vagrant, or you can use the ID directly with Vagrant commands from any directory. For example: "vagrant destroy 1a2b3c4d"
The above command will list the VM id, name, provider, state of the VM, and the virtual environment directory.
Sometimes the output might be cached and it may not be correct. So, run the following command to remove the invalid entries and get the up-to-date status of the virtual environment:
$ vagrant global-status --prune
3.8. Suspend Virtual machines
To suspend a running VM, run:
$ vagrant suspend
==> default: Saving VM state and suspending execution…
3.9. Resume Virtual machines
To resume a suspended VM in the current virtual environment, run:
$ vagrant resume
==> default: Resuming suspended VM... ==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2222 default: SSH username: vagrant default: SSH auth method: private key ==> default: Machine booted and ready! ==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision` ==> default: flag to force provisioning. Provisioners marked to run always will still run.
3.10. Restart Virtual machines
To restart a running VM, do:
$ vagrant reload
This command will gracefully shutdown the VM and start it again.
3.11. Stop/Shutdown Virtual machines
To stop or shutdown a running VM, do:
$ vagrant halt
3.12. Delete Virtual machines
To stop and delete all traces of a VM, run:
$ vagrant destroy
Type "y" and hit ENTER to delete the virtual machine.
If you want to delete the VM without any confirmation, run:
$ vagrant destroy -f
3.13. Reset Virtual machines
Sometimes, you might want to reset your virtual machine to its original state, without actually deleting the box. This can be helpful to deploy a clean virtual environment without having to download a vagrant box over and over.
To reset a virtual machine to its original state, simply do:
$ vagrant destroy
$ vagrant up
The first command will shutdown the running virtual machine and delete all the resources associated to it. And the second command will re-create a new fresh Virtual machine using the existing vagrant box.
For more details, refer the following link:
3.14. List Vagrant boxes
To list all available boxes that are installed with Vagrant, run:
$ vagrant box list
hashicorp/bionic64 (virtualbox, 1.0.282)
If you want to display some additional box details such as author name, website, repository, description etc., use
$ vagrant box list -i
generic/alpine38 (virtualbox, 3.1.16) - Author: Ladar Levison - Website: https://roboxes.org/ - Artifacts: https://vagrantcloud.com/generic/ - Repository: https://github.com/lavabit/robox/ - Description: Basic virtual machine images, for a variety of operating systems/hypervisors, and ready to serve as base bxoes.
3.15. Check if a Vagrant box is outdated
To check if the box you are using on your vagrant environment is outdated, go to the Vagrant environment i.e. project's directory,
$ cd myvagrants/
$ vagrant box outdated Checking if box 'hashicorp/bionic64' version '1.0.282' is up to date…
3.16. Update Vagrant boxes
If there are any outdated boxes, you can update them like below:
$ vagrant box update
==> default: Checking for updates to 'hashicorp/bionic64' default: Latest installed version: 1.0.282 default: Version constraints: default: Provider: virtualbox ==> default: Box 'hashicorp/bionic64' (v1.0.282) is running the latest version.
3.17. Download Vagrant boxes
Instead of using "vagrant init" command, you can also manually download the VM and edit its vagrant file and then start it.
To download a Vagrant box, run:
$ vagrant box add bento/debian-10.5
The above command will download Debian 10.5 version box published by Bento. You will be asked to choose the provider (E.g. virtualbox or vmware) you are currently using now. Just choose one and hit ENTER to download the box.
==> box: Loading metadata for box 'bento/debian-10.5' box: URL: https://vagrantcloud.com/bento/debian-10.5 This box can work with multiple providers! The providers that it can work with are listed below. Please review the list and choose the provider you will be working with. 1) parallels 2) virtualbox 3) vmware_desktop Enter your choice: 2 ==> box: Adding box 'bento/debian-10.5' (v202008.16.0) for provider: virtualbox box: Downloading: https://vagrantcloud.com/bento/boxes/debian-10.5/versions/202008.16.0/providers/virtualbox.box Download redirected to host: vagrantcloud-files-production.s3.amazonaws.com ==> box: Successfully added box 'bento/debian-10.5' (v202008.16.0) for 'virtualbox'
You can verify it by listing the available boxes:
$ vagrant box list
bento/debian-10.5 (virtualbox, 202008.16.0) hashicorp/bionic64 (virtualbox, 1.0.282)
All downloaded Vagrant boxes will be available in "~/.vagrant.d/boxes" directory in your host system.
3.18. Add downloaded .box file to vagrant
Many Linux distributions are distributed via pre-configured Vagrant boxes. So you can quickly grab the vagrant box and run it using the respective virtualization application. For more details, refer the following guide:
3.19. Create a Virtual machine using Vagrant box
To create a new VM with the newly downloaded box, go to your project's directory and intialize the vagrant environment:
$ vagrant init
Note: Delete existing Vagrantfile before initializing a new vagrant environment.
This will create a new Vagrantfile in the current directory.
Edit the Vagrant file and update the VM details and replace the following line:
Vagrant.configure("2") do |config| [...] config.vm.box = "base" [...]
with the following:
config.vm.box = "bento/debian-10.5"
You can explicitly specify the version for the new VM by adding the following lines:
config.vm.box = "bento/debian-10.5" config.vm.box_version = "1.0"
You can even specify the download URL as well:
config.vm.box = "bento/debian-10.5" config.vm.box_version = "1.0" config.vm.box_url = "https://app.vagrantup.com/bento/boxes/debian-10.5/"
Now, create and start the VM based on the this Vagrantfile with command:
$ vagrant up
Alternatively, you can directly mention the box name while initializing the Vagrant environment. This can be useful if you have more than one vagrant boxes.
First, list the available vagrant boxes using command:
$ vagrant box list
Fedora33 (libvirt, 0) archlinux/archlinux (virtualbox, 20201201.10292) fedora33 (virtualbox, 0) generic/alpine38 (virtualbox, 3.1.16) oraclelinux/7 (virtualbox, 7.9.184) oraclelinux/8 (libvirt, 8.3.183)
Let us you want to create a virtual machine from a box named "generic/alpine38". To do so, simply run:
$ vagrant init generic/alpine38
This command will create a new Vagrantfile and initialize the vagrant environment with given box configuration. No need to manually edit Vagrantfile and update the box details.
Next, start the virtual machine using command:
$ vagrant up
3.20. Use Vagrant With Libvirt KVM Provider
Like I already stated, Vagrant uses Virtualbox to run Virtual machines by default. It is also possible to tell Vagrant to use another provider, for example, Libvirt KVM, to run VMs using vagrant-libvirt plugin. This plugin adds the Libvirt provider to Vagrant and allows Vagrant to control and provision machines via Libvirt. To learn how to use libvirt as Vagrant provider, refer the following guide:
3.21. Configure Networking In Vagrant
In order to provide network access between guest machines and host system, Vagrant offers the following three options:
- Port forwarding
- Private network (host-only network)
- Public network (bridged network)
Each option has its own ups and downs. You can configure any one or all of the Vagrant network options as described in the following guide:
3.22. Increase Memory and CPU on Vagrant machine
Having performance issues with your Vagrant machine? It is probably because of insufficient Memory or CPU. Simply add more RAM and CPU core to Vagrant machine to improve its performance as shown in the following link.
3.23. Remove outdated Vagrant boxes
You might have downloaded several versions of Vagrant boxes and some of them might be pretty outdated! If they are no longer required, you can safely delete the old versions of installed Vagrant boxes as described in the following link.
3.24. Delete Vagrant boxes permanently
To remove a vagrant box, for example hashicorp/bionic64, run:
$ vagrant box remove hashicorp/bionic64
Type "y" and hit ENTER to confirm deletion:
Box 'hashicorp/bionic64' (v1.0.282) with provider 'virtualbox' appears to still be in use by at least one Vagrant environment. Removing the box could corrupt the environment. We recommend destroying these environments first: default (ID: 20864823c72f45568d251070b5ce2661) Are you sure you want to remove this box? [y/N] y Removing box 'hashicorp/bionic64' (v1.0.282) with provider 'virtualbox'…
If you don't know the name of the box, just run the following command to list all installed boxes:
$ vagrant box list
At this stage, you should have learned basics of Vagrant usage. Vagrant is a vast topic and I will try to cover as much as I can in our upcoming articles. Stay tuned!
In this comprehensive guide, we learned what is Vagrant and the vagrant terminologies such as vagrant boxes, vagrantfile, and provisioning tools. We also learned how to install vagrant on Linux operating systems and finally we discussed a few basic vagrant commands to create and manage virtual machines from command line in Linux.
If you're a DevOps engineer, knowing how to use Vagrant will be very useful. Vagrant is one of the important tool that you should have on your system.