Manage the Terraform CLI Config from atmos.yaml
Atmos can now manage the Terraform/OpenTofu runtime configuration (RC) for you. Declare it once under components.terraform.rc, and Atmos writes a temporary CLI config file and points the subprocess at it via TF_CLI_CONFIG_FILE and TOFU_CLI_CONFIG_FILE — no hand-managed dotfiles, no manual env exports.
What is the "RC" file?
"RC" is runtime configuration — the same convention as .bashrc or .npmrc. Terraform and OpenTofu read a CLI configuration file (named .terraformrc / terraform.rc for Terraform and .tofurc / .terraformrc for OpenTofu) that controls how the CLI itself behaves — distinct from your .tf code, which describes infrastructure. It is where you configure things like:
provider_installation— where providers come from: network mirrors, filesystem mirrors, or goingdirectto registries (and include/exclude rules for supply-chain control).host— service-discovery overrides, e.g. redirecting a registry'smodules.v1endpoint.credentials— API tokens for private registries.plugin_cache_dir— a shared provider plugin cache.
This file is normally a hand-edited dotfile in your home directory, pointed to by the TF_CLI_CONFIG_FILE environment variable. Atmos now lets you declare it per stack/component instead.
What changed
Until now there was no way to declare this runtime configuration in Atmos — you had to hand-author a .terraformrc and export TF_CLI_CONFIG_FILE yourself. Now you declare it in your stack configuration:
components:
terraform:
rc:
enabled: true
# Rendered verbatim into Terraform's native CLI configuration.
provider_installation:
- network_mirror:
url: "https://terraform-mirror.example.com/"
- direct:
exclude:
- "registry.terraform.io/hashicorp/*"
host:
"registry.terraform.io":
services:
"modules.v1": "https://modules.example.com/v1/modules/"
Atmos renders that into the native HCL CLI-config grammar and exposes it to terraform/tofu automatically. No Terraform code, provider declarations, or module sources change.
How it works
When components.terraform.rc.enabled is set, then for each terraform/tofu invocation Atmos:
- Renders the
rc:section into Terraform's native CLI-config (HCL) grammar — preserving block semantics like the orderedprovider_installationmethods and labeledhost/credentialsblocks. - Writes it to a temporary file with an atomic write (so a partial file is never observed).
- Exposes it to the subprocess by setting both
TF_CLI_CONFIG_FILEandTOFU_CLI_CONFIG_FILEto that file. - Cleans up the temp file after the whole pipeline finishes — it survives
init,workspace, andplan/applywithin a single invocation.
If you already manage your own CLI config via either env var (or the legacy TERRAFORM_CONFIG), Atmos detects it and renders nothing, deferring to you.
A passthrough, not a new abstraction
The rc: section is near-opaque: keys map directly to Terraform CLI-config directives (provider_installation, host, credentials, plugin_cache_dir, …). New directives work immediately without waiting for an Atmos release, because Atmos renders the section rather than modeling it.
Terraform and OpenTofu, no guessing
Atmos sets both TF_CLI_CONFIG_FILE and TOFU_CLI_CONFIG_FILE to the generated file, so your config is honored whether the resolved binary is terraform or tofu — no heuristic about which tool you're running. If you already manage your own CLI config (via either env var or the legacy TERRAFORM_CONFIG), Atmos detects it and defers to you.
The foundation for the registry cache
RC management is useful on its own, and it's also the injection point the new Terraform Registry Cache builds on — the cache contributes its network_mirror and module host directives into this same generated CLI config. Enable the cache and the RC plumbing is driven for you.
Get involved
This feature is experimental. Try declaring a components.terraform.rc block in a stack and inspect the generated config Terraform receives. Feedback welcome.
