gpt4 book ai didi

Terraform 在 map 列表中循环

转载 作者:行者123 更新时间:2023-12-04 15:24:08 25 4
gpt4 key购买 nike

我有一个生成 map 输出列表的 Terraform 模块:

object_ids = [
{
"object_id" = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
"upn" = "john@domain.com"
"user" = "john"
},
{
"object_id" = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
"upn" = "martin@domain.com"
"user" = "martin"
},
]

使用 for_each 我可以循环一个值来构建这个资源:

resource "azurerm_role_assignment" "subread" {
for_each = toset(module.user.map_object_ids[*].object_id)
scope = data.azurerm_subscription.primary.id
role_definition_name = "Reader"
principal_id = each.value
}

但是我不知道如何循环多个值。

我对另一个需要 2 个不同输出值的资源尝试了以下操作:

resource "azurerm_role_assignment" "contribrg" {
scope = [for map in module.user.map_object_ids[*]: "${data.azurerm_subscription.primary.id}/resourceGroups/${lookup(map,"user")}"]
role_definition_name = "Contributor"
principal_id = [for map in module.user.map_object_ids[*]: lookup(map,"object_id")]
}

出现以下错误:

Error: Incorrect attribute value type
module.user.map_object_ids is tuple with 2 elements
Inappropriate value for attribute "scope": string required.
Inappropriate value for attribute "principal_id": string required.

最佳答案

资源 for_each 的一个基本要求是您正在使用的集合必须为您要创建的每个实例都有一个元素,因此不可能基于多个值重复,但是幸运的是,我认为这实际上不是您在这里要问的。

相反,您似乎希望为 module.user.map_object_ids 的每个元素创建一个实例,因此我们需要处理的唯一额外问题是 for_each 期望得到对象映射而不是对象列表,因此它可以使用映射键作为每个实例的标识符。

我们可以使用 for expression 将对象列表转换为对象映射。 ,尽管我们需要确定嵌套对象的属性之一,该属性将用作每个元素的唯一键。我将在这里使用 user,因为它看起来是一个很好的人类可理解的、配置选择的唯一标识符:

resource "azurerm_role_assignment" "contribrg" {
for_each = { for obj in module.user.map_object_ids : obj.user => obj }

scope = "${data.azurerm_subscription.primary.id}/resourceGroups/${each.value.user}"
role_definition_name = "Contributor"
principal_id = each.value.object_id
}

上面的 for 表达式会将您的对象列表投影到对象映射中,如下所示:

{
"john" = {
"object_id" = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
"upn" = "john@domain.com"
"user" = "john"
}
"martin" = {
"object_id" = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
"upn" = "martin@domain.com"
"user" = "martin"
}
}

然后在资源参数表达式中 each.key 将引用用户名(因为它们现在是键)而 each.value 将引用对象,并且所以我们可以使用each.value.object_id来获取对应的对象标识符。

据此,Terraform 将计划创建具有以下地址的资源实例:

  • azurerm_role_assignment.contribrg["john"]
  • azurerm_role_assignment.contribrg["马丁"]

旁注:我发现您的输出被命名为 object_ids 时它不只是返回 id,这有点令人困惑。将其命名为 objects 可能更清楚。

关于Terraform 在 map 列表中循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62679195/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com