如何使用Terraform for_each和Dynamic for资源azurerm_Network_Security_group避免多个循环? [英] How I can avoid multiple loops with Terraform for_each and dynamic for resource azurerm_network_security_group?

查看:0
本文介绍了如何使用Terraform for_each和Dynamic for资源azurerm_Network_Security_group避免多个循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下所示的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)
    }

但我正在为每个SG寻找我在CSV中提到的单一规则,当我在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_security_group资源上进行了测试。

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

locals {
  # get csv content in a list
  nsgs = csvdecode(file("nsgs.csv"))
  # get all the unique nsg_names
  names = distinct(local.nsgs[*].nsg_name)
  # for each unique name, find all the items in the list
  # with the same name and use the name as the key and set
  # its value to the matching items
  combine = {
    for name in local.names : 
      "${name}" => [
        for nsg in local.nsgs : nsg
        if name == nsg.nsg_name
      ]
  }
}

resource "aws_security_group" "example" {
  for_each = local.combine

  name        = each.key
  description = "test"
  vpc_id      = "test"

  dynamic "ingress" {
    for_each = each.value

    content { 
      from_port = ingress.value["priority"]
      to_port   = ingress.value["priority"]
      protocol  = ingress.value["protocol"]
    }
  }
}
$ terraform plan
  # aws_security_group.example["testinsg"] will be created
  + resource "aws_security_group" "example" {
      + arn                    = (known after apply)
      + description            = "test"
      + egress                 = (known after apply)
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = []
              + description      = ""
              + from_port        = 100
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 100
            },
          + {
              + cidr_blocks      = []
              + description      = ""
              + from_port        = 101
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 101
            },
          + {
              + cidr_blocks      = []
              + description      = ""
              + from_port        = 103
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 103
            },
        ]
      + name                   = "testinsg"
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + vpc_id                 = "test"
    }

  # aws_security_group.example["testinsg2"] will be created
  + resource "aws_security_group" "example" {
      + arn                    = (known after apply)
      + description            = "test"
      + egress                 = (known after apply)
      + id                     = (known after apply)
      + ingress                = [
          + {
              + cidr_blocks      = []
              + description      = ""
              + from_port        = 101
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 101
            },
        ]
      + name                   = "testinsg2"
      + owner_id               = (known after apply)
      + revoke_rules_on_delete = false
      + vpc_id                 = "test"
    }

Plan: 2 to add, 0 to change, 0 to destroy.

因此我们应该能够使用您的资源来执行相同的操作

resource "azurerm_network_security_group" "this" {
  for_each = local.combine

  name                = each.key
  location            = var.location

  # This value has to be unique so let's try setting it to
  # local.combine's key instead of the original static value (var.resource_group)
  # resource_group_name = var.resource_group
  resource_group_name = each.value.key

  dynamic "security_rule" {
    for_each = each.value

    content {
      name                        = security_rule.value["nsg_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"]
    }
  }
}

这篇关于如何使用Terraform for_each和Dynamic for资源azurerm_Network_Security_group避免多个循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