Terraform
Infrastructure from declared state - one workspace per VM so a mistake blasts one machine, not the fleet, and a pipeline that rolls forward cleanly when a step fails.
What it is & why I use it
Terraform is how VMs come into existence in AutomationLab. The hypervisor is driven
entirely through the bpg/proxmox provider - there is no hand-built guest
anywhere in the lab. Terraform owns the "make the machine exist and match what the code
says" half of provisioning; configuration management takes it from there.
I use it because infrastructure should be declarative and diffable. A plan shows exactly what will change before anything does, and drift surfaces as a diff instead of a surprise - which is the whole reason to treat infrastructure as code rather than as a sequence of console clicks.
How I use it in the lab
- One workspace per VM. Each machine has its own workspace and state rather than one giant shared state for the whole lab. A bad apply can only touch the one VM it owns.
- Driven by the pipeline. Terraform runs as the provision stage of the Jenkins flow, after IP allocation and before configuration - plan, gated apply, then hand off.
- Roll-forward on partial failure. If a later stage fails, the pipeline cleans up forward to a consistent state rather than leaving a half-built VM lying around, and a decommission path reverses what was created.
- Pinned provider and tool versions. The provider and the Terraform binary are pinned to explicit versions so a run is reproducible and does not silently change behavior when an upstream release lands.
Architecture
In action
Lessons learned & gotchas
- Per-VM state is worth the extra files. One monolithic state for everything is tidy until a single bad apply or a lock left behind takes the whole lab's provisioning hostage. Small, isolated states keep the blast radius to one machine.
- The plan is the review, so gate the apply. Applying straight from a push defeats the point of a plan. A human-gated apply in the pipeline means the diff is actually looked at before infrastructure moves.
- Roll-forward beats leaving wreckage. A failed provision that cleans up to a known state is recoverable; a half-built VM with orphaned state is a manual mess. Write the failure path, do not just hope for the happy one.
Impact
Terraform is what makes the lab reproducible from the metal up: every VM is described in code, isolated in its own state, and created through a gated, roll-forward pipeline. The version-pinning lesson is a small one that saves a whole class of "worked yesterday, broken today" failures - proof that in IaC the boring details are exactly where reliability lives.
Code & further reading
Published modules are scrubbed of internal addresses, hostnames, IDs, and any credential references before they go public.