You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:45:05