Let's leverage Stacks' global Terraform code feature to simplify multi-account AWS provider management.
# stacks/aws.tf
{% macro aws_provider(alias, region, role) -%}
provider "aws" {
{% if alias -%}
alias = "{{ alias }}"
{% endif -%}
region = "{{ region }}"
assume_role {
role_arn = "{{ role }}"
}
default_tags {
tags = {
stacks_path = "{{ var.stacks_path }}"
}
}
}
{% endmacro -%}
# injects default provider in var.aws_region with var.aws_role_arn
{{ aws_provider(alias=None, region=var.aws_region, role=var.aws_role_arn) }}
# injects provider with var.aws_role_arn in all var.aws_regions
{% for region in var.aws_regions -%}
{{ aws_provider(alias=region, region=region, role=var.aws_role_arn) }}
{% endfor -%}
# injects providers for all other environments in all var.aws_regions
{% for environment, variables in var.stacks_environments.items() -%}
{{ aws_provider(alias=environment, region=variables.aws_region, role=variables.aws_role_arn) }}
{% for region in var.aws_regions -%}
{{ aws_provider(alias=[environment,region]|join("_"), region=region, role=variables.aws_role_arn) }}
{% endfor -%}
{% endfor -%}
# stacks/aws.tfvars
aws_regions = [
"us-east-1",
"us-east-2",
"us-west-1",
"us-west-2",
"eu-central-1",
]
# environments/production/env.tfvars
aws_region = "us-east-1"
aws_role_arn = "arn:aws:iam::0123456789:role/Terraform"
and
# environments/development/env.tfvars
aws_region = "eu-south-2"
aws_role_arn = "arn:aws:iam::9876543210:role/Terraform"
# stacks/vpc/base/foo.tf
resource "foo" "bar" { # uses the environment's account and region (default provider)
foo = "bar"
}
or
# stacks/vpc/base/foo.tf
resource "foo" "bar" {
provider = aws.us-west-2 # uses the environment's account in the us-west-2 region
foo = "bar"
}
or
# stacks/vpc/base/foo.tf
resource "foo" "bar" {
provider = aws.development # uses the "development" environment's account and region
foo = "bar"
}
or
# stacks/vpc/base/foo.tf
resource "foo" "bar" {
provider = aws.development_us-east-2 # uses the "development" environment's account in the us-east-2 region
foo = "bar"
}