Struggling to (if even possible) pass a dynamic provider.alias in a module for_each block

13 views Asked by At

My use case is creating IAM_Roles and TFC_Workspaces across multiple AWS accounts as defined in

variable "tfc_workspaces" {
  type = map(object({
    aws_account_id           = string
    aws_account_name         = string
    aws_run_role             = string
    aws_provider_alias       = string
    workspace_name           = string
    workspace_project        = string
    workspace_description    = string
    github_repository_id     = string
    github_oauth_token_id    = string
    github_branch            = string
    github_working_directory = string
  }))
  description = "TFC workspace details"
}

and .tfvars

tfc_workspaces = {
  "prod-secops-usw2" = {
    aws_account_id           = "some id"
    aws_account_name         = "secops"
    aws_run_role_name        = "tfc_secops_run_role"
    aws_provider_alias       = "aws.prod-secops"
    workspace_name           = "prod-secops-usw2"
    workspace_project        = "SecOps"
    workspace_description    = "Production network and security resources."
    github_repository_id     = "org/repo"
    github_oauth_token_id    = "some token"
    github_branch            = "main"
    github_working_directory = "/env/prod/secops"
  },
  "sdlc-secops-usw2" = {
    aws_account_id           = "some id"
    aws_account_name         = "secops"
    aws_run_role_name        = "tfc_secops_run_role"
    aws_provider_alias       = "aws.sdlc-secops"
    workspace_name           = "sdlc-secops-usw2"
    workspace_project        = "SecOps"
    workspace_description    = "Non-production network and security resources."
    github_repository_id     = "org/repo"
    github_oauth_token_id    = "some token"
    github_branch            = "main"
    github_working_directory = "/env/sdlc/secops"
  }
  // Add more workspaces as needed
}

I've defined these in providers.tf

provider "tfe" {
  alias = "tfe_secops"
  hostname = var.tfc_hostname
}

provider "aws" {
  alias   = "sdlc-secops"
  region  = var.aws_region
  profile = "sdlc-secops"
}

provider "aws" {
  alias   = "prod-secops"
  region  = var.aws_region
  profile = "prod-secops"
}

My question: How do I pass the provider.alias specific to each AWS account? Here is my current attempt:

module "tfc_workspace" {
  source = "../../modules/tfc/workspace"

  for_each = { for ws in var.tfc_workspaces : ws.workspace_name => ws }
  providers = {
    aws = **???**
    tfc = tfe.tfe_secops
  }
  aws_region                   = var.aws_region
  aws_run_role                 = data.terraform_remote_state.secops.outputs.tfc_secops_role_arn.arn
  tfc_organization             = var.tfc_organization
  tfc_project_name             = each.value.tfc_project_name
  tfc_workspace_name           = each.value.workspace_name
  tfc_workspace_description    = each.value.workspace_description
  github_repository_identifier = each.value.github_repository_id
  github_oauth_token_id        = each.value.github_oauth_token_id
  github_branch                = each.value.github_branch
  github_working_directory     = each.value.github_working_directory
}

I've successfully done everything by duplicating the module calls within the root and explicitly passing provider.alias, but I'd love to refine this into something more elegant as I would like to reuse this across multiple clients with thousands of accounts.

I've tried about every variation I can think of and everything the AIs can suggest providers = {

    aws = each.value.aws_provider_alias
...
    aws = aws[each.value.aws_provider_alias]
...
    aws = aws.each.value.aws_provider_alias
...
    aws = ${each.value.aws_provider_alias}

I've configured the receiving module's required_providers {

    aws = {
      source                = "hashicorp/aws"
      version               = ">= 5.42.0"
      configuration_aliases = [sldc-secops, prod-secops, sdlc-app, sdlc-ucx, uat-ucx, prod-app, prod-ucx, prod-lake]
    }
    tfc = {
      source  = "hashicorp/tfe"
      version = ">= 0.53.0"
    }
  }

...but nuthin worx! :(

0

There are 0 answers