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

Terraform创建AWS SSO用户组关联失败:setproduct未获取正确ID

问题描述

目标

创建一个Terraform模块,用于创建AWS SSO用户、用户组及组内成员关系。用户和组通过for循环创建,要求所有用户创建完成后,每个用户都被分配到所有组中。

问题

setproduct似乎是实现该需求的最佳方案,但组内成员关系创建步骤失败,无法获取正确的用户ID和组ID(每个成员关系需要这两个ID)。

模块代码(用户和组已正确创建)

variables.tf 内容

data "aws_ssoadmin_instances" "ssoadmin_instances" {}
output "arn" {
  value = tolist(data.aws_ssoadmin_instances.ssoadmin_instances.arns)[0]
}
output "identity_store_id" {
  value = tolist(data.aws_ssoadmin_instances.ssoadmin_instances.identity_store_ids)[0]
}

locals {
  users = {
    "user1" = {
      username = "test.user"
      email    = "test.user@example.com"
      first_name = "Test"
      surname = "User"
    },
    "user2" = {
      username = "test.user2"
      email    = "test.user2@example.com"
      first_name = "Test"
      surname = "User2"
    }
  }
  groups = {
    "group1" = {
      group_name = "test-management-admin"
      description    = "Management account administrators"
    },
    "group2" = {
      group_name = "test-management-readonly"
      description    = "Management account readonly"
    }
  }
}

main.tf 内容

# Groups

resource "aws_identitystore_group" "groups" {
  for_each = local.groups

  description       = each.value.description
  display_name      = each.value.group_name
  identity_store_id = tolist(data.aws_ssoadmin_instances.ssoadmin_instances.identity_store_ids)[0]
}

# Users

resource "aws_identitystore_user" "users" {
  for_each = local.users

  display_name = join(" ", [each.value.first_name, each.value.surname])
  emails {
    value = each.value.email
  }
  identity_store_id = tolist(data.aws_ssoadmin_instances.ssoadmin_instances.identity_store_ids)[0]
  name {
    given_name  = each.value.first_name
    family_name = each.value.surname
  }
  user_name = each.value.username
}

# Group Membership

locals {
  user_ids = [
    for user_key, user in aws_identitystore_user.users : {
      key     = user_key
      user_id = user.user_id
    }
  ]
  group_ids = [
    for group_key, group in aws_identitystore_group.groups : {
      key      = group_key
      group_id = group.group_id
    }
  ]
  memberships = [
    for pair in setproduct(local.user_ids, local.group_ids) : {
      user_key  = pair[0].key
      group_key = pair[1].key
    }
  ]
}

resource "aws_identitystore_group_membership" "memberships" {
  for_each = {
    for membership in local.memberships : "${membership.user_key}.${membership.group_key}" => membership
  }

  identity_store_id = tolist(data.aws_ssoadmin_instances.ssoadmin_instances.identity_store_ids)[0]
  group_id          = each.value.group_key
  member_id         = each.value.user_key

  lifecycle {
    create_before_destroy = true
  }
}

执行情况

执行terraform plan时,Terraform检测到需创建2个用户、2个组及4个成员关系,但成员关系资源的group_id和member_id字段使用的是user1、group1这类占位键值,而非实际的AWS SSO用户/组ID(用户和组实际已存在,应该能获取到正确ID),导致后续执行失败。计划输出如下:

Terraform will perform the following actions:

  # module.sso-base-identity.aws_identitystore_group_membership.memberships["user1.group1"] will be created
  + resource "aws_identitystore_group_membership" "memberships" {
      + group_id          = "group1"
      + id                = (known after apply)
      + identity_store_id = "d-93670a4657"
      + member_id         = "user1"
      + membership_id     = (known after apply)
    }

  # module.sso-base-identity.aws_identitystore_group_membership.memberships["user1.group2"] will be created
  + resource "aws_identitystore_group_membership" "memberships" {
      + group_id          = "group2"
      + id                = (known after apply)
      + identity_store_id = "d-93670a4657"
      + member_id         = "user1"
      + membership_id     = (known after apply)
    }

  # module.sso-base-identity.aws_identitystore_group_membership.memberships["user2.group1"] will be created
  + resource "aws_identitystore_group_membership" "memberships" {
      + group_id          = "group1"
      + id                = (known after apply)
      + identity_store_id = "d-93670a4657"
      + member_id         = "user2"
      + membership_id     = (known after apply)
    }

  # module.sso-base-identity.aws_identitystore_group_membership.memberships["user2.group2"] will be created
  + resource "aws_identitystore_group_membership" "memberships" {
      + group_id          = "group2"
      + id                = (known after apply)
      + identity_store_id = "d-93670a4657"
      + member_id         = "user2"
      + membership_id     = (known after apply)
    }

Plan: 4 to add, 0 to change, 0 to destroy.

请问我哪里操作错误?


解决方案

你的问题出在成员关系资源中没有引用实际的用户ID和组ID,而是用了定义时的键名。具体来说:

  1. 在local.memberships里,你只保留了user_key和group_key,丢弃了已经获取到的user_id和group_id。
  2. 最终在aws_identitystore_group_membership资源中,你把each.value.group_key和each.value.user_key赋值给了group_id和member_id,这自然只会得到group1、user1这类字符串,而非AWS生成的实际ID。

修正步骤:

1. 修改local.memberships,保留用户ID和组ID

把locals中的memberships定义改成:

memberships = [
  for pair in setproduct(local.user_ids, local.group_ids) : {
    user_key  = pair[0].key
    user_id   = pair[0].user_id
    group_key = pair[1].key
    group_id  = pair[1].group_id
  }
]

2. 在成员关系资源中引用正确的ID

修改aws_identitystore_group_membership资源的group_id和member_id字段:

resource "aws_identitystore_group_membership" "memberships" {
  for_each = {
    for membership in local.memberships : "${membership.user_key}.${membership.group_key}" => membership
  }

  identity_store_id = tolist(data.aws_ssoadmin_instances.ssoadmin_instances.identity_store_ids)[0]
  group_id          = each.value.group_id  # 引用实际的组ID
  member_id         = each.value.user_id   # 引用实际的用户ID

  lifecycle {
    create_before_destroy = true
  }
}

简化写法(可选)

你也可以跳过中间的user_ids和group_ids本地变量,直接用setproduct处理资源对象:

locals {
  memberships = setproduct(values(aws_identitystore_user.users), values(aws_identitystore_group.groups))
}

resource "aws_identitystore_group_membership" "memberships" {
  for_each = {
    for pair in local.memberships : "${pair[0].user_name}.${pair[1].display_name}" => pair
  }

  identity_store_id = tolist(data.aws_ssoadmin_instances.ssoadmin_instances.identity_store_ids)[0]
  group_id          = each.value[1].group_id
  member_id         = each.value[0].user_id

  lifecycle {
    create_before_destroy = true
  }
}

这样修改后,Terraform就能正确引用用户和组的实际ID,成员关系创建就能正常执行了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 04:52:56