Provider Development Pattern
When developing custom Terraform providers, you need to test them locally without publishing development versions to a registry. This pattern demonstrates how to use Terraform's development overrides with Atmos to streamline your provider development workflow.
You will learn
- How to configure local provider binaries for testing with Atmos
- The distinction between provider configuration and development overrides
- Best practices for iterating on custom provider development
- Managing development configurations across team members
The Problem
When developing custom Terraform providers, the standard workflow involves:
- Making code changes to your provider
- Publishing a new version to a registry (public or private)
- Updating version constraints in your Terraform code
- Testing the changes
This creates several pain points:
- Slow iteration cycles - Each change requires publishing and version updates
- Version pollution - Development versions clutter your registry
- Testing friction - Hard to test breaking changes before they're published
- Collaboration overhead - Sharing pre-release versions with team members is cumbersome
The Solution
Terraform provides development overrides that allow you to point Terraform directly to locally-built provider binaries. Combined with Atmos, this enables rapid iteration without publishing intermediate versions.
Understanding the Two Mechanisms
It's important to understand that provider development with Atmos involves two separate mechanisms:
1. Provider Configuration (Atmos Stack Manifests)
The providers section in Atmos stack manifests controls how providers behave - credentials, regions, endpoints, etc. Atmos serializes this to providers_override.tf.json.
stacks/catalog/myapp/defaults.yaml
This configures the provider's runtime behavior.
2. Development Overrides (Terraform CLI Configuration)
The .terraformrc file tells Terraform where to find the provider binary during development. This is Terraform's native feature, not an Atmos feature.
.terraformrc
This controls where Terraform finds the provider executable.
Implementation
Step 1: Project Structure
Organize your provider development environment:
my-project/
├── providers/
│   └── terraform-provider-mycloud/ # Your provider source code
│       └── bin/                    # Build output directory
└── infrastructure/
    ├── atmos.yaml
    ├── components/
    │   └── terraform/
    │       └── myapp/
    │           ├── .terraformrc          # CLI config (not committed)
    │           ├── .gitignore            # Exclude .terraformrc
    │           ├── .terraformrc.example  # Template for team members
    │           ├── main.tf
    │           ├── providers.tf
    │           └── versions.tf
    └── stacks/
        └── catalog/
            └── myapp/
                └── defaults.yaml
The .terraformrc file must be in the component folder, not the infrastructure repository root. This is because
Atmos executes Terraform from within the component directory, and Terraform loads CLI configuration relative to its
working directory.
Step 2: Create Terraform CLI Configuration
Create .terraformrc in your component directory:
components/terraform/myapp/.terraformrc
The path in dev_overrides must be:
- Absolute path to the directory containing the provider binary
- The directory, not the binary itself
- Terraform expects the binary to be named terraform-provider-<name>
The provider_installation block with dev_overrides must be in a Terraform CLI configuration file
(.terraformrc or terraform.rc). It cannot be defined in .tf files like providers.tf because it's a
CLI-level setting that applies across all Terraform operations, not infrastructure-specific configuration.
Step 3: Configure Environment in Atmos
Add the CLI configuration path to your component's environment:
stacks/catalog/myapp/defaults.yaml
Since Atmos executes Terraform from within the component directory (components/terraform/myapp), you can use a
relative path like .terraformrc. This will correctly resolve to the file in the component folder.
Step 4: Provider Build Script
Create a build script for your provider:
providers/terraform-provider-mycloud/build.sh
Step 5: Development Workflow
Your development workflow now looks like this:
Best Practices
Developer-Specific Configuration
The .terraformrc file contains paths specific to each developer's machine. Don't commit it to version control. Add
it to your component's .gitignore:
components/terraform/myapp/.gitignore
Instead, provide a template for team members:
components/terraform/myapp/.terraformrc.example
Document in your component's README:
components/terraform/myapp/README.md
Using settings for Shared Configuration
Use Atmos settings to manage shared development configuration:
stacks/orgs/acme/_defaults.yaml
stacks/catalog/myapp/defaults.yaml
Toggling Development Mode
Make it easy to switch between development and production modes:
stacks/orgs/acme/_defaults.yaml
stacks/catalog/myapp/defaults.yaml
The conditional templating above uses Atmos Go templates to only set TF_CLI_CONFIG_FILE when provider_dev_mode is true. This allows you to toggle development mode globally.
Provider Versioning in Development
During development, your provider won't have meaningful version numbers. Document expected behavior:
components/terraform/myapp/versions.tf
When dev_overrides are active, Terraform ignores version constraints and uses your local binary.
Common Patterns
Multi-Provider Development
Developing multiple providers simultaneously:
.terraformrc
Team Collaboration
When multiple developers are working on the same provider:
stacks/catalog/myapp/defaults.yaml
Each developer sets their own environment variable:
CI/CD Integration
Ensure your CI/CD pipeline doesn't use development overrides:
.github/workflows/terraform.yml
Troubleshooting
Warning Message
When dev_overrides are active, Terraform shows a warning:
Warning: Provider development overrides are in effect
This is expected behavior and confirms your local provider is being used. To remove the warning, remove or comment out the dev_overrides block.
Provider Not Found
If Terraform can't find your provider:
- Check the path - Must be absolute path to the directory containing the binary
- Check the binary name - Must be terraform-provider-<name>(exact match)
- Check the permissions - Binary must be executable (chmod +x)
- Check TF_CLI_CONFIG_FILE - Verify the environment variable points to your .terraformrc
Version Conflicts
If you see version-related errors, verify:
- The provider address in dev_overridesexactly matches thesourcein yourrequired_providersblock
- The provider binary name matches the provider name (last segment of the address)
Real-World Example
Here's a complete working example for developing a custom cloud provider:
Project Structure:
my-project/
├── providers/
│   └── terraform-provider-acme/
│       ├── main.go
│       ├── provider.go
│       └── bin/
│           └── terraform-provider-acme  # Built binary
└── infrastructure/
    ├── components/
    │   └── terraform/
    │       └── web-app/
    │           ├── .terraformrc
    │           ├── .terraformrc.example
    │           ├── .gitignore
    │           ├── main.tf
    │           ├── providers.tf
    │           └── versions.tf
    └── stacks/
        └── catalog/
            └── web-app/
                └── defaults.yaml
components/terraform/web-app/.terraformrc
components/terraform/web-app/.gitignore
stacks/orgs/acme/_defaults.yaml
stacks/catalog/web-app/defaults.yaml
You can use Atmos settings and templating to conditionally enable dev overrides:
env:
  TF_CLI_CONFIG_FILE: >-
    {{ if .settings.provider_dev_mode }}.terraformrc{{ end }}
Set provider_dev_mode: true in your global defaults when doing provider development, and false (or omit) when using published versions.
providers/terraform-provider-acme/Makefile
components/terraform/web-app/.terraformrc.example
Development workflow:
Related Patterns
- Component Catalog - Organize reusable components
- Defaults Pattern - Manage default configurations
- Component Overrides - Override component configurations
See Also
- Terraform Providers - Provider configuration reference
- Terraform Development Overrides - Official Terraform documentation