I’m facing an issue where I’d like to use the azurerm_network_security_rule
module to specify some “conflicting” rules that I’d like applied to my network security group.
In the module documentation I understand that there is a field for destination_port_range
and destination_port_ranges
. I want to specify some security rules that enable two seperate rules, each using one of the mentioned fields. I have the following sub-module to bypass conflicts, which does work, but when I execute terraform apply
and second time it removes the configuration.
for_each = { for rule in var.security_rules : rule.name => rule }
name = each.key
direction = each.value.direction
access = each.value.access
priority = each.value.priority
protocol = each.value.protocol
resource_group_name = var.resource_group_name
network_security_group_name = var.network_security_group_name
source_port_range = try(each.value.source_port_range, null)
source_port_ranges = try(each.value.source_port_ranges, null)
destination_port_range = try(each.value.destination_port_range, null)
destination_port_ranges = try(each.value.destination_port_ranges, null)
source_address_prefix = try(each.value.source_address_prefix, null)
source_address_prefixes = try(each.value.source_address_prefixes, null)
destination_address_prefix = try(each.value.destination_address_prefix, null)
destination_address_prefixes = try(each.value.destination_address_prefixes, null)
source_application_security_group_ids = try(each.value.source_application_security_group_ids, null)
destination_application_security_group_ids = try(each.value.destination_application_security_group_ids, null)
lifecycle {
prevent_destroy = true
}
}```
variables.tf:
```variable "resource_group_name" {
description = "Name of the resource group"
type = string
}
variable "network_security_group_name" {
description = "Name of the NSG to attach the rules to"
type = string
}
variable "security_rules" {
description = "A list of network security rules to apply to the NSG."
type = list(object({
name = string
priority = number
direction = string
access = string
protocol = string
source_port_range = optional(string)
source_port_ranges = optional(list(string))
destination_port_range = optional(string)
destination_port_ranges = optional(list(string))
source_address_prefix = optional(string)
source_address_prefixes = optional(list(string))
destination_address_prefix = optional(string)
destination_address_prefixes = optional(list(string))
source_application_security_group_ids = optional(list(string))
destination_application_security_group_ids = optional(list(string))
}))
}
Usage in my root module:
source = "../../modules/network_security_group"
nsg_name = "${local.subscription_prefix}-nsg1"
resource_group_name = module.resource_group_state.resource_group_name_output
location = var.location
tags = var.tags
}
module "network_security_rules" {
source = "../../modules/network_security_rule_advanced_for_each"
resource_group_name = module.resource_group_state.resource_group_name_output
network_security_group_name = module.nsg_state.nsg_name_output
security_rules = var.security_rules
}
.tfvars:
{
name = "AllowHTTPSInboundFromAzure"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_ranges = ["443"] # Keep as list for specific ports
source_address_prefix = "AzureCloud"
destination_address_prefix = "*"
},
{
name = "DenyAllInbound"
priority = 4000
direction = "Inbound"
access = "Deny"
protocol = "*"
source_port_range = "*"
destination_port_range = "*" # Use singular for all ports
source_address_prefix = "*"
destination_address_prefix = "*"
}
]
If anyone can give me some direction, I would appreciate it. Thanks!