← All TILs · terraform

What Terraform/OpenTofu actually is, and how it works

terraform - 2026-09-17

Starting a second from-scratch series, this time on HashiCorp's infrastructure tooling: Terraform/OpenTofu, Packer, and Nomad. First subject: what Terraform/OpenTofu actually does under the hood, since almost everything else about it follows from one thing — it only ever converges when you tell it to, unlike a system with a live controller watching state continuously.

Terraform and OpenTofu are the same tool, split by a license change

OpenTofu is a fork of Terraform, created after HashiCorp switched Terraform's license to the BUSL. The fork is now governed by the Linux Foundation and aims to stay at feature parity with Terraform going forward. Practically: same HCL syntax, same state file format, same provider ecosystem, same commands — everything in this TIL applies to both, and either binary would run the examples.

The pieces

flowchart TB
    HCL[HCL config: .tf files] --> CORE[Terraform or OpenTofu core]
    STATE[(State file)] --> CORE
    CORE --> GRAPH[Dependency graph of resources]
    GRAPH --> PROV1[Provider: cloud A]
    GRAPH --> PROV2[Provider: cloud B]
    PROV1 --> API1[Real infrastructure API]
    PROV2 --> API2[Real infrastructure API]

Write, plan, apply — and nothing runs in between

Per Terraform's own docs, the core workflow is three steps: write, plan, apply. plan refreshes its view of real infrastructure by querying providers, compares that against both the state file and your HCL, and shows you exactly what it would create, change, or destroy — without touching anything yet. apply is the only step that actually calls providers to change infrastructure.

sequenceDiagram
    actor You
    participant Core as Terraform or OpenTofu core
    participant State as State file
    participant API as Provider and cloud API

    You->>Core: terraform plan
    Core->>State: read last-known state
    Core->>API: refresh, query real resources
    Core->>Core: diff desired config vs actual state
    Core-->>You: show the plan (create, update, destroy)
    You->>Core: terraform apply
    Core->>API: create, update, destroy resources
    Core->>State: write new state

The thing worth sitting with: there is no daemon. Between one apply and the next, nothing is watching whether the real infrastructure has drifted from what's in the state file. If someone changes a security group rule by hand in the cloud console, Terraform doesn't notice or correct it until you run plan again. That's the opposite of a system built around a continuously running controller — Terraform's convergence is something you trigger, not something that's always happening.

Where this series goes next

Packer builds the images Terraform then provisions infrastructure from, and Nomad is what actually runs workloads on infrastructure Terraform stood up — the next two entries cover each in turn, then a final one on how the three actually fit together. Queued after that: a Terraform state management deep-dive (locking, drift, import/moved/removed), Terraform modules (input/output contracts, local vs Registry), ephemeral values and write-only arguments for handling secrets, and the handful of things OpenTofu genuinely has that Terraform doesn't — native state/plan encryption being the headline.

Created 2026-09-17T18:52:56+02:00 · Edit