Vagrant is a command-line tool for creating and managing reproducible local development environments backed by virtual machines. Combined with VirtualBox as a hypervisor, it lets developers spin up a fresh Linux VM with a single command, configure it through a version-controlled Vagrantfile, and destroy it just as easily. This eliminates the “works on my machine” problem by ensuring every team member develops against an identical environment. This guide covers installing VirtualBox and Vagrant on RHEL 9 and creating your first managed virtual machine.

Prerequisites

  • RHEL 9 workstation or server with hardware virtualization enabled in BIOS/UEFI (Intel VT-x or AMD-V)
  • A user account with sudo privileges
  • At least 8 GB RAM (VMs need memory on top of the host OS)
  • Secure Boot disabled in UEFI (required for third-party kernel modules)

Step 1 — Install Kernel Development Headers

# VirtualBox needs kernel modules compiled against your running kernel
sudo dnf install -y kernel-devel kernel-headers gcc make perl

# Verify the kernel headers match your running kernel
uname -r
ls /usr/src/kernels/

# Update the system first to ensure kernel and headers are in sync
sudo dnf update -y
sudo reboot

Step 2 — Add the VirtualBox Repository and Install VirtualBox

# Add the official Oracle VirtualBox repository
sudo tee /etc/yum.repos.d/virtualbox.repo > /dev/null <<EOF
[virtualbox]
name=Oracle Linux / RHEL / CentOS-$releasever / $basearch - VirtualBox
baseurl=https://download.virtualbox.org/virtualbox/rpm/el/$releasever/$basearch
enabled=1
gpgcheck=1
gpgkey=https://www.virtualbox.org/download/oracle_vbox_2016.asc
EOF

# Install VirtualBox 7.0
sudo dnf install -y VirtualBox-7.0

# Build the kernel modules
sudo /usr/lib/virtualbox/vboxdrv.sh setup

# Add your user to the vboxusers group
sudo usermod -aG vboxusers $USER

# Verify the kernel module is loaded
lsmod | grep vbox

Step 3 — Add the HashiCorp Repository and Install Vagrant

# Add the HashiCorp YUM repository
sudo tee /etc/yum.repos.d/hashicorp.repo > /dev/null <<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

# Install Vagrant
sudo dnf install -y vagrant

# Verify installation
vagrant --version
virtualbox --version

Step 4 — Create Your First Vagrantfile

# Create a project directory
mkdir ~/vagrant-ubuntu && cd ~/vagrant-ubuntu

# Initialize a Vagrantfile for an Ubuntu 22.04 VM
vagrant init ubuntu/jammy64

# Or create a more customized Vagrantfile manually:
cat > Vagrantfile <<'EOF'
Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/jammy64"
  config.vm.hostname = "dev-server"

  # Forward port 8080 on the guest to 8080 on the host
  config.vm.network "forwarded_port", guest: 8080, host: 8080

  # Create a private network
  config.vm.network "private_network", ip: "192.168.56.10"

  # Share the current directory to /vagrant on the guest
  config.vm.synced_folder ".", "/vagrant"

  config.vm.provider "virtualbox" do |vb|
    vb.name   = "ubuntu-dev"
    vb.memory = "2048"
    vb.cpus   = 2
  end

  # Run a shell provisioner on first boot
  config.vm.provision "shell", inline: <<-SHELL
    apt-get update
    apt-get install -y nginx git curl
  SHELL
end
EOF

Step 5 — Manage the VM with Vagrant Commands

# Start and provision the VM (downloads the box if not cached)
vagrant up

# SSH into the running VM
vagrant ssh

# Inside the VM, check the shared folder
ls /vagrant

# Exit the SSH session
exit

# Suspend the VM (saves state to disk)
vagrant suspend

# Resume a suspended VM
vagrant resume

# Gracefully shut down the VM
vagrant halt

# Re-run provisioners on a running VM
vagrant provision

# Destroy the VM entirely (removes disk image)
vagrant destroy

# Check the status of all Vagrant VMs
vagrant global-status

Conclusion

You now have a working Vagrant and VirtualBox environment on RHEL 9 that enables you to spin up isolated Linux VMs in seconds. The version-controlled Vagrantfile is the key artifact — commit it to your project repository so every team member and CI system boots an identical environment. Use the provisioner block to automate software installation, ensuring machines are always configured consistently. Test your Ansible playbooks, Docker Compose stacks, and application deployments locally before promoting changes to staging or production.

Next steps: How to Install Packer for Machine Image Automation on RHEL 9, How to Provision Vagrant VMs with Ansible on RHEL 9, and How to Install and Use Podman with Buildah on RHEL 9.