Project 2: “Build Your Own Vagrant Clone” — DevOps / Infrastructure as Code

A CLI tool that reads a configuration file, provisions VMs (using libvirt/QEMU or VirtualBox), configures networking, and runs provisioning scripts—like a simplified Vagrant.

Quick Reference

Attribute Value
Primary Language See main guide
Alternative Languages N/A
Difficulty Intermediate
Time Estimate 1-2 weeks
Knowledge Area See main guide
Tooling See main guide
Prerequisites Python or Go, basic Linux administration, familiarity with VMs as a user

What You Will Build

A CLI tool that reads a configuration file, provisions VMs (using libvirt/QEMU or VirtualBox), configures networking, and runs provisioning scripts—like a simplified Vagrant.

Why It Matters

This project builds core skills that appear repeatedly in real-world systems and tooling.

Core Challenges

  • Interfacing with hypervisor APIs (libvirt, VirtualBox SDK) programmatically (maps to: hypervisor management)
  • Managing virtual disk images and copy-on-write overlays (maps to: storage virtualization)
  • Configuring virtual networks and SSH access (maps to: network virtualization)
  • Implementing idempotent provisioning (maps to: infrastructure-as-code principles)

Key Concepts

  • Concept Resource
  • |———|———-|
  • libvirt architecture “libvirt Application Development Guide Using Python” - libvirt.org documentation
  • QCOW2 disk format “QEMU QCOW2 Specification” - QEMU documentation
  • Virtual networking “Linux Bridge-Networking Tutorial” - kernel.org bridge documentation
  • SSH automation “The Secure Shell: The Definitive Guide” Ch. 2-3 - Barrett & Silverman

Real-World Outcome

$ cat Myboxfile
vm:
  name: "dev-ubuntu"
  image: "ubuntu-22.04-base.qcow2"
  memory: 2048
  cpus: 2
  network:
    type: "nat"
    forward_port: "8080:80"
  provision:
    - type: "shell"
      script: "./setup.sh"

$ ./mybox up

[Mybox] Reading configuration from Myboxfile... OK
[Mybox] Checking for libvirt connection... Connected to qemu:///system
[Mybox] Creating VM 'dev-ubuntu' from base image 'ubuntu-22.04-base.qcow2'...
  → Creating copy-on-write overlay disk... done (2s)
  → Overlay: /var/lib/libvirt/images/dev-ubuntu-overlay.qcow2 (547MB)
[Mybox] Configuring VM resources...
  → CPUs: 2 cores
  → Memory: 2048 MB
  → Network: NAT with port forward 8080→80
[Mybox] Starting VM... done (8s)
[Mybox] Waiting for VM to boot and get IP address...
  → IP assigned: 192.168.122.45 (12s)
[Mybox] Configuring SSH access...
  → Injecting SSH keys... done
  → Testing connection... connected!
[Mybox] Running provisioning scripts...
  → Executing 'setup.sh'...
    ✓ apt-get update
    ✓ Installing nginx
    ✓ Configuring firewall
  → Provisioning complete (42s)

[Mybox] VM 'dev-ubuntu' is ready!
  SSH: ssh -p 22 -i .mybox/private_key vagrant@192.168.122.45
  Web: http://localhost:8080 (forwarded to VM port 80)

Total setup time: 64 seconds

$ ./mybox status

NAME          STATE    IP              UPTIME   MEMORY    CPU
dev-ubuntu    running  192.168.122.45  2m 14s   341/2048  12%

$ ./mybox snapshot create baseline

[Mybox] Creating snapshot 'baseline' for VM 'dev-ubuntu'...
  → Pausing VM... done
  → Creating memory snapshot... done (1.2s)
  → Creating disk snapshot... done (0.3s)
  → Resuming VM... done
[Mybox] Snapshot 'baseline' created successfully

$ ./mybox destroy

[Mybox] Destroying VM 'dev-ubuntu'...
  → Stopping VM... done (3s)
  → Removing overlay disk... done
  → Removing VM definition... done
[Mybox] VM 'dev-ubuntu' destroyed

Implementation Guide

  1. Reproduce the simplest happy-path scenario.
  2. Build the smallest working version of the core feature.
  3. Add input validation and error handling.
  4. Add instrumentation/logging to confirm behavior.
  5. Refactor into clean modules with tests.

Milestones

  • Milestone 1: Minimal working program that runs end-to-end.
  • Milestone 2: Correct outputs for typical inputs.
  • Milestone 3: Robust handling of edge cases.
  • Milestone 4: Clean structure and documented usage.

Validation Checklist

  • Output matches the real-world outcome example
  • Handles invalid inputs safely
  • Provides clear errors and exit codes
  • Repeatable results across runs

References

  • Main guide: VIRTUALIZATION_HYPERVISORS_HYPERCONVERGENCE.md
  • Primary references are listed in the main guide