Table of Contents
Sure, here is the entire explanation and working code in DokuWiki format:
```
Terraform: Using Maps of Objects for Network Security Rules
This guide explains how to use maps of objects to manage network security rules in Terraform, combining them with subnets for simplicity and maintainability.
Step 1: Define Security Rules as a Map of Objects
First, define the security rules as a map of objects:
```hcl variable “security_rules” {
type = map(object({
name = string
priority = number
direction = string
access = string
protocol = string
source_port_range = string
destination_port_range = string
source_address_prefix = string
destination_address_prefixes = list(string)
}))
}
locals {
security_rules = {
"AllowSSHjumphostinitialconfig" = {
name = "AllowSSHjumphostinitialconfig"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "193.41.37.210"
destination_address_prefixes = ["*"]
},
"AllowHTTPSjumphostinitialconfig" = {
name = "AllowHTTPSjumphostinitialconfig"
priority = 1002
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "193.41.37.210"
destination_address_prefixes = ["*"]
}
}
} ```
Step 2: Combine Security Rules with Subnets
Create a combined list of security rules and subnets:
```hcl locals {
combined_security_rules_list = flatten([
for sk, sv in local.subnets : [
for sr_key, sr in local.security_rules : {
subnet_key = sk
name = sr.name
priority = sr.priority
direction = sr.direction
access = sr.access
protocol = sr.protocol
source_port_range = sr.source_port_range
destination_port_range = sr.destination_port_range
source_address_prefix = sr.source_address_prefix
destination_address_prefixes = sr.destination_address_prefixes
}
]
])
} ```
Step 3: Convert the List into a Map
Convert the list into a map with unique keys:
```hcl locals {
combined_security_rules_map = {
for rule in local.combined_security_rules_list :
"${rule.subnet_key}-${rule.name}" => rule
}
} ```
Step 4: Use the Map in the Resource
Use the map in the `for_each` expression of the `azurerm_network_security_rule` resource:
```hcl resource “azurerm_network_security_rule” “subnet_nsg_rule” {
for_each = local.combined_security_rules_map
name = each.value.name priority = each.value.priority direction = each.value.direction access = each.value.access protocol = each.value.protocol source_port_range = each.value.source_port_range destination_port_range = each.value.destination_port_range source_address_prefix = each.value.source_address_prefix destination_address_prefixes = each.value.destination_address_prefixes resource_group_name = azurerm_resource_group.rg.name network_security_group_name = azurerm_network_security_group.subnet_nsg[each.value.subnet_key].name
} ```
Explanation
Step 1: Define Security Rules as a Map of Objects
The security rules are defined as a map of objects, ensuring a consistent structure and easy access by keys. Each rule includes attributes like name, priority, direction, access, protocol, port ranges, and address prefixes.
Step 2: Combine Security Rules with Subnets
A local value `combined_security_rules_list` is created by flattening the nested combination of subnets and security rules. This ensures that each subnet is combined with each security rule.
Step 3: Convert the List into a Map
The list of combined rules is converted into a map, using unique keys composed of the subnet key and the rule name. This structure is suitable for the `for_each` expression in Terraform.
Step 4: Use the Map in the Resource
The `for_each` expression in the `azurerm_network_security_rule` resource uses the combined map. This creates network security rules for each subnet based on the defined security rules, ensuring consistency and simplicity.
This approach simplifies the management of security rules and their assignment to subnets, making the Terraform configuration more readable and maintainable. ```
