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
相关产品推荐
相关产品推荐

