Skip to content
Terraform

Day 6: Declare It. Version It. Trust It. — Making IaC a Discipline, Not Just a Tool

Installing Terraform doesn't give you Infrastructure as Code. Treating your .tf files with the same rigor as application code does — and that means module design, review, and state management with real discipline behind them.

Thamunkpillai 4 min read

Yesterday's article made the case for why infrastructure should be code at all — consistency, version control, speed, auditability. None of that shows up automatically the moment a team installs Terraform. A .tf file sitting in a repo that nobody reviews, with state nobody's locked, that one person applies from their laptop because "the pipeline's slower," gets you a text file that describes your infrastructure. It doesn't get you the guarantees IaC is supposed to provide. Those guarantees come from discipline layered on top of the tool, and that discipline is where most teams' IaC adoption quietly stalls.

The workflow that actually earns the guarantees

The mechanics are simple to state and easy to skip under pressure: write, commit, plan, apply. Every infrastructure change starts as code, gets committed to version control, gets a plan run against it so the team can see exactly what will change before it changes, and only then gets applied.

Note

The plan step is the one teams cut corners on first, usually under incident pressure — "I already know what this does, let me just apply it." That's precisely the moment a plan review catches the thing you didn't know it would also do: the resource it will silently recreate, the dependency it will tear down first.

Terraform, Pulumi, CloudFormation, Ansible, Azure Bicep — pick based on your cloud footprint and team preference, and move on. The tool choice gets an outsized share of the debate in most teams and deserves a much smaller share than it gets. What actually determines whether your IaC practice holds up over eighteen months is the stuff around the tool: module design that doesn't calcify into an unmaintainable pile of conditionals, a state management strategy that survives more than one engineer working concurrently, and a review culture that treats a Terraform diff with the same seriousness as an application code diff.

Drift is the tell

Configuration drift — someone runs kubectl scale or clicks a console change directly, bypassing the declared config entirely — is where IaC discipline gets tested for real. It's not a hypothetical: it's the single most common way teams quietly lose the guarantees IaC is supposed to provide, one "just this once, I'll fix the code later" at a time.

YAML
# Before: what's declared in Git
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  replicas: 2
 
# What someone ran directly against the cluster, bypassing Git:
# kubectl scale deployment/webapp --replicas=1

A team with real IaC discipline treats that gap as a bug to detect and correct, not a footnote. This is precisely the problem GitOps controllers are built to solve — continuously reconciling live state back to what's declared, rather than trusting that the last apply is still an accurate description of reality. Day 29 of this series covers that mechanism directly; for now, the takeaway that matters is narrower: if your team can't tell you, right now, whether production infrastructure currently matches what's in Git, you don't have IaC discipline yet — you have IaC-flavored console changes with extra steps.

Warning

"I'll fix the code to match after the incident" is the most common way IaC discipline dies. It's said in good faith, under real pressure, and it's almost never followed up on — because by the time the incident's over, there's a new fire, and the drift just sits there until the next audit finds it.

What you're actually buying with the discipline

Instead of thisYou get this
Manual steps, remembered by whoever's been here longestRepeatable, defined-in-code provisioning
Inconsistent environments that "mostly" matchSame code, same result, every environment
Tribal knowledge as the audit trailA Git history that is the audit trail
Copy-pasted scripts, silently diverging over timeVersioned modules, reviewed like any other code

If application code lives in Git, reviewed and tested before it ships, infrastructure code should live under exactly the same rules — same principles, same power, same consequences for skipping them. The tool gets you the file. The discipline gets you the guarantees the file was supposed to provide in the first place.

Written by Thamunkpillai · Have a question or a correction? Reach out via email.

Get the useful stuff, not the noise.

Occasional notes on engineering, Platform Engineering, AI, cloud and things I’m learning along the way.

No spam. Unsubscribe anytime.