Skip to content

Latest commit

 

History

History
112 lines (89 loc) · 2.38 KB

3.2.2. Terraform provider generation.md

File metadata and controls

112 lines (89 loc) · 2.38 KB

Terraform provider generation

Let's leverage Stacks' global Terraform code feature to simplify multi-account AWS provider management.

1. Define AWS providers template

# 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 -%}

2. Define aws_regions

# stacks/aws.tfvars
aws_regions = [
  "us-east-1",
  "us-east-2",
  "us-west-1",
  "us-west-2",
  "eu-central-1",
]

3. Define per-environment aws_region and aws_role_arn

# 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"

4. Use the automatically-injected providers

# 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"
}