Terraform Providers
Terraform utilizes plugins known as providers for communication with cloud providers, SaaS providers, and various APIs.
In order for Terraform to install these providers, the corresponding Terraform configurations need to explicitly state what providers are required. Furthermore, certain providers require additional configuration, such as specifying endpoint URLs or cloud regions, before they can be used.
Provider Configuration in Terraform
When working with Terraform, you specify provider configurations in your Terraform code. This involves declaring which providers your infrastructure requires and providing any necessary configuration parameters. These parameters may include endpoint URLs, cloud regions, access credentials, or any other provider-specific configuration parameters.
To declare a provider in Terraform, use a provider block within your Terraform configuration files,
usually in a providers.tf file in the component (a.k.a. root module) directory.
The provider block specifies the provider type and all the necessary configuration parameters.
Here's an AWS provider configuration example for a vpc component. The provider config is defined in
the components/terraform/vpc/providers.tf file:
components/terraform/vpc/providers.tf
In this example, the aws provider block includes the region and IAM role required for Terraform to communicate
with the AWS services.
By correctly defining provider configurations in your Terraform code, you ensure that Terraform can seamlessly install, configure, and use the necessary plugins to manage your infrastructure across various cloud and services.
Provider Configuration and Overrides in Atmos Manifests
Atmos allows you to define and override provider configurations using the providers section in Atmos stack manifests.
The section can be defined globally for the entire organization, OU/tenant, account, region, or per component.
For example, the providers section at the global scope can look like this:
stacks/orgs/acme/_defaults.yaml
Similarly, it can be defined (or overridden) at the OU/tenant, account and region scopes in the corresponding
_defaults.yaml stack manifests.
If you want to override a provider configuration for a specific component, use the component.terraform.<component>.providers
section. For example, the following config can be used to override the assume_role parameter just for the vpc component:
stacks/catalog/vpc/defaults.yaml
You can include the providers sections in any Atmos stack manifest at any level of inheritance. Atmos will process,
deep-merge and override all the providers configurations for a component in the following order:
- Global scopes (
terraform.providerssections for the Org, OUs, accounts and regions) - Base component scope (
component.terraform.<base_component>.providerssection) - Current component scope (
component.terraform.<component>.providerssection)
Refer to Atmos Component Inheritance for more information on all types of component inheritance supported by Atmos
When you define the providers sections, Atmos processes the inheritance chain for a component and generates a
file providers_override.tf.json in the component's folder with the final values for all the defined providers.
For example:
The generated providers_override.tf.json file would look like this:
providers_override.tf.json
Terraform then uses the values in the generated providers_override.tf.json to
override the parameters for all the providers in the file.
alias: Multiple Provider Configuration in Atmos Manifests
Atmos allows you to define multiple configurations for the same provider using a list of provider blocks and the
alias meta-argument.
The generated providers_override.tf.json file will have a list of provider configurations, and Terraform/OpenTofu
will use and override the providers as long as the aliased providers are defined in the Terraform component.
For example:
stacks/catalog/vpc/defaults.yaml
The above example uses a list of configuration blocks for the aws provider.
Since it's a list, by default it doesn't work with deep-merging of stacks in the inheritance chain since list are not deep-merged, they are replaced.
If you want to use the above configuration in the inheritance chain and allow appending or merging of lists, consider
configuring the settings.list_merge_strategy in the atmos.yaml CLI config file.
For more details, refer to Atmos CLI Settings.
Local Provider Development with Dev Overrides
When developing custom Terraform providers locally, you need a way to test them without publishing to a registry. Terraform supports this through development overrides, which allows you to point Terraform to locally-built provider binaries.
This section covers development overrides for locally-built provider binaries, which is separate from the provider configuration described in the sections above:
- Provider Configuration (
providerssection in Atmos stacks) → Controls provider behavior (credentials, regions, endpoints) - Development Overrides (
.terraformrcfile) → Points to local provider binaries during development
Understanding Provider Configuration vs. Development Overrides
The providers section in Atmos stack manifests (covered above) configures how providers behave - things like
credentials, regions, and endpoints. This configuration is serialized to providers_override.tf.json and used by
Terraform to override provider settings.
Development overrides work at a different level: they tell Terraform where to find the provider binary itself.
This is configured in Terraform's CLI configuration file (.terraformrc or terraform.rc), not in your stack manifests.
Setting Up Development Overrides with Atmos
To use locally-built providers with Atmos, follow these steps:
1. Create a Terraform CLI configuration file with dev_overrides in your component folder.
Create a .terraformrc file in your component directory (e.g., components/terraform/mycomponent/.terraformrc):
components/terraform/mycomponent/.terraformrc
Replace myorg/myprovider with your provider's registry address and /absolute/path/to/provider/binary/directory
with the absolute path to the directory containing your locally-built provider binary (not the binary itself).
The .terraformrc file should be placed in each component folder that needs to use the local provider, not in
your infrastructure repository root. This is because Terraform's CLI configuration is loaded relative to where
Terraform runs, and Atmos executes Terraform from within the component directory.
Do not commit .terraformrc to version control - it contains developer-specific local paths. Add it to your
component's .gitignore or your global .gitignore.
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, not infrastructure configuration.
2. Point Terraform to your CLI configuration.
Set the TF_CLI_CONFIG_FILE environment variable in your component's env section to tell Terraform where to find
this configuration:
stacks/catalog/mycomponent/defaults.yaml
Since Atmos executes Terraform from within the component directory, you can use a relative path like .terraformrc.
Atmos will resolve it correctly to components/terraform/mycomponent/.terraformrc.
Alternatively, you can use an absolute path or ${PWD}/.terraformrc if you prefer explicit paths.
3. Build your provider.
Build your provider and place the binary in the directory you specified:
4. Run Atmos commands as usual.
Now when you run Atmos commands, Terraform will use your locally-built provider:
During active development, you can:
- Make changes to your provider code
- Rebuild the provider binary
- Run
atmos terraform plan/applyimmediately without publishing a release - Iterate quickly on provider functionality
This eliminates the need to publish development versions to a registry during active development.
Using settings Section for Environment Variables
You can also use the settings section to manage environment variables across your stack hierarchy:
stacks/orgs/acme/_defaults.yaml
Then reference these settings in your components as needed. However, note that the actual .terraformrc file
configuration cannot be templated through Atmos - it must exist as a file that Terraform can read directly.
When dev_overrides are active, Terraform will show a warning on every command:
Warning: Provider development overrides are in effect
This is expected behavior and confirms that your local provider is being used. Remove or comment out the
dev_overrides block in .terraformrc when you're ready to use the published provider version.
Example: Complete Setup
Here's a complete example for developing a custom provider:
Directory Structure:
infrastructure/
├── components/
│ └── terraform/
│ └── myapp/
│ ├── .terraformrc # CLI config (not committed)
│ ├── .gitignore # Ignore .terraformrc
│ ├── main.tf
│ ├── providers.tf
│ └── versions.tf
└── stacks/
└── catalog/
└── myapp/
└── defaults.yaml
components/terraform/myapp/.terraformrc
components/terraform/myapp/.gitignore
stacks/catalog/myapp/defaults.yaml
With this setup:
.terraformrclives in the component folder where Terraform executes- Terraform finds your local provider binary via
.terraformrc - Atmos configures the provider's behavior via the
providerssection - Your component works seamlessly with the local provider during development
- The file is not committed, so each developer can have their own local paths
References
- Terraform Providers
- Terraform Override Files
- alias: Multiple Provider Configurations
- Terraform Development Overrides
- Provider Development Pattern - Complete guide for developing custom providers with Atmos