← Back to DevOps and CI/CD

Terraform Execution Model

Terraform execution through state, dependency graphs, planning, and provider APIs.

DevOps and CI/CDInfrastructure as CodeTerraform

Terraform turns infrastructure code into cloud resources by comparing a desired state written in configuration files with a recorded current state and then asking provider APIs to close the gap. That sentence sounds simple, but it hides the key idea: Terraform is not a shell script runner. It is a state driven reconciliation tool. It decides what must be created, changed, or destroyed based on a graph of resources and dependencies.

From configuration to plan

An engineer writes configuration in HashiCorp Configuration Language, declaring resources such as networks, buckets, databases, or IAM roles. Variables and modules let teams compose reusable patterns, but the unit of work is still a declarative resource block. Terraform then loads the relevant provider plugins, validates the configuration, and refreshes its view of remote objects.

The state file is central here. It maps Terraform resource addresses to real cloud objects and stores computed attributes needed for future planning. Without state, Terraform would not know whether an S3 bucket already exists because it created it last week or whether a database identifier changed outside the tool.

Using configuration, provider schemas, and state, Terraform builds an execution plan. That plan is effectively a diff: create this subnet, update that security group, replace this instance because an immutable field changed. Reviewing the plan is one of Terraform's most valuable safety features because it makes potentially destructive changes visible before the apply step.

Why the dependency graph matters

Terraform constructs a graph from explicit references and some implicit dependencies. A VPC must exist before a subnet, and a subnet before an instance that lives inside it. The graph allows Terraform to parallelise independent operations while preserving ordering where required. That is how a large infrastructure change can be both fast and predictable.

The graph also explains some awkward behaviours. If a small looking change affects a resource that many others depend on, the blast radius can grow quickly. For example, replacing a core networking component may force recreation of downstream resources or at least temporary drift until the graph converges.

Real operational constraints

The pleasant declarative model stops being pleasant when state is mishandled. A lost or divergent state file can cause Terraform to recreate resources that already exist or to stop managing resources it previously owned. That is why teams store state remotely, lock it during applies, and control who can run changes.

Another constraint is that cloud APIs are not perfectly declarative. Some attributes are computed asynchronously, some changes take minutes, and some replacements are unavoidable because the provider API itself does not support in place mutation. Terraform exposes those realities rather than hiding them.

What good usage looks like

Terraform works best when modules are small enough to reason about, plans are reviewed, and state boundaries reflect ownership. One giant workspace for an entire company looks simple until every change contends on the same lock and any mistake has enormous scope.

In short, Terraform turns code into cloud by planning against state and executing a dependency graph through provider APIs. The power comes from determinism and reviewability. The risk comes from the same place: when the declared state is wrong, Terraform can be very efficient at making the real world match that mistake.