[email protected]

How-to · Kubernetes

Migrate Terraform to OpenTofu: Guide with Compatibility Framework

Editorial note: Versions, commands and prices may change. Please verify critical steps independently before production use. This guide does not replace individual professional, legal or tax advice.

Provision Kubernetes clusters from Terraform or OpenTofu code? Terraform/OpenTofu is part of how we provision Kubernetes clusters on Hetzner and Proxmox. See Kubernetes on Hetzner

This guide describes how Terraform configurations can be moved to OpenTofu, which Terraform versions come into question and where migrations fail. As of October 2026: Terraform is at version 1.17.1 (28 October 2026), OpenTofu at 1.13.2 (21 October 2026). The basis is the primary sources: HashiCorp, the OpenTofu project, the Linux Foundation and the CNCF, retrieved on 28 October 2026. The article is neither legal advice nor a recommendation to switch, but a basis for decision and implementation.

Contents

What OpenTofu is and why the fork exists

OpenTofu is an open-source fork of Terraform under the MPL-2.0. On 10 August 2023 HashiCorp announced that it would move the licence of future releases from MPL 2.0 to the Business Source License 1.1 (BSL). Terraform 1.5.7 (7 September 2023) is still under MPL-2.0, 1.6.0 (4 October 2023) under the BSL. On 20 September 2023 the Linux Foundation announced the formation of OpenTofu, and OpenTofu 1.6.0 was released on 10 January 2024. Since 23 April 2025 the project has been part of the CNCF as a sandbox project.

The BSL permits production use as long as Terraform is not offered to third parties on a hosted or embedded basis in order to compete with the licensor's paid versions. The current LICENSE file names IBM as the licensor and treats products as competitive if they are offered for payment, including through paid support, and significantly overlap with IBM's paid versions. Internal use is explicitly not a competitive offering. Each version converts to MPL 2.0 four years after publication. Whether a specific use falls under the clause is a question for your legal department, not for this article.

Licence and project status compared

Terraform OpenTofu
Licence MPL-2.0 up to 1.5.x, BSL 1.1 from 1.6.0 MPL-2.0
Steward licensor according to LICENSE: IBM OpenTofu, a Series of LF Projects, LLC; CNCF sandbox since 23 Apr 2025
Current version 1.17.1 (28 Oct 2026) 1.13.2 (21 Oct 2026)
Latest minor releases 1.15.0 (29 Apr), 1.16.0 (26 Aug), 1.17.0 (21 Oct 2026) 1.11.0 (9 Dec 2025), 1.12.0 (14 May), 1.13.0 (30 Sep 2026)
Registry registry.terraform.io registry.opentofu.org
Support period not part of this evaluation 1.12 until 1 Feb 2027, 1.13 until 1 Aug 2027; for the series 1.14, which is not yet released, 1 Feb 2028 is planned

Sources: releases of Terraform and OpenTofu, support periods at the top of the changelogs of 1.12, 1.13 and main, OpenTofu FAQ.

Compatibility framework by Terraform version

The OpenTofu FAQ says: OpenTofu works with state files up to and including Terraform 1.5.x. For the versions after that, the documentation up to OpenTofu 1.9 had version-specific guides for Terraform 1.5 to 1.9, for example for Terraform 1.9. Each applies to a specific patch level (1.5.7, 1.6.6, 1.7.5, 1.8.2, 1.9.8); older patch levels have to be raised first. The guides yield the following framework:

Terraform version Entry with OpenTofu Required code changes according to the guide
1.5.7 (raise older versions to 1.5.7 first) 1.6.2 none
1.6.x 1.6.2 S3 backend: remove skip_s3_checksum, endpoints.sso and AWS_ENDPOINT_URL
1.7.x 1.7.1 additionally removed block without lifecycle (OpenTofu behaves differently), mock overrides in tests
1.8.x 1.8.2 additionally replace the functions encode_tfvars, decode_tfvars, encode_expr
1.9.x 1.9.0 additionally variable validation without references to other variables
1.10 to 1.17 no version-specific guide general guide: a tofu plan without changes decides

The guides recommend switching to the matching OpenTofu version first and updating to the current series afterwards. For Terraform 1.10 and later, only the general guide has existed since OpenTofu 1.10. Features that Terraform introduced after 1.9 have to be checked individually: the changelogs of OpenTofu 1.10 to 1.13 list no counterpart to the action blocks and to list resources with terraform query from Terraform 1.14 (changelog) or to Terraform Policy, which became generally available in 1.17 (changelog). OpenTofu has supported ephemeral values and write-only attributes since 1.11.

OpenTofu features by version

Not every feature is a reason to migrate, but anyone who uses them makes the way back to Terraform harder. The table comes from the changelogs of the respective series; whether Terraform offers a counterpart is not part of the evaluation.

