【问题标题】:How to pass values from one's module list to another module with for_each如何使用 for_each 将值从一个模块列表传递到另一个模块
【发布时间】:2021-11-13 08:01:03
【问题描述】:

我有一个创建 vnet 和子网的模块(模块 vnet):

resource "azurerm_virtual_network" "xxx" {
  count               = length(var.vnets)
  name                = var.vnets[count.index].vnet_name
  address_space       = var.vnets[count.index].address_space
  location            = var.resource_location
  resource_group_name = var.resource_group_name

  dynamic "subnet" {
    for_each = var.vnets[count.index].subnets

    content {
      name           = subnet.value.name
      address_prefix = subnet.value.address
      security_group = azurerm_network_security_group.xxx.id
    }
  }

  tags = var.tags

}

var.vnets 是

vnets = [
  {
    vnet_name     = "01-vnet"
    address_space = ["10.0.0.0/23"]
    subnets = [
      {
        name    = "workloads-01"
        address = "10.0.0.0/24"
      }
    ]
  },
  {
    vnet_name     = "02-vnet"
    address_space = ["10.0.2.0/23"]
    subnets = [
      {
        name    = "workloads-02"
        address = "10.0.2.0/24"
      }
    ]
  }
]

然后我将子网传递给我的根文件

output "subnets" {
  value = flatten(azurerm_virtual_network.xxx[*].subnet[*].id)

}

结果输出

Outputs:

subnets = [
  "/subscriptions/XXX/resourceGroups/EIS/providers/Microsoft.Network/virtualNetworks/eis-01-vnet/subnets/eis-workloads-01",
  "/subscriptions/XXX/resourceGroups/EIS/providers/Microsoft.Network/virtualNetworks/eis-02-vnet/subnets/eis-workloads-02",
]

现在我想在另一个模块(vm 模块)中创建虚拟机时使用这些子网:

resource "azurerm_network_interface" "nics" {
  for_each            = var.vms
  name                = "${each.value.name}-nic"
  location            = var.resource_location
  resource_group_name = var.resource_group_name

  ip_configuration {
    name                          = "iface-${each.value.name}"
    subnet_id                     = element(var.subnet_id, count.index)
    private_ip_address_allocation = "Dynamic"
  }

  tags = var.tags

}

var.vms 在哪里

vms = {
  vm1 = {
    name      = "vm1"
    vm_size   = "Standard_B1ms"
    username  = "centos"
    password  = "222!"
    disk_size = "30"
    sku       = "7_9"
    ext_ip    = "1"
  },
  vm2 = {
    name      = "vm2"
    vm_size   = "Standard_B1ls"
    username  = "centos"
    password  = "111!"
    disk_size = "35"
    sku       = "7_9"
    ext_ip    = ""
  }
}

而 var.subnet_id 只是,在 vm 模块中定义。

variable "subnet_id" {}

我的根目录的 main.tf

module "vm" {
  source = "./modules/vm"
  for_each = var.vms

  vms                 = var.vms
  publicip_name       = var.publicip_name
  subnet_id           = module.vnet.subnets[*]
  resource_group_name = azurerm_resource_group.xxx.name
  resource_location   = azurerm_resource_group.xxx.location

  tags = local.common_tags
}

如何将子网 ID 从模块 vnet 传递到模块 vm,因此资源“azurerm_network_interface”将为 vms 中定义的每个键使用一个子网 ID?

我会使用“element(var.subnet_id, count.index)”作为计数,但是如何将这些子网 ID 传递给将使用 for_each 创建的资源?

【问题讨论】:

  • flatten(azurerm_virtual_network.eis[*].subnet[*].id)结果的例子是什么?
  • 你能用格式正确的代码更新问题吗?
  • 刚刚做了,是的。
  • element(var.subnet_id, count.index)module.vnet.subnets[*] 有什么关系? var.subnet_id 也没有显示?这是一些平面列表吗?
  • 我使用 for_each 从映射 vms 创建 NIC。如您所见,我已经定义了其中的 2 个。我还刚刚在另一个模块中创建了 2 个子网,我需要将该子网的 id 传递给我要创建 NIC 的资源。就是这样。

标签: azure terraform terraform-provider-azure


【解决方案1】:

您可以使用以下索引遍历您的var.vms

resource "azurerm_network_interface" "nics" {
  for_each            = {for idx, vm in keys(var.vms): idx => var.vms[vm]}
  name                = "${each.value.name}-nic"
  location            = var.resource_location
  resource_group_name = var.resource_group_name

  ip_configuration {
    name                          = "eis-iface-${each.value.name}"
    subnet_id                     = element(var.subnet_id, each.key)
    private_ip_address_allocation = "Dynamic"
  }

  tags = var.tags

}

注意:keys 按字母顺序返回地图键(如果有)。

【讨论】:

  • 嘿,还有一个问题。使用该块,它会创建 4 个 NIC,而不是 2 个。我已经为 NIC 的 ID 创建了输出,我看到了以下内容。
  • nics = [ [ "/subscriptions/XXX/resourceGroups/EIS/providers/Microsoft.Network/networkInterfaces/vm1-nic", "/subscriptions/XXX/resourceGroups/EIS/providers/Microsoft.Network/networkInterfaces/vm2-nic", ], [ "/subscriptions/XXX/resourceGroups/EIS/providers/Microsoft.Network/networkInterfaces/vm1-nic", "/subscriptions/XXX/resourceGroups/EIS/providers/Microsoft.Network/networkInterfaces/vm2-nic", ], ] 为什么是 4 个?必须是 2。
  • @DmitryP azurerm_network_interface.nics 将只有两个元素,它不会是一个列表。 azurerm_network_interface.nics 将是一张地图,因此我不确定 nics 你在展示什么。
猜你喜欢
  • 2019-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-18
  • 1970-01-01
  • 1970-01-01
  • 2019-03-02
  • 2021-03-07
相关资源
最近更新 更多