RousselTMLEARNING

Article · Vagrant: From Discovery to Expertise

Vagrant best practices

1. Principles #

Reproducible, disposable, versioned.

The golden rules #

Vagrant lifecycle
An environment that cannot be destroyed and recreated with confidence is not reproducible.
  • Version the Vagrantfile and provisioning scripts with the project code.
  • Pin the box version (config.vm.box_version) so the whole team has the same base.
  • Provision idempotently (Ansible, rerunnable scripts): vagrant provision must be safe to run again.
  • Store no valuable data in the VM: it must be possible to destroy it at any time.

2. A clean Vagrantfile #

Variables, pinned boxes and resources.

Multi-machine example #

# Vagrantfile
Vagrant.require_version ">= 2.4.0"

NODES = {
  "web" => { ip: "192.168.56.11", cpus: 1, memory: 1024 },
  "db"  => { ip: "192.168.56.12", cpus: 2, memory: 2048 },
}

Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-24.04"
  config.vm.box_version = "202407.22.0"
  config.vm.box_check_update = false
  config.vm.synced_folder ".", "/vagrant", type: "rsync", rsync__exclude: [".git/", "node_modules/"]

  NODES.each do |name, cfg|
    config.vm.define name do |node|
      node.vm.hostname = "#{name}.lab"
      node.vm.network "private_network", ip: cfg[:ip]
      node.vm.provider "virtualbox" do |vb|
        vb.name = "lab-#{name}"
        vb.cpus = cfg[:cpus]
        vb.memory = cfg[:memory]
        vb.linked_clone = true            # démarrage plus rapide, moins d'espace disque
      end
    end
  end

  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "provision/site.yml"
    ansible.groups = { "webservers" => ["web"], "dbservers" => ["db"] }
  end
end

3. Everyday commands #

Working efficiently.

Work cycle #

vagrant validate                               # vérifier le Vagrantfile
vagrant up --provider=virtualbox                # créer et démarrer
vagrant up web --no-provision                   # une seule machine, sans re-provisionner
vagrant status && vagrant global-status --prune
vagrant ssh web -c "systemctl status nginx"
vagrant provision web                           # rejouer le provisioning
vagrant reload --provision                      # redémarrer en réappliquant la config
vagrant snapshot save web avant-migration       # point de restauration
vagrant snapshot restore web avant-migration
vagrant halt / vagrant suspend / vagrant destroy -f
vagrant box list && vagrant box outdated && vagrant box prune
Good practice: Take a snapshot before any risky operation: restoring takes a few seconds, much less than rebuilding.

Performance and alternatives #

  • Use linked clones and lightweight boxes (bento, generic).
  • Prefer rsync or nfs to vboxsf for large shared folders.
  • On Linux, the libvirt provider (KVM) performs better than VirtualBox.
vagrant plugin list
vagrant plugin install vagrant-libvirt vagrant-hostmanager
VAGRANT_DEFAULT_PROVIDER=libvirt vagrant up
VAGRANT_LOG=debug vagrant up 2> vagrant.log          # diagnostic
Common mistake: Do not let forgotten VMs consume RAM: vagrant global-status lists all machines, whatever the folder.

Reference diagram and quick check #

Visualize the principle and check it from the command line.

Reference diagram #

Vagrant architecture
The Vagrantfile is the single source of truth.
vagrant status
vagrant ssh-config web
vagrant box list

📄 Vagrant best practices: reproducible and fast environments →

My progress

  • ⏱ Estimated time : ≈ 9 min

Sign in to track your progress and take notes. Sign in

💬 Questions about this lesson

No questions yet: be the first to ask for help or share your configuration.

Ask a question about this lesson →

Recommended Articles

Vagrant multi-machine: deploying a ready-to-use Docker Swarm cluster

Use a single Vagrantfile to build a three-node Docker Swarm cluster (one manager, two workers) wi...

Vagrant: overview and vocabulary (box, provider, provisioner, Vagrantfile)

The essential notions for following the Vagrant course: what Vagrant is for, the lifecycle of an ...

Vagrant plugins: extending providers, provisioners and commands

Understand Vagrant's plugin system: what a plugin can add (provider, provisioner, command, capabi...

Sharing a Vagrant environment: ngrok and the vagrant-share plugin

Make an application running in a Vagrant machine accessible to a colleague or a client: port forw...

Ansible best practices: structure, idempotence, security and quality

Ansible best practices: project organization, naming, FQCN, idempotence, modules rather than shel...

Ansible: ad-hoc commands

Run immediate actions on a fleet of servers with ansible: the ping, command, shell, copy, apt, se...

Grafana best practices: dashboards, provisioning, performance and security

Grafana best practices: designing readable dashboards, variables, dashboards as code, provisionin...

Grafana provisioning: automate the management of your dashboards and data sources

Learn how to use Grafana provisioning to manage your configuration (dashboards, data sources, not...

Containers, Kubernetes and cloud native in a DevOps approach

The role of containers and Kubernetes in DevOps: reproducible images, multi-stage Dockerfiles, re...

Support us

♥ SUPPORT US

Support RousselTM Learning

Courses, articles, labs and certificates stay free with no intrusive ads. A voluntary contribution, of any amount you choose, pays for hosting, lab environments and new content.

Contribute with PayPal Any amount · card or PayPal accountLearn more
QR code PayPal
Or scan this QR code with your phone

Thank you, every contribution counts!