Erik Asplund
Erik Asplund

Reputation: 833

Using for_each with provider setting

I try to create VPCs in different regions for doing this I have multiple providers set up that I have given the alias equal to its region. The VPCs is set up with a for_each where the each.key is the region I want to spin up the VPC in. The issue I have is that i can't find a way to use the each.key with the "aws." prefix needed for the provider setting for the resource.

This is what I try to do:

provider "aws" {
  alias = "eu-west-1"
  profile = "Terraform"
  region = "eu-west-1"
}
provider "aws" {
  alias = "eu-west-2"
  profile = "Terraform"
  region = "eu-west-2"
}

locals {
  pools = {
    "eu-west-1" = "${data.aws_vpc_ipam_pool.pooleu-west-1.id}"
    "eu-west-2" = "${data.aws_vpc_ipam_pool.pooleu-west-2.id}"
  }
}

resource "aws_vpc" "default" {
  for_each = local.pools
  provider = aws.${each.key}
  ipv4_ipam_pool_id = each.value
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "main-vpc-${each.key}"
  }
}

Can this be done or should I try to find another solution? I cant find any answers to this and I am to under experienced with terraform to know this.

Upvotes: 9

Views: 11434

Answers (2)

BCS
BCS

Reputation: 78683

If you throw out the requirement of immediate convergence and allow eventual consistency (i.e. keep running terraform apply until it becomes a no-op), a lot of the places where Terraform is annoying become much more manageable.

For example to solve this case you should be able to use local_file to have your Terraform config generate itself.

NOTE: this has the issue that if the local version of generated files are out of date, this could try to delete some resource on the first invocation. Making sure that the first invocation always only --targets the generation would be advisable.

locals {
  regions = toset([
    "us-east-1",
    "us-east-2",
    "us-west-1",
    "us-west-2",
  ])
}

resource "local_file" "per_region_mod" {
  for_each = local.regions
  filename = "./region.${each.key}.tf"
  file_permission = "0600"
  content  = <<EOT
provider "aws" {
  alias = "${each.key}"
  region = "${each.key}"
}

module "region-${each.key}" {
  providers = { aws = aws.${each.key} }
  // ...
}
EOF
}

NOT tested... yet.

Upvotes: 0

Erik Asplund
Erik Asplund

Reputation: 833

After a lot of resource I have found this thread on the topic and it's not possible (yet and maybe never) to assign the provider dynamically...

You can read more here: https://github.com/hashicorp/terraform/issues/24476

Upvotes: 14

Related Questions