在terraform中循环使用外部数据源

在terraform中循环使用外部数据源,terraform,Terraform,我试图在terraform中提供n个VM(假设n=5) 问题是,对于分配给相应VM的每个IP,我首先需要调用一个外部工具(an.exe)。此工具有两个参数:要获取的IP的正则表达式模式和机器名。然后,该工具根据提供的正则表达式,从充当IPAM(IP地址管理解决方案)的Sharepoint Excel文件中读取要使用的单个空闲IP地址。该工具还更新Excel文件,以便在返回的IP旁边标记提供的机器名 对于单个VM来说,这一切都很好,一切都按预期完成,利用了一个外部数据源和一个资源。机器名从输入文件

我试图在terraform中提供n个VM(假设n=5)

问题是,对于分配给相应VM的每个IP,我首先需要调用一个外部工具(an.exe)。此工具有两个参数:要获取的IP的正则表达式模式和机器名。然后,该工具根据提供的正则表达式,从充当IPAM(IP地址管理解决方案)的Sharepoint Excel文件中读取要使用的单个空闲IP地址。该工具还更新Excel文件,以便在返回的IP旁边标记提供的机器名

对于单个VM来说,这一切都很好,一切都按预期完成,利用了一个外部数据源和一个资源。机器名从输入文件中读取,与IP的正则表达式相同,它使用自己的文件。然后调用外部工具:

data "external" "Machine_name" {
    program = ["cmd.exe", "/c type c:\\Users\\malbert\\Desktop\\Excel2VM\\MachineName.txt"]
}

data "external" "IPregexMatchPattern" {
    program = ["cmd.exe", "/c type c:\\Users\\malbert\\Desktop\\Excel2VM\\IPregexMatchPattern.txt"]
}

output "MachineName" {
  value = "${data.external.Machine_name.result.name}"
}

data "external" "NetworkObtainedData" {
      program = ["cmd.exe", "/c ExcelUpdateTool.exe ${data.external.IPregexMatchPattern.result.IPregex} ${data.external.Machine_name.result.name} available" ]
}

# Use as an output so the user can see the value as well
output "ip" {
    value = "${data.external.NetworkObtainedData.result.ip}"
}
output "netmask" {
    value = "${data.external.NetworkObtainedData.result.netmask}"
}

output "gw" {
    value = "${data.external.NetworkObtainedData.result.gw}"
接下来,将根据输入文件命名VM:

resource "vsphere_virtual_machine" "vm" {
  # Name the VM
  name             = "${data.external.Machine_name.result.name}"

  resource_pool_id = "${data.vsphere_resource_pool.pool.id}"
  datastore_id     = "${data.vsphere_datastore.datastore.id}"
然而,当尝试为n个VM扩展时,我遇到了以下问题:我可以在资源部分中迭代n个项目,从而生成n个VM; 但是,我不知道如何对外部数据源执行相同的操作,因为此数据源不支持为循环设计的结构(计数/长度(…)。到目前为止,我所取得的成就如下。定义了一个新的.tf文件,以便它包含列表中所有机器的名称:

variable machineNamesList {
        default = [ "terraform-firstMachine", "terraform-secondMachine"]
}
在“资源”部分下,列表循环浏览:

resource "vsphere_virtual_machine" "vm" {
  count = "${length(var.machineNamesList)}"
  # We'll name the VM the same as the guest running inside
  name             = "${var.machineNamesList[count.index]}"

  resource_pool_id = "${data.vsphere_resource_pool.pool.id}"
  datastore_id     = "${data.vsphere_datastore.datastore.id}"
但是,如何在每次处理新VM时调用外部工具n次呢


任何指向正确方向的指针都将受到欢迎。

所有
资源
数据
块都支持
计数
参数,因此您可以通过将不同对象上的
计数
设置为同一表达式来实现这一点:

variable "machine_count" {
}

data "external" "machine_name" {
  count = "${var.machine_count}"

  # (presumably in practice you'll use count.index in here somewhere)
  program = ["cmd.exe", "/c", "type c:\\Users\\malbert\\Desktop\\Excel2VM\\MachineName.txt"]
}

resource "vsphere_virtual_machine" "vm" {
  count = "${var.machine_count}"

  name = "${data.external.machine_name.*.result.name[count.index]}"

  # ...etc...
}

在Terraform文档的一节中有关于这种机制的更多信息。尽管这里的示例讨论的是
资源
块,
计数
机制对
资源
数据
块的作用是相同的。

如果您能够展示您迄今为止对单个VM的工作代码和对多个VM不工作的代码所做的尝试,以及它不工作的原因,这将非常有用(显示任何错误或解释它的作用以及它与您想要的不同之处)。@ydaetskcoR:你说得对-我的原始帖子是在匆忙中写的。我现在已经扩展了它,还插入了图片(不幸的是,没有插入,因为我还没有所需的最低声誉)。请不要包括代码的屏幕截图。而是将代码粘贴到问题中作为文本,并将其格式化为代码(通过UI按钮,将所有内容缩进4个空格,或突出显示所有内容并按ctrl-k)@ydaetskcoR谢谢。完成:)谢谢,Martin。我遇到的问题是NetworkAcquiredData外部数据源需要调用机器计数次。我在NetworkAcquiredData中添加了
count=“${var.machine\u count}”
,就在要调用的程序的正上方。但是,当尝试在资源内部使用
ipv4\u address=“${data.external.networkacquireddata.result.*.IP[count.index]}”分配返回给VM的每个IP地址时,我得到
vsphere\u virtual\u machine.VM[0]:Resource'data.external.NetworkAcquiredData'not found for variable'data.external.NetworkAcquiredData.result.*.ip'
在地形图的输出中。正如您在中很好地指出的,我使用的是…result.*.ip。。。而不是…*.result.ip。改变之后,一切都很完美。