Using dev_overrides for Local Terraform Provider Development¶
When you are building a Terraform provider, the default installation mechanism works against you. Every time you want to test a change, Terraform looks up the provider in a registry. That means you either publish a pre-release to the Terraform Registry on every iteration, configure a private local mirror, or wire up a complex network mirror configuration just to try out a two-line fix. None of those options belong in a tight edit-compile-test loop.
The dev_overrides block in the Terraform CLI configuration file solves this. It tells Terraform to skip the registry entirely for a named provider and load the binary from a local path instead. On macOS and Linux, this file is ~/.terraformrc. On Windows, it is %APPDATA%\terraform.rc.
The Problem with the Default Workflow¶
Terraform's normal provider installation flow looks like this:
terraform initreadsrequired_providersin your configuration.- Terraform contacts the registry (or a mirror) to resolve the provider version.
- The provider binary is downloaded and cached in the
.terraformdirectory.
This is exactly right for production use. During provider development, it becomes an obstacle. You need to test a change you just made to the Go source, and the registry has no idea that change exists. Cutting a pre-release tag, waiting for CI, and updating your test consumer configuration on every iteration adds minutes to what should be a seconds-long feedback loop.
Configuring dev_overrides¶
Add the following block to the Terraform CLI configuration file (~/.terraformrc on macOS and Linux; %APPDATA%\terraform.rc on Windows):
provider_installation {
dev_overrides {
"vmware/vsphere" = "/Users/tenthirtyam/go/bin"
}
direct {}
}
Two things to notice:
- The path is your Go install binary directory. When you run
go installinside the provider repository, Go places the compiled binary in$GOBINif it is set, or falls back to$GOPATH/binif not. Terraform will pick it up from that location directly. direct {}is required. Without it,dev_overridestakes over the entire provider installation block, and Terraform will not be able to resolve any other provider from the registry. Thedirect {}stanza tells Terraform to handle all providers that are not listed indev_overridesusing the normal registry path.
Finding Your Go Binary Path¶
If you are unsure where go install is placing binaries, confirm it at the terminal:
If this prints a non-empty path, that is the directory to use in your dev_overrides configuration.
If it is empty, Go falls back to $GOPATH/bin. In that case, run:
Append /bin to the returned value. For example, if go env GOPATH returns /Users/tenthirtyam/go, your binary path is /Users/tenthirtyam/go/bin.
The Development Loop¶
With dev_overrides in place, the workflow collapses to three steps:
1. Make a change to the provider source.
2. Build and install the binary.
Run this from the root of the provider repository. Go compiles the provider and writes the binary to $GOBIN (or $GOPATH/bin if GOBIN is not set). Because dev_overrides points Terraform at that exact directory, no additional copy or installation step is needed.
3. Test the change.
Or run terraform apply against a test configuration that exercises the resource or data source you just modified. After you have run terraform init at least once in this working directory, Terraform skips re-installing the overridden provider on subsequent runs and loads the binary straight from your Go binary directory.
Repeat from step one. The whole cycle takes as long as go install runs, which is typically a few seconds for an incremental build.
What terraform init still does with dev_overrides
When dev_overrides is active, terraform init will print a warning and skip installation of the overridden provider binary, but you still must run terraform init at least once in each working directory (and again whenever you change your backend, modules, or add other providers). After that initial init, you can iterate with go install + terraform plan or terraform apply without rerunning terraform init just to pick up provider changes. This is expected behavior and not an error.
The Runtime Warning¶
Terraform prints a notice whenever dev_overrides is active:
╷
│ Warning: Provider development overrides are in effect
│
│ The following provider development overrides are set in the CLI configuration:
│ - vmware/vsphere in /Users/tenthirtyam/go/bin
│
│ The behavior may therefore not match any released version of the provider and
│ applying changes may cause the state to become incompatible with published
│ releases.
╵
This is intentional. It is a reminder that the binary on disk does not correspond to any published version and that the state file produced during testing may not be compatible with a release version of the provider. The warning does not indicate a problem.
What to Keep in Mind¶
Do not use dev_overrides in CI or production.
The Terraform CLI configuration file (~/.terraformrc on macOS and Linux; %APPDATA%\terraform.rc on Windows) with a dev_overrides block is a local developer configuration. It should never be committed to version control and should never be present on CI runners or in any environment where reproducible, registry-sourced providers are required.
CI pipelines should always install providers through the normal terraform init path so that the exact published version is used and the installation is reproducible across runs.
The provider address must match exactly.
The key in dev_overrides must match the provider source address in your required_providers block exactly, including the namespace. vmware/vsphere and registry.terraform.io/vmware/vsphere are equivalent, but a custom provider registered under a different namespace must use that namespace in the override key.
References¶
- Development Overrides for Provider Developers, Terraform CLI documentation
- Terraform CLI Configuration File, Terraform CLI documentation
- Plugin Development: Provider development best practices, HashiCorp Developer