a aakura/notes
essay · mar 30 · 2026

Terraform modules age like milk. Mine, anyway.

A long honest look at every shared module I've shipped over four years, what broke, what calcified, and the small ergonomic shifts I'd make if I started again tomorrow.

The thing nobody tells you about shared Terraform modules is that they go bad in exactly two ways and you have to choose which one you can live with.

Mode A: the calcified module

A calcified module is one nobody updates because everyone depends on it. It locks itself in place; new flags get added at the edges; the underlying provider quietly diverges from the abstraction. After two years the module is no longer “infrastructure-as-code” — it’s a museum piece.

Mode B: the bleeding module

The opposite: a module that changes weekly, breaking three consumers each time, until the consumers fork it and never come back. Now you have N divergent copies of “the platform module” and no one quite knows which is canonical.

The interesting thing is that both failure modes start from the same place: the moment you decide a module is “stable enough to share.”

What I’d do differently

If I started over, three small ergonomic shifts:

  • Version every module from day one. Even v0.0.1 is a contract.
  • Reserve latest for the platform team. No one else pins to it.
  • Write a migration guide before bumping the major. If you can’t, the bump isn’t ready.

Modules are not free abstractions. They are a kind of currency, and the cost of issuing them is paid by everyone downstream for years.