The Unyielding Anvil: Questioning the Cult of Immutability
There is a mantra in our circles, repeated with near-religious fervor: make your infrastructure immutable. The idea is seductive. You forge a server image, a container, a configuration—your perfect, hardened artifact—and you never change it. To update, you simply cast a new one and destroy the old. It’s clean, it’s predictable, and it promises to banish the dreaded configuration drift, that slow decay of a system as it’s poked and prodded over time. The immutable artifact is the unyielding anvil upon which we are told to hammer out reliability. But I’ve come to question if we’ve mistaken the tool for the truth.
The appeal is obvious. An immutable system is, in theory, a known quantity. Its state is a direct reflection of the code that built it. This reproducibility is powerful, especially when scaling or recovering from failure. Yet, this very strength breeds a subtle and dangerous weakness: the illusion of finality. We pour our effort into crafting the perfect image, we version it, we bless it, and we deploy. In doing so, we risk believing the work is done. The system is declared ‘cattle,’ and we become butchers, not shepherds.
But systems, even cattle, exist in a world. They interact with networks, caches, databases, and other services—all of which are fluid, stateful, and decidedly mutable. The immutable server becomes a perfect island in a sea of chaos. When a problem arises that is not contained within its pristine walls—a strange network latency, a peculiar interaction with a stateful partner, a dependency with a newly discovered flaw—our immutable artifact offers no clues. It is a black box, a sealed tomb. We cannot ssh in to run a quick tcpdump. We cannot tweak a setting on the fly to test a hypothesis. The very act of investigation is forbidden by the philosophy.
This rigidity can turn a five-minute troubleshooting session into a multi-hour deployment cycle. You must first divine the issue from external metrics alone, then modify your infrastructure-as-code, commit, trigger a build, and deploy a whole new instance to see if your guess was correct. The feedback loop is punishingly slow. We traded the potential messiness of mutable systems for a different kind of fragility: a brittleness that breaks not from entropy, but from our own inability to gently probe and understand.
I am not advocating for a return to the wild west of manual shell access and snowflake servers. The principles behind immutability are sound. But perhaps the dogma is too pure. The true goal isn’t immutability for its own sake; it’s reliability and reproducibility. Sometimes, the most reliable path to understanding a system’s behavior in the real, messy world is to have a controlled, audited way to peek inside the running machine—not to change it permanently, but to learn from it. The anvil is a wonderful tool, but a blacksmith who cannot feel the heat of the metal is just pounding on a rock.
Notes & further reading
A few pages I came back to while writing this:
- one area's overview
- The Flawed Compass: When Standardized Tools Mislead the Homesteader
- Huntsville, AL
- The Unwatched Pot: An Argument for Selective Ignorance in Monitoring
- a nearby resource
- The Clockmaker's Regulator: On the Tempo of Systems
- a practical rundown
- a local resource
- a regional guide
- Visalia, CA
- Vermont
- Knoxville, TN
- Cleveland, OH