OpenTofu Date Features (selection)
1.6.0 10 Jan 2024 tofu test stable; registry registry.opentofu.org; cloud and remote without default hostname
1.7.0 30 Apr 2024 state and plan encryption; removed block; provider-defined functions
1.8.0 29 Jul 2024 variables and locals in module sources and backend configuration; .tofu files
1.9.0 9 Jan 2025 for_each for provider blocks; planning option -exclude
1.10.0 24 Jun 2025 OCI registries for modules and providers; S3 locking without DynamoDB
1.11.0 9 Dec 2025 ephemeral values and write-only attributes; enabled meta-argument
1.12.0 14 May 2026 language block for version constraints; h1 hashes from the registry in the lock file
1.13.0 30 Sep 2026 experimental: linting and symbol libraries

On state encryption, the documentation describes encryption at rest for local state and backends. The method is AES-GCM; keys come from a passphrase (PBKDF2), AWS KMS, GCP KMS, Azure Key Vault, OpenBao, OVHcloud KMS or an external program. The documentation sets limits: encryption does not protect against data loss or replay, and without the key the state is unreadable. Once data is encrypted, key providers and methods must not be renamed; changes go through fallback blocks. The documentation recommends a separate KMS key per state. Encryption can be removed through the unencrypted method.

Migration in seven steps

The steps follow the official guide and add checkpoints from the changelogs.

  1. Take inventory. Terraform version per configuration, providers, modules, backends, required_version, functions in use from the tables above, pipelines, and all configurations that use terraform_remote_state.
  2. Back up. Copy local state; for remote state use the backend's backup procedures (for example S3 versioning); commit the code to a migration branch; back up .terraform.lock.hcl as well. Actually test the restore once.
  3. Finish the Terraform state. Apply all changes with terraform apply; terraform plan shows no changes. According to the version-specific guides, pending changes during the migration are possible but not recommended.
  4. Install OpenTofu. Pick the version that fits the framework and check it with tofu --version. Both binaries stay available side by side until acceptance.
  5. Initialise. tofu init downloads providers and modules from the OpenTofu registry and initialises the backend. The lock file keeps the name .terraform.lock.hcl but contains entries of the form registry.opentofu.org/hashicorp/<provider>. Review the diff and commit it. Use -upgrade only deliberately, since it selects new provider versions.
  6. Check the plan, apply, test. tofu plan must show "No changes". If there are unexpected changes, do not apply; clarify the cause or go back. Then run tofu apply (it updates the state format if needed) and test a small, non-critical change.
  7. Switch CI/CD. GitHub Actions: opentofu/setup-opentofu with a pinned tofu_version. Change commands from terraform to tofu, reset caches for .terraform and providers, and test hooks, linters and policy checks for compatibility. Plan and apply run with the same tool; plan files are not handed over between terraform and tofu (assessment). Finally, update to the current OpenTofu series (upgrade guide).

Several dependent configurations

Systems made of several configurations that share data through terraform_remote_state follow a separate guide. The basis: OpenTofu reads Terraform state, but Terraform does not reliably read OpenTofu state, especially with OpenTofu-specific features. Therefore the migration runs from the bottom up: first the configurations that no other configuration reads, the roots last. For the transition period: avoid OpenTofu-specific features, bring all configurations to the same Terraform version beforehand and document which configuration runs on which tool.

Pitfalls

  • required_version: Terraform 1.17 and OpenTofu 1.13 are different version series. For modules that serve both tools, the documentation recommends a versions.tofu with the OpenTofu constraint and a versions.tf with the Terraform constraint. If .tf and .tofu files with the same name exist, OpenTofu loads only the .tofu file.
  • Registry: If a provider or module is missing from the OpenTofu registry, tofu init fails with Failed to query available provider packages or Module not found. The guide advises requesting the entry in the registry repository.
  • Lock file and platforms: If the pipeline runs on a different platform than the developer machine or obtains providers through a mirror, hashes of the target platform can be missing from the lock file. OpenTofu 1.12 records hashes for all supported platforms through the registry (h1); before that, tofu providers lock with the target platforms was the remedy of choice (lock file).
  • State addresses and namespaces: Since 1.6.0, OpenTofu treats provider addresses from registry.terraform.io in the state as registry.opentofu.org, which can be turned off with OPENTOFU_STATEFILE_PROVIDER_ADDRESS_TRANSLATION=0. Providers without a namespace receive opentofu instead of hashicorp; an explicit source in required_providers avoids surprises.
  • cloud and remote: Since 1.6.0 the hostname has to be specified explicitly; OpenTofu does not fall back to app.terraform.io. Functions tied to the Terraform vendor's platform need an alternative; the OpenTofu documentation points to TACOS platforms.
  • Missing functions in older OpenTofu series: The guides for Terraform 1.8 and 1.9 list encode_tfvars, decode_tfvars and encode_expr as unsupported. Since OpenTofu 1.10 the built-in provider terraform offers functions for encoding and decoding .tfvars and for encoding expressions.
  • Encrypted state: If you introduce encryption together with the migration, separate the two changes: migrate and accept first, then encrypt.

