Terraform 每个回路的地形或回路不工作的地形

Terraform 每个回路的地形或回路不工作的地形,terraform,terraform-provider-azure,terraform0.12+,Terraform,Terraform Provider Azure,Terraform0.12+,我正在尝试为多个服务主体设置azure容器注册表的角色 variable "custom_role_list" { type = list(object ({ service_principal_id = string, role = string }) ) } 当我试图从资源模块设置它时,我不确定这是正确的方法 resource "azurerm_role_assignment" "ad_sp_role_assignment" { scope

我正在尝试为多个服务主体设置azure容器注册表的角色

variable "custom_role_list" {

  type        = list(object ({ service_principal_id = string, role = string }) )

} 
当我试图从资源模块设置它时,我不确定这是正确的方法

resource "azurerm_role_assignment" "ad_sp_role_assignment" {

  scope                = azurerm_container_registry.acr.id
  for_each = var.custom_role_list
  role_definition_name           = each.value.role
  principal_id = each.value.service_principal_id

}
本质上,我试图将azure容器注册表设置为与具有特定访问角色的多个服务主体一起工作

下面是var的定义

custom_role_list = [
    {
        service_principal_id = aserviceprincipal.id
        role = "Contributor"
    },

    {
        service_principal_id = bserviceprincipal.id
        role = "Contributor"
    }


]
当我执行它时,我得到以下错误

Error: Invalid for_each argument

  on ../modules/az-acr/main.tf line 46, in resource "azurerm_role_assignment" "ad_sp_role_assignment":
  46:   for_each = var.custom_role_list

The given "for_each" argument value is unsuitable: the "for_each" argument
must be a map, or set of strings, and you have provided a value of type list
of object.

如果有人能给你指点,我会很有帮助的。谢谢

如错误所示,
for_each
仅在与资源一起使用时支持贴图和集。您正在尝试使用对象列表

相反,您的变量可能只是类型
map
,其中每个服务原则都是一个键,其对应的角色是值。例如:

variable "custom_role_list" {
  type        = map
}
变量定义:

custom_role_map = {
  aserviceprincipal.id = "Contributor"
  bserviceprincipal.id = "Contributor"
}
最后对每一个使用

resource "azurerm_role_assignment" "ad_sp_role_assignment" {
  for_each = var.custom_role_map

  scope                    = azurerm_container_registry.acr.id
  role_definition_name     = each.value
  principal_id             = each.key
}

您可能会发现,在Terraform中使用循环和条件有助于您。

正如错误所示,
for\u each
仅在与资源一起使用时支持贴图和集。您正在尝试使用对象列表

相反,您的变量可能只是类型
map
,其中每个服务原则都是一个键,其对应的角色是值。例如:

variable "custom_role_list" {
  type        = map
}
变量定义:

custom_role_map = {
  aserviceprincipal.id = "Contributor"
  bserviceprincipal.id = "Contributor"
}
最后对每一个使用

resource "azurerm_role_assignment" "ad_sp_role_assignment" {
  for_each = var.custom_role_map

  scope                    = azurerm_container_registry.acr.id
  role_definition_name     = each.value
  principal_id             = each.key
}

您可能会找到一些方法来帮助您在Terraform中使用循环和条件。

您可以使用
for_each
循环来处理对象列表,方法是将代码调整为以下内容:

variable "custom_role_list" {
  type = list(object({
    service_principal_id = string
    role  = string 
  }))
  default = [
    {
        service_principal_id= "27d653c-aB53-4ce1-920",
        role  = "Contributor"
    },
     {
        service_principal_id= "57d634c-aB53-4ce1-397",
        role  = "Contributor"
    }
  ]
}
    
resource "azurerm_role_assignment" "ad_sp_role_assignment" {

for_each = {for sp in var.custom_role_list: sp.service_principal_id => sp}
    
scope                    = azurerm_container_registry.acr.id
role_definition_name     = each.value.service_principal_id 
principal_id             = each.value.role 
}

通过使代码适应以下内容,您可以在对象列表中使用
for_each
循环:

variable "custom_role_list" {
  type = list(object({
    service_principal_id = string
    role  = string 
  }))
  default = [
    {
        service_principal_id= "27d653c-aB53-4ce1-920",
        role  = "Contributor"
    },
     {
        service_principal_id= "57d634c-aB53-4ce1-397",
        role  = "Contributor"
    }
  ]
}
    
resource "azurerm_role_assignment" "ad_sp_role_assignment" {

for_each = {for sp in var.custom_role_list: sp.service_principal_id => sp}
    
scope                    = azurerm_container_registry.acr.id
role_definition_name     = each.value.service_principal_id 
principal_id             = each.value.role 
}

是的,我想到了这一点,相反,我使用了count,它为对象列表提供了简洁的实现。正如我链接的博文中提到的,使用count和列表有一个缺点,如果你从列表的中间删除一个项目,它将导致所有其他资源都有一个新的索引,Terraform将想要删除并重新创建它们。我建议您尝试使用
map
来避免这种情况。在我目前的情况下,我无法更改要求。i、 e.提供的输入,自定义角色列表。是的,我想到了这一点,相反,我使用了count,它为对象列表提供了简洁的实现。正如我链接的博文中提到的,将count与列表一起使用有一个缺点,即如果你从列表中间删除一个项目,它将导致所有其他资源都有一个新的索引,Terraform会想删除并重新创建它们。我建议您尝试使用
map
来避免这种情况。在我目前的情况下,我无法更改要求。i、 e.提供的输入、自定义角色列表。