Request an exact quote
IaC & Secrets migration path

From HashiCorp Terraform to OpenTofu

Why OpenTofu exists, why the switch is mostly a CI/CD and version-pinning exercise, and the state, registry, and version-drift details to get right.

Effort
Low
Est. timeline
~12 wks
OpenTofu model
Free (open source)
Open source
Yes
▶ Model your savings in the interactive calculator

In August 2023 HashiCorp relicensed Terraform from the open-source MPL to the Business Source License (BSL), which restricts competing commercial use. The community responded by forking the last MPL version into OpenTofu, now a Linux Foundation project under a permissive license. OpenTofu is a deliberate drop-in replacement, which makes this the lowest-risk migration on this site: for most teams it’s a tooling swap, not a rewrite.

Why teams move

The driver is licensing, not features. Vendors and platforms that build on Terraform faced redistribution risk under the BSL; many users simply want to stay on genuinely open-source IaC. OpenTofu keeps the same HCL language, the same workflow, and a compatible state format, so the cost of switching is low and the cost of not switching is mostly governance and supply-chain risk.

There is a second, quieter driver: cost at scale. HCP Terraform prices on a per-resource basis, so large estates can see the bill climb as managed resource counts grow. OpenTofu itself is a Linux Foundation project with no per-resource licensing, which removes that variable entirely. If you are running your own state backend and CI, the ongoing cost of OpenTofu is the infrastructure you already own. Use the calculator above to compare your current HCP posture against a self-hosted OpenTofu setup before you assume the savings, and confirm any commercial-support arrangements separately, since community-governed does not mean vendor-supported.

What stays the same

  • The language. Your .tf files, modules, the terraform {} block, and provider/resource syntax are unchanged.
  • State. OpenTofu reads existing Terraform state; the format is compatible.
  • Providers and modules. OpenTofu uses its own public registry but resolves the same providers (the major clouds, Kubernetes, etc.) and modules.
  • The workflow. init, plan, apply, destroy, same commands, under the tofu binary.

The migration, step by step

  1. Install the tofu CLI and pin a specific version in CI and in developer tooling.
  2. Back up state (or rely on remote-backend versioning) before the first run, standard hygiene.
  3. Run tofu init in a workspace, then tofu plan and confirm it reports no changes against current infrastructure. A clean, empty diff is your proof of parity.
  4. Update CI/CD to call tofu instead of terraform, and refresh any wrappers (Atlantis, Terragrunt, pipelines) to the OpenTofu binary.
  5. Apply through the new pipeline and watch the first few runs closely.

Because state and HCL are compatible, there is no data migration, the work is swapping the binary everywhere it’s invoked and proving plan parity.

Handing state over without moving it

The phrase “migrating state” undersells what happens here, because the whole point of the fork is that the state format carries over untouched. What actually moves is which binary is authoritative for that state. The safe sequence is: freeze changes to the workspace, run tofu init against the existing backend so OpenTofu records itself as the tool of record, run tofu plan, and read the diff carefully. A truly empty diff, no adds, no changes, no destroys, is the signal that OpenTofu sees your infrastructure exactly as Terraform did.

If the plan is not empty, do not apply it. A non-empty diff usually means one of three things: a provider resolved to a different version under OpenTofu’s registry, a lock file that was not regenerated, or HCL that used a Terraform-version-specific behavior. Investigate the diff line by line rather than accepting it. For remote backends, the state object itself does not need to be copied; both tools read the same backend. For local state, back up the .tfstate file first as a matter of course, even though you expect not to need it.

The three buckets

To keep the two columns clear:

  • Unchanged: your HCL, modules, the resource graph, remote backend configuration, and the state file itself.
  • Changed: the binary name (tofu in place of terraform), the provider lock file and mirrors, and every place your CI, wrappers, and developer docs invoke the tool.
  • Watch closely: version pins on both the CLI and providers, and any workflow that assumed a Terraform-only feature.

Version drift is the one real catch

OpenTofu forked from Terraform around the 1.5/1.6 line and the two have diverged since. OpenTofu added features such as state encryption, early variable evaluation, and provider-defined functions on its own timeline; Terraform has added features on its. Practical implications:

  • Pin versions on both sides. Don’t let a terraform block’s required_version or a provider lock drift between tools.
  • Mind the lock file. .terraform.lock.hcl and provider mirrors should be regenerated under OpenTofu so hashes match its registry.
  • Avoid mixing tools on one state. Pick OpenTofu per workspace and stay there; round-tripping between newer Terraform and OpenTofu can introduce features the other can’t read.
  • Terraform Cloud/HCP users: OpenTofu works with most standard backends, but HCP/TFC-specific workflows differ, plan that backend separately.

