如何用yq将YAML序列转为Map并用于Terraform的locals.tf?
将YAML序列转换为Terraform locals可用的Map结构
需求说明
原始YAML序列:
- cidr: 192.168.0.1/32 description: "test" - cidr: 192.168.0.2/32 description: "test"
需要转换为Terraform locals支持的Map结构:
Rule1: - cidr: 192.168.0.1/32 description: "test" Rule2: - cidr: 192.168.0.2/32 description: "test"
实现方法
1. 手动转换(适合条目较少的场景)
直接给每个序列项添加命名键,遵循Terraform HCL的缩进规范:
- 给第一个规则添加
Rule1:作为键,将原规则内容缩进2个空格放在其下方 - 第二个规则同理添加
Rule2:,依次完成所有条目
2. 使用Terraform内置函数自动转换(推荐)
无需修改原始数据,直接在locals.tf中通过for循环将列表转换为Map结构,后续可直接引用生成的Map:
locals { # 原始规则列表(直接沿用原YAML结构,调整为Terraform列表格式) original_rules = [ { cidr = "192.168.0.1/32" description = "test" }, { cidr = "192.168.0.2/32" description = "test" } ] # 转换为目标Map结构 mapped_rules = { for idx, rule in local.original_rules : "Rule${idx + 1}" => [rule] # 用[]包裹匹配目标格式的列表结构 } }
执行terraform console验证结果,local.mapped_rules会输出符合要求的Map:
{ "Rule1" = [ { cidr = "192.168.0.1/32" description = "test" } ] "Rule2" = [ { cidr = "192.168.0.2/32" description = "test" } ] }
3. 脚本批量转换(适合条目较多的场景)
如果原始规则条目数量大,可以用Python脚本批量处理:
import yaml # 读取原始YAML文件 with open("original_rules.yaml", "r") as f: rules = yaml.safe_load(f) # 构建目标Map converted = {} for num, rule in enumerate(rules, start=1): converted[f"Rule{num}"] = [rule] # 写入转换后的内容到文件(适配HCL格式) with open("converted_locals.tf", "w") as f: for key, value in converted.items(): f.write(f"{key}:\n") for item in value: f.write(" - cidr: {}\n".format(item['cidr'])) f.write(" description: {}\n".format(item['description']))
运行脚本后,converted_locals.tf会生成符合要求的内容,直接复制到你的locals.tf即可。
内容的提问来源于stack exchange,提问作者surya
相关产品推荐
相关产品推荐

