Terraform template_file使用列表类型变量生成metadata配置时报错求助
Terraform template_file使用列表类型变量生成metadata配置时报错求助
嗨,我来帮你搞定这个问题~你遇到的报错核心原因很明确:旧版的data "template_file"数据源的vars参数只支持字符串类型的值,而你传入的var.vm_nameservers是列表类型,这就触发了类型不匹配的错误。
最推荐的解决方案:改用templatefile内置函数
从Terraform 0.12开始,官方就已经推荐用内置的templatefile函数替代data "template_file"了,它天然支持列表、映射这类复杂类型变量,用法更简洁,完全能解决你的问题。
具体修改步骤如下:
- 替换原来的
data "template_file"块为本地值(或者直接在需要用到metadata内容的地方调用函数):
locals { metadata_content = templatefile("${path.module}/templates/metadata.tftpl", { vm_name = var.vm_name vm_ip = var.vm_ip vm_gateway = var.vm_gateway vm_nameservers = var.vm_nameservers }) }
- 你的
metadata.tftpl模板完全不需要修改,原来的for循环语法对templatefile函数完全兼容:
instance-id: ${vm_name} local-hostname: ${vm_name} network: version: 2 ethernets: ens192: dhcp4: false addresses: - ${vm_ip} gateway4: ${vm_gateway} nameservers: addresses: %{ for addr in vm_nameservers ~} - ${addr} %{ endfor ~}
- 变量声明可以稍微优化得更严谨一点(不优化也能正常运行):
variable "vm_nameservers" { type = list(string) # 明确指定是字符串类型的列表 }
- tfvars里的写法保持你原来的样子就行:
vm_nameservers = ["10.10.0.2", "10.10.0.3"]
如果你一定要坚持用data "template_file"(不推荐)
那得把列表转换成字符串再传入,用join函数拼接元素,然后在模板里处理,不过这种方法比较绕:
- 修改data块的vars,把列表转成带格式的字符串:
data "template_file" "metadata" { template = "${file("${path.module}/templates/metadata.tftpl")}" vars = { vm_name = var.vm_name vm_ip = var.vm_ip vm_gateway = var.vm_gateway vm_nameservers = join("\n - ", var.vm_nameservers) } }
- 修改模板里的nameservers部分:
nameservers: addresses: %{ if length(vm_nameservers) > 0 ~} - ${vm_nameservers} %{ endif ~}
这种方法需要注意空列表的情况,容易生成冗余空行,所以还是优先用第一种方案更稳妥。
总结一下,templatefile是官方推荐的新方式,你的Terraform 1.2.8版本完全支持,用它就能完美解决列表变量传入模板的问题啦~
备注:内容来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

