You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform:重构AWS SSO账号分配变量为值列表形式

解决方案

1. 定义新版变量结构

先把原来的principal_name字段替换为字符串列表principal_names,让同一权限集下的多个主体可以合并在一个对象中:

variable "account_assignments" {
  type = list(object({
    permission_set_arn = string
    account_id         = string
    principal_type     = string # 比如 "USER" 或 "GROUP"
    principal_names   = list(string) # 存储同一权限集下的多个主体名称
  }))
  default = []
}

2. 扁平化变量结构适配for_each

由于aws_ssoadmin_account_assignment资源要求每个条目对应单个主体,需要先把新版变量中的principal_names列表展开为单独的条目,同时生成for_each所需的唯一键:

locals {
  # 第一步:将每个权限集下的多个主体拆分为独立条目
  flattened_assignments = flatten([
    for assignment in var.account_assignments : [
      for principal in assignment.principal_names : {
        permission_set_arn = assignment.permission_set_arn
        account_id         = assignment.account_id
        principal_type     = assignment.principal_type
        principal_name     = principal
      }
    ]
  ])

  # 第二步:生成唯一键,避免资源重复创建
  assignment_keys = {
    for item in local.flattened_assignments : 
    "${item.permission_set_arn}-${item.account_id}-${item.principal_type}-${item.principal_name}" => item
  }
}

3. 配置资源的for_each

直接使用上面生成的assignment_keys作为for_each的参数,每个键对应一个独立的账号分配资源:

resource "aws_ssoadmin_account_assignment" "main" {
  for_each = local.assignment_keys

  permission_set_arn = each.value.permission_set_arn
  account_id         = each.value.account_id
  principal_type     = each.value.principal_type
  principal_id       = each.value.principal_name # 注意:如果主体名称不是ID(比如用户名/组名),需要先查询对应ID,见下文补充
}

补充:主体名称转ID的处理

如果你的principal_names存储的是IAM Identity Center的用户名或组名(而非ID),需要通过数据源查询对应的主体ID,调整如下:

# 查询用户ID(根据用户名)
data "aws_ssoadmin_user" "users" {
  for_each = {
    for item in local.flattened_assignments : 
    "${item.principal_name}-${item.principal_type}" => item
    if item.principal_type == "USER"
  }

  user_name    = each.value.principal_name
  instance_arn = "arn:aws:sso:::instance/ssoins-xxxxxx" # 替换为你的SSO实例ARN
}

# 查询组ID(根据组名)
data "aws_ssoadmin_group" "groups" {
  for_each = {
    for item in local.flattened_assignments : 
    "${item.principal_name}-${item.principal_type}" => item
    if item.principal_type == "GROUP"
  }

  group_name   = each.value.principal_name
  instance_arn = "arn:aws:sso:::instance/ssoins-xxxxxx" # 替换为你的SSO实例ARN
}

# 调整locals中的assignment_keys,替换为主体ID
locals {
  assignment_keys = {
    for item in local.flattened_assignments : 
    "${item.permission_set_arn}-${item.account_id}-${item.principal_type}-${item.principal_name}" => {
      permission_set_arn = item.permission_set_arn
      account_id         = item.account_id
      principal_type     = item.principal_type
      principal_id       = item.principal_type == "USER" 
        ? data.aws_ssoadmin_user.users["${item.principal_name}-USER"].user_id 
        : data.aws_ssoadmin_group.groups["${item.principal_name}-GROUP"].group_id
    }
  }
}

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 22:09:20