Other Parts of This Series:


DevOps Vagrant (Photo Credit: Unsplash)

DevOps Vagrant (Photo Credit: Unsplash)

Story:

Rasel explored the virtualization and virtual machine. First he learned to create a virtual machine in a manual manner using VirtualBox, where all the machine configuration was done manually by installing a user interface. Secondly, he learned a way to create and configure virtual machines automatically using a tool called Vagrant. But now Rasel wants to earn the efficiency and understand the Vagrantfile details so that he can use it consciously, not blindly.


What is a Vagrantfile?

A Vagrantfile is a Ruby-based configuration file that tells Vagrant how to set up and manage a virtual machine. It includes the box to use, network settings, resources, provisioning scripts, and more.


Different Section of Vagrantfile with Use Case:

Vagrant.configure(“2”) do |config|

  • This is the starting point and defines the Vagrant configuration version.
1
Vagrant.configure("2") do |config|        
  • Example: Use Vagrant version 2.X.X.
  • Use Case: Required for compatibility with the latest Vagrant features.

config.vm.box + config.vm.box_version

  • Specifies which base image (box) to use for the VM. And the other indicates the box or image version.
1
2
config.vm.box = "eurolinux-vagrant/centos-stream-9"
config.vm.box_version = "9.0.48"        
  • Example: Use CentOS 9 Linux distro.
  • Use Case: Ensures everyone on your team uses the same OS and environment.

config.vm.network

  • Configures networking options like port forwarding or private IPs or public IPs.
1
2
3
config.vm.network "private_network", ip: "192.168.56.10"
config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
config.vm.network "public_network"        
  • Example: Run a web server inside the VM and access it via http://localhost:8080.
  • Use Case: Simulate production networking, test APIs locally, or run multiple services.

config.vm.provider

  • Defines VM resources like RAM, CPU, and provider-specific settings.
1
2
3
4
5
config.vm.provider "virtualbox" do |vb|
  vb.name = "devops_vm"
  vb.memory = "1024"
  vb.cpus = 2
end        
  • Example: Allocate 1 GB RAM and 2 CPU cores for performance testing.
  • Use Case: Optimize resource usage for different environments (testing, CI/CD, etc.).

config.vm.provision

  • Automates provisioning (setup scripts), like installing packages or running commands.
1
2
3
4
config.vm.provision "shell", inline: <<-SHELL
  yum update
  yum install -y nginx
SHELL        
  • Example: Automatically install Nginx when the VM starts.
  • Use Case: Create repeatable environments with pre-installed tools, great for onboarding or CI.

Synced Folders (config.vm.synced_folder)

  • Syncs a folder from your host to the VM.
1
config.vm.synced_folder "./app", "/home/vagrant/app"        
  • Example: Edit code on your host (e.g., VSCode), run it inside the VM.
  • Use Case: Live-reload web development, shared logs/configs, or test scripts.

✅ Full Example: Web Server Setup for Testing

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Vagrant.configure("2") do |config|
  config.vm.box = "eurolinux-vagrant/centos-stream-9"
  config.vm.box_version = "9.0.48"
  
  
  config.vm.network "private_network", ip: "192.168.56.10"
  config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
  config.vm.network "public_network"

  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1024"
    vb.cpus = 2
  end

  config.vm.provision "shell", inline: <<-SHELL
    yum update
    yum install -y nginx
  SHELL
end        

Real-Life Use Case: A DevOps engineer wants a repeatable test environment to develop and debug web applications before deploying them to production. Instead of setting it up manually each time, they use this Vagrantfile.


Multi-VM Setup with Vagrant

We can define multiple virtual machines in a single Vagrantfile. Each VM will have its own name, configuration, and purpose. All controlled in one place using a single Vagrantfile.

Scenario: Suppose we need a setup like a web-server will be accessed a external database and the server will be accessed via a load balancer. The web-server and load balancer will be used centos but database will be used ubuntu. Also they will be used different set of resources.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
Vagrant.configure("2") do |config|

  # Web Server VM
  config.vm.define "web" do |web|
    config.vm.box = "eurolinux-vagrant/centos-stream-9"
    config.vm.box_version = "9.0.48"

    web.vm.hostname = "web.local"
    web.vm.network "private_network", ip: "192.168.56.11"

    web.vm.provider "virtualbox" do |vb|
      vb.memory = "512"
      vb.cpus = 2
    end

    web.vm.provision "shell", inline: <<-SHELL
      yum update
      yum install -y nginx
    SHELL
  end

  # Database VM
  config.vm.define "db" do |db|
    db.vm.box = "ubuntu/bionic64"

    db.vm.hostname = "db.local"
    db.vm.network "private_network", ip: "192.168.56.12"

    db.vm.provider "virtualbox" do |vb|
      vb.memory = "1024"
      vb.cpus = 1
    end

    db.vm.provision "shell", inline: <<-SHELL
      apt-get update
      apt-get install -y mysql-server
    SHELL
  end

  # Load Balancer VM
  config.vm.define "lb" do |lb|
    config.vm.box = "eurolinux-vagrant/centos-stream-9"
    config.vm.box_version = "9.0.48"

    lb.vm.hostname = "lb.local"
    lb.vm.network "private_network", ip: "192.168.56.13"

    lb.vm.provider "virtualbox" do |vb|
      vb.memory = "512"
      vb.cpus = 1
    end

    lb.vm.provision "shell", inline: <<-SHELL
      yum update
      yum install -y haproxy
    SHELL
  end

end        

How to Use This Multi-VM Setup

  • Start All VMs:
1
vagrant up
  • SSH into a Specific VM:
1
2
3
vagrant ssh web
vagrant ssh db
vagrant ssh lb        
  • Then halt and destroy
1
2
vagrant halt
vagrant destroy --force        

Real-Life Use Case (DevOps Style)

As a DevOps engineer, you want to simulate a full-stack application:

  • A web server serves content.
  • A database stores user data.
  • A load balancer distributes traffic across future multiple web servers.

Using this setup:

  • You can test deployments, configurations, and load balancing.
  • You can try provisioning with Ansible or Docker later.
  • All your team members can spin up the same environment with one command.

Summary:

A Vagrantfile is a script that tells Vagrant how to build your virtual machine. It defines which OS to use, how much RAM/CPU to give, what network settings to apply, and what software to install on create which called provisioning. It helps developers and DevOps teams automate setup so they can build and test in the same environment every time. Means no more “it works on my machine” issues!