TerraformVI · Providers and the Provider EcosystemProduction Terraform
Provider Sources and Registries
What you'll learn
- Read and write a provider source address in the canonical three-part form
- Distinguish the public registry, a private registry, and a filesystem mirror
- Configure `provider_installation` in the CLI config to redirect sources
- Recognise the trust difference between official and community providers
- Diagnose the common source-related failure modes
Prerequisites
None — start here.
Verified against Terraform CLI 1.9.x · OpenTofu 1.7.x · HCL 2.0 · bpg/proxmox provider 0.66+ · hashicorp/local provider 2.5+ · hashicorp/null provider 3.2+ · hashicorp/random provider 3.6+ · hashicorp/http provider 3.4+ · Ubuntu 24.04 LTS · Debian 12 (Bookworm) · 2026-08-13
A provider source is the address Terraform uses to fetch a provider binary. The address is more than a name. It tells Core which registry to talk to, which namespace to look in, and which type to download. Get the address wrong and the init fails. Get the trust wrong and the binary runs in your estate. The lesson teaches the address format, the kinds of sources Terraform supports, and the production trade-offs between them.
The source address
Every provider declaration includes a source. The canonical form is three parts:
[<HOSTNAME>/]<NAMESPACE>/<TYPE>
Examples:
terraform {
required_providers {
aws = { source = "hashicorp/aws" }
azurerm = { source = "hashicorp/azurerm" }
github = { source = "integrations/github" }
mycompany = { source = "mycorp.example.com/mycompany/internal" }
local = { source = "hashicorp/local" }
}
}
- HOSTNAME (optional). Defaults to
registry.terraform.io, the public registry. A different hostname selects a private registry. - NAMESPACE. A namespace owned by an organisation.
hashicorp/*is the official set;integrations/githubis the GitHub-maintained provider;mycompany/*is internal. - TYPE. The provider name itself.
The HOSTNAME/NAMESPACE/TYPE triplet is the unique key. Two
providers in different namespaces can share the same TYPE
(hashicorp/aws and mycorp/aws-experimental are different
providers).
The four kinds of sources
Terraform 1.9 supports four kinds of provider sources:
1. The public registry. registry.terraform.io. The
default. Hosts hashicorp/* plus third-party providers. Free
to use, signed, versioned, and documented. Every CI runner in
the world can reach it. No auth is required for download.
2. A private registry. A Terraform-native registry
running inside your organisation. Examples include HashiCorp’s
self-hosted Terraform Cloud private registry, plus open-source
options like terustry and boring-registry. A private
registry is a real Terraform-native service: it speaks the
discovery protocol, signs binaries with a configurable GPG
key, and exposes an HTTP API Terraform can consume.
3. A network mirror. A simple HTTP(S) endpoint that mirrors the public registry’s protocol. Tools like JFrog Artifactory, Sonatype Nexus, and Cloudsmith implement this. A network mirror is a cache and a control point, not a full registry. The downside: it usually does not sign binaries.
4. A filesystem mirror. A local directory layout that mirrors the registry structure. Used for air-gapped environments and offline workstations.
A host can use any combination. The CLI config chooses.
Configuring where Terraform looks
The CLI config file (~/.terraformrc for the user,
/etc/terraformrc for the host) controls the installation
method:
# CONFIGURATION: ~/.terraformrc
provider_installation {
# Method 1: a private registry for `mycorp/*`,
# the public registry for everything else.
network_mirror {
url = "https://artifactory.mycorp.example.com/terraform/"
include = ["mycorp/*"]
}
direct {
exclude = ["mycorp/*"]
}
}
# Method 2: a filesystem mirror for everything.
# provider_installation {
# filesystem_mirror {
# path = "/opt/terraform-mirror"
# }
# direct {
# # The default fallback when the mirror has nothing.
# }
# }
Two important behaviours:
- First match wins. Terraform walks the methods in order. The first that claims the provider and serves the binary is the one used.
includeandexcludeare optional. With no filters, a method handles every provider. With filters, the method handles only the listed sources.
The filesystem mirror
For air-gapped production environments, a filesystem mirror is the standard. The layout is the same as the public registry:
/opt/terraform-mirror/
└── registry.terraform.io/
└── hashicorp/
└── aws/
├── 5.80.0.json
└── terraform-provider-aws_5.80.0_linux_amd64.zip
Populate it with a script that periodically pulls from the
public registry on a host that has network access. The
metadata JSON describes the available versions and platforms.
The .zip is the signed binary bundle.
To use the mirror:
# CONFIGURATION: ~/.terraformrc
provider_installation {
filesystem_mirror {
path = "/opt/terraform-mirror"
}
direct {} # Used only as a fallback.
}
Official versus community providers
The public registry hosts both hashicorp/* providers and
community-maintained providers. The trust posture is
different:
| Namespace | Publisher | Signing | Cadence | Production posture |
|---|---|---|---|---|
hashicorp/* | HashiCorp | Yes (HashiCorp key) | Predictable | Default for AWS, GCP, Azure, Vault, etc. |
integrations/* | Named partner (GitHub, MongoDB, Datadog) | Yes (partner key) | Predictable | Default for the partner’s own service |
*/* | Third party | Optional | Variable | Vet before use |
For a production estate:
- Default to
hashicorp/*andintegrations/*for the services you actually use. AWS, Azure, GCP, Vault, Kubernetes, GitHub, Datadog all have first-class providers. - Treat every third-party provider as a supply-chain dependency. Pin the version. Read the changelog. Confirm the namespace owner is who you think it is. Confirm the provider is signed.
- Mirror what you can. A private registry or a network
mirror gives you a single control point for the supply
chain. A
gitleaksrule against provider source addresses is not enough on its own.
Production failure modes
Five failure modes recur:
1. Typo in the source address. The most common cause of
“provider not found”. hashicorp/aws is correct;
hashicorp/aws-sdk is a different (non-existent) provider.
The fix is to read the source address back from the public
registry page, not from memory.
2. Mirror outage. A network mirror is down. Terraform
falls back to direct if configured to do so, otherwise the
init fails. The fix is to allow a fallback with exclude on
the mirror, but not without it.
3. Private registry auth. A private registry is configured
but Terraform cannot authenticate. The init errors out with
“401 Unauthorized”. The fix is to set the bearer token via
TF_TOKEN_<HOSTNAME> environment variable or in the CLI
config.
4. Private registry with a self-signed certificate. A
private registry uses a certificate not in the system trust
store. The fix is to add the CA bundle to
SSL_CERT_FILE or to the system trust store; do not disable
verification.
5. Filesystem mirror out of date. The mirror contains
version 5.0 but required_providers asks for 5.80. The fix
is to update the mirror — running terraform init will not
fix it; the binary has to be on disk.
Operational guidance
For a production estate:
- Pick a source policy and write it down. Which namespaces are approved? Which mirror handles which providers? What is the fallback when the mirror is down?
- Use a network mirror where possible. It gives you one place to audit and cache. JFrog Artifactory and Cloudsmith are common choices.
- Sign what you publish. Internal
mycorp/*providers should be GPG-signed and served from a registry that enforces the signature. - Test the fallback. Periodically disable the mirror and
confirm
initcan resolve viadirect. The mirror is not the only path; the team should know what the fallback does.
What comes next
The next lesson is on provider version constraints and the dependency lock — the production control for which version of a given provider runs in your estate.
Verification
Knowledge check · 6 questions
Q1. What is the canonical form of a provider source address?
Q2. What is the role of the `provider_installation` block in the CLI config?
Q3. A network mirror can fully replace the public registry for an air-gapped environment.
Q4. Which CLI configuration uses a filesystem mirror with no fallback?
Q5. Which of the following are production failure modes for provider sources? (Select all that apply.)
Q6. A team wants to use a third-party provider for a niche SaaS. The provider is signed and on the public registry. What is the right first step?
Passing score: 75%. Answers are checked in this browser.