Overview
Declarative IaC (e.g. Terraform, CloudFormation) has you specify the desired end state of infrastructure and lets an engine figure out how to get there. Imperative IaC (e.g. shell scripts, Chef recipes, raw CLI calls) has you write the exact sequence of commands to execute. The distinction matters because it determines who — you or the tool — is responsible for ordering, idempotency, and reconciling drift.
Comparison Diagram
Comparison Table
| Aspect | Declarative | Imperative |
|---|---|---|
| Authoring model | Write a desired-state spec | Write an ordered command list |
| Execution engine | Resolves a dependency graph | Runs a sequential interpreter |
| State tracking | Maintains a state file | Stateless execution |
| Applying changes | Single apply command | Run the script/playbook |
| Ordering & dependencies | Auto-resolved by engine | Manually sequenced by author |
| Idempotency | Guaranteed by design | Developer-enforced |
| Drift detection | Built-in plan diff | Not built-in |
| Failure handling | Partial apply, replan | Manual rollback |
Key Differences
- Declarative code answers ‘what’, imperative code answers ‘how’.
- Declarative tools rely on a state file to know current vs. desired infrastructure; imperative scripts have no memory of prior runs.
- Idempotent re-runs are automatic in declarative tools but must be hand-coded (checks, conditionals) in imperative scripts.
- Declarative engines build a dependency graph to order operations; imperative code hardcodes that order line by line.
- Drift correction in declarative IaC is a matter of re-running plan/apply; imperative approaches require re-running or rewriting the exact script.
When to Use Each
Declarative
- Long-Lived Cloud Infrastructure Provisioning: A state file that tracks current vs. desired infrastructure gives consistent, repeatable results across repeated applies, which is what tools like Terraform and CloudFormation are built for.
- Automatic Drift Reconciliation: The built-in plan diff lets teams detect and correct drift by re-running plan/apply instead of manually auditing what changed.
- Idempotent, Repeatable Deployments: Idempotency guaranteed by the engine means re-running the same configuration safely converges to the desired state without hand-written guards.
Imperative
- One-Off Operational Tasks: A stateless script is simpler for a single ad hoc action that doesn’t need lasting drift tracking or a state file.
- Complex Multi-Step Orchestration With Conditional Logic: Because imperative code runs as a sequential interpreter, it fits logic-heavy bootstrap or configuration flows that don’t map cleanly to a state model.
- Fine-Grained Manual Control Over Ordering: Authors who need to hand-sequence operations, such as in Chef recipes or CLI automation, get direct control over execution order that declarative engines abstract away.