Two ways of asking for the same thing
Suppose you need three servers behind a load balancer. There are two ways to write that.
Ordering (a script): create a server, create another, create a third, create the load balancer, connect all three. It works the first time. And the second? It creates three more servers. And if there were already two? It creates three, leaving five. And if it fails at step four? It is left halfway, and you have to guess what was done.
Declaring (infrastructure as code): 'there must be three servers of this size behind a load balancer'. A tool compares what is declared with what exists and does only what is missing.
Why declaring is safer
- It can be repeated without fear. Running the same thing twice leaves the same result. If it is already as it should be, nothing is touched.
- What exists is respected. If two of the three servers already exist, only the third is created.
- Failures recover. If something fails halfway, you run it again and the tool carries on from where it stopped.
- The code reads as a description. Whoever opens it sees what is there, not a recipe they have to run in their head to understand.
When ordering is still needed
Some tasks are steps by nature: migrating data, rotating a key, restarting services in a particular order. For those, scripts remain the right tool, with two conditions: that they check before acting (not creating what already exists) and that they can be repeated without breaking anything.
Declaring what must exist has a practical consequence: the tool needs to remember what it created and how it relates that to the code. That memory is the state.
How we apply it: Automation and IaC.