如何使用Terraform for_和dynamic for resource azurerm_network_security_group避免多个循环?
我有一个CSV文件,如下所示如何使用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
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名称)
#对于每个唯一的名称,查找列表中的所有项目
#使用相同的名称,并使用该名称作为键和
#它对匹配项的值
合并={
在当地的名字。