azure Terraform:在从具有lists属性的扁平化对象列表创建的另一个for_each资源中引用for_each示例时出现问题

2vuwiymt  于 2023-05-29  发布在  其他
关注(0)|答案(1)|浏览(118)

我尝试通过循环遍历包含角色名称和具有安全组的列表属性的对象数组来创建Azure AD目录角色分配。我发现我首先需要将它展平,以访问每个对象的列表。但是,我现在很难引用在另一个for_each循环中创建的安全组,因为它与属性名称不匹配。这都是因为azuread_directory_role_assignment资源只采用1:1关联。
这是我生成的两个变量数组,我打算从中创建安全组和Azure AD目录角色分配:

{
  "variable": {
    "rbac-adorggroups": {
      "default": [
        {
          "adgroup-name": "tst-as-azp_platformowner-members",
          "adgroup-members": [],
          "adgroup-aadroleenabled": true
        },
        {
          "adgroup-name": "tst-as-azp_platformmanager-members",
          "adgroup-members": [],
          "adgroup-aadroleenabled": true
        },
        {
          "adgroup-name": "tst-as-azp_grc-members",
          "adgroup-members": [],
          "adgroup-aadroleenabled": true
        },
        {
          "adgroup-name": "tst-as-azp_ccc-members",
          "adgroup-members": [],
          "adgroup-aadroleenabled": true
        },
        {
          "adgroup-name": "tst-as-azp_platformops-members",
          "adgroup-members": [],
          "adgroup-aadroleenabled": true
        },
        {
          "adgroup-name": "tst-as-azp_networkops-members",
          "adgroup-members": [],
          "adgroup-aadroleenabled": true
        },
        {
          "adgroup-name": "tst-as-azp_securityops-members",
          "adgroup-members": [],
          "adgroup-aadroleenabled": true
        },
        {
          "adgroup-name": "tst-as-azp_iamops-members",
          "adgroup-members": [],
          "adgroup-aadroleenabled": true
        }
      ]
    },
    "rbac-aadroles": {
      "default": [
        {
          "aadrole-name": "Application Administrator",
          "aadrole-groups": [
            "tst-as-azp_iamops-members"
          ]
        },
        {
          "aadrole-name": "Authentication Administrator",
          "aadrole-groups": [
            "tst-as-azp_iamops-members"
          ]
        },
        {
          "aadrole-name": "Authentication Policy Administrator",
          "aadrole-groups": [
            "tst-as-azp_securityops-members"
          ]
        },
        {
          "aadrole-name": "Billing Administrator",
          "aadrole-groups": [
            "tst-as-azp_platformmanager-members"
          ]
        },
        {
          "aadrole-name": "Compliance Administrator",
          "aadrole-groups": [
            "tst-as-azp_securityops-members",
            "tst-as-azp_grc-members"
          ]
        },
        {
          "aadrole-name": "Conditional Access Administrator",
          "aadrole-groups": [
            "tst-as-azp_iamops-members"
          ]
        },
        {
          "aadrole-name": "Global Reader",
          "aadrole-groups": [
            "tst-as-azp_platforowner-members",
            "tst-as-azp_platformmanager-members",
            "tst-as-azp_grc-members",
            "tst-as-azp_ccc-members",
            "tst-as-azp_platformops-members",
            "tst-as-azp_securityops-members"
          ]
        },
        {
          "aadrole-name": "Guest Inviter",
          "aadrole-groups": [
            "tst-as-azp_platformmanager-members"
          ]
        },
        {
          "aadrole-name": "Hybrid Identity Administrator",
          "aadrole-groups": [
            "tst-as-azp_iamops-members"
          ]
        },
        {
          "aadrole-name": "Identity Governance Administrator",
          "aadrole-groups": [
            "tst-as-azp_securityops-members"
          ]
        },
        {
          "aadrole-name": "License Administrator",
          "aadrole-groups": [
            "tst-as-azp_platformmanager-members"
          ]
        },
        {
          "aadrole-name": "Privileged Authentication Administrator",
          "aadrole-groups": [
            "tst-as-azp_platformmanager-members",
            "tst-as-azp_securityops-members"
          ]
        },
        {
          "aadrole-name": "Privileged Role Administrator",
          "aadrole-groups": [
            "tst-as-azp_platformmanager-members",
            "tst-as-azp_securityops-members"
          ]
        },
        {
          "aadrole-name": "Security Administrator",
          "aadrole-groups": [
            "tst-as-azp_securityops-members"
          ]
        },
        {
          "aadrole-name": "User Administrator",
          "aadrole-groups": [
            "tst-as-azp_iamops-members"
          ]
        }
      ]
   }
}

下面是我使用的flatten函数,它用于通过azuread_directory_role_assignment资源的for_each循环获取每个角色的安全组列表:

locals {
    flattended_role_assignments = flatten([
        for assignment in var.rbac-aadroles : [
            for security-group in assignment.aadrole-groups : {
                role-name = assignment.aadrole-name
                role-group = security-group
            }
        ]
    ])
}

首先,我创建了安全组,稍后我将引用这些安全组:

resource "azuread_group" "rbac-adorggroups" {
    for_each = {for org in var.rbac-adorggroups: org.adgroup-name => org}
    display_name = each.value.adgroup-name
    security_enabled = true
    assignable_to_role = each.value.adgroup-aadroleenabled
    members = toset([for member in each.value.adgroup-members: data.azuread_user.rbac-userids[(member)].object_id])
    prevent_duplicate_names = true
}

现在我激活目录角色:

resource "azuread_directory_role" "aadr-enable" {
    for_each = {for role in var.rbac-aadroles: role.aadrole-name => role}
    display_name = each.value.aadrole-name
}

最后创建角色分配:

resource "azuread_directory_role_assignment" "aadr-adorggroups" {
    for_each = {for assignment in local.flattended_role_assignments: "${assignment.role-name}-${assignment.role-group}" => assignment}
    role_id = azuread_directory_role.aadr-enable[each.value.role-name].template_id
    principal_object_id = azuread_group.rbac-adorggroups[*][each.value.role-group].object_id
    depends_on = [
        azuread_directory_role.aadr-enable,
        azuread_group.rbac-adorggroups
     ]
}

但是最后一点在引用principal_object_id时给我带来了麻烦:

Error: Invalid index
│
│   on rbac-mainv3.tf line 60, in resource "azuread_directory_role_assignment" "aadr-adorggroups":
│   60:     principal_object_id = azuread_group.rbac-adorggroups[*][each.value.role-group].object_id
│     ├────────────────
│     │ each.value.role-group is "tst-as-azp_platforowner-members"
│
│ The given key does not identify an element in this collection value.

在正确引用安全组以将其分配给角色时,我缺少什么?我尝试了多种引用方法。

aiazj4mn

aiazj4mn1#

该错误可能是由于azuread_directory_role_assignment资源中的for-each循环中的([*])。尝试在引用Map值时删除asteric *。
代码:

resource "azuread_directory_role_assignment" "aadr-adorggroups" {
       for_each            = { for assignment in 
        local.flat_assignments :"${assignment.role-name}-${assignment.role-group}" => assignment }
       role_id             = azuread_directory_role.aadr-enable[each.value.role-name].id
       principal_object_id = azuread_group.rbac-adorggroups[each.value.role-group].id
     
       depends_on = [
         azuread_directory_role.aadr-enable,
         azuread_group.rbac-adorggroups
       ]
     }

可以交替使用以下模式将Map的角色分配给组。
示例:
variables.tf

variable "group_mem" {
  type = map(object({
    members = list(string)
  }))
  default = {
    group1 = {
      members = ["myuser1", "myuser2"]
    },
    group2 = {
      members = ["myuser3"]
    }
  }
}

variable "role_assignments" {
  type = map(list(string))
  default = {
    Contributor = ["group1"],
    Reader      = ["group2"]
  }
}

main.tf:

resource "azuread_group" "example_group" {
  for_each = var.group_mem

  name = each.key
}

resource "azuread_directory_role" "example_role" {
  for_each = var.role_assignments

  role_name = each.key
}

resource "azuread_directory_role_assignment" "example_assignment" {
  for_each = var.role_assignments

  role_definition_id = azuread_directory_role.example_role[each.key].id
  principal_id       = azuread_group.example_group[each.value[0]].id
}

相关问题