Rollback

The documentation describes the way back as follows: stop using OpenTofu, restore the state from the backup (if it was changed), run terraform init and terraform plan and check that no unexpected changes appear, then continue with Terraform. The version-specific guides additionally recommend testing the way back with a small, non-critical change. The more OpenTofu features are used, the closer the rollback gets to a restore from backup in which changes since the switch are lost (assessment). In practice: keep the backup state and lock file until acceptance, rehearse the way back on a non-critical configuration and use OpenTofu-specific features only after acceptance.

Checklist before the switch

  1. The Terraform version of each configuration is known and within the framework of the table.
  2. Functions in use have been checked against the guide for the version and the OpenTofu changelog.
  3. All providers and modules are available in registry.opentofu.org or mirrored.
  4. State backup and restore have been tested.
  5. required_version and file names (.tf or .tofu) are settled.
  6. Backends with cloud or remote have an explicit hostname.
  7. Configurations with terraform_remote_state are put in order (bottom up).
  8. The CI/CD image, caches, hooks and policy checks have been tested with tofu.
  9. The lock file contains the hashes of all target platforms.
  10. The rollback has been rehearsed on a non-critical configuration.
  11. The licence status of Terraform has been assessed by the legal department.
  12. Who decides on acceptance, and until when does Terraform remain available?

Status and methodology

The statements reflect the state as of 28 October 2026. Versions and dates come from the GitHub releases, licences from the LICENSE files of the repositories, features from the changelogs and documentation of the OpenTofu project. The Terraform columns rely on HashiCorp's releases, LICENSE and changelog. The table on Terraform versions takes over the version-specific guides of the OpenTofu documentation up to series 1.9; no such guide exists for newer Terraform versions. No migration was tested and nothing was measured. Assessments are labelled as such.

Sources, retrieved on 28 October 2026:

Our approach at WZ-IT

Terraform or OpenTofu is part of how we provision Kubernetes clusters, as described on the page Kubernetes on Hetzner. The guide Automate Talos on Proxmox with OpenTofu shows the setup with pinned provider versions, a protected state and acceptance. For your own team, this guide yields the following order: record configurations, backends, providers and pipelines, check the functions in use against the tables in this article and migrate one non-critical configuration as a trial. The remaining configurations follow from the bottom up, the pipelines are switched, and the rollback stays available until acceptance.

Have a cluster built from Terraform or OpenTofu code? Terraform/OpenTofu is part of how we provision Kubernetes clusters on Hetzner and Proxmox. Kubernetes on Hetzner · Automate Talos on Proxmox with OpenTofu

Rather have it operated?

You'd rather not run Kubernetes yourself? WZ-IT handles setup, operations and maintenance - privacy-focused from Germany.

Enquiry

Design, take over, or operate Kubernetes

We design and operate Kubernetes on bare metal, Proxmox, and European cloud platforms, including networking, GitOps, observability, and backups.

  • Straight with Timo and Robin - no sales team, no pitch
  • A professional assessment of your situation
  • Concrete next steps for infrastructure, software or AI

The conversation is free and non-binding.

WZ-IT supported us professionally with the provisioning and setup of NetBird. Alongside the technical implementation, we also received well-founded advice on connecting our Kubernetes clusters. The recommendations were concrete and directly actionable. The collaboration was consistently reliable, fast and on equal terms. We can recommend WZ-IT without reservation.
Kai ClaußHead of Development, SweetConnect GmbH
Timo and Robin, founders of WZ-IT

Design, take over, or operate Kubernetes

WZ-IT supported us professionally with the provisioning and setup of NetBird. Alongside the technical implementation, we also received well-founded advice on connecting our Kubernetes clusters. The recommendations were concrete and directly actionable. The collaboration was consistently reliable, fast and on equal terms. We can recommend WZ-IT without reservation.
Kai ClaußHead of Development, SweetConnect GmbH

Frequently Asked Questions

Answers to the most important questions

Knowledge

More on Kubernetes

Companies worldwide trust WZ-IT

  • Stadtwerke Brühl
  • DGHO e.V.
  • solarwerkstatt berlin
  • Krüger Dirndl
  • ABCO Water Systems
  • Golem.de
  • EVADXB
  • nextGYM
  • AInergy
  • ml&s
  • Odiseo Solutions
  • Annota
  • ARGE
  • SweetConnect GmbH
  • Aphy AG
  • CORGOS
  • Rekorder
  • SolidProof
  • Yonju
  • Keymate
  • Paritel
  • Mr. Clipart
  • Millenium
  • Negosh
  • Führerscheinmacher
  • BTI
  • Deutsche Gesellschaft für Datenschutz
Read client reviews