在 for 循环中进行 Terraform for 循环
Terraform for loop in a for loop
我的 terraform 模块中有以下 Azure AD 服务主体。
module "test_app" {
source = "../../../../../my-adapplication/"
app_owners = ["riker@domain.com","picard@domain.com"]
app_roles = [
{
allowed_member_types = [
"User"
]
description = "Read access to Test app"
display_name = "Test App Read"
is_enabled = true
value = "TestApp.Read"
id = random_uuid.test_app_read.result
},
{
allowed_member_types = [
"User"
]
description = "Write access to Test app"
display_name = "Test App Write"
is_enabled = true
value = "TestApp.Write"
id = random_uuid.test_app_write.result
},
{
allowed_member_types = [
"User"
]
description = "Admin access to Test app"
display_name = "Test App Admin"
is_enabled = true
value = "TestApp.Admin"
id = random_uuid.test_app_admin.result
}
]
app_role_assignments = [
{
app_role_id = random_uuid.test_app_read.result #"TestApp.Read"
principal_object_id = data.azuread_group.group_role_read.object_id
},
{
app_role_id = random_uuid.test_app_write.result #"TestApp.Write"
principal_object_id = data.azuread_group.group_role_write.object_id
},
{
app_role_id = random_uuid.test_app_admin.result #"TestApp.Admin"
principal_object_id = data.azuread_group.group_role_write.object_id
}
]
}
resource "random_uuid" "test_app_read" {
}
resource "random_uuid" "test_app_write" {
}
resource "random_uuid" "test_app_admin" {
}
data "azuread_group" "group_role_read" {
display_name = "group-role-read"
}
data "azuread_group" "group2_role_read" {
display_name = "group2-role-read"
}
data "azuread_group" "group_role_write" {
display_name = "group-role-write"
}
data "azuread_group" "group_role_admin" {
display_name = "group-role-admin"
}
my-adapplication
模块文件如下所示:
resource "azuread_application" "app" {
...
...
dynamic "app_role" {
for_each = var.app_roles
content {
id = app_role.value["id"]
allowed_member_types = app_role.value["allowed_member_types"]
description = app_role.value["description"]
display_name = app_role.value["display_name"]
enabled = app_role.value["is_enabled"]
value = app_role.value["value"]
}
}
}
resource "azuread_service_principal" "sp" {
application_id = azuread_application.app.application_id
}
resource "azuread_app_role_assignment" "role" {
for_each = { for a in var.app_role_assignments : a.app_role_id => a }
app_role_id = each.value["app_role_id"]
principal_object_id = each.value["principal_object_id"]
resource_object_id = azuread_service_principal.sp.object_id
}
我遇到的问题与 app_role_assignments 有关。如果我只传入一个 principal_object_id
它就可以了。但是,如果我传入多个 principal_object_id
s,它就不起作用。例如下面的TestApp.Read
:
app_role_assignments = [
{
app_role_id = random_uuid.test_app_read.result #"TestApp.Read"
principal_object_id = [data.azuread_group.group_role_read.object_id,data.azuread_group.group2_role_read.object_id]
},
{
app_role_id = random_uuid.test_app_write.result #"TestApp.Write"
principal_object_id = data.azuread_group.group_role_write.object_id
},
{
app_role_id = random_uuid.test_app_admin.result #"TestApp.Admin"
principal_object_id = data.azuread_group.group_role_write.object_id
}
]
收到的错误是:
Error: Incorrect attribute value type
│
│ on .terraform/modules/test_app/main.tf line 116, in resource "azuread_app_role_assignment" "role":
│ 116: principal_object_id = each.value["principal_object_id"]
│ ├────────────────
│ │ each.value["principal_object_id"] is tuple with 2 elements
│
│ Inappropriate value for attribute "principal_object_id": string required.
╵
如何让 Terraform 遍历这个 principal_object_id
列表?我想我在循环中循环之后。有没有比我上面的方法更好的方法呢?
是否可以使用 for_each
来做到这一点,所以如果我使用 count
/for
.
,我不会遇到列表顺序更改的问题
非常感谢。
您必须 re-organize 您的 app_role_assignments
然后 展平 它。如果您希望 principal_object_id
有多个值,它应该始终是一个 list,即使对于单个元素也是如此:
app_role_assignments = [
{
app_role_id = random_uuid.test_app_read.result #"TestApp.Read"
principal_object_id = [data.azuread_group.group_role_read.object_id,data.azuread_group.group2_role_read.object_id]
},
{
app_role_id = random_uuid.test_app_write.result #"TestApp.Write"
principal_object_id = [data.azuread_group.group_role_write.object_id]
},
{
app_role_id = random_uuid.test_app_admin.result #"TestApp.Admin"
principal_object_id = [data.azuread_group.group_role_write.object_id]
}
]
然后你可以展平为:
locals {
app_role_assignments_flat = merge([
for val in var.app_role_assignments: {
for principal_object_id in val["principal_object_id"]:
"${val.app_role_id}-${principal_object_id}" => {
app_role_id = val.app_role_id
principal_object_id = principal_object_id
}
}
]...) # please do NOT remove the dots
}
然后
resource "azuread_app_role_assignment" "role" {
for_each = local.app_role_assignments_flat
app_role_id = each.value["app_role_id"]
principal_object_id = each.value["principal_object_id"]
resource_object_id = azuread_service_principal.sp.object_id
}
我的 terraform 模块中有以下 Azure AD 服务主体。
module "test_app" {
source = "../../../../../my-adapplication/"
app_owners = ["riker@domain.com","picard@domain.com"]
app_roles = [
{
allowed_member_types = [
"User"
]
description = "Read access to Test app"
display_name = "Test App Read"
is_enabled = true
value = "TestApp.Read"
id = random_uuid.test_app_read.result
},
{
allowed_member_types = [
"User"
]
description = "Write access to Test app"
display_name = "Test App Write"
is_enabled = true
value = "TestApp.Write"
id = random_uuid.test_app_write.result
},
{
allowed_member_types = [
"User"
]
description = "Admin access to Test app"
display_name = "Test App Admin"
is_enabled = true
value = "TestApp.Admin"
id = random_uuid.test_app_admin.result
}
]
app_role_assignments = [
{
app_role_id = random_uuid.test_app_read.result #"TestApp.Read"
principal_object_id = data.azuread_group.group_role_read.object_id
},
{
app_role_id = random_uuid.test_app_write.result #"TestApp.Write"
principal_object_id = data.azuread_group.group_role_write.object_id
},
{
app_role_id = random_uuid.test_app_admin.result #"TestApp.Admin"
principal_object_id = data.azuread_group.group_role_write.object_id
}
]
}
resource "random_uuid" "test_app_read" {
}
resource "random_uuid" "test_app_write" {
}
resource "random_uuid" "test_app_admin" {
}
data "azuread_group" "group_role_read" {
display_name = "group-role-read"
}
data "azuread_group" "group2_role_read" {
display_name = "group2-role-read"
}
data "azuread_group" "group_role_write" {
display_name = "group-role-write"
}
data "azuread_group" "group_role_admin" {
display_name = "group-role-admin"
}
my-adapplication
模块文件如下所示:
resource "azuread_application" "app" {
...
...
dynamic "app_role" {
for_each = var.app_roles
content {
id = app_role.value["id"]
allowed_member_types = app_role.value["allowed_member_types"]
description = app_role.value["description"]
display_name = app_role.value["display_name"]
enabled = app_role.value["is_enabled"]
value = app_role.value["value"]
}
}
}
resource "azuread_service_principal" "sp" {
application_id = azuread_application.app.application_id
}
resource "azuread_app_role_assignment" "role" {
for_each = { for a in var.app_role_assignments : a.app_role_id => a }
app_role_id = each.value["app_role_id"]
principal_object_id = each.value["principal_object_id"]
resource_object_id = azuread_service_principal.sp.object_id
}
我遇到的问题与 app_role_assignments 有关。如果我只传入一个 principal_object_id
它就可以了。但是,如果我传入多个 principal_object_id
s,它就不起作用。例如下面的TestApp.Read
:
app_role_assignments = [
{
app_role_id = random_uuid.test_app_read.result #"TestApp.Read"
principal_object_id = [data.azuread_group.group_role_read.object_id,data.azuread_group.group2_role_read.object_id]
},
{
app_role_id = random_uuid.test_app_write.result #"TestApp.Write"
principal_object_id = data.azuread_group.group_role_write.object_id
},
{
app_role_id = random_uuid.test_app_admin.result #"TestApp.Admin"
principal_object_id = data.azuread_group.group_role_write.object_id
}
]
收到的错误是:
Error: Incorrect attribute value type
│
│ on .terraform/modules/test_app/main.tf line 116, in resource "azuread_app_role_assignment" "role":
│ 116: principal_object_id = each.value["principal_object_id"]
│ ├────────────────
│ │ each.value["principal_object_id"] is tuple with 2 elements
│
│ Inappropriate value for attribute "principal_object_id": string required.
╵
如何让 Terraform 遍历这个 principal_object_id
列表?我想我在循环中循环之后。有没有比我上面的方法更好的方法呢?
是否可以使用 for_each
来做到这一点,所以如果我使用 count
/for
.
非常感谢。
您必须 re-organize 您的 app_role_assignments
然后 展平 它。如果您希望 principal_object_id
有多个值,它应该始终是一个 list,即使对于单个元素也是如此:
app_role_assignments = [
{
app_role_id = random_uuid.test_app_read.result #"TestApp.Read"
principal_object_id = [data.azuread_group.group_role_read.object_id,data.azuread_group.group2_role_read.object_id]
},
{
app_role_id = random_uuid.test_app_write.result #"TestApp.Write"
principal_object_id = [data.azuread_group.group_role_write.object_id]
},
{
app_role_id = random_uuid.test_app_admin.result #"TestApp.Admin"
principal_object_id = [data.azuread_group.group_role_write.object_id]
}
]
然后你可以展平为:
locals {
app_role_assignments_flat = merge([
for val in var.app_role_assignments: {
for principal_object_id in val["principal_object_id"]:
"${val.app_role_id}-${principal_object_id}" => {
app_role_id = val.app_role_id
principal_object_id = principal_object_id
}
}
]...) # please do NOT remove the dots
}
然后
resource "azuread_app_role_assignment" "role" {
for_each = local.app_role_assignments_flat
app_role_id = each.value["app_role_id"]
principal_object_id = each.value["principal_object_id"]
resource_object_id = azuread_service_principal.sp.object_id
}