Terraform local exec Provisioner在多个Azure虚拟机上运行

Terraform local exec Provisioner在多个Azure虚拟机上运行,azure,ansible,cloud,terraform,Azure,Ansible,Cloud,Terraform,我有一个工作TF设置来在Azure中启动多个Linux虚拟机。我在一个null_资源中运行一个本地exec provisioner来执行Ansible playbook。我正在从TF状态文件中提取私有IP地址。状态文件存储在本地 我最近配置了Azure后端,现在状态文件存储在存储帐户中 我已经修改了本地provisioner,正在尝试获取所有私有IP地址以运行Ansible playbook,如下所示: resource "null_resource" "Ansible4Ubuntu" {

我有一个工作TF设置来在Azure中启动多个Linux虚拟机。我在一个null_资源中运行一个本地exec provisioner来执行Ansible playbook。我正在从TF状态文件中提取私有IP地址。状态文件存储在本地

我最近配置了Azure后端,现在状态文件存储在存储帐户中

我已经修改了本地provisioner,正在尝试获取所有私有IP地址以运行Ansible playbook,如下所示:

resource "null_resource" "Ansible4Ubuntu" {
  provisioner "local-exec" {
    command = "sleep 20;ansible-playbook -i '${element(azurerm_network_interface.unic.*.private_ip_address, count.index)}', vmlinux-playbook.yml"
我也尝试过:

resource "null_resource" "Ansible4Ubuntu" {
  provisioner "local-exec" {
    command = "sleep 20;ansible-playbook -i '${azurerm_network_interface.unic.private_ip_address}', vmlinux-playbook.yml"
它们都可以只处理第一个VM,而忽略其余VM。我也尝试过使用
count.index+1和self.private\u ip\u address
,但没有成功

实际结果:TF只提供Ansible的第一个VM的私有IP

预期结果:TF向Ansible提供所有私有IP的列表,以便它可以针对所有IP运行playbook

PS:我也在考虑使用TF的remote_状态数据结构,但状态文件似乎也包含以前版本中的IP,因此很难提取适合当前版本的IP

我将感谢任何帮助

谢谢
Asghar

正如Matt所说,null_资源只运行一次,因此它只在第一个VM上运行良好,而忽略其余的VM。您需要使用NIC列表为null_资源配置触发器,以使其运行多次。示例代码如下:

resource "null_reousrce" "Ansible4Ubuntu" {

    triggers = {
      network_interface_ids = "${join(",", azurerm_network_interface.unic.*.id)}"
    }

    provisioner "local-exec" {
      command = "sleep 20;ansible-playbook -i '${join(" ", azurerm_network_interface.unic.*.private_ip_address)}, vmlinux-playbook.yml"
  }

}

你可以随心所欲地改变它。有关信息,请参阅。

正如Matt所说,null\u资源只运行一次,因此它只适用于第一个VM,而忽略其余VM。您需要使用NIC列表为null_资源配置触发器,以使其运行多次。示例代码如下:

resource "null_reousrce" "Ansible4Ubuntu" {

    triggers = {
      network_interface_ids = "${join(",", azurerm_network_interface.unic.*.id)}"
    }

    provisioner "local-exec" {
      command = "sleep 20;ansible-playbook -i '${join(" ", azurerm_network_interface.unic.*.private_ip_address)}, vmlinux-playbook.yml"
  }

}

你可以随心所欲地改变它。有关信息,请参阅。

我觉得这里的实际问题是,
local exec
每个块只执行一次,而不是每个资源迭代执行一次,这就是为什么您只能在第一个ip地址上执行。一个更好的解决问题的方法可能是使用Terraform
模板将所有ip地址输出到一个Ansible hosts文件中,然后您可以使用它。我觉得这里的实际问题是
本地执行
只会在每个块执行一次,而不是在每个资源中执行一次迭代,这就是为什么只在第一个ip地址上执行。一个更好的解决问题的方法可能是使用Terraform
模板将所有ip地址输出到一个Ansible hosts文件中,然后您可以利用该文件。谢谢Charles。代码就像一个符咒,在命令中有一个小小的变化(引号中有一个逗号):command=“sleep 20;ansible playbook-i${join(“,”,azurerm_network_interface.cnic.*.private_ip_address)}vmlinux playbook.yml”刚刚尝试了为单个虚拟机设置,ansible报告了清单错误:null_resource.DataDisks4Ubuntu(本地执行):执行:[“/bin/sh”“-c”“sleep 10;ansible playbook-i 100.96.85.4 datadisk playbook.yml”]null_resource.DataDisks4Ubuntu(本地执行):[警告]:无法解析/home/linuxadm/Automation/Terraform/dev这两个函数都可以作为库存源null_resource.DataDisks4Ubuntu(本地执行):[警告]:未解析清单,只有隐式localhost可用…我猜IP地址的末尾必须有逗号才能使其工作?谢谢Charles。代码就像一个符咒,只需在命令中稍作更改(引号中有一个逗号):command=“sleep 20;ansible playbook-I${join(“,“,azurerm_network_interface.cnic.*.private_ip_address)}vmlinux playbook.yml”刚刚尝试为单个VM和Ansible报告的资源清册设置错误:null_resource.DataDisks4Ubuntu(local exec):执行:[“/bin/sh”“-c”“sleep 10;Ansible playbook-i 100.96.85.4 datadisk playbook.yml”]null_resource.DataDisks4Ubuntu(local exec):[警告]:无法将/home/linuxadm/Automation/Terraform/dev tworks/100.96.85.4解析为清单源null_resource.DataDisks4Ubuntu(local exec):[警告]:未解析清单,只有隐式localhost可用……我想IP地址末尾必须有逗号才能使其工作?