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

Terraform解析JSON生成Azure MySQL防火墙规则报错求助

解决Terraform处理重复键JSON生成Azure MySQL防火墙规则的问题

问题说明

通过Python external_data_source 获取到存在重复start/end键的扁平JSON,尝试用Terraform生成对应Azure MySQL灵活服务器防火墙规则时触发报错。

原始JSON数据

{"start":"55.555.100.101","end":"55.555.100.174","start":"40.00.000.161","end":"40.00.000.174"}

初始Terraform代码

resource "azurerm_mysql_flexible_server_firewall_rule" "ip_rule" {
  name                = format("iprule-%s", count.index)
  count               = length(values(data.external.python.result))/2
  resource_group_name = module.resource-group.name
  server_name         = azurerm_mysql_flexible_server.example.name
  start_ip_address    = element(data.external.python.result.start, count.index)
  end_ip_address      = element(data.external.python.result.end, count.index)
}

执行报错

Error: Error in function call

  on mysql_flexible.tf line 105, in resource "azurerm_mysql_flexible_server_firewall_rule" "ip_rule":
 105:   start_ip_address    = element(data.external.python.result.start, count.index)
    |----------------
    | count.index is 0
    | data.external.python.result.start is "40.70.173.161"

Call to function "element" failed: cannot read elements from string.

问题根源

JSON规范不允许重复键,绝大多数解析器(包括Terraform使用的解析器)会自动覆盖重复键,仅保留最后一组键值对。因此data.external.python.result.start实际是字符串类型而非数组,element函数无法从字符串中读取元素,导致报错。

解决方案

1. 修正Python脚本输出格式

修改Python脚本,输出合法的数组结构JSON,避免重复键:

import json

# 示例:生成包含多组IP规则的数组
ip_rules = [
    {"start": "55.555.100.101", "end": "55.555.100.174"},
    {"start": "40.00.000.161", "end": "40.00.000.174"}
]

# 输出包含数组的JSON对象
print(json.dumps({"ip_rules": ip_rules}))

2. 更新Terraform代码

解析修正后的JSON数组,通过for_each遍历生成防火墙规则:

data "external" "python" {
  program = ["python", "./path/to/your/script.py"]
}

locals {
  # 解析JSON并提取IP规则列表
  ip_rules = jsondecode(data.external.python.result).ip_rules
}

resource "azurerm_mysql_flexible_server_firewall_rule" "ip_rule" {
  # 用for_each遍历规则,确保每个规则唯一标识
  for_each            = { for idx, rule in local.ip_rules : "iprule-${idx}" => rule }
  name                = each.key
  resource_group_name = module.resource-group.name
  server_name         = azurerm_mysql_flexible_server.example.name
  start_ip_address    = each.value.start
  end_ip_address      = each.value.end
}

关键说明

  • 若无法修改Python脚本,重复键的JSON无法被正确解析为多组IP规则,因为解析后仅保留最后一组数据,无法生成多防火墙规则。
  • 使用for_each替代count可获得更稳定的资源标识,避免因列表顺序变化导致资源重建。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:05:39