CI/CD and validation

Most of the real work lives in the pipeline, because that is where the binary is invoked dozens of times a day. Inventory every place the string terraform appears: pipeline steps, Makefiles, pre-commit hooks, wrapper tools like Terragrunt or Atlantis, and any container image that bakes in the CLI. Swap each to the pinned tofu binary. Pinning matters more than usual here: because the forks diverge, an unpinned CLI can silently pull a newer OpenTofu that introduces a feature your state or teammates cannot read.

A low-risk way to prove parity before you commit is to run OpenTofu alongside Terraform in CI for a cycle. Have the pipeline generate a tofu plan next to the existing terraform plan and diff the two. When the OpenTofu plan is a consistent no-op across several runs and several workspaces, flip the default. This gives you evidence rather than faith, and it surfaces provider or lock-file drift while the incumbent is still authoritative.

Backing out

Rollback is about as simple as it gets on this path. Because the state format is shared, reverting is a matter of pointing CI and developers back at the terraform binary and the previous lock file. There is no state to un-migrate. Keep the pre-cutover state snapshot and the original .terraform.lock.hcl until you have several clean OpenTofu applies in production, then retire them.

A note on the siblings

The same BSL change hit Vault and Consul, whose open forks are OpenBao (Vault) and community alternatives for Consul. If you adopted OpenTofu for licensing reasons, it’s worth auditing the rest of your HashiCorp footprint for the same exposure.

The short version

Terraform → OpenTofu is mostly mechanical: install the binary, pin versions, run tofu plan to confirm an empty diff, and swap CI/CD over. The only thing to watch is version drift between the two forks, pin deliberately and don’t straddle both on one state. There’s no per-resource licensing to model here, but use the calculator above to weigh the broader IaC and secrets footprint, and confirm any commercial support assumptions before you commit.

Tooling & automation for this path

OpenTofu is a drop-in fork, pin the OpenTofu CLI, migrate state (format-compatible), update provider mirrors and CI/CD; diff plans to confirm parity before cutover.

Primary references: official OpenTofu documentation ↗ and the HashiCorp Terraform documentation ↗ , always verify version-specific behavior against them before you migrate.

Frequently asked questions

Is OpenTofu state actually compatible with existing Terraform state?

Yes. OpenTofu reads and writes the same state format as the Terraform version it forked from, so there is no state conversion step. You point tofu at your existing backend and state file, and a clean tofu plan should report no changes. Keep a state snapshot or rely on remote-backend versioning before the first run as normal hygiene.

Do I need to change my providers or the registry OpenTofu pulls them from?

OpenTofu resolves the same providers (the major clouds, Kubernetes, and so on) but uses its own public registry. Regenerate the .terraform.lock.hcl lock file and refresh any provider mirrors under OpenTofu so the recorded hashes match its registry. The provider and resource syntax in your .tf files does not change.

Can I run Terraform and OpenTofu against the same state at the same time?

Avoid it. The two forks have diverged since the split, and newer features on either side (state encryption, provider-defined functions, and others) can write state or config the other cannot read. Pick one tool per workspace and stay there rather than round-tripping between them.

Does OpenTofu work with Terraform Cloud and HCP backends?

OpenTofu works with most standard remote backends, but HCP Terraform and Terraform Cloud specific workflows differ and should be planned separately. If you rely on TFC-native features, validate that path on its own before assuming parity, and confirm any commercial support assumptions before you cut over.

Model your 3-year cost

Pre-filled for HashiCorp Terraform → OpenTofu; adjust every figure with your own numbers. Estimates are illustrative, not vendor quotes, see our methodology.

Sized at 3,000 managed resources, cost is computed on this.
Stay on HashiCorp Terraform (3yr)
$162,000
Move to OpenTofu (3yr + migration)
$48,000
Projected savings
$114,000 (70%)
Payback period
10.7 mo
Build a decision report from these numbers:

Illustrative, editable figures, not vendor pricing (defaults reviewed May 2026).

Request a vendor-accurate OpenTofu quote

A guided builder that turns your estimates into a requirements report (RFQ) you can send to a vendor, partner, or distributor for a binding quote, then feed the real prices back into the calculator above. How our estimates work.

  1. 1Size it
  2. 2Requirements
  3. 3Your details
  4. 4Channels & export

How big is your HashiCorp Terraform estate?

Approximate count of IaC-managed resources / secrets clients. Not sure? Enter rough numbers, the distributor confirms exact counts later.

3,000 managed resources
Default mid-size assumption (3,000 managed resources)