Terraform — How It Works¶
Provider plugin architecture, state management, plan/apply lifecycle, and dependency graph.
Core Lifecycle¶
sequenceDiagram
participant User as User
participant CLI as Terraform CLI
participant State as State File
participant Provider as Provider Plugin (gRPC)
participant Cloud as Cloud API
User->>CLI: terraform plan
CLI->>State: Read current state
CLI->>Provider: Refresh resource statuses
Provider->>Cloud: API calls to check real state
Provider-->>CLI: Current state
CLI->>CLI: Diff: desired (HCL) vs current
CLI-->>User: Execution plan (+ / ~ / -)
User->>CLI: terraform apply
CLI->>CLI: Build dependency graph (DAG)
CLI->>Provider: Create/Update/Delete resources
Provider->>Cloud: API calls
Provider-->>CLI: Resource attributes
CLI->>State: Write updated state
Dependency Graph (DAG)¶
Terraform builds a Directed Acyclic Graph of all resources, ensuring correct ordering:
flowchart TB
VPC["aws_vpc"] --> Subnet["aws_subnet"]
Subnet --> SG["aws_security_group"]
Subnet --> Instance["aws_instance"]
SG --> Instance
Instance --> EIP["aws_eip"]
style VPC fill:#ff6f00,color:#fff
Resources without dependencies are created in parallel.
Provider Plugin Architecture¶
flowchart LR
CLI_T["Terraform CLI\n(core engine)"] <-->|"gRPC"| AWS["AWS Provider\n(plugin binary)"]
CLI_T <-->|"gRPC"| GCP["GCP Provider"]
CLI_T <-->|"gRPC"| K8s_P["K8s Provider"]
CLI_T <-->|"gRPC"| Custom["Custom Provider"]
style CLI_T fill:#7b42bc,color:#fff
Each provider is a separate binary communicating via gRPC. Providers are downloaded during terraform init from the Terraform Registry.
State File¶
| Aspect | Detail |
|---|---|
| Purpose | Maps HCL resources to real-world objects |
| Format | JSON (human-readable but not for editing) |
| Locking | DynamoDB (AWS), GCS, Consul for remote |
| Sensitive data | ⚠️ Stored in plaintext (use remote backend + encryption) |
| Remote backends | S3, GCS, Azure Blob, Terraform Cloud, Consul |