如何删除 Terraform 中两个列表的笛卡尔积元素?

How to delete an element of cartesian product of a two lists in Terraform?

我想使用 Terraform 在不同子网之间的 Azure 中创建一组网络安全 (nsg) 规则。为此,我编写了以下代码:

#here, a set of subnets are created according to the value of count. 
resource "azurerm_subnet" "mysubnets" {
    count = var.subnet_number
    name = join("-", ["subnet", count.index])
    resource_group_name = var.rgname
    virtual_network_name = azurerm_virtual_network.Global_VNet.name
    address_prefix = join(".", ["10.0", "${count.index}", "0/24"])
}

product 下面的变量是为了创建带有子网对的 nsg 规则而创建的。它可以迭代子网对。我在资源声明中检索 address_prefixes azurerm_network_security_rule

locals {
  product = "${setproduct(azurerm_subnet.mysubnets, azurerm_subnet.mysubnets)}"
}

resource "azurerm_network_security_rule" "myNSGrule" {
      count                       = var.subnet_number * var.subnet_number
      source_address_prefix       = lookup(element(local.product, count.index)[0],"address_prefix")
      destination_address_prefix  = lookup(element(local.product, count.index)[1],"address_prefix")
      name                        = join("-", ["nsg","${count.index}"])
      priority                    = 100 + count.index
      direction                   = "Outbound"
      access                      = "Allow"
      protocol                    = "*"
      source_port_range           = "*"
      destination_port_range      = "*"
      resource_group_name         = var.rgname
      network_security_group_name = azurerm_network_security_group.myNSG.name

}


resource "azurerm_virtual_network" "Global_VNet" {
  name                = var.vnetname
  resource_group_name = var.rgname
  address_space       = var.VNetAddressSpace
  location            = var.location
}

resource "azurerm_network_security_group" "myNSG" {
  name                = join("-", ["${var.rgname}", "nsg"])
  location            = var.location
  resource_group_name = var.rgname
}


#NSG subnet association
 resource "azurerm_subnet_network_security_group_association" "LabNSGAssoc" {
  count                     = var.subnet_number
  subnet_id                 = azurerm_subnet.mysubnets[count.index].id
  network_security_group_id = azurerm_network_security_group.myNSG.id
} 

我想避免目标和源前缀相同的 nsg 规则,如下所示:

我尝试了几种不同的 Terraform 功能,但找不到解决方案。你有什么想法?

您可以使用 for expression 的可选 if 子句过滤集合:

locals {
  product = [
    for pair in setproduct(azurerm_subnet.mysubnets, azurerm_subnet.mysubnets) : pair
    if pair[0] != pair[1]
  ]
}

if 子句过滤掉给定条件不成立的任何元素,因此对于上述条件,结果将仅包括 pair 的第一个和第二个元素为不同。