Air-gapped installs, checksum errors, provider upgrades and custom providers all depend on this model.
Terraform core knows nothing about clouds. Each provider is a separate executable that Terraform starts as a child process and talks to over gRPC (plugin protocol version 5 or 6). Core asks it for its schema (resource types, attributes, which are computed or force replacement), then calls operations such as PlanResourceChange, ApplyResourceChange, ReadResource and ImportResourceState. The provider translates them into API calls.
Consequences you'll notice:
- "forces replacement" decisions come from the provider's schema and plan logic, not from Terraform core.
- Provider upgrades can change defaults or schemas; a resource's schema version with state upgraders migrates stored attributes. Read changelogs for major versions.
- Bugs that look like Terraform bugs are usually provider bugs; check the provider's issue tracker.
Installation: init resolves versions from the registry, downloads the zip for your OS/architecture, and verifies its signature. .terraform.lock.hcl stores h1: and zh: checksums; on another platform the hash may be missing, so run terraform providers lock -platform=linux_amd64 -platform=darwin_arm64 to record all you need.
For restricted networks use terraform providers mirror to a directory and configure provider_installation in the CLI config (~/.terraformrc) with filesystem_mirror or network_mirror. For provider development, dev_overrides points at a local build.
New providers are written in Go with the Terraform Plugin Framework.
Example
terraform providers
# Providers required by configuration:
# ├── provider[registry.terraform.io/hashicorp/aws] ~> 6.0
# └── module.vpc
# └── provider[registry.terraform.io/hashicorp/aws] >= 6.0
terraform providers lock -platform=linux_amd64 -platform=darwin_arm64
terraform providers mirror /opt/tf-mirror # for air-gapped installs
terraform providers schema -json | jq '.provider_schemas | keys'
# ~/.terraformrc
# provider_installation {
# filesystem_mirror { path = "/opt/tf-mirror" }
# direct { exclude = ["registry.terraform.io/*/*"] }
# }Remember
- Providers are plugin processes talking gRPC to core
- Replacement and defaults come from provider schemas
- Lock file hashes per platform; mirrors for restricted networks
Watch out for
- Generating the lock file on macOS only, so Linux CI fails checksum verification.