Linux home lab

January 22, 2022

For relaxing times, make it Linux time. For hardware, though, Macs are usually good choices (update: and the latest MacBook Pro M1 is a beast). If you find yourself needing multiple Linux VMs with custom IP addresses, hostnames, and more, Vagrant is your tool.

To spin up one Ubuntu VM using Vagrant, the following Vagrantfile script is enough:

Vagrant.configure("2") do |config|
  config.vm.box = "lma/ubuntu-21.04"
  config.vm.hostname = "minikube.host"
  config.vm.synced_folder ".", "/vagrant"
  config.vm.network "private_network", ip: "10.10.10.210"
  config.vm.provider "vmware_fusion" do |v|
    v.vmx["memsize"] = "4096"
    v.gui = false
  end
end

Run vagrant up and you’ll end up with a VM running Ubuntu 21.04. It can be pinged from your host and does not include a GUI. Your current folder on the will also be mounted under /vagrant in the VM, effectively sharing it with the VM. This is useful when you want to write code in your host using your favorite IDE but run it inside the VM.

When setting up a lab, you usually need more than one VM. With Vagrant, that’s easy too. Check this out:

HOSTNAME_SUFFIX = "mylab.local"
PRIV_NET = "10.10.10"
MACHINES = {
    :node1 => { :hostname => "node1.#{HOSTNAME_SUFFIX}", :ip => "#{PRIV_NET}.10" },
    :node2 => { :hostname => "node2.#{HOSTNAME_SUFFIX}", :ip => "#{PRIV_NET}.20" },
    :node3 => { :hostname => "node3.#{HOSTNAME_SUFFIX}", :ip => "#{PRIV_NET}.30" },
}

Vagrant.configure("2") do |config|
    MACHINES.each_with_index do |(name, machine), index|
        config.vm.define machine[:hostname] do |node|
            node.vm.hostname = machine[:hostname]
            node.vm.box = "lma/ubuntu-21.04"
            node.vm.synced_folder ".", "/vagrant", disabled: true
            node.vm.network "private_network", ip: machine[:ip]
            node.vm.provider "vmware_fusion" do |vf|
                vf.vmx["memsize"] = 1024
                vf.gui = false
            end

            node.vm.provision :shell, inline: <<-SHELL
                sudo apt-get update
            SHELL
        end
    end
end

Now we have 3 VMs, each with their own ip address (*.10.10.10), custom hostnames (node{n}.mylab.local), and 1GB of RAM. The shared folder is disabled, and apt-get update provisions each machine. To SSH into each machine, you need to specify its name (e.g., vagrant ssh node1.mylab.local).

There are many patterns for setting up labs with Vagrant (e.g., configuring multiple machines with mixed private and public networks, non-default SSH keys, port forwarding, etc.). Perhaps one day I’ll write about them… stay tuned (or not)!