Define a default provider block for the management account and additional alias blocks: provider "aws" { alias = "staging"; assume_role { role_arn = "arn:aws:iam::<staging-account-id>:role/TerraformRole" } }
Pass the aliased provider to resources or child modules explicitly: resource "aws_s3_bucket" "staging" { provider = aws.staging ... }
For child modules, declare a required_providers block with configuration_aliases to receive the aliased provider: required_providers { aws = { source = "hashicorp/aws"; configuration_aliases = [aws.staging] } }
Pass the alias into the module call: module "network" { source = "./modules/network"; providers = { aws = aws.staging } }
Set session_name in the assume_role block for CloudTrail auditability: assume_role { role_arn = "..."; session_name = "terraform-ci" }
Run terraform plan and confirm resource addresses reference the correct provider by checking the Provider column in plan output or terraform providers
Known gotchas
Child modules that do not declare configuration_aliases in their required_providers block cannot accept aliased providers from the caller; the plan will error with a provider configuration not present message
Using assume_role without setting an explicit duration_seconds defaults to the role's maximum session duration; if the Terraform run exceeds that duration, provider calls will fail with expired token errors mid-apply
A module passed providers = { aws = aws.staging } will only see that alias inside the module; any resource inside that module that tries to use the default aws provider will fail unless the default is also passed in the providers map
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp