Terraform 不允许我将字符串连接到 for 循环中的变量来引用另一个变量

问题描述 投票:0回答:1

我确信这不是一个独特的要求,我已经在其他一些编程和脚本环境中使用 eval() 语法解决了此类问题。

我的问题:我正在尝试基于本地变量创建一个azurerm_pim_active_role_assignment,该变量在内部是基于地图对象(group_roles)创建的。如果您看到下面的代码,我特别面临有关

role_definition_id = "${data.azurerm_subscription.primary.id}${local.DataFactoryContributor}"
的问题,因为如果我应用此逻辑,我必须为每个角色定义类型(例如 DataFactoryContributor)创建不同的资源块,因为我无法执行以下操作:
eval("${data.azurerm_subscription.primary.id}${local.${group.role})
。 我想了解 HCL 是否支持执行类似的操作,或者我必须为每个角色定义创建不同的资源代码块?

保存所有角色和 Entra 组详细信息的变量对象(仅共享 1 个作为示例)

variable "groupsetuparray"{
    type = list(object({
        name       = string,
        group_name = string,
        resource_group_name = string,
        resource_name = string,
        group_roles = list(string),
        members    = list(string)
    }))
    default = [
        {
        name = "DFDeveloperTeam",
        group_name = "DFDeveloperTeam",
        resource_group_name = "",
        resource_name = "",
        group_roles = ["DataFactoryContributor","SQLServerContributor"]
        members = []
        }

用于生成组角色的局部变量

locals {
  group_roles = flatten([for group in var.groupsetuparray : [
      for role in group.group_roles : {
        name = group.name
        role = role
        rg = group.resource_group_name
      }
    ]
  ])
DataFactoryContributor = data.azurerm_role_definition.DataFactoryContributor.id
SQLServerContributor = data.azurerm_role_definition.SQLServerContributor.id
}

引用内置角色定义的数据资源

data "azurerm_role_definition" "DataFactoryContributor" {
  name = "Data Factory Contributor"
}

data "azurerm_role_definition" "SQLServerContributor" {
  name = "SQL Server Contributor"
}

用于为每个循环创建 PIM 激活角色分配的资源

resource "azurerm_pim_active_role_assignment" "DataFactoryContributorAssignment" {
  for_each = { for group in local.group_roles : "${group.name}-${group.role}" => group if group.role == "DataFactoryContributor" }
  scope              = data.azurerm_subscription.primary.id
  role_definition_id = "${data.azurerm_subscription.primary.id}${group.role}.id"
#=====BELOW IS CODE THAT WORKS BUT I HAVE TO GIVE DIRECT REFERENCE FOR EACH ROLE DEFINITION, WHICH IS NOT BEST WAY=====
#role_definition_id = "${data.azurerm_subscription.primary.id}${local.DataFactoryContributor}"
#=====
  principal_id       = azuread_group.group[each.value.name].object_id
  schedule {
    start_date_time = time_static.example.rfc3339
    expiration {
      duration_hours = 8
    }
  }
  justification = "Expiration Duration Set"
    ticket {
    number = "1"
    system = "example ticket system"
  }

}

如果我使用上面的代码块,我会收到错误消息

Error: Reference to undeclared resource
│
│   on main.tf line 61, in resource "azurerm_pim_active_role_assignment" "DataFactoryContributor":
│   61:   role_definition_id = "${data.azurerm_subscription.primary.id}${group.role}.id"
│
│ A managed resource "group" "role" has not been declared in the root module.

我仍在学习 TF HCL(正如您在查看上面的代码后可能会感觉到的那样),因此如果有人能指出我正确的方向,这将是很大的帮助。

我已经尝试过:我尝试使用查找功能,但这不起作用。我也尝试过不同的表达和插值方式,但没有成功。

for-loop terraform eval string-interpolation hcl
1个回答
0
投票

下面是一个使用

for_each
处理您的数据的小示例...

我做了一些改变:

  • 将默认输入减少为对象中的几个属性
  • 使用
    type = any
    只是为了让代码更小
  • 为了显示循环,我使用了带有一些触发器的
    null_resource
variable "groupsetuparray" {
  type = any
  default = [
    {
      name        = "DFDeveloperTeam",
      group_roles = ["DataFactoryContributor", "SQLServerContributor"]
    }
  ]
}

locals {
  group_roles = flatten([
    for group in var.groupsetuparray : [
      for role in group.group_roles : {
        name = group.name
        role = role
      }
    ]
  ])
}

resource "null_resource" "test" {
  for_each = {
    for group in local.group_roles :
    "${group.name}-${group.role}" => group
    if group.role == "DataFactoryContributor"
  }
  triggers = {
    "key"  = each.key
    "role" = each.value.role
  }
}

地形计划将如下所示:

Terraform will perform the following actions:

  # null_resource.test["DFDeveloperTeam-DataFactoryContributor"] will be created
  + resource "null_resource" "test" {
      + id       = (known after apply)
      + triggers = {
          + "key"  = "DFDeveloperTeam-DataFactoryContributor"
          + "role" = "DataFactoryContributor"
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.