Comparisons
Pairs that get conflated in real conversations, and a few that get treated as synonyms when one is a prerequisite for the other. Neither column wins — what decides is the change in front of you. Each record leads with the confusion, because the confusion is why the record exists.
Declarative vs Imperative Infrastructure as Code
People believe declarative means "no order of operations" and "safe by construction". It means neither. The tool still computes and applies an ordered plan with real dependencies, and the plan can delete data — a renamed resource or a changed immutable field becomes destroy-then-create, which is exactly how a declarative apply drops a database. The real distinction is convergence: declarative tools can be re-run to reconcile drift, imperative scripts generally cannot be re-run safely. That property is worth a lot, and it is not the same as safety.
Use declarative when you want to describe the desired end state and let a tool compute the difference from what exists.
Use imperative when the change is a sequence of operations whose order and side effects matter, or when no declarative model exists for what you are doing.
| Dimension | Declarative | Imperative |
|---|---|---|
| What you write | The desired end state | The steps to reach it |
| Re-running it | Converges — a no-op if reality already matches | Often unsafe; needs its own idempotence |
| Drift | Detectable by diffing state against reality | Invisible unless something else checks |
| Preview | A plan you can read before applying | Usually only what the script prints as it goes |
| Hard part | Understanding what the computed plan will destroy | Keeping the sequence correct as it grows |
| Fails by | A rename or an immutable-field change becoming a replacement | Half-applied state after a step fails midway |