【问题标题】:Terraform interpolation data sourcesTerraform 插值数据源
【发布时间】:2019-12-20 03:38:42
【问题描述】:

我正在配置 Terraform 以在 VMware 中配置虚拟机。每个 VM 将被分配一个与特定 VLAN 连接的第二个网络适配器。 VLAN是根据VM的名字分配的

数据源似乎查询得很好,因为它们都存在。但是,我无法将 count.index 传递到 network_interface 部分的 network_id 中。 我已经尝试了以下方法:

  1. network_id = "${data.vsphere_network.network1."${var.policy_name}".id}"

  2. network_id = "${"${format("%s", "data.vsphere_network.network1.${count.index}.id")}"}"

  3. network_id = "${format("%s", "$${data.vsphere_network.network1.${count.index}.id")}"

唯一可行的方法是我直接分配:

network_id = "${data.vsphere_network.network1.0.id}"

其中 0 是实例。

 data "vsphere_network" "network1" {
  count = "${var.count}"
  name = "${var.network_name1}-${format("%02d", count.index + var.start_index)}"
  datacenter_id = "${data.vsphere_datacenter.datacenter.id}"
 }


 network_interface {
    network_id = "${data.vsphere_network.network1.0.id}" 
    adapter_type = "vmxnet3"
    use_static_mac = "${var.static_mac}"
 }

我希望将 VLAN 01 分配给 VM01。 VLAN 02 分配给 VM02,一直到 48(因为这是我拥有的 VLAN 数量)

【问题讨论】:

  • network_interface 块嵌套在我的资源块中。我可以让它工作的唯一方法是指定“$ {data.vsphere_network.network1.0.id}” - 它只会指向一个vLan,而不是我需要的。我尝试的任何东西都将其转换为字符串并且无法使用。如果我尝试动态分配 ${data.vsphere_network.network1.0.id} 中的数字,它将失败并出现解析错误

标签: terraform


【解决方案1】:

以下示例使用 Terraform 0.12 功能声明每个网络应该有一个实例,并通过其网络 ID 标识每个实例,以便将来添加和删除网络也会导致添加/删除相应的实例:

data "vsphere_network" "network1" {
  count = var.count
  name = "${var.network_name1}-${format("%02d", count.index + var.start_index)}"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

resource "vsphere_virtual_machine" "per_network" {
  # Create one VM per network and identify them using the
  # id value of each one.
  for_each = { for net in data.vsphere_network.network1 : net.id => net }

  # (...other virtual machine arguments...)

  network_interface {
    # each.key is the key from the map in for_each, which is
    # the network id in this case
    network_id = each.key
  }
}

在这里使用for_each 有两个关键优势:

  • 它让未来的读者更清楚,其目的是为每个网络创建一个 VM,因为在 for_each 表达式中直接引用了网络数据资源。

  • 它允许您选择当 Terraform 在状态下跟踪它们时识别每个实例的键。因为在这种情况下,虚拟机由它们的网络唯一标识,所以我们使用网络接口 id,因此 Terraform 将能够正确推断,例如添加一个新网络应该会导致一个新的虚拟机被创建,而移除一个网络应该只会导致对应的虚拟机被销毁。

【讨论】:

  • 嗨,马丁,我很欣赏这篇文章。我尝试实现这一点,它在包含 for_each = { for net in data.vsphere_network.network1 : net.id => net } 的行上显示非法字符。任何建议表示赞赏!
  • 我没有提到它是冒号上的非法字符
  • 您使用的是哪个版本的 Terraform?
  • 最新版本,v0.12.6。我能够让它工作一点,但现在我在资源块中的动态名称不能使用 count.index。 vLans 很好地分配,使用 for_each。但是现在使用新的 terraform 我不能在同一资源块中使用 count 和 for_each 。这是我目前拥有的:name = "${var.vmname}${format("%02d", count.index + var.start_index)}"
  • 确实,您将无法在其中使用count.index,因为这些实例是由网络 ID 而非列表中的位置来键入的。我建议改用${var.vmname}-${each.key} 之类的命名方案,以直接反映它属于哪个网络的名称,这样您就可以很容易地看到在更改网络集时哪些会受到影响。或者,如果你真的想使用索引,你可以从each.value.name 中提取它,它的末尾会有网络号。
猜你喜欢
  • 2018-01-28
  • 2018-09-20
  • 2017-06-11
  • 1970-01-01
  • 2022-12-17
  • 2019-03-04
  • 2021-11-20
  • 1970-01-01
  • 2019-11-18
相关资源
最近更新 更多