1.1.2. Declarative vs. Imperative Thinking
💡 First Principle: When you tell a tool what the end state should look like rather than how to achieve it, the tool can compute the difference between now and the goal — which means it can be run repeatedly and safely without you tracking what's already done.
Terraform is declarative: you write that you want, say, three servers and a load balancer, and Terraform figures out the create/update/delete operations needed to make reality match. An imperative approach (a script) is a sequence of commands — "create server, then create another, then attach the balancer" — where you are responsible for knowing the current state and not repeating steps.
The payoff of declarative thinking is idempotency: running the same configuration twice produces the same result. The second run sees that everything already matches and does nothing. An imperative script run twice might try to create the servers again and fail. This is why Terraform can be safely re-run any time, and why "I'll just run it again" is a reasonable recovery strategy.
| Dimension | Declarative (Terraform) | Imperative (scripts) |
|---|---|---|
| You specify | The desired end state | The exact steps to take |
| Knows current state? | Yes (via state + refresh) | No — you must track it |
| Safe to re-run? | Yes (idempotent) | Often not |
| Detects drift? | Yes | No |
| Order of operations | Tool computes it | You define it |
⚠️ Exam Trap: "Declarative" does not mean "order doesn't matter at all." Terraform still computes an order — it builds a dependency graph and works out what must happen before what. What declarative means is that you don't write the order by hand; you write the goal and the references between resources, and Terraform derives the sequence.
Reflection Question: Why can a declarative tool detect configuration drift while an imperative script generally cannot?