gpt4 book ai didi

terraform - 如何在 terraform 中对来自多个来源的资源组 ID 运行 for_each?

转载 作者:行者123 更新时间:2023-12-04 10:41:14 24 4
gpt4 key购买 nike

我首先从以下代码开始:

resource "azurerm_role_assignment" "pod_sp" {
for_each = toset(concat(
[for component in local.components: tostring(azurerm_resource_group.setup[component].id)],
[tostring(module.component_remote_state.rg_id)]
))

scope = each.value
role_definition_id = data.azurerm_role_definition.contributor.id
principal_id = azuread_service_principal.pod_sp.id
}

它给了我这个:
Error: Invalid for_each set argument

on ..\..\modules\bootstrap\to_inject.tf line 58, in resource "azurerm_role_assignment" "pod_sp":
58: for_each = toset(concat(
59: [for component in local.components: tostring(azurerm_resource_group.setup[component].id)],
60: [tostring(module.component_remote_state.rg_id)]
61: ))

The given "for_each" argument value is unsuitable: "for_each" supports maps
and sets of strings, but you have provided a set containing type dynamic.

然后我找到了 https://github.com/hashicorp/terraform/issues/22437并将我的代码更改为:
resource "azurerm_role_assignment" "pod_sp" {
for_each = {for k in concat(
[for component in local.components: tostring(azurerm_resource_group.setup[component].id)],
[tostring(module.component_remote_state.rg_id)]
): k => k}

scope = each.value
role_definition_id = data.azurerm_role_definition.contributor.id
principal_id = azuread_service_principal.pod_sp.id
}

这给了我这个:
Error: Invalid for_each argument


on ..\..\modules\bootstrap\to_inject.tf line 59, in resource "azurerm_role_assignment" "pod_sp":
59: for_each = {for k in concat(
60: [for component in local.components: tostring(azurerm_resource_group.setup[component].id)],
61: [tostring(module.component_remote_state.rg_id)]
62: ): k => k}

The "for_each" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the for_each depends on.

我不明白为什么它在 local.components 时说“无法预测”众所周知:
locals {
components = toset(["web", "data"])
}

是否可以使其工作而无需先对目标运行应用程序?

最佳答案

这里不可预测的部分是 id来自 azurerm_resource_group.setup 的属性值.因为您将它们用作 map 中的某些键,所以结果是一个键集不完全已知的 map ,因此 Terraform 无法确定该 map 中最终会有多少元素以及它们的所有键将是什么是。

为了完成这项工作,我建议使用来自 local.components 的字符串。作为键,因为您注意到这些是您的配置中的常量,因此保证在规划期间是已知的:

  for_each = merge(
{ for component in local.components : component => azurerm_resource_group.setup[component].id },
{ "from_remote_state" = module.component_remote_state.rg_id },
)

以上假设 local.components永远不会包含字符串 from_remote_state ,因此可以安全地用作特殊组件名称来处理与其他值不同的额外值。由于您比我更了解这方面的要求,因此您可能会在那里找到更合适的不同名称,但这里的一般想法是生成一个映射,即使某些值不知道,其键也全部已知:
{
"web": (known after apply),
"data": (known after apply),
"from_remote_state": "<your known rg id from the remote state>",
}

从这里,Terraform 可以看到您打算创建多少个资源实例以及它们的地址必须是什么:
  • azurerm_role_assignment.pod_sp["web"]
  • azurerm_role_assignment.pod_sp["data"]
  • azurerm_role_assignment.pod_sp["from_remote_state"]
  • 关于terraform - 如何在 terraform 中对来自多个来源的资源组 ID 运行 for_each?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59920918/

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