Skip to main content
BlogDevOps

OpenTofu vs Terraform: Migrating After the License Change

After HashiCorp's BSL relicense, is switching to OpenTofu worth it? A hands-on look at compatibility, state, the registry, and the actual migration commands.

Matthews Wong

Software Engineer

July 20269 min read
OpenTofu vs Terraform: Migrating After the License Change

Photo by Collins, Tudor Washington, 1898-1970, photographer via Wikimedia Commons (CC BY 4.0)

Key Takeaway

OpenTofu is a drop-in, MPL-licensed fork of Terraform. State files are binary-compatible with Terraform 1.5.x in both directions, providers resolve from the same names, and most migrations are a binary swap plus tofu init -upgrade and a zero-change plan. Enabling OpenTofu state encryption is the one one-way door.

In August 2023 HashiCorp relicensed Terraform from the MPL 2.0 open-source license to the Business Source License. The BSL is not open source: it restricts anyone from offering a competing product built on the code. The community forked the last MPL version, and that fork became OpenTofu, now governed under the Linux Foundation. Three years on, the question every platform team eventually asks is simple: do I stay on Terraform, or move to OpenTofu, and what does moving actually cost me?

I run my own infrastructure as code on a self-hosted VPS fleet, and I went through this evaluation for real. The short version: for most teams the license risk is the only argument that matters, and OpenTofu removes it without asking you to relearn the tool. But there are real caveats around state, the registry, and the point where the two projects have genuinely diverged. Here is what actually happens when you switch.

The license is the real reason to move

Terraform's BSL means you cannot build a commercial product that competes with HashiCorp using their code, and the exact boundary of what counts as competing is deliberately vague. For a company just provisioning its own cloud, this rarely bites in practice. But it is a compliance question your legal team will eventually raise, and it is a real blocker if you sell any kind of platform or managed service. OpenTofu is MPL 2.0, an OSI-approved license with no such clause. If license certainty matters to you, that alone settles the decision. Everything below is about how painless the switch is once you have decided.

Compatibility: it really is a drop-in replacement

OpenTofu forked from Terraform 1.5.x, so the HCL syntax, module structure, provider protocol, and command surface are identical. Your existing .tf files, your modules, your variable files, all of it works unchanged. The CLI is named tofu instead of terraform, but the subcommands (init, plan, apply, destroy, state) are the same. In most projects the only edit you make is renaming the binary you invoke in CI. Providers are the big compatibility win: the same provider binaries serve both engines, and shorthand addresses like hashicorp/aws resolve automatically.

Do not delete the terraform binary on day one. Keep both installed during migration so you can run terraform plan and tofu plan side by side and diff the output. A clean zero-change plan from tofu against your existing state is your proof the swap was transparent.

State files: compatible in both directions, with one exception

This is the part people worry about most, and the good news is that state format is binary-compatible between Terraform 1.5.x and OpenTofu in both directions. You point OpenTofu at your existing state file, whether it lives in an S3 backend, a GCS bucket, or a local file, and it reads it directly. No state migration command, no conversion step, no re-import. That is why a well-behaved migration ends in a plan showing zero changes: OpenTofu sees exactly the resources Terraform recorded.

The one-way door is state encryption. OpenTofu can encrypt state and plan files at rest with your own keys, a feature Terraform's open CLI does not have. Once you enable it, those files are unreadable to Terraform. If you turn on encryption you are committed to OpenTofu, so decide that deliberately and only after the plain migration is verified.

The migration, step by step

Here is the actual sequence I use for a single project. It backs up state first, keeps the state backend untouched, and verifies with a plan before anything is applied. On a small project this is genuinely a five-minute job; the afternoon-long variants come from hardcoded binary names in wrapper scripts, lock-file churn, and CI runner images that still ship only terraform.

  1. Back up your state file (pull a copy from the remote backend) and commit your .tf code so you have a clean rollback point.
  2. Install the tofu binary alongside terraform; do not remove terraform yet.
  3. Run tofu init -upgrade to pull providers from the OpenTofu registry and refresh the dependency lock file.
  4. Run tofu plan and confirm it reports zero changes against your existing state.
  5. Update your CI pipeline and any wrapper scripts to call tofu instead of terraform, then run the pipeline end to end.
  6. Only after a full green run, retire the terraform binary. Consider enabling state encryption as a separate, later change.
# 1. Back up remote state before touching anything
terraform state pull > terraform.tfstate.backup

