In this lesson we cover provider versions and version constraints in OpenTofu. Providers are published to the public registry and distributed as plugins. By default, runningDocumentation Index
Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
Use this file to discover all available pages before exploring further.
tofu init downloads the latest provider versions required by your configuration, but pinning or constraining versions is important to maintain reproducible, stable deployments.
Example resource
This simple example uses thelocal provider to write to a file:
Default behavior of tofu init
When you run tofu init, OpenTofu locates and installs provider plugins. By default it selects the latest compatible versions and records those selections in a lock file:
Include the generated .terraform.lock.hcl in version control to ensure consistent provider selection across runs and machines.
Pinning an exact provider version
To pin a provider to a single specific version, declare it in theterraform block using required_providers with source and version:
tofu init with that configuration installs the exact version you requested:
Using version constraints
If you want flexibility while still controlling upgrades, use version constraints. Theversion attribute accepts constraint expressions similar to common package managers.
Examples below show how to express different constraints while using the same local_file resource.
- Not-equal constraint (
!=)
- Less-than or greater-than constraints
- Combining constraints (comma-separated)
The pessimistic operator (~>)
The pessimistic operator~> is useful when you want to allow non-breaking updates but prevent potentially breaking ones. Its behavior depends on the specificity of the version you supply.
~> 2.2
~> 2.2 is equivalent to ”>= 2.2.0, < 3.0.0” — this permits any 2.x version at or above 2.2.0 (2.2.1, 2.3.0, 2.4.1, etc.) but prevents upgrades to 3.x.
~> 2.2.0
~> 2.2.0 is equivalent to ”>= 2.2.0, < 2.3.0” — this allows patch-level updates within the 2.2 series, but not newer minor versions (2.3.x or later).
Quick reference: constraint operators
| Operator | Meaning | Example |
|---|---|---|
| exact | Pin to a single version | version = "2.3.0" |
| != | Exclude a specific version | version = "!= 2.4.1" |
| <, <=, >, >= | Range comparisons | version = "< 2.4.1" |
| , (comma) | Combine multiple constraints | version = "> 2.2.3, < 2.4.1" |
| ~> | Pessimistic operator (allow compatible updates) | version = "~> 2.2.0" |
Best practices
- Use an exact version when you require strict reproducibility across environments.
- Use range comparisons or the pessimistic operator to permit safe, non-breaking updates while avoiding unintended major upgrades.
- Exclude known-broken versions with
!=when necessary. - Always commit
.terraform.lock.hclto version control so subsequent runs use the same provider selections.
When adjusting provider constraints, test upgrades in a staging environment before applying changes in production. Provider releases can introduce behavior changes even when the API surface looks compatible.
Links and references
- OpenTofu CLI plugins and provider signing: https://opentofu.org/docs/cli/plugins/signing/
- OpenTofu documentation: https://opentofu.org/docs/
- Provider registry (examples and discovery): https://registry.opentofu.org/