A shared Terraform module is backward compatible when users can upgrade without changing the code that calls it. Breaking that expectation creates work for every dependent team, often without an immediate benefit to them. Preserve the module’s existing interface where practical, and treat unavoidable changes as planned migrations. section 9.6.1
Semantic versioning makes the upgrade risk visible: patch releases cover fixes, minor releases add features, and a major release signals a backward-incompatible change. For example, exposing additional resource parameters as variables can be a minor release; refactoring input variable names calls for a major release. section 8.1.1
Allow compatible module upgrades
A module constraint of `~> 1.1` admits versions from 1.1 up to, but not including, 2.0. It lets users receive minor and patch releases without automatically crossing a major-version boundary. By contrast, `~> 1.1.0` admits patch updates only. Choose the lowest version the module needs and avoid unnecessarily narrow constraints that can conflict with other modules. section 8.1.1
Table 8.2 Example constraints with their allowed versions (view table figure)
| Constraint |
Allowed versions |
|---|---|
| = 1.1.1 |
Only v1.1.1 is allowed. |
| >= 1.1.0, < 2.0.0 |
The minimum version is v1.1.0, and any Minor or Patch versions are allowed. Upgrading the Major version is not allowed. |
| >= 1.1.0, < 2.0.0, != 1.3.2 |
The same as above, except we’re also forbidding version v1.3.2 from being used. Excluding specific versions is useful when bugs are introduced to a specific version and then fixed. |
| ~> 1.1.0 |
The pessimistic constraint operator allows only the rightmost field to be upgraded. In this case, that means v1.1 and any bug fixes are allowed, but Minor and Major upgrades are excluded. |
| ~> 1.1 |
This sets the floor at v1.1, but since the rightmost value is the Minor field it allows Minor and Patch upgrades. It is the exact same as >= 1.1.0, <2.0.0 but is more concise. |
Compare exact, bounded, and pessimistic version constraints before choosing an upgrade range. section 8.1.1
Manage changes that cannot remain compatible:
- Use automated module tests to catch regressions and reveal breaking changes during review; update tests when bugs are found. section 9.0
- Break compatibility when necessary—for example, to replace insecure defaults, rename confusing variables, accommodate a breaking provider release, or enable functionality that requires a changed interface. section 9.6.1
- Where possible, group breaking changes into one release rather than repeatedly forcing users to update. A major provider upgrade can be a practical point to coordinate them. section 9.6.1
Compatibility also matters when choosing an engine. OpenTofu has remained compatible with Terraform code, and a Makefile can select `terraform` or `tofu` for the same commands and CI tests. Do not assume that compatibility works in both directions indefinitely: OpenTofu-only features can complicate a return to Terraform, while new Terraform features may reach OpenTofu later. section 1.6.5 section 7.2.4

