# 2. Confirm both binaries are available
terraform version   # e.g. Terraform v1.14.x
tofu version        # e.g. OpenTofu v1.12.x

# 3. Re-init with OpenTofu, refreshing provider lock
tofu init -upgrade

# 4. The proof: this MUST say "No changes"
tofu plan

# Expected tail of output:
#   No changes. Your infrastructure matches the configuration.

# 5. If a provider is not on the OpenTofu registry, pin it
#    explicitly to the Terraform registry in required_providers:
#
#    source = "registry.terraform.io/namespace/name"

Registry: same names, different default host

Terraform pulls providers and modules from registry.terraform.io; OpenTofu defaults to registry.opentofu.org. The OpenTofu registry mirrors the major providers you already use (AWS, AzureRM, Google, and thousands more) and resolves the same shorthand source addresses, so most configs need no change. When a provider is not yet published to the OpenTofu registry, you override the source to the fully-qualified Terraform registry address in your required_providers block. OpenTofu 1.10 also added OCI registry support, letting you host providers in a standard container registry, which is handy for air-gapped or tightly-controlled environments.

Where the two have diverged

For the first couple of years the projects tracked each other closely. In 2026 they have genuinely diverged: OpenTofu ships CLI features Terraform's open binary does not have. State and plan encryption arrived in 1.7, early variable evaluation (including in backend configuration) in 1.8, provider iteration with for_each and the -exclude targeting flag in 1.9, and OCI registry support in 1.10. If any of those solve a real problem for you, that is now a reason to move beyond just the license. Conversely, Terraform's paid HCP Terraform platform and its Stacks feature remain HashiCorp's own, so a team deeply invested in that managed tooling has a reason to stay.

OpenTofu vs Terraform at a glance

DimensionOpenTofuTerraform
LicenseMPL 2.0, OSI-approved open sourceBusiness Source License (not open source)
GovernanceLinux Foundation, multi-vendorHashiCorp (IBM-owned)
State file formatBinary-compatible with Terraform 1.5.x both waysSame base format (fork origin)
State encryptionBuilt in since 1.7 (one-way once enabled)Not in the open CLI
Default registryregistry.opentofu.org (+ OCI, + TF registry fallback)registry.terraform.io
Migration effortBinary swap + tofu init -upgrade + zero-change planN/A (source)

My recommendation

For a new project, or any team without a hard dependency on HCP Terraform, I default to OpenTofu. The license certainty is free, the extra CLI features are real, and the migration is close to a no-op. For an established Terraform shop, treat it as a low-risk, high-value move: migrate one non-critical project first, prove the zero-change plan, update CI, then roll the pattern out. Leave state encryption as a deliberate second step, because that is the only decision you cannot easily walk back. The compatibility promise is not marketing here; it genuinely held up when I ran it.

FAQ

Frequently Asked Questions

Short answers to what readers ask most about this topic.

Is OpenTofu fully compatible with Terraform?

For the forked baseline (Terraform 1.5.x), yes: the HCL syntax, module structure, provider protocol, and state file format are identical, and the same provider binaries work with both. Most projects migrate with no source changes at all. The two have diverged since 2026, though, so OpenTofu-only features like state encryption are not portable back to Terraform.

Do I need to migrate my Terraform state file to use OpenTofu?

No. State files are binary-compatible between Terraform 1.5.x and OpenTofu in both directions. You point OpenTofu at your existing state, whether local or in a remote backend, and it reads it directly. A correct migration ends with a plan showing zero changes.

What is the actual command to migrate from Terraform to OpenTofu?

After backing up your state, install the tofu binary and run tofu init -upgrade in the project directory, then tofu plan. The init pulls providers from the OpenTofu registry and refreshes the lock file, and the plan should report no changes against your existing state. Then update your CI to call tofu instead of terraform.

Can I switch back from OpenTofu to Terraform if I change my mind?

Yes, in the general case, because state stays binary-compatible in both directions. The one exception is OpenTofu's state encryption: once you encrypt state and plan files, Terraform can no longer read them. Treat enabling encryption as a committed, one-way decision made separately from the initial migration.

Why did Terraform change its license and what is the BSL?

In August 2023 HashiCorp moved Terraform from the open-source MPL 2.0 to the Business Source License, which restricts building competing commercial products on the code and is not OSI-approved open source. The community forked the last MPL release into OpenTofu, now governed under the Linux Foundation with an MPL 2.0 license. For teams selling platforms or managed services, that license difference is usually the deciding factor.