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. ```