Terraform使用for_each处理Azure API管理多产品关联问题
解决Terraform批量关联Azure API管理产品与API的问题
问题根源
- 资源关联逻辑错误:
azurerm_api_management_product_api要求每个实例对应一个API与一个产品的配对,但当前代码直接将API的产品列表赋值给product_id,不符合资源的单实例语义,导致批量场景报错。 - 变量格式错误:示例中
products = ["product1,product2"]是包含单个字符串的列表,实际需要拆分为独立元素的列表["product1", "product2"]。
修正方案
1. 重构产品资源的循环方式
将产品资源从count改为for_each,用产品ID作为键,后续引用更直观:
resource "azurerm_api_management_product" "products" { for_each = toset(var.create_product_groups) api_management_name = azurerm_api_management.api-mgmt-service.name display_name = each.key product_id = each.key published = true resource_group_name = azurerm_api_management.api-mgmt-service.resource_group_name subscription_required = true # 可选参数 approval_required = true description = "" subscriptions_limit = 1 terms = "" }
2. 扁平化API-产品配对集合
通过本地变量将每个API的产品列表展开,生成所有需要关联的API-产品配对,再用for_each遍历这些配对创建关联资源:
locals { # 展开所有API与产品的配对 api_product_combinations = flatten([ for api_key, api in var.apis : [ for product_id in api.products : { api_key = api_key product_id = product_id api_name = api.name } ] ]) # 转换为可用于for_each的映射(键需唯一) api_product_map = { for combo in local.api_product_combinations : "${combo.api_key}-${combo.product_id}" => combo } } resource "azurerm_api_management_product_api" "products" { for_each = local.api_product_map api_management_name = azurerm_api_management.api-mgmt-service.name api_name = each.value.api_name product_id = each.value.product_id resource_group_name = azurerm_api_management.api-mgmt-service.resource_group_name }
3. 修正变量的产品列表格式
确保products是包含独立产品ID的字符串列表:
apis = { api1 = { name = "api1" revision = "1" path = "pathapi" content_value = file("./files/api.yaml") k8s_backend = "https://xyz.cloud" products = ["product1", "product2"] # 拆分为独立元素 } }
说明
- 用
for_each替代count管理产品资源,避免因列表顺序变化导致资源重建,同时简化后续引用。 - 扁平化配对集合确保每个API-产品组合对应一个独立的
azurerm_api_management_product_api实例,符合Azure资源的创建逻辑。
内容的提问来源于stack exchange,提问作者Matt Bernard
相关产品推荐
相关产品推荐

