flowchart LR C[Git repo: tf + playbooks] --> P[terraform plan] P --> A[terraform apply] A --> PVE[(Proxmox VMs)] PVE --> INV[Dynamic inventory] INV --> PB[ansible-playbook] PB --> CFG[Configured services]
Terraform + Ansible for a Home Lab
Provision with Terraform, configure with Ansible - the split that keeps a Proxmox home lab reproducible instead of a pile of hand-clicked VMs.
A home lab rots the moment it becomes un-reproducible. The fix is the same as at work: Terraform provisions the infra, Ansible configures it. Two tools, one clean seam. Built out across Terraform and Ansible in WEB_doc, running on Proxmox from Software_Tools.
- Terraform: https://bthek1.github.io/WEB_doc/17_Terraform
- Ansible: https://bthek1.github.io/WEB_doc/18_Ansible
- Proxmox host: https://bthek1.github.io/Software_Tools/03_Proxmox
Two tools, one seam
| Terraform | Ansible | |
|---|---|---|
| Job | Provision (create VMs, networks, storage) | Configure (packages, services, files) |
| Model | Declarative desired-state | Declarative-ish, procedural playbooks |
| State | Tracks a state file | Stateless; idempotent tasks |
| Idempotent | Yes (plan/apply) | Yes (per task) |
| Best at | “What exists” | “How it’s set up” |
The seam: Terraform stops once a VM boots with an IP; Ansible takes over from the IP. Don’t make Terraform install packages, and don’t make Ansible create VMs.
The workflow
The lab it builds
flowchart TB PVE[Proxmox host] --> VM1[VM: Docker host] PVE --> VM2[VM: k3s node] PVE --> VM3[LXC: services] VM1 --> D[(Containers)] VM3 --> DB[(Postgres / Influx)]
Why bother: hands-on minutes to rebuild
The payoff is disaster recovery. Rebuilding by hand is an afternoon; rebuilding from code is a coffee.
Takeaway
Keep the seam clean and the whole lab lives in git: terraform apply then ansible-playbook rebuilds everything from bare Proxmox. Details in Terraform and Ansible.