How to Install OpenTofu on macOS, Linux, and Windows
Step-by-step guide to install OpenTofu on macOS (Homebrew), Linux (apt, dnf, rpm), and Windows (Chocolatey, Scoop). Includes verification, version pinning...
OpenTofu
How OpenTofu resolves providers from registry.opentofu.org, configures the registry, sets up filesystem mirrors for air-gapped environments, and caches...
OpenTofu maintains its own provider registry at registry.opentofu.org,
mirroring HashiCorp's registry.terraform.io for community providers and
hosting OpenTofu-specific releases. This guide covers how providers are
resolved, how to configure mirrors, and how to keep CI builds fast and
deterministic.
When you write:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.70"
}
}
}OpenTofu resolves hashicorp/aws to a concrete download URL via:
required_providers.<name>.source — the address. By default the host
is registry.opentofu.org.tofu init — queries the registry's /v1/providers/<namespace>/<name>/versions
endpoint for available versions.~> 5.70.linux_amd64, darwin_arm64, windows_amd64, etc.)..terraform.lock.hcl.You can point at any registry, including registry.terraform.io or a
private one, via the source address:
required_providers {
aws = {
source = "registry.terraform.io/hashicorp/aws"
version = "~> 5.70"
}
}For organisation-wide overrides, use the CLI config file
~/.tofurc (Linux/macOS) or %APPDATA%\opentofu.rc (Windows):
provider_installation {
network_mirror {
url = "https://providers.example.com/"
}
direct {
exclude = ["hashicorp/*"]
}
}This mirrors all providers and avoids talking to the public registries directly — required by many compliance regimes.
For air-gapped CI runners or strict change-control environments, build a filesystem mirror once and ship it with the build agents:
tofu providers mirror /srv/tofu-mirror
ls /srv/tofu-mirror/registry.opentofu.org/hashicorp/aws/
# 5.70.0/ index.json versions.jsonThen point the runners at it:
# ~/.tofurc on every CI agent
provider_installation {
filesystem_mirror {
path = "/srv/tofu-mirror"
include = ["*/*"]
}
direct {
exclude = ["*/*"]
}
}tofu init now installs offline.
For local work and CI, set a shared cache directory so providers are downloaded once and re-used:
export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache"
mkdir -p "$TF_PLUGIN_CACHE_DIR"
tofu initIn GitHub Actions:
- name: Cache OpenTofu plugins
uses: actions/cache@v4
with:
path: ~/.terraform.d/plugin-cache
key: tofu-plugins-${{ hashFiles('**/.terraform.lock.hcl') }}
- name: Init
env:
TF_PLUGIN_CACHE_DIR: ~/.terraform.d/plugin-cache
run: tofu initCold-start init drops from ~60s to <5s on subsequent runs.
OpenTofu writes .terraform.lock.hcl automatically. Always commit it:
provider "registry.opentofu.org/hashicorp/aws" {
version = "5.70.0"
constraints = "~> 5.70"
hashes = [
"h1:abc...",
"zh:def...",
]
}Refresh checksums for additional platforms before merging:
tofu providers lock \
-platform=linux_amd64 \
-platform=darwin_arm64 \
-platform=darwin_amd64 \
-platform=windows_amd64This prevents "works on my Mac, fails in CI Linux" hash mismatches. See Inconsistent dependency lock file for the same issue's symptoms in Terraform.
OpenTofu speaks the standard registry protocol, so any tool that hosts Terraform providers also hosts OpenTofu providers:
terraform repository type.Authenticate via ~/.tofurc:
credentials "registry.example.com" {
token = "ghp_xxx"
}Or via env: TF_TOKEN_registry_example_com=ghp_xxx.
OpenTofu providers signed by HashiCorp keep their original signatures,
verified at download. Community-maintained providers in the OpenTofu
registry use the OpenTofu signing key. tofu providers schema -json
exposes the registry origin so you can audit:
tofu providers schema -json | jq '.provider_schemas | keys'OpenTofu's provider story mirrors Terraform's, with the bonus of an
independent, MPL-licensed registry. For air-gapped or compliance-heavy
shops, filesystem mirrors and tofurc overrides give you full control over
where binaries come from. Combined with the lock file and plugin cache, you
get fast, reproducible, auditable provisioning.
Step-by-step guide to install OpenTofu on macOS (Homebrew), Linux (apt, dnf, rpm), and Windows (Chocolatey, Scoop). Includes verification, version pinning...
OpenTofu's early evaluation lets you use variables and locals in backend configuration, module sources, and required_providers — features Terraform doesn't...
Configure OpenTofu's built-in state encryption to protect sensitive values at rest. AES-GCM with PBKDF2 or AWS KMS / GCP KMS / Azure Key Vault key providers.
Fix Terraform provider version conflicts between modules, lock files, and constraint mismatches. Resolve dependency lock errors, upgrade providers safely