Steven's Knowledge

OpenTofu

The open-source Terraform fork - why it exists, how it stays compatible, its divergent features (client-side state encryption, early variable evaluation), and how to migrate

OpenTofu

OpenTofu is an open-source fork of Terraform, stewarded by the Linux Foundation. For most code it is a drop-in replacement; the tofu CLI reads the same HCL, uses the same providers, and operates on the same state files.

Why It Exists

In August 2023, HashiCorp relicensed Terraform from the MPL 2.0 (a permissive open-source license) to the BUSL (Business Source License), which restricts commercial use that competes with HashiCorp. The community forked the last MPL-licensed version; that fork became OpenTofu, reaching GA as 1.6 in January 2024 under the MPL 2.0.

The practical upshot: if you want a genuinely open-source IaC tool with the Terraform workflow and ecosystem — no license risk, community-governed — OpenTofu is it.

Compatibility

AspectStatus
HCL syntaxIdentical
ProvidersSame provider binaries, via registry.opentofu.org (a mirror)
ModulesSame; public registry mirrored, plus the Terraform Registry usable
State filesReads and writes the same .tfstate format (for matching versions)
CLItofu instead of terraform; same commands and flags
File extensions.tf works; .tofu files are also recognized for fork-specific overrides

OpenTofu 1.6 lines up with Terraform 1.6. After that the two diverge — each adds features the other doesn't — so a state written by a newer OpenTofu may not be readable by Terraform, and vice versa.

Features OpenTofu Has That Terraform Doesn't

The fork is not just "Terraform with a different license" anymore. The notable additions:

Client-Side State Encryption

OpenTofu can encrypt state and plan files end-to-end, before they ever reach the backend — closing the long-standing "secrets sit in plaintext in tfstate" gap at the tool level (not just at the backend's at-rest encryption).

terraform {
  encryption {
    key_provider "pbkdf2" "passphrase" {
      passphrase = var.state_passphrase   # or pull from a real KMS
    }

    method "aes_gcm" "default" {
      keys = key_provider.pbkdf2.passphrase
    }

    state {
      method = method.aes_gcm.default
    }
    plan {
      method = method.aes_gcm.default
    }
  }
}

Key providers include PBKDF2 (passphrase) and cloud KMS (AWS/GCP/Azure) for production key management.

Early / Static Variable Evaluation

OpenTofu lets you use variables and locals in places Terraform forbids them — most usefully in module source and version, and in backend configuration:

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = var.vpc_module_version     # not allowed in Terraform
}

This removes a class of copy-paste that Terraform forces, where the module version has to be hard-coded per call.

Other Divergences

  • -exclude flag — the inverse of -target: apply everything except the named resources.
  • Provider iteration with for_each for some configurations, and continued investment in built-in testing/mocking.

These are moving targets — both tools ship every few months. Treat the list as "the kinds of things that differ," and check the current OpenTofu changelog for what's landed in the version you run.

Migrating From Terraform

For a project still on Terraform 1.6-compatible features, migration is usually painless:

# Install the tofu CLI (brew, apt, or the install script), then:
cd my-terraform-project
tofu init                  # reads your existing backend + state
tofu plan                  # should show no changes

Notes and caveats:

  • Version alignment. Migrate from a Terraform version at or below your target OpenTofu's compatibility line (1.6). Coming from a much newer Terraform that used post-fork features, expect to adjust.
  • One-way, in practice. Once OpenTofu writes a newer state format or you adopt fork-only features (state encryption, early eval), you can't cleanly go back to Terraform.
  • The cloud {} block targets HCP Terraform, a HashiCorp service — it isn't the OpenTofu path. Use a standard remote backend (S3/GCS/azurerm) or a platform like Spacelift/Scalr that supports OpenTofu (see HCP Terraform & Automation Platforms).
  • Provider addresses. Providers resolve through OpenTofu's registry; in rare cases of legacy addresses you may need state replace-provider (see Refactoring & State Evolution).
  • CI. Swap hashicorp/setup-terraform for opentofu/setup-opentofu, and terraform invocations for tofu.

Terraform or OpenTofu?

Choose Terraform whenChoose OpenTofu when
You want HCP Terraform / Terraform Enterprise as your platformYou want a fully open-source (MPL 2.0) tool
You rely on the latest HashiCorp-only featuresYou want client-side state encryption built in
Your org has standardized on it alreadyLicense terms (BUSL) are a concern for your use case
You want first-party Sentinel policyYou're happy with OPA and community governance

Either way, everything else in this section — modules, state, refactoring, testing, expert patterns — applies unchanged. The two tools share the same mental model.

What's Next

You've now seen Terraform end to end: the language, state, modules, the advanced and expert features, refactoring, testing, platforms, and the open-source fork. Tie it together with the production playbook → Best Practices.

On this page