Terraform生成Ansible动态清单报错:列表类型不匹配template_file vars
Terraform 生成Ansible动态清单时类型不匹配问题解决
问题场景
通过带count的Terraform模块创建多台VM,模块输出public_ip为包含多个IP的列表(如["10.3.1.150","10.3.1.151"]),尝试用template_file数据源将该列表写入文件生成Ansible动态清单时,触发类型不匹配错误。
报错信息如下:
Error: Incorrect attribute value type │ │ on output.tf line 11, in data "template_file" "ansible_inventory": │ 11: vars = { │ 12: consul-ip = module.vm-consul.public_ip │ 13: } │ ├──────────────── │ │ module.vm-consul.public_ip is tuple with 2 elements │ │ Inappropriate value for attribute "vars": element "consul-ip": string required.
报错原因
template_file数据源的vars参数要求所有值必须是字符串类型,但传递的module.vm-consul.public_ip是元组(列表)类型,因此触发类型校验错误。
解决方案
方法1:将列表转为字符串传递(兼容旧版写法)
使用join函数把IP列表拼接成换行分隔的字符串,适配Ansible清单的格式要求。
修改template_file配置:
data "template_file" "ansible_inventory" { template = file("ansible_inventory.tpl") vars = { consul-ip = join("\n", module.vm-consul.public_ip) } }
对应的ansible_inventory.tpl模板内容:
[consul] ${consul-ip}
方法2:使用templatefile内置函数(推荐)
Terraform 0.12+推荐使用内置的templatefile函数替代template_file数据源,它支持直接传递列表、映射等复杂类型,模板内还能使用循环、条件逻辑,更灵活。
示例代码(结合local_file生成清单文件):
resource "local_file" "ansible_inventory" { filename = "./ansible_inventory.ini" content = templatefile("ansible_inventory.tpl", { consul_ips = module.vm-consul.public_ip }) }
对应的ansible_inventory.tpl模板(直接遍历列表):
[consul] %{ for ip in consul_ips ~} ${ip} %{ endfor ~}
总结
两种方法都能解决类型不匹配问题,方法2更符合现代Terraform的最佳实践,支持更复杂的模板逻辑,建议优先使用。
内容的提问来源于stack exchange,提问作者Allanian Shade
相关产品推荐
相关产品推荐

