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,而是用了定义时的键名。具体来说:
- 在
local.memberships里,你只保留了user_key和group_key,丢弃了已经获取到的user_id和group_id。 - 最终在
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
相关产品推荐
相关产品推荐

