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

Terraform AzureRM:For_each调用模块返回资源ID遇错求助

问题解决:Terraform Synapse池模块输出及循环调用错误修正

错误原因分析

你的错误源于对Terraform模块实例和资源对象的理解偏差:

  • 被调用的synapse_pool模块是通过for_each创建的多个独立实例,每个模块实例内部仅包含一个azurerm_synapse_sql_pool资源对象,而非map集合。
  • 原输出中使用values(azurerm_synapse_sql_pool.synapse_sql_pool).*.id是错误的:values()函数仅适用于map类型,而单个资源对象是primitive类型,无法用该函数处理。

分步解决方案

1. 修正synapse_pool模块的输出

将模块内的输出改为返回单个资源的ID,因为每个模块实例仅对应一个Synapse池:

resource "azurerm_synapse_sql_pool" "synapse_sql_pool" {
  name                      = var.name
  sku_name                  = var.synapse_pool_sku_name
  # 其他配置项
}

output "synapse_sql_pool_id" {
  value = azurerm_synapse_sql_pool.synapse_sql_pool.id
}

2. 调整调用方的循环逻辑

由于module.create_synapse_pools是一个map类型的模块实例集合(键为Synapse池名称,值为对应模块实例),你需要从这个map中提取所有ID来供后续模块循环使用。

方式1:使用名称-ID映射的map(推荐,避免重复ID冲突)

这种方式保留了池名称与ID的关联,便于后续模块中识别资源:

module "grant_rbac_on_pools_to_automation_account" {
  source       = "../../resource_modules/role_assignment"
  for_each     = { for pool_name, pool_module in module.create_synapse_pools : pool_name => pool_module.synapse_sql_pool_id }
  
  # 示例:传递池ID作为权限作用域
  scope        = each.value
  # 其他RBAC配置项
}

方式2:使用ID列表(仅当ID无重复时可用)

如果仅需要ID的集合,可通过splat表达式提取:

module "grant_rbac_on_pools_to_automation_account" {
  source       = "../../resource_modules/role_assignment"
  for_each     = toset(values(module.create_synapse_pools)[*].synapse_sql_pool_id)
  
  scope        = each.value
  # 其他RBAC配置项
}

关键知识点

  • 当使用for_each调用模块时,模块引用会变成一个map,键为for_each定义的键,值为对应模块实例的输出。
  • 单个模块实例内的资源是独立对象,直接访问其属性即可,无需使用values()或splat处理(除非资源本身是通过for_each创建的多个实例)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 17:25:06