DevOps Peach

Advanced Terraform · OpenTofu, Terragrunt and Security · Lesson 2 of 4

OpenTofu: the Open-Source Fork

OpenTofu forked from Terraform 1.5 after the 2023 licence change; it keeps HCL and state compatible and adds features such as client-side state encryption, early variable evaluation and provider for_each.

Practice interactively →

In August 2023 HashiCorp moved Terraform from the open-source MPL 2.0 licence to the Business Source License (BSL 1.1). A group of companies forked the last MPL version (1.5) as OpenTofu, now run under the Linux Foundation and still MPL-licensed. The CLI is tofu; the language is the same HCL.

flowchart LR
  T15["Terraform 1.5 (MPL)"] --> TF["Terraform 1.6+ (BSL)"]
  T15 --> OT["OpenTofu 1.6+ (MPL)"]
  OT --> ENC["State and plan encryption"]
  OT --> EV["Early variable evaluation"]
  OT --> PFE["Provider for_each"]
  TF --> HCP["HCP Terraform features"]
  %% step T15: Both tools share history and the HCL language up to Terraform 1.5.
  %% step TF: Terraform continues under the BSL, with HCP Terraform as its commercial platform.
  %% step OT: OpenTofu continues under MPL 2.0 with its own registry and releases.
  %% step ENC: OpenTofu can encrypt state and plan files on the client before they reach the backend.
  %% step EV: Variables and locals can be used in backend blocks and module sources.
  %% step PFE: One provider block can create many configurations with for_each, for example one per region.

What is the same

What OpenTofu adds (examples)

terraform {
  encryption {
    key_provider "pbkdf2" "main" {
      passphrase = var.state_passphrase          # or aws_kms, gcp_kms, openbao
    }
    method "aes_gcm" "main" {
      keys = key_provider.pbkdf2.main
    }
    state { method = method.aes_gcm.main }
    plan  { method = method.aes_gcm.main }
  }

  backend "s3" {
    key = "${var.env}/app.tfstate"               # early evaluation: variables allowed
    # ...
  }
}
Feature OpenTofu Terraform
Client-side state encryption Yes (1.7+) No (relies on backend encryption)
Variables in backend and module source Yes (1.8+) No
for_each on provider blocks Yes (1.9+) No
-exclude flag (opposite of -target) Yes (1.9+) No
HCP Terraform, Sentinel No Yes
Licence MPL 2.0 BSL 1.1

Both projects keep adding features (ephemeral values, for example, exist in both), so check each tool's docs for the version you run.

Migrating Terraform → OpenTofu

  1. Upgrade to a Terraform version that OpenTofu's migration guide supports and get a clean terraform plan.
  2. Back up the state (terraform state pull > backup.tfstate).
  3. Install tofu, run tofu init (providers come from registry.opentofu.org).
  4. tofu plan must show no changes; then tofu apply once to write the state.
  5. Update CI to tofu, and only then start using OpenTofu-only features.

Going back is possible only until you use features the other tool does not understand (an encrypted state, for example).

Traps: the two tools diverge release by release, so "compatible" means compatible with what you actually use; and once state encryption is on, losing the key means losing the state.

Practice interactively →