You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform条件for_each报错:条件结果类型不一致问题

解决Terraform中for_each条件表达式类型不一致问题

错误原因

报错核心是条件表达式的两个分支类型不匹配:

  • 条件为true时,你通过toset()把列表转换成了set(string)类型
  • 条件为false时,返回的{}是一个空对象(object({})类型)
    Terraform要求条件表达式的两个结果必须是相同类型,同时var.environment可能在apply阶段才能确定值,进一步要求类型严格一致。

解决方案

方案1:统一条件分支的类型

将false分支的空对象{}替换为空集合toset([]),确保两个分支都返回set(string)类型:

variable "environment" {
   default = "dev"
}

locals {
    management_groups = [
        "/providers/Microsoft.Management/managementGroups/one",
        "/providers/Microsoft.Management/managementGroups/two"
    ]

    management_groups_aux = [
        "/providers/Microsoft.Management/managementGroups/three",
        "/providers/Microsoft.Management/managementGroups/four"
    ]
}

resource "azurerm_resource_group" "this" {
  name     = "myrg"
  location = "West Europe"
}

resource "azurerm_user_assigned_identity" "this" {
    name = "myuai"
    resource_group_name = azurerm_resource_group.this.name
    location  = azurerm_resource_group.this.location
}

resource "azurerm_role_assignment" "dev" {
  for_each             = lower(var.environment) == "dev" ? toset(local.management_groups) : toset([])
  scope                = each.value
  role_definition_name = "Reader"
  principal_id         = resource.azurerm_user_assigned_identity.this.principal_id
}

resource "azurerm_role_assignment" "production" {
  for_each             = lower(var.environment) == "production" ? toset(local.management_groups_aux) : toset([])
  scope                = each.value
  role_definition_name = "Reader"
  principal_id         = resource.azurerm_user_assigned_identity.this.principal_id
}

方案2:优化为单个资源块(推荐)

通过local变量动态选择对应环境的管理组列表,再统一转换为集合,避免重复定义资源块:

variable "environment" {
   default = "dev"
}

locals {
    management_groups = [
        "/providers/Microsoft.Management/managementGroups/one",
        "/providers/Microsoft.Management/managementGroups/two"
    ]

    management_groups_aux = [
        "/providers/Microsoft.Management/managementGroups/three",
        "/providers/Microsoft.Management/managementGroups/four"
    ]

    # 根据环境动态选择管理组列表
    selected_management_groups = lower(var.environment) == "dev" ? local.management_groups :
                                 lower(var.environment) == "production" ? local.management_groups_aux :
                                 [] # 其他环境返回空列表
}

resource "azurerm_resource_group" "this" {
  name     = "myrg"
  location = "West Europe"
}

resource "azurerm_user_assigned_identity" "this" {
    name = "myuai"
    resource_group_name = azurerm_resource_group.this.name
    location  = azurerm_resource_group.this.location
}

resource "azurerm_role_assignment" "this" {
  for_each             = toset(local.selected_management_groups)
  scope                = each.value
  role_definition_name = "Reader"
  principal_id         = resource.azurerm_user_assigned_identity.this.principal_id
}

这个方案更简洁,减少了代码冗余,同时天然保证了类型一致性——所有分支都返回tuple(string)类型,转换为set后可以直接用于for_each。

内容的提问来源于stack exchange,提问作者Ricky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 08:40:39