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

