A constraint allowing Terraform 1.6
Past the fork point, so state may not come back
terraform {
required_version = ">= 1.6.0"
}Find out what actually has to change to run OpenTofu. Usually the configuration needs no edits at all, and the lock file, the state and where runs happen are the whole job.
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.
The answer appears here
Paste on the left and press Check. Nothing leaves this tab.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.
Past the fork point, so state may not come back
terraform {
required_version = ">= 1.6.0"
}The one thing that does not port, and it decides the shape of the whole migration
terraform {
cloud {
organization = "acme"
workspaces {
name = "prod"
}
}
}At the fork point, so state moves both ways while you decide
terraform {
required_version = "~> 1.5.0"
backend "s3" {
bucket = "my-state"
}
}These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
State written by Terraform 1.6 or later may not be readable by OpenTofu, and once OpenTofu writes it, Terraform may refuse it. There is no downgrade path.
Instead:Run terraform state pull > before-tofu.tfstate and keep it. It is the only way back.
Its entries are keyed by registry.terraform.io, and OpenTofu resolves unqualified providers against its own registry, so the entries do not match what it installs.
Instead:Delete it, run tofu init, then tofu providers lock with a -platform flag per platform, and commit the result.
It is the HCP Terraform integration, so state and runs both live there. It is not a line to edit, it is where the whole migration is decided.
Instead:Move to a standard backend first, as its own migration, then change tools.
Moving is generally straightforward. Coming back is the part with no guarantee, and the fork point is why.
Both projects understand state at the 1.5 format. State written by Terraform 1.6 or later can use format details OpenTofu does not know, and once OpenTofu has written the state, Terraform may refuse it in turn. Take a copy before the first apply with either tool: that file is the only route back.
OpenTofu 1.6, 1.7 and 1.8 are not Terraform 1.6, 1.7 and 1.8, and each has features the other does not. So required_version = ">= 1.6.0" is satisfied by both and no longer tells a reader which tool the configuration needs. Say which one the repository targets in its README and enforce it in CI, because the constraint cannot.
Every entry is keyed by a full address such as registry.terraform.io/hashicorp/aws, and OpenTofu resolves unqualified providers against registry.opentofu.org instead. Delete the file, run tofu init, then run tofu providers lock with a -platform flag for every platform you use, because a fresh init records only the one it ran on.
The cloud block is the HCP Terraform integration: state, runs and policy all live there, and OpenTofu is not that. If you have one, work out where state and runs will live before anything else, and treat moving to an S3 or GCS backend as its own migration to do first.
S3, GCS, azurerm and the rest are the same in both projects with the same arguments. State encryption and for_each on a provider block are OpenTofu features with no Terraform equivalent, so adopting them closes the door: fine once the decision is made, worth avoiding while it is still a trial.
The command is tofu, .terraformrc becomes .tofurc and terraform.d becomes tofu.d, with the old names still read as a fallback. TF_VAR_, TF_LOG and the rest are unchanged, which is why a half-migrated pipeline can look like it is working. Search for the terraform command rather than the word, and check every wrapper script and Makefile target.