如何使用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?
本文介绍了如何使用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屋!
查看全文