This repository contains the terraform scripts to provision my homelab. The homelab is self contained on a single laptop running Proxmox (with a remote hetzner node for monitoring) and is able to perform the following tasks:
- Connect to any WiFi network and create a secondary
AP-modeinterface to host a WiFi network.- Requires a WiFi adapter that supports both
APandmanagedmodes. ArchWiki#Software_access_point - Use
hostapdto configure theAPinterface.
- Requires a WiFi adapter that supports both
- Run PfSense as a VM to act as a router and firewall, with WAN as the primary WiFi interface, LAN as the secondary
APinterface, and LAN2 as the internal network for VMs.- Use
/etc/network/interfacesto configurevmbr0to NAT overwlan0, makingvmbr0the WAN interface. - Create
vmbr1and usebridge=vmbr1option inhostapdto redirect traffic fromAPinterface tovmbr1, makingvmbr1the LAN interface. - Create
vmbr2and use it as the internal network for VMs, makingvmbr2the LAN2 interface. - Runs
tailscalepackage to advertise the internal network to the tailscale network.
- Use
- Run a minimal VM to act as a network storage provider with backups to external storage.
- Has a single disk image attached to it from a SSD storage pool.
- The disk image is backed up to an external storage pool by proxmox on daily and weekly schedules with a retention policy.
- Shares chunks of the disk image over the network using
nfsto various ephemeral/immutable VMs (like Fedora CoreOS etc.) for their storage needs. - Maintains a copy of contents of the disk image on the external storage pool using
rsyncon a hourly schedule.
- Run Fedora CoreOS to serve the homelab services.
- Runs
traefikas a reverse proxy to route traffic to various services. traefikis configured with two entrypoints, one forhttpand one forhttps.- Exposes
httpsentrypoint to the internal network with custom CA certificates. - Uses
pangolinto tunnel traffic from a public domain to thehttpentrypoint as tls is terminated athetzner.
- Runs
- Has a primary VM to run Steam and LM Studio.
- Uses
vfioto passthrough the dGPU to the VM. - Passes built-in
eDPdisplay to the VM. - Passes keyboard, trackpad, and USB ports to the VM.
- Uses
- Has a secondary VM as a development environment.
Requires the following to be installed on the runner machine:
- Basics like
git,ssh,nvim, etc. hashicorp/vaultcli to store secrets.hashicorp/terraformcli to run the terraform scripts.redhat/ansiblecli to run the Ansible playbooks.
Ensure that the following things are setup:
-
Setup BIOS settings for target machine.
- Enable virtualization
- Enable IOMMU (if using dGPU passthrough)
- Disable integrated graphics (if using dGPU passthrough and built-in display)
- Set boot password (Optional)
-
Create a
vaultserver to store secrets on the runner machine.- Homebrew install
vaultcli. - Run
vault server -config=vault.hclto start the vault server. - Use the web UI to setup the vault server, create a
kv2secret engine and auserpassauth method. - Load required secrets into the vault server as defined below.
- Homebrew install
-
Create
infrastructure/terraform.tfvarsfile with the following variables:vault_username = "username" vault_password = "password" vault_cert = "path/to/cert.pem"
-
Install Standard Proxmox VE on the target machine.
- Run ansible playbook
base_system/main.ymlto verify Proxmox VE on the target machine.- Note: HostAPD 5GHz with intel cards is weird, as their LAR feature cannot be disabled, leading to no channels being available from use. Use 2.4GHz in these cases. Refer to ArchWiki SAP doc.
- Disable
pve-enterpriserepository and enablepve-no-subscriptionrepository. - Set
cpupower frequency-set -u 2.7GHzto limit clocks. - Create required storage pools like
local(ISOs),local-lvm(Disks), andlocal-hdd(Backups). - Finally create an API Token for the terraform provider from the GUI.
- Run ansible playbook
Assuming base kv2 store path as homelab/terraform. The following secrets need to be loaded into the vault server:
homelab/terraform/tokens{ "endpoint_external": "https://<external_ip>:8006/", "endpoint_internal": "https://<internal_domain>:8006/", "username": "root@pam", "password": "password", "node": "pve" }