Terraform vs OpenTofu: Two Years After the Fork โ
Two years ago I wrote that Terraform was the Infrastructure as Code tool. A few weeks later, HashiCorp changed its licence and the community forked it. Two years on, the fork is a real project with its own features, and "Terraform" no longer means one thing. Here's where the two stand in mid-2025, and how I'd pick between them.
๐ How We Got Here โ
- 10 August 2023: HashiCorp announced that future releases of its products would move from the Mozilla Public License 2.0 (MPL) to the Business Source License 1.1 (BSL). Terraform 1.5.x was the last MPL release, and 1.6.0 was the first under the BSL. The BSL is fine for most end users, but it restricts vendors who offer products that compete with HashiCorp.
- Late August 2023: the OpenTF manifesto asked HashiCorp to reverse the change. When it didn't, the group forked the last MPL code.
- 20 September 2023: the project joined the Linux Foundation and was renamed OpenTofu.
- 10 January 2024: OpenTofu 1.6.0, the first stable release, shipped.
- 24 April 2024: IBM announced it would acquire HashiCorp for $35 a share, about $6.4 billion. The deal closed on 27 February 2025. Terraform stayed under the BSL.
- 23 April 2025: OpenTofu was accepted into the CNCF as a Sandbox project.
๐ Where OpenTofu Went Its Own Way โ
OpenTofu started as a drop-in replacement. Since 1.7 it has shipped features Terraform doesn't have.
State encryption (1.7, April 2024) โ
This is the feature people asked for most. OpenTofu can encrypt state and plan files on the client before they reach your backend. You can use a passphrase or a key management service such as AWS KMS:
terraform {
encryption {
key_provider "pbkdf2" "main" {
passphrase = var.state_passphrase
}
method "aes_gcm" "main" {
keys = key_provider.pbkdf2.main
}
state {
method = method.aes_gcm.main
}
}
}Your state file usually holds secrets in plain text, so I think this is a big deal.
Early variable evaluation (1.8, July 2024) โ
Since 1.8, you can use variables and locals in places that used to need literal values, such as backend configuration and module versions:
terraform {
backend "s3" {
region = var.aws_region
}
}If you've ever kept a separate -backend-config file for each environment, you'll see why that helps. 1.8 also added .tofu files. If a .tofu file and a .tf file share a name, OpenTofu reads the .tofu one, so a module can support both tools.
And more โ
1.7 also added loopable import blocks. 1.9 (January 2025) added for_each on provider blocks, which makes multi-region setups much tidier, plus an -exclude flag. 1.10 (June 2025) added OCI registry support for providers and modules, and native S3 state locking without DynamoDB.
๐๏ธ What Terraform Has Been Shipping โ
Terraform hasn't stood still:
- 1.8 (April 2024): provider-defined functions, such as
provider::aws::arn_parse. OpenTofu shipped them in 1.7 a few weeks later, so this is one area where the two still match. - 1.9 (June 2024): input validation that can refer to other variables, plus
templatestring. - 1.10 (November 2024): ephemeral values and resources. These keep secrets out of plan and state files altogether.
- 1.11 (February 2025): write-only attributes, and native S3 state locking (
use_lockfile) became generally available. - 1.13 (August 2025): a
terraform stacksCLI command for HCP Terraform Stacks.
Both tools tackled secrets in state, but differently. OpenTofu encrypts the state. Terraform keeps certain values out of it. OpenTofu doesn't have ephemeral resources or write-only attributes yet, and Terraform doesn't have state encryption.
๐ฆ Registry and Provider Compatibility โ
Providers are the good news. They're separate plugins, most are still MPL-licensed, and they speak the same protocol. In practice, the AWS provider you use with Terraform works with OpenTofu too.
The registries are separate, though. In 2023, HashiCorp updated the Terraform Registry's terms to limit downloads to use with HashiCorp Terraform. So OpenTofu runs its own registry at registry.opentofu.org. When you write hashicorp/aws, each tool resolves it against its own registry. That's invisible for popular providers. For niche ones, check they're listed before you migrate.
The bigger catch is the language. Once a codebase uses encryption blocks or provider for_each, it's OpenTofu-only. Once it uses ephemeral resources, it's Terraform-only. Switching later gets harder with every feature you adopt.
๐งญ How I'd Choose โ
Stick with Terraform if:
- You use HCP Terraform or Terraform Enterprise, or you want Stacks.
- You need ephemeral resources and write-only attributes today.
- You want a commercial vendor behind your tooling.
Choose OpenTofu if:
- Open-source licensing and foundation governance matter to your organisation.
- You build a platform or product around IaC, which is where the BSL actually bites.
- You want client-side state encryption, early evaluation or provider
for_each. - You already use a third-party automation platform such as Spacelift, env0 or Scalr. All three backed the fork.
If you're still on Terraform 1.5.x, migrating is easy because the code is close to identical. Follow the official migration guide, back up your state, and run a plan before anything else.
๐ฏ Conclusion โ
Two years on, neither tool is the obvious winner. They're siblings growing apart. For a new project I'd lean towards OpenTofu for the licence and state encryption, unless I were already invested in HCP Terraform. Whichever you choose, pick one per codebase. The "works with both" window is closing.