How to Set Up Vagrant and VirtualBox on RHEL 7
Vagrant is an open-source tool by HashiCorp that automates the creation, configuration, and management of virtualized development environments. Combined with VirtualBox as a hypervisor backend, Vagrant allows developers and operations engineers on RHEL 7 to spin up reproducible Linux (or Windows) virtual machines with a single command: vagrant up. This eliminates the “works on my machine” problem by encoding the entire environment — base OS, packages, network, shared folders, and provisioning scripts — in a version-controlled Vagrantfile. This tutorial covers adding the VirtualBox yum repository, installing VirtualBox, installing Vagrant from the HashiCorp repository, creating and connecting to a first VM, mastering the Vagrantfile, and configuring multi-machine environments.
Prerequisites
- RHEL 7 host with hardware virtualization support (Intel VT-x or AMD-V enabled in BIOS/UEFI)
- Root or sudo access
- At least 4 GB of RAM free for guest VMs
- Active RHEL subscription or configured yum repositories
- Kernel headers and development tools installed (
yum install -y kernel-devel kernel-headers gcc make) - Internet access or an internal mirror containing the VirtualBox and HashiCorp repositories
Step 1: Verify Hardware Virtualization
Before installing VirtualBox, confirm that hardware virtualization is available and not already consumed by another hypervisor such as KVM:
# Check for Intel VT-x or AMD-V flags in the CPU
egrep -c '(vmx|svm)' /proc/cpuinfo
# Output > 0 means virtualization is available
# Confirm no conflicting KVM modules are loaded
lsmod | grep kvm
# If kvm_intel or kvm_amd appear, either remove them or use KVM instead of VirtualBox
# sudo modprobe -r kvm_intel kvm
Step 2: Install Required Build Dependencies
VirtualBox compiles kernel modules during installation, which requires the kernel development headers and GCC toolchain:
sudo yum install -y kernel-devel kernel-headers dkms gcc make perl
sudo yum install -y "kernel-devel-$(uname -r)"
If the kernel-devel package for the exact running kernel is not available in the default repositories, you can find it on the RHEL subscription portal or the CentOS Vault mirror.
Step 3: Add the VirtualBox yum Repository
Oracle provides an official yum repository for VirtualBox. Add it to your system:
sudo tee /etc/yum.repos.d/virtualbox.repo <<'EOF'
[virtualbox]
name=Oracle Linux / RHEL / CentOS-$releasever / $basearch - VirtualBox
baseurl=https://download.virtualbox.org/virtualbox/rpm/el/$releasever/$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://www.virtualbox.org/download/oracle_vbox_2016.asc
EOF
# Import the GPG key manually to avoid warnings
sudo rpm --import https://www.virtualbox.org/download/oracle_vbox_2016.asc
# Verify the repo is recognized
yum repolist | grep virtualbox
Step 4: Install VirtualBox
# List available VirtualBox versions
yum list available | grep VirtualBox
# Install the latest VirtualBox 7.0 (or the version appropriate for your use case)
sudo yum install -y VirtualBox-7.0
# The postinstall script will compile and load the kernel modules automatically
# Verify the modules loaded correctly
sudo /sbin/vboxconfig
Expected output from /sbin/vboxconfig:
vboxdrv.sh: Stopping VirtualBox services.
vboxdrv.sh: Starting VirtualBox services.
vboxdrv.sh: Building VirtualBox kernel modules.
vboxdrv.sh: done.
Add your current user to the vboxusers group to allow non-root access to VirtualBox:
sudo usermod -aG vboxusers $USER
# Log out and back in for the group change to take effect
Step 5: Add the HashiCorp yum Repository and Install Vagrant
HashiCorp maintains an official yum repository for RHEL-based systems. This is the safest way to install Vagrant and receive updates:
sudo tee /etc/yum.repos.d/hashicorp.repo <<'EOF'
[hashicorp]
name=HashiCorp Stable - $basearch
baseurl=https://rpm.releases.hashicorp.com/RHEL/$releasever/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://rpm.releases.hashicorp.com/gpg
EOF
# Import the HashiCorp GPG key
sudo rpm --import https://rpm.releases.hashicorp.com/gpg
# Install Vagrant
sudo yum install -y vagrant
# Verify installation
vagrant --version
# Vagrant 2.x.x
Step 6: Initialize and Start Your First VM
Create a working directory for your project and initialize a Vagrantfile using a standard Ubuntu 20.04 (Focal Fossa) base box:
mkdir ~/vagrant-demo && cd ~/vagrant-demo
# Initialize with the ubuntu/focal64 box from Vagrant Cloud
vagrant init ubuntu/focal64
# This creates a Vagrantfile in the current directory
# Start the VM (downloads the box on first run — ~600 MB)
vagrant up
During vagrant up, you will see Vagrant download the base box (if not already cached), import it into VirtualBox, boot it, and apply any configured provisioning. Box downloads are cached in ~/.vagrant.d/boxes/ so subsequent vagrant up commands for the same box are near-instant.
Step 7: Connect to the VM with vagrant ssh
# SSH into the running VM (no password needed — Vagrant handles key exchange)
vagrant ssh
# Inside the VM
uname -a
# Linux ubuntu-focal ...
cat /etc/os-release
# Ubuntu 20.04 LTS
# Exit the VM shell
exit
Vagrant automatically configures SSH port forwarding and injects an insecure (development-only) keypair. The host key and connection details are in .vagrant/machines/default/virtualbox/.
Step 8: Mastering the Vagrantfile
The Vagrantfile is a Ruby DSL file that fully describes your VM configuration. Here is a comprehensive example with common options:
Vagrant.configure("2") do |config|
# Base box
config.vm.box = "ubuntu/focal64"
config.vm.box_version = ">= 20240101.0.0"
config.vm.hostname = "dev-server"
# Network — forward host port 8080 to guest port 80
config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
# Private network — assign a static IP (host-only adapter)
config.vm.network "private_network", ip: "192.168.56.10"
# Synced folder — share project code into the VM
config.vm.synced_folder "./app", "/var/www/app",
owner: "vagrant", group: "vagrant"
# VirtualBox-specific provider settings
config.vm.provider "virtualbox" do |vb|
vb.name = "dev-server"
vb.memory = "2048" # MB
vb.cpus = 2
vb.gui = false # headless mode
# Enable nested virtualization if needed
# vb.customize ["modifyvm", :id, "--nested-hw-virt", "on"]
end
# Shell provisioner — runs once on first vagrant up
config.vm.provision "shell", inline: <<-SHELL
apt-get update -y
apt-get install -y nginx git curl
systemctl enable nginx
systemctl start nginx
echo "Provisioning complete"
SHELL
end
Apply changes to a running VM:
# Re-run provisioners on an already-running VM
vagrant provision
# Reload (restart) the VM and re-apply Vagrantfile changes
vagrant reload
# Reload and re-run provisioners
vagrant reload --provision
Step 9: VM Lifecycle — halt, suspend, destroy
# Gracefully shut down the VM (preserves disk state)
vagrant halt
# Suspend to disk (saves RAM state, fast resume)
vagrant suspend
vagrant resume
# Delete the VM entirely (frees disk space; Vagrantfile is retained)
vagrant destroy
# Destroy without confirmation prompt
vagrant destroy -f
# Check status of all VMs in the current directory
vagrant status
# Check status of all Vagrant VMs on the host
vagrant global-status
Step 10: Multi-Machine Environments
Vagrant supports defining multiple VMs in a single Vagrantfile, enabling you to replicate complex environments — for example, a load balancer, two web servers, and a database — on a single RHEL 7 development host:
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
# Database server
config.vm.define "db" do |db|
db.vm.hostname = "db-server"
db.vm.network "private_network", ip: "192.168.56.20"
db.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
vb.cpus = 1
end
db.vm.provision "shell", inline: <<-SHELL
apt-get update -y
apt-get install -y postgresql
systemctl enable postgresql
SHELL
end
# Web application servers (2 instances using a loop)
(1..2).each do |i|
config.vm.define "web#{i}" do |web|
web.vm.hostname = "web-server-#{i}"
web.vm.network "private_network", ip: "192.168.56.#{10 + i}"
web.vm.provider "virtualbox" do |vb|
vb.memory = "512"
vb.cpus = 1
end
web.vm.provision "shell", inline: <<-SHELL
apt-get update -y
apt-get install -y nginx
echo "web#{i}" > /var/www/html/index.html
SHELL
end
end
end
Manage individual machines by name:
# Start only the db machine
vagrant up db
# SSH into web1
vagrant ssh web1
# Halt all machines
vagrant halt
# Destroy a specific machine
vagrant destroy web2 -f
Vagrant and VirtualBox together on RHEL 7 deliver a powerful, reproducible development platform that any team member can replicate in minutes. By encoding your environment in a versioned Vagrantfile, you eliminate configuration drift between development, staging, and production-like test environments. For teams practicing infrastructure-as-code, the Vagrantfile becomes the single authoritative description of the local development environment — committed to version control, reviewed like application code, and reproduced with a single command on any RHEL 7 workstation or server with hardware virtualization support.