Skip to content

OpenTofu

OpenTofu is a community-driven, open-source fork of Terraform created in response to HashiCorp’s 2023 license change. It is designed as a drop-in replacement - the same language, the same workflow, the same providers - but governed by the Linux Foundation instead of a single company.


Terraform launched under the Mozilla Public License (MPL), granting users freedom to view, modify, and distribute the code. This open foundation fostered a massive community that built essential providers, documentation, testing frameworks, and modules - all of which drove Terraform’s adoption.

By 2021, however, HashiCorp had shifted its focus inward, updating contributor guidelines to state it would no longer review external pull requests for the core Terraform project.

Starting with Terraform v1.6, HashiCorp moved the core software to the Business Source License (BSL) - a proprietary “shared source” license. The code remains publicly viewable, but the BSL prohibits building hosted or embedded products that compete with HashiCorp’s commercial offerings.

What changedWhat stayed open-source
Terraform core (v1.6+)Terraform providers
Vault, Consul, NomadIndividual HashiCorp libraries

The reaction was overwhelmingly negative. A coalition of 150+ companies, 11 software projects, and 750+ individual developers published a manifesto demanding HashiCorp reverse the decision - with the ultimatum that the project would be forked if HashiCorp refused to negotiate.

HashiCorp did not respond. The community followed through.

OpenTofu was created as a direct fork of Terraform’s last MPL-licensed version. It launched with significant backing:

BackerCommitment
Scalr, env0, Spacelift, HarnessFunded 18 dedicated developers for at least 5 years
GruntworksPledged development support
Linux FoundationGoverns the project (with goals to join the CNCF)

The project operates transparently with a public RFC (Request for Comments) system - anyone can submit feature proposals.


OpenTofu’s tofu CLI mirrors the exact commands of the terraform CLI. Users can alias the command and use it seamlessly:

Terminal window
alias terraform=tofu

OpenTofu has begun implementing community-requested features that Terraform historically ignored, making it a superset of Terraform:

DirectionDifficulty
Terraform → OpenTofuStraightforward migration
OpenTofu → TerraformPotentially difficult if the project uses OpenTofu-specific features

Because Terraform is no longer open source, many package managers stopped distributing versions beyond v1.5.7:

PlatformTerraformOpenTofu
Homebrew (macOS)❌ Stopped at v1.5.7✅ Available
Linux distributions❌ Stopped at v1.5.7✅ Available
Chocolatey (Windows)⚠️ Varies✅ Available

Introduced in OpenTofu v1.8, tofu files let module developers write a single codebase compatible with both engines while safely using OpenTofu-exclusive features:

EngineReads .tfReads .tofuOverride behaviour
Terraform❌ Ignores completely-
OpenTofuIf name.tofu exists alongside name.tf, OpenTofu uses .tofu and ignores .tf

Example - engine-specific configuration:

# compatibility.tf (used by Terraform)
locals {
engine = "terraform"
}
# compatibility.tofu (used by OpenTofu - overrides compatibility.tf)
locals {
engine = "opentofu"
}

Terraform reads compatibility.tf and sets engine = "terraform". OpenTofu detects the matching filename, ignores the .tf file, and reads compatibility.tofu instead.


Manually configuring quality-control tools and CI pipelines from scratch for every project is error-prone and inconsistent. Use template repositories for boilerplate, or Cookiecutter for dynamic scaffolding:

Terminal window
cookiecutter gh:org/terraform-template

Cookiecutter prompts for inputs (project name, license, cloud provider) and generates customised project files.

The Terraform ecosystem uses dozens of commands that developers shouldn’t need to memorise. Abstract them behind simple Make targets:

.PHONY: format validate lint test
format:
$(TF_ENGINE) fmt -recursive
validate:
$(TF_ENGINE) validate
lint:
tflint --recursive
test:
$(TF_ENGINE) test

Make is highly portable, supports target grouping (make tests triggers a sequence), and works identically locally and in CI.

Define a TF_ENGINE variable in your Makefile to swap engines without changing code:

TF_ENGINE ?= terraform
format:
$(TF_ENGINE) fmt -recursive

Override at the command line to test compatibility:

Terminal window
make format TF_ENGINE=tofu

tenv is a version manager for Terraform, OpenTofu, and Terragrunt:

  • Intercepts calls to terraform or tofu and routes to the correct version binary
  • Reads .terraform-version or .opentofu-version files in the project directory
  • Supports exact versions, constraint ranges, or latest-allowed for testing minimum/maximum supported ranges

Makefiles can detect the user’s OS package manager and install required tools:

install:
ifeq ($(shell uname -s),Darwin)
brew install tflint checkov tenv
else
# Linux package manager commands
sudo apt-get install -y tflint checkov
endif

Pre-commit hooks run automatically before every git commit. If a check fails, the commit is blocked:

.pre-commit-config.yaml
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
hooks:
- id: terraform_fmt
- id: terraform_validate
- id: terraform_tflint

Use what your organisation already has. Terraform doesn’t require a specialised CI system. GitHub Actions and GitLab Pipelines are recommended because they integrate directly with your SCM.

Every CI job follows the same pattern:

  1. Check out the project repository
  2. Install task-specific dependencies
  3. Run the checks (using the same Makefile commands as local development)

If any step fails, the workflow fails and the PR is flagged.

Validating Both Engines with Matrix Strategies

Section titled “Validating Both Engines with Matrix Strategies”

Use a matrix strategy to test the same code across both engines and multiple versions simultaneously:

.github/workflows/ci.yml
strategy:
matrix:
engine: [terraform, opentofu]
version: ["1.6", "1.7", "1.8"]

This runs the full test suite across every combination. For alpha/beta versions, use continue-on-error: true so experimental failures don’t block the PR.

Configure branch protection rules in your SCM to prevent merging unless:

  • All automated CI tests pass
  • The code receives peer review approval (at least one reviewer)

Emergency overrides are available for administrators during severe outages or broken CI pipelines.

Dependabot automates version bumps for GitHub Actions, providers, and modules:

.github/dependabot.yml
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "terraform"
directory: "/"
schedule:
interval: "weekly"

When an update is found, Dependabot opens a PR automatically - the CI pipeline reveals whether the bump breaks anything.


ScenarioRecommendation
New projects with no existing Terraform investmentOpenTofu - open-source, actively governed, widely available in package managers
Existing projects on Terraform ≤ v1.5OpenTofu - seamless migration; avoids BSL restrictions
Teams using HCP Terraform (Terraform Cloud)Terraform - HCP doesn’t support OpenTofu
Teams needing the absolute newest HashiCorp featuresTerraform - OpenTofu may lag slightly on Terraform-originated features
Organisations building products on top of IaCOpenTofu - BSL prohibits competing products built on Terraform
Teams wanting community-driven governanceOpenTofu - Linux Foundation governance, public RFC process
Self-hosted CD platforms (Atlantis, Terrakube)Either - self-hosting legally permits both