im·a·cto
← choices

$ cat choices/terraform.md

Terraform

the call

Terraform is the tracks. If infrastructure isn't code, your speed has a ceiling you'll hit at the worst possible time. I'd rather hit it on a Tuesday than during an incident.

why

The train can only move as fast as the tracks it’s built on. Infrastructure that lives in someone’s head, or in a console nobody dares touch, is a ceiling on every future move. Terraform turns that into code: reviewable, diffable, reproducible. You stop guessing what’s deployed and start reading it. The first time you tear an environment down and stand it back up identically, you understand why this is non-negotiable.

when I don’t

A single box you’ll never reproduce doesn’t need a state file. Terraform earns its keep when infrastructure is shared, repeated, or load-bearing, not for a one-off you’ll throw away tomorrow. And it’s not a config-management tool: don’t reach for it to manage what’s inside a running machine. Wrapping a quick experiment in HCL just to feel rigorous is ceremony, not engineering. The state file is a liability you’re now responsible for. Only take it on when reproducibility actually buys you something.

And the big one: don’t use Terraform to build and deploy your applications. It provisions the infrastructure; it is not your release pipeline. App code ships many times a day and rolls back fast. Infrastructure moves slowly and rolls back carefully. Jam both into one terraform apply and you’ve welded two things that need different speeds, blast radii, and on-call instincts. Now a routine deploy can touch your VPC, and a rollback is terrifying. Keep Terraform under the app, and let CI build and a CD tool like Argo CD deploy.

in production

At GigSmart the infrastructure ran as code in Terraform: the tracks the whole team moved on, not a pile of hand-clicked console state nobody could explain. Every change to the network, the clusters, the IAM was a reviewable diff instead of a late-night console click someone half-remembered. That’s the line between infrastructure you operate and infrastructure you’re just hoping holds. When it’s code, you can read what’s deployed, review what’s changing, and rebuild it if you have to. Terraform owns that slow-moving layer, the building, and hands the fast-moving app deploys off to GitOps.— see: works / GigSmart · choices / argo-cd

the principle under it

Anything you can’t reproduce, you don’t actually control. You’re just borrowing it until it breaks. The discipline isn’t loving Terraform; it’s refusing to let critical infrastructure exist in a form nobody can review or rebuild. Snowflakes feel fast right up until the day you need a second one and can’t remember how you made the first.

the gaps — what it costs even when it’s right

State is a single point of failure. The state file becomes the source of truth, and a corrupted or drifted state is its own outage. You’re now operating a system whose job is to describe your other systems, and it needs locking, backups, and discipline of its own.

Drift is silent until it isn’t. The moment someone clicks something in a console, your code and reality diverge, and Terraform won’t tell you until the next plan. Usually mid-change, usually when you least want surprises.

HCL is a ceiling of its own. It’s declarative until you need a loop or a conditional, and then you’re fighting the language. The abstraction leaks, and the better you get, the more time you spend reasoning about the tool instead of the infrastructure.

© 2026 — written by a human, with help, and said so canonical jasonwaldrip.com · delivered through The Bushido Collective