Vagrant & Ansible: The Perfect Duo for Eliminating Environment Mismatches

Virtualization tutorial - IT technology blog
Virtualization tutorial - IT technology blog

Classic Scenario: “It works on my machine, so why does it fail on the server?”

Every developer has likely experienced the bitter taste of code running perfectly locally but crashing as soon as it hits staging. The culprit is usually a mismatch in PHP versions, missing system libraries, or differing Nginx configurations. Instead of manually installing every package and wasting an entire morning, I choose to automate the whole process.

Currently, I run a Proxmox homelab with about 12 VMs. This is where I test everything before pushing it to production. To ensure my 5-person team always uses a standardized environment, I use the **Vagrant** and **Ansible** duo. Vagrant handles the skeleton (VM, IP, RAM), while Ansible takes care of the “meat” (installing software, configuring services).

Why use Ansible instead of Shell Scripts?

Many of you might wonder: “Vagrant has a shell provisioner, why bother learning Ansible?” The answer lies in **Idempotency**. If you run a shell script to install Nginx twice, it might throw an error or overwrite configuration files unpredictably. With Ansible, you can run a playbook 100 times; if the machine is already correctly configured, it won’t do anything. This makes it extremely safe for your systems.

  • Vagrant: Manages the infrastructure layer. It controls VirtualBox or KVM to quickly create VMs.
  • Ansible: Manages configuration. It uses SSH to log into the VM and execute commands based on a predefined script.

Required Tools

To get started, download these tools to your host machine:

  1. VirtualBox: A popular and free virtual machine emulator.
  2. Vagrant: A tool for orchestrating the virtual machine lifecycle.
  3. Ansible: Install on macOS/Linux to control the VMs. If you’re on Windows, don’t worry—we’ll use the ansible_local mode.

Building an Automated Web Server in 5 Minutes

We will create an Ubuntu 22.04 VM, automatically install Nginx, and create a custom index page. Everything is contained within just two configuration files.

Step 1: Create the project directory

mkdir vagrant-ansible-demo && cd vagrant-ansible-demo
touch Vagrantfile playbook.yml

Step 2: Configure the Vagrantfile

This file defines the VM parameters. Note the config.vm.provision section; this is where Vagrant hands over control to Ansible.

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/jammy64"
  config.vm.network "private_network", ip: "192.168.56.10"

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

  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
  end
end

Step 3: Write the Ansible Playbook

The playbook.yml file uses the highly readable YAML format. You just list what you want, and Ansible handles the execution.

---
- name: Setup Web Server
  hosts: all
  become: true
  tasks:
    - name: Update apt cache
      apt: { update_cache: yes, cache_valid_time: 3600 }

    - name: Install Nginx
      apt: { name: nginx, state: present }

    - name: Custom Index Page
      copy:
        content: "<h1>Successfully deployed from itfromzero.com!</h1>"
        dest: /var/www/html/index.html

    - name: Start Nginx
      service: { name: nginx, state: started, enabled: yes }

Execution and Verifying Results

Now it’s time to enjoy the results. Open your terminal and type:

vagrant up

Vagrant will automatically download the image, create the VM, and call Ansible. You’ll see logs scrolling by. If the text appears green or yellow, everything is fine. It takes about 2-3 minutes to complete the entire server setup. Visit http://192.168.56.10, and if you see the welcome message, congratulations—you’ve succeeded!

Troubleshooting Tips (Debug)

Working with VMs can occasionally lead to minor issues. Here are a few tips I’ve gathered:

  • SSH Connection Errors: If Ansible cannot access the VM, run vagrant ssh-config to check the port and key. Sometimes, a simple vagrant reload is all you need.
  • Using Windows? Switch to config.vm.provision "ansible_local". In this mode, Vagrant will install Ansible inside the VM itself and run the playbook from within.
  • Check Syntax: YAML files are very sensitive to whitespace. Use the command ansible-playbook --syntax-check playbook.yml to spot errors before running.

Conclusion

Combining Vagrant and Ansible makes your workflow much more professional. When a new team member joins, they just need to git clone and vagrant up to have an environment identical to yours. This is a solid stepping stone for diving deeper into the world of DevOps and Infrastructure as Code (IaC).

Share: