如何使用Terraform for_和dynamic for resource azurerm_network_security_group避免多个循环?

如何使用Terraform for_和dynamic for resource azurerm_network_security_group避免多个循环?,terraform,terraform-provider-azure,Terraform,Terraform Provider Azure,我有一个CSV文件,如下所示 nsg_name,nsg_rule_name,priority,direction,access,protocol,source_port_range,destination_port_range,source_address_prefix,destination_address_prefix,description testinsg,testrule,100,Inbound,Allow,Tcp,*,*,*,*,test testinsg2,testrule2,10

我有一个CSV文件,如下所示

nsg_name,nsg_rule_name,priority,direction,access,protocol,source_port_range,destination_port_range,source_address_prefix,destination_address_prefix,description
testinsg,testrule,100,Inbound,Allow,Tcp,*,*,*,*,test
testinsg2,testrule2,101,Outbound,Allow,Tcp,*,*,*,*,test
resource "azurerm_network_security_group" "this" {
  count               = length(local.nsgs) > 0 && var.create ? length(local.nsgs) : 0
  name                = local.nsgs[count.index].nsg_name
  location            = var.location
  resource_group_name = var.resource_group
  dynamic "security_rule" {
    for_each = [for n in local.nsgs : {
      name                        = n.nsg_rule_name
      priority                    = n.priority
      direction                   = n.direction
      access                      = n.access
      protocol                    = n.protocol
      source_port_range           = n.source_port_range
      destination_port_range      = n.destination_port_range
      source_address_prefix       = n.source_address_prefix
      destination_address_prefix  = n.destination_address_prefix
      description                 = n.description

    }]
    content {
      name                        = security_rule.value.name
      priority                    = security_rule.value.priority
      direction                   = security_rule.value.direction
      access                      = security_rule.value.access
      protocol                    = security_rule.value.protocol
      source_port_range           = security_rule.value.source_port_range
      destination_port_range      = security_rule.value.destination_port_range
      source_address_prefix       = security_rule.value.source_address_prefix
      destination_address_prefix  = security_rule.value.destination_address_prefix
      description                 = security_rule.value.description
    }
  }
}
  # module.nsgs_with_rules.azurerm_network_security_group.this[0] will be created
  + resource "azurerm_network_security_group" "this" {
      + id                  = (known after apply)
      + location            = "southeastasia"
      + name                = "testinsg"
      + resource_group_name = "pub_testing_tf_mofule_env"
      + security_rule       = [
          + {
              + access                                     = "Allow"
              + description                                = "test"
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Inbound"
              + name                                       = "testrule"
              + priority                                   = 100
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
          + {
              + access                                     = "Allow"
              + description                                = "test"
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Outbound"
              + name                                       = "testrule2"
              + priority                                   = 101
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
        ]
      + tags                = (known after apply)
    }

  # module.nsgs_with_rules.azurerm_network_security_group.this[1] will be created
  + resource "azurerm_network_security_group" "this" {
      + id                  = (known after apply)
      + location            = "southeastasia"
      + name                = "testinsg2"
      + resource_group_name = "pub_testing_tf_mofule_env"
      + security_rule       = [
          + {
              + access                                     = "Allow"
              + description                                = "test"
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Inbound"
              + name                                       = "testrule"
              + priority                                   = 100
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
          + {
              + access                                     = "Allow"
              + description                                = "test"
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Outbound"
              + name                                       = "testrule2"
              + priority                                   = 101
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
        ]
      + tags                = (known after apply)
    }
并且具有如下所示的资源块

nsg_name,nsg_rule_name,priority,direction,access,protocol,source_port_range,destination_port_range,source_address_prefix,destination_address_prefix,description
testinsg,testrule,100,Inbound,Allow,Tcp,*,*,*,*,test
testinsg2,testrule2,101,Outbound,Allow,Tcp,*,*,*,*,test
resource "azurerm_network_security_group" "this" {
  count               = length(local.nsgs) > 0 && var.create ? length(local.nsgs) : 0
  name                = local.nsgs[count.index].nsg_name
  location            = var.location
  resource_group_name = var.resource_group
  dynamic "security_rule" {
    for_each = [for n in local.nsgs : {
      name                        = n.nsg_rule_name
      priority                    = n.priority
      direction                   = n.direction
      access                      = n.access
      protocol                    = n.protocol
      source_port_range           = n.source_port_range
      destination_port_range      = n.destination_port_range
      source_address_prefix       = n.source_address_prefix
      destination_address_prefix  = n.destination_address_prefix
      description                 = n.description

    }]
    content {
      name                        = security_rule.value.name
      priority                    = security_rule.value.priority
      direction                   = security_rule.value.direction
      access                      = security_rule.value.access
      protocol                    = security_rule.value.protocol
      source_port_range           = security_rule.value.source_port_range
      destination_port_range      = security_rule.value.destination_port_range
      source_address_prefix       = security_rule.value.source_address_prefix
      destination_address_prefix  = security_rule.value.destination_address_prefix
      description                 = security_rule.value.description
    }
  }
}
  # module.nsgs_with_rules.azurerm_network_security_group.this[0] will be created
  + resource "azurerm_network_security_group" "this" {
      + id                  = (known after apply)
      + location            = "southeastasia"
      + name                = "testinsg"
      + resource_group_name = "pub_testing_tf_mofule_env"
      + security_rule       = [
          + {
              + access                                     = "Allow"
              + description                                = "test"
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Inbound"
              + name                                       = "testrule"
              + priority                                   = 100
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
          + {
              + access                                     = "Allow"
              + description                                = "test"
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Outbound"
              + name                                       = "testrule2"
              + priority                                   = 101
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
        ]
      + tags                = (known after apply)
    }

  # module.nsgs_with_rules.azurerm_network_security_group.this[1] will be created
  + resource "azurerm_network_security_group" "this" {
      + id                  = (known after apply)
      + location            = "southeastasia"
      + name                = "testinsg2"
      + resource_group_name = "pub_testing_tf_mofule_env"
      + security_rule       = [
          + {
              + access                                     = "Allow"
              + description                                = "test"
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Inbound"
              + name                                       = "testrule"
              + priority                                   = 100
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
          + {
              + access                                     = "Allow"
              + description                                = "test"
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Outbound"
              + name                                       = "testrule2"
              + priority                                   = 101
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
        ]
      + tags                = (known after apply)
    }
当我进行计划/应用时,资源试图创建如下规则

nsg_name,nsg_rule_name,priority,direction,access,protocol,source_port_range,destination_port_range,source_address_prefix,destination_address_prefix,description
testinsg,testrule,100,Inbound,Allow,Tcp,*,*,*,*,test
testinsg2,testrule2,101,Outbound,Allow,Tcp,*,*,*,*,test
resource "azurerm_network_security_group" "this" {
  count               = length(local.nsgs) > 0 && var.create ? length(local.nsgs) : 0
  name                = local.nsgs[count.index].nsg_name
  location            = var.location
  resource_group_name = var.resource_group
  dynamic "security_rule" {
    for_each = [for n in local.nsgs : {
      name                        = n.nsg_rule_name
      priority                    = n.priority
      direction                   = n.direction
      access                      = n.access
      protocol                    = n.protocol
      source_port_range           = n.source_port_range
      destination_port_range      = n.destination_port_range
      source_address_prefix       = n.source_address_prefix
      destination_address_prefix  = n.destination_address_prefix
      description                 = n.description

    }]
    content {
      name                        = security_rule.value.name
      priority                    = security_rule.value.priority
      direction                   = security_rule.value.direction
      access                      = security_rule.value.access
      protocol                    = security_rule.value.protocol
      source_port_range           = security_rule.value.source_port_range
      destination_port_range      = security_rule.value.destination_port_range
      source_address_prefix       = security_rule.value.source_address_prefix
      destination_address_prefix  = security_rule.value.destination_address_prefix
      description                 = security_rule.value.description
    }
  }
}
  # module.nsgs_with_rules.azurerm_network_security_group.this[0] will be created
  + resource "azurerm_network_security_group" "this" {
      + id                  = (known after apply)
      + location            = "southeastasia"
      + name                = "testinsg"
      + resource_group_name = "pub_testing_tf_mofule_env"
      + security_rule       = [
          + {
              + access                                     = "Allow"
              + description                                = "test"
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Inbound"
              + name                                       = "testrule"
              + priority                                   = 100
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
          + {
              + access                                     = "Allow"
              + description                                = "test"
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Outbound"
              + name                                       = "testrule2"
              + priority                                   = 101
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
        ]
      + tags                = (known after apply)
    }

  # module.nsgs_with_rules.azurerm_network_security_group.this[1] will be created
  + resource "azurerm_network_security_group" "this" {
      + id                  = (known after apply)
      + location            = "southeastasia"
      + name                = "testinsg2"
      + resource_group_name = "pub_testing_tf_mofule_env"
      + security_rule       = [
          + {
              + access                                     = "Allow"
              + description                                = "test"
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Inbound"
              + name                                       = "testrule"
              + priority                                   = 100
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
          + {
              + access                                     = "Allow"
              + description                                = "test"
              + destination_address_prefix                 = "*"
              + destination_address_prefixes               = []
              + destination_application_security_group_ids = []
              + destination_port_range                     = "*"
              + destination_port_ranges                    = []
              + direction                                  = "Outbound"
              + name                                       = "testrule2"
              + priority                                   = 101
              + protocol                                   = "Tcp"
              + source_address_prefix                      = "*"
              + source_address_prefixes                    = []
              + source_application_security_group_ids      = []
              + source_port_range                          = "*"
              + source_port_ranges                         = []
            },
        ]
      + tags                = (known after apply)
    }
但我正在寻找我在CSV中为每个SG提到的单一规则,当我在CSV中给出重复的nsg名称时,多个规则应适用

nsg_name,nsg_rule_name,priority,direction,access,protocol,source_port_range,destination_port_range,source_address_prefix,destination_address_prefix,description
testinsg,testrule,100,Inbound,Allow,Tcp,*,*,*,*,test
testinsg,testrule2,101,Outbound,Allow,Tcp,*,*,*,*,test
testinsg,testrule3,103,Outbound,Allow,Tcp,*,*,*,*,test
我也尝试过下面的方法,但没有成功

dynamic "security_rule" {
        for_each = [for n in local.nsgs[count.index] : {

请帮我解决这个问题好吗?

我想我可能已经找到了答案,但我没有访问Azure的权限,所以我在一个
aws\u安全组
资源上测试了这个问题

nsgs.csv

nsg_name,nsg_rule_name,priority,direction,access,protocol,source_port_range,destination_port_range,source_address_prefix,destination_address_prefix,description
testinsg,testrule,100,Inbound,Allow,Tcp,*,*,*,*,test
testinsg,testrule2,101,Outbound,Allow,Tcp,*,*,*,*,test
testinsg,testrule3,103,Outbound,Allow,Tcp,*,*,*,*,test
testinsg2,testrule2,101,Outbound,Allow,Tcp,*,*,*,*,test
main.tf

本地人{
#获取列表中的csv内容
nsgs=csvdecode(文件(“nsgs.csv”))
#获取所有唯一的nsg_名称
名称=不同(local.nsgs[*].nsg\u名称)
#对于每个唯一的名称,查找列表中的所有项目
#使用相同的名称,并使用该名称作为键和
#它对匹配项的值
合并={
对于local.names中的名称:
“${name}”=>[
对于本地的nsg.nsg:nsg
如果名称==nsg.nsg\u名称
]
}
}
资源“aws\U安全组”示例{
对于_each=local.combine
name=each.key
description=“测试”
vpc_id=“测试”
动态“入口”{
for_each=each.value
内容{
from_port=入口值[“优先级”]
to_port=入口值[“优先级”]
协议=入口。值[“协议”]
}
}
}
$terraform平面图
#aws_安全组。将创建示例[“testinsg”]
+资源“aws\U安全组”示例{
+arn=(应用后已知)
+description=“测试”
+出口=(应用后已知)
+id=(应用后已知)
+入口=[
+ {
+cidr_块=[]
+description=“”
+从_端口=100
+ipv6_cidr_块=[]
+前缀\u列表\u ID=[]
+协议=“tcp”
+安全组=[]
+self=false
+至_端口=100
},
+ {
+cidr_块=[]
+description=“”
+从_端口=101
+ipv6_cidr_块=[]
+前缀\u列表\u ID=[]
+协议=“tcp”
+安全组=[]
+self=false
+至_端口=101
},
+ {
+cidr_块=[]
+description=“”
+从_端口=103
+ipv6_cidr_块=[]
+前缀\u列表\u ID=[]
+协议=“tcp”
+安全组=[]
+self=false
+至_端口=103
},
]
+name=“testinsg”
+所有者id=(应用后已知)
+在删除时撤销规则=false
+vpc_id=“测试”
}
#aws_安全组。将创建示例[“Testing2”]
+资源“aws\U安全组”示例{
+arn=(应用后已知)
+description=“测试”
+出口=(应用后已知)
+id=(应用后已知)
+入口=[
+ {
+cidr_块=[]
+description=“”
+从_端口=101
+ipv6_cidr_块=[]
+前缀\u列表\u ID=[]
+协议=“tcp”
+安全组=[]
+self=false
+至_端口=101
},
]
+name=“testinsg2”
+所有者id=(应用后已知)
+在删除时撤销规则=false
+vpc_id=“测试”
}
计划:2添加,0更改,0销毁。
因此,我们应该能够使用您的资源来做同样的事情

资源“azurerm\u网络安全组”“此”{
对于_each=local.combine
name=each.key
位置=变量位置
#此值必须是唯一的,因此让我们尝试将其设置为
#local.combine的键而不是原始静态值(var.resource\u group)
#资源组名称=变量资源组
资源组名称=each.value.key
动态“安全规则”{
for_each=each.value
内容{
名称=安全规则。值[“nsg\U名称”]
优先级=安全规则。值[“优先级”]
方向=安全规则。值[“方向”]
访问权限=安全性\规则值[“访问”]
协议=安全规则。值[“协议”]
源\端口\范围=安全\规则。值[“源\端口\范围”]
目的地\端口\范围=安全\规则。值[“目的地\端口\范围”]
源地址前缀=安全规则。值[“源地址前缀”]
目的地地址前缀=安全规则。值[“目的地地址前缀”]
description=security\u rule.value[“description”]
}
}
}

我想我可能已经找到了答案,但我没有访问Azure的权限,所以我在一个
aws\u security\u组
资源上测试了这一点

nsgs.csv

nsg_name,nsg_rule_name,priority,direction,access,protocol,source_port_range,destination_port_range,source_address_prefix,destination_address_prefix,description
testinsg,testrule,100,Inbound,Allow,Tcp,*,*,*,*,test
testinsg,testrule2,101,Outbound,Allow,Tcp,*,*,*,*,test
testinsg,testrule3,103,Outbound,Allow,Tcp,*,*,*,*,test
testinsg2,testrule2,101,Outbound,Allow,Tcp,*,*,*,*,test
main.tf

本地人{
#获取列表中的csv内容
nsgs=csvdecode(文件(“nsgs.csv”))
#获取所有唯一的nsg_名称
名称=不同(local.nsgs[*].nsg\u名称)
#对于每个唯一的名称,查找列表中的所有项目
#使用相同的名称,并使用该名称作为键和
#它对匹配项的值
合并={
在当地的名字。