Reference · Terraform

The Apply Lifecycle & the Graph

How Terraform decides order, what runs in parallel, and what happens when an apply fails.

The graph in one paragraph

Terraform builds a DAG (directed acyclic graph) from your config: every reference is an edge (subnet referencing vpc.id ⇒ VPC first), plus any explicit depends_on edges. Apply walks the graph: a node runs as soon as all its dependencies are done, with up to 10 nodes concurrently by default (-parallelism=N to change). Order is never alphabetical, never file order — only the graph.

Source: Dependency graph internals

Implicit vs explicit dependencies

Replacement order: two nodes, not one

A -/+ replace splits into a destroy node and a create node — necessary because destroy order is the reverse of create order.

ModeOrderTrade-off
Defaultdestroy old → create newDowntime window; safe for unique names
create_before_destroycreate new → destroy oldNo gap — but old + new must coexist (unique names break it). Opt-in via lifecycle {}.

Source: lifecycle meta-argument

When an apply fails — the part nobody tells you

There is no rollback. Terraform is not transactional. Resources already created stay created and stay in state; the failed resource is recorded as tainted if it half-exists (created but provisioning failed); everything downstream is simply not attempted. The fix is normal: correct the problem, run apply again — Terraform resumes from where reality is. Tainted resources are planned as -/+ replace on the next run.

Other lifecycle controls

ToolWhat it doesCaution
prevent_destroy = truePlan that would destroy this resource → hard errorLives in the block — deleting the whole block removes the guard too
ignore_changes = [attr]Diff ignores those attributes (tolerated drift)Permanent blind spot — document why
-target=ADDRApply only ADDR + its dependenciesEmergency tool. Routine use leaves state diverged from config
-parallelism=NConcurrency of the graph walk (default 10)Raising it mostly moves the bottleneck to API rate limits
terraform graphDump the DAG (DOT format)Pipe to Graphviz to actually see it