DevOps Peach

Advanced Terraform · OpenTofu, Terragrunt and Security · Lesson 4 of 4

Provider Aliases, Many Accounts and Big Runs

Use provider aliases for several regions or accounts, pass them into modules explicitly, assume a role per account, and keep -target and -parallelism for the rare cases that need them.

Practice interactively →

Real estates span several regions and accounts. One configuration can talk to all of them through provider configurations with aliases.

flowchart LR
  P1["provider aws (default, ap-southeast-1)"] --> M1["module.app_sg"]
  P2["provider aws.us (us-east-1)"] --> M2["module.cdn_cert"]
  P3["provider aws.prod (assume_role prod)"] --> M3["module.app_prod"]
  CI["CI role (OIDC)"] -->|"sts:AssumeRole"| P3
  %% step P1: The default provider configuration has no alias and is used when nothing else is set.
  %% step P2: An alias such as aws.us adds a second configuration, here for resources that must live in us-east-1.
  %% step M2: Modules get a specific configuration through the providers argument of the module block.
  %% step P3: An alias can also assume a role in another account, so one pipeline reaches several accounts.
  %% step CI: The pipeline itself holds only one identity and assumes roles from there.

Aliases

provider "aws" {
  region = "ap-southeast-1"
}

provider "aws" {
  alias  = "us"
  region = "us-east-1"
}

provider "aws" {
  alias  = "prod"
  region = "ap-southeast-1"
  assume_role {
    role_arn = "arn:aws:iam::123456789012:role/terraform-deployer"
  }
}

resource "aws_acm_certificate" "cdn" {
  provider    = aws.us                 # CloudFront certificates must be in us-east-1
  domain_name = "shop.example.com"
}

Passing providers into modules

module "app_prod" {
  source    = "./modules/app"
  providers = {
    aws = aws.prod
  }
}

A module that needs two configurations declares them:

# modules/cdn/versions.tf
terraform {
  required_providers {
    aws = {
      source                = "hashicorp/aws"
      configuration_aliases = [aws.us]
    }
  }
}

Modules should never define provider blocks themselves (topic 1.1); they receive them.

Big runs: -target and -parallelism

Option Use Risk
-target=ADDRESS Emergency fix of one resource, or bootstrapping in steps Plans an incomplete graph; state and code can drift apart. Follow with a full plan
-parallelism=N (default 10) Lower it when an API rate-limits you; raise it carefully for huge states Too high → throttling errors
-refresh=false Quick look at a huge plan Plan can be wrong
Split states (2.4) The real fix for slow plans Needs planning

Terraform itself warns when targeting is used: it is not a workflow, it is an escape hatch.

Many accounts: a pattern

Traps: forgetting provider = aws.us silently creates the resource in the default region; and removing a provider alias while resources in state still use it fails the plan until you move or destroy those resources first.

Practice interactively →