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! :(