Vagrant
What is Vagrant?
CLI tool for managing the life-cycle of VMs
- Reproducible local dev environments
- Vagrantfile, akin to Dockerfile for VMs
Installation
See the official Vagrant downloads page
Ubuntu/Debian:
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install vagrant
You also need VirtualBox, VMware or Hyper-V on your machine.
Important Commands
Initialize a new Vagrant environment by creating a Vagrantfile:
vagrant init
Starts and provisions the Vagrant environment:
vagrant up
Connects to machine via ssh:
vagrant ssh
Outputs status of the machine:
vagrant status
Suspends the machine:
vagrant suspend
Stops the machine:
vagrant halt
Stops and deletes all traces of the machine:
vagrant destroy
Boxes
Vagrant base images are called boxes.
See the official Vagrant boxes page
Synced Folders
By default, Vagrant will share your project directory (the directory with the Vagrantfile) to /vagrant
.
Vagrantfile
Example Vagrantfiles:
Vagrantfile for Jenkins
This Vagrantfile installs Jenkins, AWS CLI, unzip and zip tools.# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
# Port forwarding
config.vm.network "forwarded_port", guest: 8080, host: 8080
config.vm.provision "shell", inline: <<-SHELL
# Update repositories
sudo apt-get update
# Install CA certificates (optional but recommended)
sudo apt-get install -y ca-certificates
# Install Java (a requirement for Jenkins)
sudo apt-get install -y openjdk-11-jdk
# Add Jenkins repository
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
# Install Jenkins
sudo apt-get install -y jenkins
# Start Jenkins
sudo systemctl start jenkins
# Install necessary utilities
sudo apt-get install -y unzip
sudo apt-get install -y zip
# Install AWS CLI version 2
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
SHELL
end
Vagrantfile using Ansible for provisioning
This Vagrantfile uses an Ansible playbook for provisioning.# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/bionic64"
config.vm.network :forwarded_port, guest: 80, host: 8080
config.vm.network :forwarded_port, guest: 443, host: 8081
config.vm.network :forwarded_port, guest: 8080, host: 8082
config.vm.provision "ansible" do |ansible|
ansible.playbook = "main.yml"
end
end
Vagrantfile with advanced networking
This Vagrantfile brings up 2 VMs, assigns them static hostnames and IPs, allows root login and password authentication, and installs Ansible on one of the VMs.# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
# Define VMs
(1..2).each do |i|
config.vm.define "vm#{i}" do |vmconfig|
# Use CentOS 8
vmconfig.vm.box = "generic/centos8"
# Set hostname
vmconfig.vm.hostname = "vm#{i}"
# Set private network
vmconfig.vm.network "private_network", ip: "192.168.56.1#{i}"
# Sync project directory to /vagrant
vmconfig.vm.synced_folder ".", "/vagrant", type: "virtualbox"
# Enable provisioning with a shell script
vmconfig.vm.provision "shell", inline: <<-SHELL
echo 'vagrant:vagrant' | chpasswd
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
systemctl restart sshd
SHELL
if i == 1
vmconfig.vm.provision "shell", inline: <<-SHELL
sudo yum update -y
sudo yum install -y epel-release
sudo yum install -y python3-pip gcc openssl-devel libffi-devel python3-devel
sudo pip3 install --upgrade pip
sudo pip3 install setuptools_rust
pip3 install ansible
SHELL
end
end
end
# Enable ssh agent forwarding
config.ssh.forward_agent = true
end