TerraformPilot

OpenTofu

OpenTofu Provider Registry: Sources, Mirrors, and Caching

How OpenTofu resolves providers from registry.opentofu.org, configures the registry, sets up filesystem mirrors for air-gapped environments, and caches...

LLuca Berton2 min read

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.

How provider resolution works

#

When you write:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.70"
    }
  }
}

OpenTofu resolves hashicorp/aws to a concrete download URL via:

  1. required_providers.<name>.source — the address. By default the host is registry.opentofu.org.
  2. tofu init — queries the registry's /v1/providers/<namespace>/<name>/versions endpoint for available versions.
  3. Version constraint — picks the highest version satisfying ~> 5.70.
  4. Download — fetches the platform-specific binary (linux_amd64, darwin_arm64, windows_amd64, etc.).
  5. Lock file — writes the resolved version and SHA-256 checksum to .terraform.lock.hcl.

Configuring an alternative registry

#

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.

Filesystem mirror (air-gapped)

#

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.json

Then 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.

Plugin cache (developer + CI speedup)

#

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 init

In 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 init

Cold-start init drops from ~60s to <5s on subsequent runs.

Lock file: pin every checksum

#

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_amd64

This prevents "works on my Mac, fails in CI Linux" hash mismatches. See Inconsistent dependency lock file for the same issue's symptoms in Terraform.

Private registries

#

OpenTofu speaks the standard registry protocol, so any tool that hosts Terraform providers also hosts OpenTofu providers:

  • Terraform Cloud / HCP Terraform — works as-is.
  • Spacelift / Scalr / env0 — works as-is.
  • JFrog Artifactory — supported via the terraform repository type.
  • GitLab — has a built-in Terraform module/provider registry.

Authenticate via ~/.tofurc:

credentials "registry.example.com" {
  token = "ghp_xxx"
}

Or via env: TF_TOKEN_registry_example_com=ghp_xxx.

Verifying provider authenticity

#

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'
#

Conclusion

#

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.

#OpenTofu#Terraform#Providers#Registry#Mirror

Share this article