我确信这不是一个独特的要求,我已经在其他一些编程和脚本环境中使用 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_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"
}
}