Immutable Infrastructure
Reliability, consistency and confidence through immutability
--
I’d like to express my gratitude to my colleagues and friends Ricardo Sueiras, Danilo Poccia, and Matt Fitzgerald for their valuable feedback and for being awesome.
Immutable:
not capable of or susceptible to change
Problems with immutability, or the lack thereof, isn’t a new thing. It has been around for as long as there have been programming languages.
For example, any Python developer knows that the mutable and immutable data types in Python are causing a lot of headaches — even to advanced developers. Consider this example:
>>> foo = ['hello']
>>> print(foo)
['hello']
>>> bar = foo
>>> bar += ['world']
>>> print(foo)
['hello', 'world'] <-- WHAT IS HAPPENING?
What is happening? Because foo
was never modified directly, but bar
was, anyone would expect the following:
>>> print(foo)
['hello'] <-- WHY IS THIS NOT HAPPENING?
But that isn’t happening, and that is mutability at work.
In Python, if you assign a variable to another variable of a mutable data type, any changes are reflected by both variables. In this example bar = foo
.
The new variable bar
is just an alias for foo
.
Put simply, mutable means ‘can change’ and immutable means ’cannot change.’
Languages such as Rust, Erlang, Scala, Haskell, and Clojure offer immutable data structures and single assignment variables with the premise that immutability leads to better code, simpler to understand, and easier to maintain.
That’s all beautiful, Adrian, but what does it have to do with software architectures?
Headaches… and no one likes headaches.
The immutable infrastructure paradigm comes from the same ideas behind immutability in programming languages — your architecture doesn’t change once deployed, and it saves you from headaches.