Terraform如何将for循环输出的VM ID通过模板保存到文件
实现方案
第一步:补全templatefile传参逻辑
你不需要在传参阶段处理for循环,直接把两个实例ID的map传入模板即可,循环逻辑放到模板文件内实现:
output "ansible_inventory" { value = templatefile("${path.module}/templates/inventory.tpl", { # 传入master实例的ID映射表 master_id_map = tomap({ for k, master in cloudstack_instance.master : k => master.id }) # 传入worker实例的ID映射表 worker_id_map = tomap({ for k, worker in cloudstack_instance.worker : k => worker.id }) # 可按需追加其他公共参数,比如SSH用户名 ansible_ssh_user = "root" } ) }
如果你需要直接把生成的清单写入本地文件,不需要用output输出,可以改用local_file资源,使用更方便:
resource "local_file" "ansible_inventory" { content = templatefile("${path.module}/templates/inventory.tpl", { master_id_map = tomap({ for k, master in cloudstack_instance.master : k => master.id }) worker_id_map = tomap({ for k, worker in cloudstack_instance.worker : k => worker.id }) ansible_ssh_user = "root" } ) filename = "${path.module}/ansible/inventory.ini" }
注意:如果你实际需要使用实例的IP而非ID作为Ansible连接地址,只需要把上述传参中
master.id/worker.id替换为实例对应的IP属性即可,CloudStack实例的公网IP属性一般为ipv4_address。
第二步:编写模板文件inventory.tpl的循环逻辑
在${path.module}/templates/inventory.tpl文件中使用Terraform模板语法的for循环生成Ansible清单:
[master] %{ for instance_name, instance_id in master_id_map ~} ${instance_name} ansible_host=${instance_id} %{ endfor ~} [worker] %{ for instance_name, instance_id in worker_id_map ~} ${instance_name} ansible_host=${instance_id} %{ endfor ~} [all:vars] ansible_user=${ansible_ssh_user} # 可按需追加其他全局变量,比如私钥路径 ansible_ssh_private_key_file = ~/.ssh/id_rsa
语法说明:模板中~符号用于消除循环生成的多余空行,不需要可直接删除
内容的提问来源于stack exchange,提问作者Agryppa
相关产品推荐
相关产品推荐

