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

