From b6d88da072e5ab8e15e685d2bdb85b39e49e2f95 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Fri, 4 Oct 2024 14:03:46 +0100 Subject: [PATCH 01/23] save changes --- ...onfig-hub-and-spoke-vnet-multi-region.yaml | 14 +- .../complete_multi_region/locals-config.tf | 42 ------ .../locals-hub-and-spoke-vnet.tf | 31 +++- .../locals-private-dns.tf | 45 +++--- .../locals-resource-names.tf | 5 + .../locals-virtual-wan.tf | 19 +-- templates/complete_multi_region/locals.tf | 43 ------ .../modules/hub-and-spoke-vnet/locals.tf | 23 +++ .../modules/hub-and-spoke-vnet/main.tf | 44 ++++++ .../modules/hub-and-spoke-vnet/outputs.tf | 7 + .../modules/hub-and-spoke-vnet/variables.tf | 34 +++++ .../modules/private-dns/locals.tf | 22 +++ .../modules/private-dns/main.tf | 14 ++ .../modules/private-dns/outputs.tf | 0 .../modules/private-dns/variables.tf | 34 +++++ .../modules/virtual-wan/locals.tf | 53 +++++++ .../modules/virtual-wan/main.tf | 105 +++++++++++++ .../modules/virtual-wan/outputs.tf | 7 + .../modules/virtual-wan/variables.tf | 73 +++++++++ .../networking-hub-and-spoke-vnet.tf | 49 +------ .../networking-private-dns.tf | 31 +--- .../networking-virtual-wan.tf | 138 +----------------- .../complete_multi_region/resource-groups.tf | 29 ++++ .../variables-connectivity.tf | 57 ++++++++ .../variables-hub-and-spoke-vnet.tf | 22 +++ .../variables-virtual-wan.tf | 55 +++++++ templates/complete_multi_region/variables.tf | 12 +- 27 files changed, 666 insertions(+), 342 deletions(-) delete mode 100644 templates/complete_multi_region/locals-config.tf create mode 100644 templates/complete_multi_region/locals-resource-names.tf delete mode 100644 templates/complete_multi_region/locals.tf create mode 100644 templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf create mode 100644 templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf create mode 100644 templates/complete_multi_region/modules/hub-and-spoke-vnet/outputs.tf create mode 100644 templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf create mode 100644 templates/complete_multi_region/modules/private-dns/locals.tf create mode 100644 templates/complete_multi_region/modules/private-dns/main.tf create mode 100644 templates/complete_multi_region/modules/private-dns/outputs.tf create mode 100644 templates/complete_multi_region/modules/private-dns/variables.tf create mode 100644 templates/complete_multi_region/modules/virtual-wan/locals.tf create mode 100644 templates/complete_multi_region/modules/virtual-wan/main.tf create mode 100644 templates/complete_multi_region/modules/virtual-wan/outputs.tf create mode 100644 templates/complete_multi_region/modules/virtual-wan/variables.tf create mode 100644 templates/complete_multi_region/resource-groups.tf create mode 100644 templates/complete_multi_region/variables-connectivity.tf create mode 100644 templates/complete_multi_region/variables-hub-and-spoke-vnet.tf create mode 100644 templates/complete_multi_region/variables-virtual-wan.tf diff --git a/templates/complete_multi_region/config-hub-and-spoke-vnet-multi-region.yaml b/templates/complete_multi_region/config-hub-and-spoke-vnet-multi-region.yaml index e36e1b12..5d6fc00a 100644 --- a/templates/complete_multi_region/config-hub-and-spoke-vnet-multi-region.yaml +++ b/templates/complete_multi_region/config-hub-and-spoke-vnet-multi-region.yaml @@ -84,6 +84,10 @@ management_groups: # `caf-enterprise-scale` module, add inputs as listed on the # Connectivity settings connectivity: + enable_private_dns_zones: true + enable_ddos_protection_plan: true + private_dns_zone_resource_group_name: rg-private-dns-${starter_location_01} + private_dns_zone_resource_group_location: ${starter_location_01} hub_and_spoke_vnet: # `avm-ptn-hubnetworking` module, add inputs as listed on the module registry where necessary. hub_virtual_networks: # Primary hub @@ -150,15 +154,5 @@ connectivity: name: pip-hub-vgw-${starter_location_02} zones: ${starter_location_02_availability_zones} - private_dns: - resource_group_name: rg-private-dns-${starter_location_01} - locations: - primary: - location: ${starter_location_01} - is_primary: true # Deploys all zones - secondary: - location: ${starter_location_02} - is_primary: false # Only deploys regional zones - # Configure root module settings enable_telemetry: true diff --git a/templates/complete_multi_region/locals-config.tf b/templates/complete_multi_region/locals-config.tf deleted file mode 100644 index 82daab9c..00000000 --- a/templates/complete_multi_region/locals-config.tf +++ /dev/null @@ -1,42 +0,0 @@ -locals { - config_file_extension = replace(lower(element(local.config_file_split, length(local.config_file_split) - 1)), local.const_yml, local.const_yaml) - config_file_name = var.configuration_file_path == "" ? "config-hub-and-spoke-vnet.yaml" : basename(var.configuration_file_path) - config_file_split = split(".", local.config_file_name) - const_yaml = "yaml" - const_yml = "yml" - - is_yaml = local.config_file_extension == local.const_yaml || local.config_file_extension == local.const_yml - config_file_content = templatefile("${path.module}/${local.config_file_name}", local.config_template_file_variables) - config = (local.is_yaml ? - yamldecode(local.config_file_content) : - jsondecode(local.config_file_content) - ) - - config_template_file_variables = { - starter_location_01 = var.starter_locations[0] - starter_location_02 = try(var.starter_locations[1], null) - starter_location_03 = try(var.starter_locations[2], null) - starter_location_04 = try(var.starter_locations[3], null) - starter_location_05 = try(var.starter_locations[4], null) - starter_location_06 = try(var.starter_locations[5], null) - starter_location_07 = try(var.starter_locations[6], null) - starter_location_08 = try(var.starter_locations[7], null) - starter_location_09 = try(var.starter_locations[8], null) - starter_location_10 = try(var.starter_locations[9], null) - starter_location_01_availability_zones = jsonencode(local.regions[var.starter_locations[0]].zones) - starter_location_02_availability_zones = jsonencode(try(local.regions[var.starter_locations[1]].zones, null)) - starter_location_03_availability_zones = jsonencode(try(local.regions[var.starter_locations[2]].zones, null)) - starter_location_04_availability_zones = jsonencode(try(local.regions[var.starter_locations[3]].zones, null)) - starter_location_05_availability_zones = jsonencode(try(local.regions[var.starter_locations[4]].zones, null)) - starter_location_06_availability_zones = jsonencode(try(local.regions[var.starter_locations[5]].zones, null)) - starter_location_07_availability_zones = jsonencode(try(local.regions[var.starter_locations[6]].zones, null)) - starter_location_08_availability_zones = jsonencode(try(local.regions[var.starter_locations[7]].zones, null)) - starter_location_09_availability_zones = jsonencode(try(local.regions[var.starter_locations[8]].zones, null)) - starter_location_10_availability_zones = jsonencode(try(local.regions[var.starter_locations[9]].zones, null)) - default_postfix = var.default_postfix - root_parent_management_group_id = var.root_parent_management_group_id == "" ? data.azurerm_client_config.current.tenant_id : var.root_parent_management_group_id - subscription_id_connectivity = var.subscription_id_connectivity - subscription_id_identity = var.subscription_id_identity - subscription_id_management = var.subscription_id_management - } -} diff --git a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf index 066d97c3..40aecd7a 100644 --- a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf @@ -1,3 +1,32 @@ locals { - vnet_gateway_default_skus = { for key, value in local.module_virtual_network_gateway : key => length(local.regions[value.location].zones) == 0 ? "Standard" : "ErGw1AZ" } + vnet_gateway_default_skus = { for key, value in var.hub_and_spoke_vnet_virtual_networks : key => length(local.regions[value.location].zones) == 0 ? { + express_route = "Standard" + vpn = "VpnGw1" + } : { + express_route = "ErGw1AZ" + vpn = "VpnGw1AZ" + } + } + + hub_and_spoke_vnet_virtual_networks = { + for key, value in var.hub_and_spoke_vnet_virtual_networks : key => { + name = templatestring(value.name, { location = value.location }) + location = value.location + resource_group_name = module.resource_group_connectivity.name + settings = value.settings + virtual_network_gateways = { + express_route = try(value.virtual_network_gateways.express_route, { + name = templatestring(value.virtual_network_gateways.express_route.name, { location = value.location }) + sku = value.virtual_network_gateways.express_route.sku == null ? vnet_gateway_default_skus[key].express_route : value.virtual_network_gateways.express_route.sku + settings = value.virtual_network_gateways.express_route.settings + }) + vpn = try(value.virtual_network_gateways.vpn, { + name = templatestring(value.virtual_network_gateways.vpn.name, { location = value.location }) + sku = value.virtual_network_gateways.vpn.sku == null ? vnet_gateway_default_skus[key].vpn : value.virtual_network_gateways.vpn.sku + settings = value.virtual_network_gateways.vpn.settings + }) + } + } + } + } diff --git a/templates/complete_multi_region/locals-private-dns.tf b/templates/complete_multi_region/locals-private-dns.tf index cea11f09..53b9d12e 100644 --- a/templates/complete_multi_region/locals-private-dns.tf +++ b/templates/complete_multi_region/locals-private-dns.tf @@ -1,31 +1,20 @@ locals { - private_dns_virtual_networks_hub_and_spoke_vnet = (local.hub_networking_enabled ? - { for key, value in try(local.module_hub_and_spoke_vnet.hub_virtual_networks, {}) : key => { vnet_resource_id = module.hub_and_spoke_vnet[0].virtual_networks[key].id } } : - {} - ) - private_dns_virtual_networks_virtual_wan = (local.virtual_wan_enabled ? - { for key, value in try(local.module_virtual_wan.virtual_hubs, {}) : key => { vnet_resource_id = module.virtual_network_private_dns[key].resource_id } } : - {} - ) - private_dns_virtual_networks = merge(local.private_dns_virtual_networks_hub_and_spoke_vnet, local.private_dns_virtual_networks_virtual_wan) - private_dns_secondary_zones = { - azure_data_explorer = { - zone_name = "privatelink.{regionName}.kusto.windows.net" + private_dns_zones_locations_hub_and_spoke_vnet = var.connectity_type == "hub_and_spoke_vnet" ? { + for key, value in var.hub_and_spoke_vnet_virtual_networks : key => { + location = value.location + is_primary = value.location == var.location } - azure_batch_account = { - zone_name = "{regionName}.privatelink.batch.azure.com" - } - azure_batch_node_mgmt = { - zone_name = "{regionName}.service.privatelink.batch.azure.com" - } - azure_aks_mgmt = { - zone_name = "privatelink.{regionName}.azmk8s.io" - } - azure_acr_data = { - zone_name = "{regionName}.data.privatelink.azurecr.io" - } - azure_backup = { - zone_name = "privatelink.{regionCode}.backup.windowsazure.com" - } - } + } : {} + private_dns_zones_locations_virtual_wan = var.connectity_type == "virtual_wan" ? {} : {} + private_dns_zone_locations = merge(local.private_dns_zones_locations_hub_and_spoke_vnet, local.private_dns_zones_locations_virtual_wan) +} + +locals { + private_dns_zones_virtual_networks_hub_and_spoke_vnet = var.connectity_type == "hub_and_spoke_vnet" ? { + for key, value in try(local.module_hub_and_spoke_vnet.hub_virtual_networks, {}) : key => { + vnet_resource_id = module.hub_and_spoke_vnet[0].virtual_networks[key].resource_id + } + } : {} + private_dns_zones_virtual_networks_virtual_wan = var.connectity_type == "virtual_wan" ? {} : {} + private_dns_zones_virtual_networks = merge(local.private_dns_zones_virtual_networks_hub_and_spoke_vnet, local.private_dns_zones_virtual_networks_virtual_wan) } diff --git a/templates/complete_multi_region/locals-resource-names.tf b/templates/complete_multi_region/locals-resource-names.tf new file mode 100644 index 00000000..7f2c2100 --- /dev/null +++ b/templates/complete_multi_region/locals-resource-names.tf @@ -0,0 +1,5 @@ +locals { + private_dns_zones_resource_group_name = templatestring(var.private_dns_zones_resource_group_name, { location = var.location }) + ddos_protection_plan_resource_group_name = templatestring(var.ddos_protection_plan_resource_group_name, { location = var.location }) + ddos_protection_plan_name = templatestring(var.ddos_protection_plan_name, { location = var.location }) +} \ No newline at end of file diff --git a/templates/complete_multi_region/locals-virtual-wan.tf b/templates/complete_multi_region/locals-virtual-wan.tf index 72036c6b..2945c1cf 100644 --- a/templates/complete_multi_region/locals-virtual-wan.tf +++ b/templates/complete_multi_region/locals-virtual-wan.tf @@ -1,17 +1,8 @@ locals { - virtual_wan_virtual_network_connections_input = try(local.module_virtual_wan.virtual_network_connections, {}) - virtual_wan_private_dns_virtual_network_connections = { for key, value in try(local.module_virtual_wan.virtual_hubs, {}) : "private_dns_vnet_${key}" => { - name = "private_dns_vnet_${key}" - virtual_hub_key = key - remote_virtual_network_id = module.virtual_network_private_dns[key].resource_id - } } - virtual_wan_virtual_network_connections = local.virtual_wan_enabled ? merge(local.virtual_wan_virtual_network_connections_input, local.virtual_wan_private_dns_virtual_network_connections) : {} - virtual_wan_firewalls = { for key, value in try(local.module_virtual_wan.firewalls, {}) : key => { - virtual_hub_key = value.virtual_hub_key - name = value.name - sku_name = value.sku_name - sku_tier = value.sku_tier - firewall_policy_id = module.firewall_policy[key].resource_id - tags = try(value.tags, null) + virtual_wan_virtual_hubs = { for key, value in var.virtual_wan_virtual_hubs : key => { + location = value.location + sku = value.sku + tags = value.tags + firewall = value.firewall } } } diff --git a/templates/complete_multi_region/locals.tf b/templates/complete_multi_region/locals.tf deleted file mode 100644 index 4f962798..00000000 --- a/templates/complete_multi_region/locals.tf +++ /dev/null @@ -1,43 +0,0 @@ -locals { - enable_telemetry = try(local.config.enable_telemetry, true) -} - -locals { - management_groups = try(merge(local.config.management_groups, {}), {}) -} - -locals { - hub_virtual_networks = try(merge(local.config.connectivity.hub_and_spoke_vnet.hub_virtual_networks, {}), {}) - module_hub_and_spoke_vnet = { - hub_virtual_networks = { - for key, hub_virtual_network in local.hub_virtual_networks : key => { - for argument, value in hub_virtual_network : argument => value if argument != "virtual_network_gateway" - } - } - } - module_virtual_network_gateway = { - for key, hub_virtual_network in local.hub_virtual_networks : key => merge( - hub_virtual_network.virtual_network_gateway, - { - location = hub_virtual_network.location - virtual_network_id = module.hub_and_spoke_vnet[0].virtual_networks[key].id - } - ) - if can(hub_virtual_network.virtual_network_gateway) - } -} - -locals { - module_virtual_wan = try(merge(local.config.connectivity.virtual_wan, {}), {}) -} - -locals { - module_private_dns = try(merge(local.config.connectivity.private_dns, {}), {}) -} - -locals { - management_groups_enabled = length(local.management_groups) > 0 - hub_networking_enabled = length(local.module_hub_and_spoke_vnet) > 0 - virtual_wan_enabled = length(local.module_virtual_wan) > 0 - private_dns_enabled = length(local.module_private_dns) > 0 -} diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf new file mode 100644 index 00000000..de1916a3 --- /dev/null +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf @@ -0,0 +1,23 @@ +locals { + virtual_network_gateways_express_route = { + for hub_network_key, hub_network_value in var.hub_virtual_networks : "${hub_network_key}-express-route" => { + name = hub_network_value.virtual_network_gateways.express_route.settings.name + type = "ExpressRoute" + sku = hub_network_value.sku + location = hub_network_value.location + virtual_network_id = module.hub_module.hub_and_spoke_vnet.virtual_networks[hub_network_key].id + settings = hub_network_value.virtual_network_gateways.express_route.settings + } if can(hub_network_value.virtual_network_gateways.express_route) + } + virtual_network_gateways_vpn = { + for hub_network_key, hub_network_value in var.hub_virtual_networks : "${hub_network_key}-vpn" => { + name = hub_network_value.virtual_network_gateways.vpn.settings.name + type = "Vpn" + sku = hub_network_value.sku + location = hub_network_value.location + virtual_network_id = module.hub_module.hub_and_spoke_vnet.virtual_networks[hub_network_key].id + settings = hub_network_value.virtual_network_gateways.vpn.settings + } if can(hub_network_value.virtual_network_gateways.vpn) + } + virtual_network_gateways = merge(local.virtual_network_gateways_express_route, local.virtual_network_gateways_vpn) +} diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf new file mode 100644 index 00000000..9ae20232 --- /dev/null +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf @@ -0,0 +1,44 @@ +module "hub_and_spoke_vnet" { + source = "Azure/avm-ptn-hubnetworking/azurerm" + version = "0.1.0" + + hub_virtual_networks = var.hub_virtual_networks + enable_telemetry = var.enable_telemetry +} + +module "virtual_network_gateway" { + source = "Azure/avm-ptn-vnetgateway/azurerm" + version = "0.3.1" + + for_each = local.virtual_network_gateways + + location = each.value.location + name = each.value.name + sku = each.value.sku + type = each.value.type + virtual_network_id = each.value.virtual_network_id + default_tags = var.tags + subnet_creation_enabled = try(each.value.settings.subnet_creation_enabled, null) + edge_zone = try(each.value.settings.edge_zone, null) + express_route_circuits = try(each.value.settings.express_route_circuits, null) + ip_configurations = try(each.value.settings.ip_configurations, null) + local_network_gateways = try(each.value.settings.local_network_gateways, null) + subnet_address_prefix = try(each.value.subnet_address_prefix, null) + tags = try(each.value.settings.tags, null) + vpn_active_active_enabled = try(each.value.settings.vpn_active_active_enabled, null) + vpn_bgp_enabled = try(each.value.settings.vpn_bgp_enabled, null) + vpn_bgp_settings = try(each.value.settings.vpn_bgp_settings, null) + vpn_generation = try(each.value.settings.vpn_generation, null) + vpn_point_to_site = try(each.value.settings.vpn_point_to_site, null) + vpn_type = try(each.value.settings.vpn_type, null) + vpn_private_ip_address_enabled = try(each.value.settings.vpn_private_ip_address_enabled, null) + route_table_bgp_route_propagation_enabled = try(each.value.settings.route_table_bgp_route_propagation_enabled, null) + route_table_creation_enabled = try(each.value.route_table_creation_enabled, null) + route_table_name = try(each.value.settings.route_table_name, null) + route_table_tags = try(each.value.settings.route_table_tags, null) + enable_telemetry = var.enable_telemetry + + depends_on = [ + module.hub_and_spoke_vnet + ] +} diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/outputs.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/outputs.tf new file mode 100644 index 00000000..04eefe68 --- /dev/null +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/outputs.tf @@ -0,0 +1,7 @@ +output "virtual_networks" { + value = { + for key, value in module.module.hub_and_spoke_vnet.virtual_networks : key => { + resource_id = value.id + } + } +} diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf new file mode 100644 index 00000000..c8940d14 --- /dev/null +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf @@ -0,0 +1,34 @@ +variable "hub_virtual_networks" { + type = map(object({ + name = string + location = string + resource_group_name = string + settings = object + virtual_network_gateways = optional(object({ + express_route = optional(object({ + name = string + sku = string + settings = object + })) + vpn = optional(object({ + name = string + sku = string + settings = object + })) + })) + })) + default = {} + description = "A map of hub networks to create. Detailed information about the hub network can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-hubnetworking" +} + +variable "enable_telemetry" { + default = true + type = bool + description = "Flag to enable/disable telemetry" +} + +variable "tags" { + default = {} + type = map(string) + description = "A map of tags to add to the private DNS zones" +} diff --git a/templates/complete_multi_region/modules/private-dns/locals.tf b/templates/complete_multi_region/modules/private-dns/locals.tf new file mode 100644 index 00000000..ed1afee1 --- /dev/null +++ b/templates/complete_multi_region/modules/private-dns/locals.tf @@ -0,0 +1,22 @@ +locals { + private_dns_secondary_zones = { + azure_data_explorer = { + zone_name = "privatelink.{regionName}.kusto.windows.net" + } + azure_batch_account = { + zone_name = "{regionName}.privatelink.batch.azure.com" + } + azure_batch_node_mgmt = { + zone_name = "{regionName}.service.privatelink.batch.azure.com" + } + azure_aks_mgmt = { + zone_name = "privatelink.{regionName}.azmk8s.io" + } + azure_acr_data = { + zone_name = "{regionName}.data.privatelink.azurecr.io" + } + azure_backup = { + zone_name = "privatelink.{regionCode}.backup.windowsazure.com" + } + } +} diff --git a/templates/complete_multi_region/modules/private-dns/main.tf b/templates/complete_multi_region/modules/private-dns/main.tf new file mode 100644 index 00000000..5cd519f4 --- /dev/null +++ b/templates/complete_multi_region/modules/private-dns/main.tf @@ -0,0 +1,14 @@ +module "private_dns_zones" { + source = "Azure/avm-ptn-network-private-link-private-dns-zones/azurerm" + version = "0.4.0" + + for_each = var.locations + + location = each.value.location + resource_group_name = var.resource_group_name + resource_group_creation_enabled = false + virtual_network_resource_ids_to_link_to = var.connected_virtual_networks + private_link_private_dns_zones = each.value.is_primary ? null : local.private_dns_secondary_zones + enable_telemetry = var.enable_telemetry + tags = var.tags +} diff --git a/templates/complete_multi_region/modules/private-dns/outputs.tf b/templates/complete_multi_region/modules/private-dns/outputs.tf new file mode 100644 index 00000000..e69de29b diff --git a/templates/complete_multi_region/modules/private-dns/variables.tf b/templates/complete_multi_region/modules/private-dns/variables.tf new file mode 100644 index 00000000..cfea1d88 --- /dev/null +++ b/templates/complete_multi_region/modules/private-dns/variables.tf @@ -0,0 +1,34 @@ +variable "resource_group_name" { + type = string + nullable = false + description = "The name of the resource group for private DNS zones" +} + +variable "locations" { + type = map(object({ + location = string + is_primary = optional(bool, false) + })) + nullable = false + description = "A map of locations to create private DNS zones" +} + +variable "connected_virtual_networks" { + type = map(object({ + vnet_resource_id = string + })) + nullable = false + description = "A map of virtual networks to attach the private DNS zones to" +} + +variable "enable_telemetry" { + type = bool + default = true + description = "Flag to enable/disable telemetry" +} + +variable "tags" { + type = map(string) + default = {} + description = "A map of tags to add to the private DNS zones" +} diff --git a/templates/complete_multi_region/modules/virtual-wan/locals.tf b/templates/complete_multi_region/modules/virtual-wan/locals.tf new file mode 100644 index 00000000..d51e8bb1 --- /dev/null +++ b/templates/complete_multi_region/modules/virtual-wan/locals.tf @@ -0,0 +1,53 @@ +locals { + virtual_network_connections_input = { for virtual_network_connection in flatten([ for virtual_hub_key, virtual_hub_value in var.virtual_hubs : + [ for virtual_network_connection_key, virtual_network_connection_value in value.virtual_network_connections : { + unique_key = "${virtual_hub_key}-${virtual_network_connection_key}" + name = virtual_network_connection_value.settings.name + virtual_hub_key = virtual_hub_key + remote_virtual_network_id = virtual_network_connection_value.remote_virtual_network_id + settings = virtual_network_connection_value.settings + } ] + ]) : virtual_network_connection.unique_key => { + name = virtual_network_connection.name + virtual_hub_key = virtual_network_connection.virtual_hub_key + remote_virtual_network_id = virtual_network_connection.remote_virtual_network_id + settings = virtual_network_connection.settings + } } + + virtual_network_connections_private_dns = var.private_dns_zones_enabled ? { for key, value in try(local.module_virtual_wan.virtual_hubs, {}) : "private_dns_vnet_${key}" => { + name = "private_dns_vnet_${key}" + virtual_hub_key = key + remote_virtual_network_id = module.virtual_network_private_dns[key].resource_id + } } : {} + + virtual_network_connections = merge(local.virtual_network_connections_input, local.virtual_network_connections_private_dns) +} + +locals { + firewall_policies = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => { + virtual_hub_key = virtual_hub_value.firewall.virtual_hub_key + name = virtual_hub_value.firewall.firewall_policy.name + location = virtual_hub_value.location + resource_group_name = virtual_hub_value.resource_group == null ? var.resource_group_name : virtual_hub_value.resource_group + settings = virtual_hub_value.firewall.firewall_policysettings + } if can(virtual_hub_value.firewall.firewall_policy) + } + + firewalls = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => { + virtual_hub_key = virtual_hub_value.firewall.virtual_hub_key + name = virtual_hub_value.firewall.name + sku_name = virtual_hub_value.firewall.sku_name + sku_tier = virtual_hub_value.firewall.sku_tier + dns_servers = try(virtual_hub_value.firewall.settings.dns_servers, null) + private_ip_ranges = try(virtual_hub_value.firewall.settings.private_ip_ranges, null) + threat_intel_mode = try(virtual_hub_value.firewall.settings.threat_intel_mode, null) + zones = virtual_hub_value.firewall.zones + vhub_public_ip_count = try(virtual_hub_value.firewall.settings.vhub_public_ip_count, null) + tags = try(virtual_hub_value.firewall.settings.tags, null) + default_ip_configuration = try(virtual_hub_value.firewall.default_ip_configuration, null) + management_ip_configuration = try(virtual_hub_value.firewall.management_ip_configuration, null) + ip_configuration = try(virtual_hub_value.firewall.ip_configuration, null) + firewall_policy_id = module.firewall_policy[virtual_hub_key].resource_id + } if can(virtual_hub_value.firewall) + } +} diff --git a/templates/complete_multi_region/modules/virtual-wan/main.tf b/templates/complete_multi_region/modules/virtual-wan/main.tf new file mode 100644 index 00000000..936fee6b --- /dev/null +++ b/templates/complete_multi_region/modules/virtual-wan/main.tf @@ -0,0 +1,105 @@ +module "firewall_policy" { + source = "Azure/avm-res-network-firewallpolicy/azurerm" + version = "0.2.3" + + for_each = local.firewall_policies + + name = each.value.name + location = each.value.location + resource_group_name = each.value.resource_group_name + firewall_policy_sku = try(each.value.settings.sku, "Standard") + firewall_policy_auto_learn_private_ranges_enabled = try(each.value.settings.auto_learn_private_ranges_enabled, null) + firewall_policy_base_policy_id = try(each.value.settings.base_policy_id, null) + firewall_policy_dns = try(each.value.settings.dns, { + servers = [module.dns_resolver[each.value.virtual_hub_key].inbound_endpoint_ips["dns"]] + proxy_enabled = true + }) + firewall_policy_threat_intelligence_mode = try(each.value.settings.threat_intelligence_mode, "Alert") + firewall_policy_private_ip_ranges = try(each.value.settings.private_ip_ranges, null) + firewall_policy_threat_intelligence_allowlist = try(each.value.settings.threat_intelligence_allowlist, null) + tags = try(each.value.settings.tags, null) + enable_telemetry = var.enable_telemetry +} + +module "virtual_wan" { + source = "Azure/avm-ptn-virtualwan/azurerm" + version = "0.5.0" + + allow_branch_to_branch_traffic = try(local.module_virtual_wan.allow_branch_to_branch_traffic, null) + disable_vpn_encryption = try(local.module_virtual_wan.disable_vpn_encryption, false) + er_circuit_connections = try(local.module_virtual_wan.er_circuit_connections, {}) + expressroute_gateways = try(local.module_virtual_wan.expressroute_gateways, {}) + firewalls = local.firewalls + office365_local_breakout_category = try(local.module_virtual_wan.office365_local_breakout_category, null) + location = var.location + p2s_gateway_vpn_server_configurations = try(local.module_virtual_wan.p2s_gateway_vpn_server_configurations, {}) + p2s_gateways = try(local.module_virtual_wan.p2s_gateways, {}) + resource_group_name = var.resource_group_name + create_resource_group = false + virtual_hubs = var.virtual_hubs + virtual_network_connections = local.virtual_network_connections + virtual_wan_name = var.name + type = try(local.module_virtual_wan.type, null) + routing_intents = try(local.module_virtual_wan.routing_intents, null) + resource_group_tags = try(local.module_virtual_wan.resource_group_tags, null) + virtual_wan_tags = try(local.module_virtual_wan.virtual_wan_tags, null) + vpn_gateways = try(local.module_virtual_wan.vpn_gateways, {}) + vpn_site_connections = try(local.module_virtual_wan.vpn_site_connections, {}) + vpn_sites = try(local.module_virtual_wan.vpn_sites, null) + tags = try(local.module_virtual_wan.tags, null) + enable_telemetry = var.enable_telemetry + + depends_on = [ + module.management_groups, + module.virtual_wan_resource_group + ] +} + +module "virtual_network_private_dns" { + source = "Azure/avm-res-network-virtualnetwork/azurerm" + version = "0.4.0" + + for_each = var.private_dns_zones_enabled ? var.virtual_hubs : {} + + address_space = each.value.private_dns_zones_networking.virtual_network.address_space + location = each.value.location + name = each.value.private_dns_zones_networking.virtual_network.name + resource_group_name = each.value.resource_group_name + enable_telemetry = var.enable_telemetry + subnets = { + dns = { + address_prefix = each.value.private_dns_zones_networking.virtual_network.private_dns_resolver_subnet.address_prefix + name = each.value.private_dns_zones_networking.virtual_network.private_dns_resolver_subnet.name + delegation = [{ + name = "Microsoft.Network.dnsResolvers" + service_delegation = { + name = "Microsoft.Network/dnsResolvers" + #actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"] + } + }] + } + } + + depends_on = [module.virtual_wan_resource_group] +} + +module "dns_resolver" { + source = "Azure/avm-res-network-dnsresolver/azurerm" + version = "0.2.1" + + for_each = var.private_dns_zones_enabled ? var.virtual_hubs : {} + + location = each.value.location + name = each.value.private_dns_zones_networking.private_dns_resolver.name + resource_group_name = each.value.resource_group_name + virtual_network_resource_id = module.virtual_network_private_dns[each.key].resource_id + enable_telemetry = var.enable_telemetry + inbound_endpoints = { + dns = { + name = "dns" + subnet_name = module.virtual_network_private_dns[each.key].subnets.dns.name + } + } + + depends_on = [module.virtual_wan_resource_group] +} diff --git a/templates/complete_multi_region/modules/virtual-wan/outputs.tf b/templates/complete_multi_region/modules/virtual-wan/outputs.tf new file mode 100644 index 00000000..c6585b91 --- /dev/null +++ b/templates/complete_multi_region/modules/virtual-wan/outputs.tf @@ -0,0 +1,7 @@ +output "private_dns_zones_virtual_networks" { + value = { + for key, value in module.virtual_network_private_dns : key => { + resource_id = value.resource_id + } + } +} \ No newline at end of file diff --git a/templates/complete_multi_region/modules/virtual-wan/variables.tf b/templates/complete_multi_region/modules/virtual-wan/variables.tf new file mode 100644 index 00000000..e7999198 --- /dev/null +++ b/templates/complete_multi_region/modules/virtual-wan/variables.tf @@ -0,0 +1,73 @@ +variable "name" { + type = string + description = "The name of the virtual WAN" + nullable = false +} + +variable "resource_group_name" { + type = string + description = "The name of the resource group for the virtual WAN" + nullable = false +} + +variable "location" { + type = string + description = "A map of locations to create the virtual WAN" + nullable = false +} + +variable "private_dns_zones_enabled" { + type = bool + description = "Flag to enable/disable private DNS zones" + default = true +} + +variable "settings" { + type = object + description = "The settings for the virtual WAN" + default = null +} + +variable "virtual_hubs" { + type = map(object({ + name = string + location = string + resource_group_name = string + virtual_network_connections = optional(object) + firewall = optional(object({ + name = string + sku_name = string + sku_tier = string + zones = optional(list(string)) + firewall_policy = object({ + name = string + settings = object + }) + settings = object + })) + address_prefix = string + tags = optional(map(string)) + hub_routing_preference = optional(string) + private_dns_zone_networking = optional(object({ + virtual_network = object({ + name = string + address_space = string + private_dns_resolver_subnet = object({ + name = string + address_prefix = string + }) + }) + private_dns_resolver = object({ + name = string + }) + })) + })) + default = {} + description = "A map of virtual hubs to create. Detailed information about the virtual hub can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-virtualhub" +} + +variable "enable_telemetry" { + type = bool + default = true + description = "Flag to enable/disable telemetry" +} \ No newline at end of file diff --git a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf index 932a6b63..b4f8b7a3 100644 --- a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf @@ -1,11 +1,11 @@ module "hub_and_spoke_vnet" { - source = "Azure/avm-ptn-hubnetworking/azurerm" + source = "./modules/hub-and-spoke-vnet" version = "0.1.0" - count = length(local.hub_virtual_networks) > 0 ? 1 : 0 + count = var.connectivity_type == "hub_and_spoke_vnet" ? 1 : 0 - hub_virtual_networks = local.module_hub_and_spoke_vnet.hub_virtual_networks - enable_telemetry = try(local.module_hub_and_spoke_vnet.enable_telemetry, local.enable_telemetry) + hub_virtual_networks = local.hub_and_spoke_vnet_virtual_networks + enable_telemetry = var.enable_telemetry providers = { azurerm = azurerm.connectivity @@ -15,44 +15,3 @@ module "hub_and_spoke_vnet" { module.management_groups ] } - -module "virtual_network_gateway" { - source = "Azure/avm-ptn-vnetgateway/azurerm" - version = "0.3.1" - - for_each = local.module_virtual_network_gateway - - location = each.value.location - name = each.value.name - sku = try(each.value.sku, null) == null ? local.vnet_gateway_default_skus[each.key] : each.value.sku - type = try(each.value.type, null) - virtual_network_id = each.value.virtual_network_id - default_tags = try(each.value.default_tags, null) - subnet_creation_enabled = try(each.value.subnet_creation_enabled, null) - edge_zone = try(each.value.edge_zone, null) - express_route_circuits = try(each.value.express_route_circuits, null) - ip_configurations = try(each.value.ip_configurations, null) - local_network_gateways = try(each.value.local_network_gateways, null) - subnet_address_prefix = try(each.value.subnet_address_prefix, null) - tags = try(each.value.tags, null) - vpn_active_active_enabled = try(each.value.vpn_active_active_enabled, null) - vpn_bgp_enabled = try(each.value.vpn_bgp_enabled, null) - vpn_bgp_settings = try(each.value.vpn_bgp_settings, null) - vpn_generation = try(each.value.vpn_generation, null) - vpn_point_to_site = try(each.value.vpn_point_to_site, null) - vpn_type = try(each.value.vpn_type, null) - vpn_private_ip_address_enabled = try(each.value.vpn_private_ip_address_enabled, null) - route_table_bgp_route_propagation_enabled = try(each.value.route_table_bgp_route_propagation_enabled, null) - route_table_creation_enabled = try(each.value.route_table_creation_enabled, null) - route_table_name = try(each.value.route_table_name, null) - route_table_tags = try(each.value.route_table_tags, null) - enable_telemetry = try(each.value.enable_telemetry, local.enable_telemetry) - - providers = { - azurerm = azurerm.connectivity - } - - depends_on = [ - module.hub_and_spoke_vnet - ] -} diff --git a/templates/complete_multi_region/networking-private-dns.tf b/templates/complete_multi_region/networking-private-dns.tf index dc5bb509..65b9770a 100644 --- a/templates/complete_multi_region/networking-private-dns.tf +++ b/templates/complete_multi_region/networking-private-dns.tf @@ -1,30 +1,13 @@ -module "private_dns_zones_resource_group" { - source = "Azure/avm-res-resources-resourcegroup/azurerm" - version = "0.1.0" - - count = local.private_dns_enabled ? 1 : 0 - - name = try(local.module_private_dns.resource_group_name, "rg-private-dns-${var.starter_locations[0]}") - location = try(local.module_private_dns.location, [for location in local.module_private_dns.locations : location if location.is_primary][0].location) - enable_telemetry = try(local.module_private_dns.enable_telemetry, local.enable_telemetry) - - providers = { - azurerm = azurerm.connectivity - } -} - module "private_dns_zones" { - source = "Azure/avm-ptn-network-private-link-private-dns-zones/azurerm" - version = "0.4.0" + source = "./modules/private-dns" - for_each = local.private_dns_enabled ? try(local.module_private_dns.locations, {}) : {} + count = var.private_dns_zones_enabled ? 1 : 0 - location = each.value.location - resource_group_name = module.private_dns_zones_resource_group[0].name - resource_group_creation_enabled = false - virtual_network_resource_ids_to_link_to = local.private_dns_virtual_networks - private_link_private_dns_zones = each.value.is_primary ? null : local.private_dns_secondary_zones - enable_telemetry = try(local.module_private_dns.enable_telemetry, local.enable_telemetry) + locations = local.private_dns_zone_locations + resource_group_name = module.resource_group_private_dns_zones.name + connected_virtual_networks = local.private_dns_zones_virtual_networks + enable_telemetry = var.enable_telemetry + tags = var.private_dns_zones_tags depends_on = [module.private_dns_zones_resource_group] diff --git a/templates/complete_multi_region/networking-virtual-wan.tf b/templates/complete_multi_region/networking-virtual-wan.tf index 50baa653..c52348ab 100644 --- a/templates/complete_multi_region/networking-virtual-wan.tf +++ b/templates/complete_multi_region/networking-virtual-wan.tf @@ -1,142 +1,16 @@ -module "virtual_wan_resource_group" { - source = "Azure/avm-res-resources-resourcegroup/azurerm" - version = "0.1.0" - - count = local.virtual_wan_enabled ? 1 : 0 - - name = try(local.module_virtual_wan.resource_group_name, "rg-connectivity-${var.starter_locations[0]}") - location = try(local.module_virtual_wan.location, var.starter_locations[0]) - enable_telemetry = try(local.module_virtual_wan.enable_telemetry, local.enable_telemetry) - - providers = { - azurerm = azurerm.connectivity - } -} - -module "firewall_policy" { - source = "Azure/avm-res-network-firewallpolicy/azurerm" - version = "0.2.3" - - for_each = local.virtual_wan_enabled ? try(local.module_virtual_wan.firewalls, {}) : {} - - name = each.value.firewall_policy.name - location = try(each.value.firewall_policy.location, try(local.module_virtual_wan.location, var.starter_locations[0])) - resource_group_name = try(local.module_virtual_wan.resource_group_name, module.virtual_wan_resource_group[0].name) - firewall_policy_sku = try(each.value.firewall_policy.sku, "Standard") - firewall_policy_auto_learn_private_ranges_enabled = try(each.value.firewall_policy.auto_learn_private_ranges_enabled, null) - firewall_policy_base_policy_id = try(each.value.firewall_policy.base_policy_id, null) - firewall_policy_dns = try(each.value.firewall_policy.dns, { - servers = [module.dns_resolver[each.value.virtual_hub_key].inbound_endpoint_ips["dns"]] - proxy_enabled = true - }) - firewall_policy_threat_intelligence_mode = try(each.value.firewall_policy.threat_intelligence_mode, "Alert") - firewall_policy_private_ip_ranges = try(each.value.firewall_policy.private_ip_ranges, null) - firewall_policy_threat_intelligence_allowlist = try(each.value.firewall_policy.threat_intelligence_allowlist, null) - tags = try(each.value.firewall_policy.tags, null) - enable_telemetry = try(local.module_virtual_wan.enable_telemetry, local.enable_telemetry) - - depends_on = [ - module.virtual_wan_resource_group - ] - - providers = { - azurerm = azurerm.connectivity - } -} - module "virtual_wan" { - source = "Azure/avm-ptn-virtualwan/azurerm" - version = "0.5.0" + source = "./modules/virtual-wan" - count = local.virtual_wan_enabled ? 1 : 0 + count = var.connectity_type == "virtual_wan" ? 1 : 0 - allow_branch_to_branch_traffic = try(local.module_virtual_wan.allow_branch_to_branch_traffic, null) - create_resource_group = try(local.module_virtual_wan.create_resource_group, false) - disable_vpn_encryption = try(local.module_virtual_wan.disable_vpn_encryption, false) - er_circuit_connections = try(local.module_virtual_wan.er_circuit_connections, {}) - expressroute_gateways = try(local.module_virtual_wan.expressroute_gateways, {}) - firewalls = local.virtual_wan_firewalls - office365_local_breakout_category = try(local.module_virtual_wan.office365_local_breakout_category, null) - location = try(local.module_virtual_wan.location, null) - p2s_gateway_vpn_server_configurations = try(local.module_virtual_wan.p2s_gateway_vpn_server_configurations, {}) - p2s_gateways = try(local.module_virtual_wan.p2s_gateways, {}) - resource_group_name = try(local.module_virtual_wan.resource_group_name, module.virtual_wan_resource_group[0].name) - virtual_hubs = try(local.module_virtual_wan.virtual_hubs, null) - virtual_network_connections = local.virtual_wan_virtual_network_connections - virtual_wan_name = try(local.module_virtual_wan.virtual_wan_name, null) - type = try(local.module_virtual_wan.type, null) - routing_intents = try(local.module_virtual_wan.routing_intents, null) - resource_group_tags = try(local.module_virtual_wan.resource_group_tags, null) - virtual_wan_tags = try(local.module_virtual_wan.virtual_wan_tags, null) - vpn_gateways = try(local.module_virtual_wan.vpn_gateways, {}) - vpn_site_connections = try(local.module_virtual_wan.vpn_site_connections, {}) - vpn_sites = try(local.module_virtual_wan.vpn_sites, null) - tags = try(local.module_virtual_wan.tags, null) - enable_telemetry = try(local.module_virtual_wan.enable_telemetry, local.enable_telemetry) + virtual_hubs = var.virtual_hubs + providers = { azurerm = azurerm.connectivity } depends_on = [ - module.management_groups, - module.virtual_wan_resource_group + module.management_groups ] -} - -module "virtual_network_private_dns" { - source = "Azure/avm-res-network-virtualnetwork/azurerm" - version = "0.4.0" - - for_each = local.virtual_wan_enabled ? try(local.module_virtual_wan.virtual_hubs, {}) : {} - - address_space = [try(each.value.private_dns_virtual_network_address_space, null)] - location = try(each.value.location, var.starter_locations[0]) - name = try(each.value.private_dns_virtual_network_name, "vnet-private-dns-${each.value.location}") - resource_group_name = try(local.module_virtual_wan.resource_group_name, module.virtual_wan_resource_group[0].name) - enable_telemetry = try(local.module_virtual_wan.enable_telemetry, local.enable_telemetry) - subnets = { - dns = { - address_prefix = try(each.value.private_dns_virtual_network_subnet_address_space, null) - name = try(each.value.private_dns_virtual_network_subnet_name, "subnet-dns") - delegation = [{ - name = "Microsoft.Network.dnsResolvers" - service_delegation = { - name = "Microsoft.Network/dnsResolvers" - #actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"] - } - }] - } - } - - depends_on = [module.virtual_wan_resource_group] - - providers = { - azurerm = azurerm.connectivity - } -} - -module "dns_resolver" { - source = "Azure/avm-res-network-dnsresolver/azurerm" - version = "0.2.1" - - for_each = local.virtual_wan_enabled ? try(local.module_virtual_wan.virtual_hubs, {}) : {} - - location = try(each.value.location, var.starter_locations[0]) - name = try(each.value.dns_resolver_name, "dpr-hub-${each.value.location}") - resource_group_name = try(local.module_virtual_wan.resource_group_name, module.virtual_wan_resource_group[0].name) - virtual_network_resource_id = module.virtual_network_private_dns[each.key].resource_id - enable_telemetry = try(local.module_virtual_wan.enable_telemetry, local.enable_telemetry) - inbound_endpoints = { - dns = { - name = "dns" - subnet_name = module.virtual_network_private_dns[each.key].subnets.dns.name - } - } - - depends_on = [module.virtual_wan_resource_group] - - providers = { - azurerm = azurerm.connectivity - } -} +} \ No newline at end of file diff --git a/templates/complete_multi_region/resource-groups.tf b/templates/complete_multi_region/resource-groups.tf new file mode 100644 index 00000000..b5c1d904 --- /dev/null +++ b/templates/complete_multi_region/resource-groups.tf @@ -0,0 +1,29 @@ +module "resource_group_private_dns_zones" { + source = "Azure/avm-res-resources-resourcegroup/azurerm" + version = "0.1.0" + + count = local.private_dns_enabled ? 1 : 0 + + name = try(local.module_private_dns.resource_group_name, "rg-private-dns-${var.starter_locations[0]}") + location = try(local.module_private_dns.location, [for location in local.module_private_dns.locations : location if location.is_primary][0].location) + enable_telemetry = try(local.module_private_dns.enable_telemetry, local.enable_telemetry) + + providers = { + azurerm = azurerm.connectivity + } +} + +module "resource_group_connectivity" { + source = "Azure/avm-res-resources-resourcegroup/azurerm" + version = "0.1.0" + + count = var.connectity_type != "none" ? 1 : 0 + + name = try(local.module_private_dns.resource_group_name, "rg-private-dns-${var.starter_locations[0]}") + location = try(local.module_private_dns.location, [for location in local.module_private_dns.locations : location if location.is_primary][0].location) + enable_telemetry = try(local.module_private_dns.enable_telemetry, local.enable_telemetry) + + providers = { + azurerm = azurerm.connectivity + } +} diff --git a/templates/complete_multi_region/variables-connectivity.tf b/templates/complete_multi_region/variables-connectivity.tf new file mode 100644 index 00000000..66ac2915 --- /dev/null +++ b/templates/complete_multi_region/variables-connectivity.tf @@ -0,0 +1,57 @@ +variable "connectivity_type" { + type = string + description = "The type of connectivity to use for the private DNS zones" + default = "hub_and_spoke_vnet" + validation { + condition = contains(["hub_and_spoke_vnet", "virtual_wan", "none"], var.connectivity_type) + error_message = "The connectivity type must be either 'hub_and_spoke_vnet', 'virtual_wan' or 'none'" + } +} + +variable "private_dns_zones_enabled" { + type = bool + description = "Flag to enable/disable private DNS zones" + default = true +} + +variable "private_dns_zones_resource_group_name" { + type = string + description = "The name of the resource group for private DNS zones" + default = "rg-private-dns-$${location}" +} + +variable "private_dns_zones_resource_group_location" { + type = string + description = "The location of the resource group for private DNS zones" + default = null +} + +variable "private_dns_zones_tags" { + type = map(string) + description = "A map of tags to add to the private DNS zones" + default = {} +} + +variable "ddos_protection_plan_enabled" { + type = bool + description = "Flag to enable/disable DDoS protection plan" + default = true +} + +variable "ddos_protection_plan_resource_group_name" { + type = string + description = "The name of the resource group for DDoS protection plan" + default = "rg-ddos-$${location}" +} + +variable "ddos_protection_plan_resource_group_location" { + type = string + description = "The location of the resource group for DDoS protection plan" + default = null +} + +variable "ddos_protection_plan_name" { + type = string + description = "The name of the DDoS protection plan" + default = "ddos-$${location}" +} diff --git a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf new file mode 100644 index 00000000..9b54e967 --- /dev/null +++ b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf @@ -0,0 +1,22 @@ +variable "hub_and_spoke_vnet_virtual_networks" { + type = map(object({ + name = optional(string, "vnet-hub-$${location}") + location = string + resource_group_name = optional(string, "rg-hub-$${location}") + settings = object + virtual_network_gateways = optional(object({ + express_route = optional(object({ + name = optional(string, "vgw-hub-expressroute-$${location}") + sku = optional(string) + settings = object + })) + vpn = optional(object({ + name = optional(string, "vgw-hub-vpn-$${location}") + sku = optional(string) + settings = object + })) + })) + })) + default = {} + description = "A map of hub networks to create. Detailed information about the hub network can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-hubnetworking" +} diff --git a/templates/complete_multi_region/variables-virtual-wan.tf b/templates/complete_multi_region/variables-virtual-wan.tf new file mode 100644 index 00000000..b0e0d003 --- /dev/null +++ b/templates/complete_multi_region/variables-virtual-wan.tf @@ -0,0 +1,55 @@ +variable "virtual_wan_name" { + type = string + description = "The name of the virtual WAN" + nullable = false +} + +variable "virtual_wan_settings" { + type = object + description = "The settings for the virtual WAN" + default = null +} + +variable "virtual_wan_virtual_hubs" { + type = map(object({ + name = optional(string, "vwan-hub-$${location}") + location = string + resource_group_name = optional(string, "rg-vwan-hub-$${location}") + virtual_network_connections = optional(object) + firewall = optional(object({ + name = optional(string, "fw-hub-$${location}") + sku_name = string + sku_tier = string + zones = optional(list(string)) + firewall_policy = object({ + name = optional(string, "fwp-hub-$${location}") + settings = object + }) + settings = object + })) + address_prefix = string + tags = optional(map(string)) + hub_routing_preference = optional(string) + private_dns_zone_networking = optional(object({ + virtual_network = object({ + name = optional(string, "vnet-hub-dns-$${location}") + address_space = string + private_dns_resolver_subnet = object({ + name = optional(string, "subnet-hub-dns-$${location}") + address_prefix = string + }) + }) + private_dns_resolver = object({ + name = optional(string, "pdr-hub-dns-$${location}") + }) + })) + })) + default = {} + description = "A map of virtual hubs to create. Detailed information about the virtual hub can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-virtualhub" +} + +variable "enable_telemetry" { + type = bool + default = true + description = "Flag to enable/disable telemetry" +} \ No newline at end of file diff --git a/templates/complete_multi_region/variables.tf b/templates/complete_multi_region/variables.tf index a702b7db..2cd1e2f1 100644 --- a/templates/complete_multi_region/variables.tf +++ b/templates/complete_multi_region/variables.tf @@ -1,6 +1,6 @@ -variable "starter_locations" { - type = list(string) - description = "The location for Azure resources. (e.g 'uksouth')|azure_location" +variable "location" { + type = string + description = "The default for Azure resources. (e.g 'uksouth')|azure_location" } variable "subscription_id_connectivity" { @@ -35,3 +35,9 @@ variable "root_parent_management_group_id" { default = "" description = "This is the id of the management group that the ALZ hierarchy will be nested under, will default to the Tenant Root Group|azure_name" } + +variable "enable_telemetry" { + type = bool + default = true + description = "Flag to enable/disable telemetry" +} From 39b74eae3b1926799ddec9ac20679c2bf4f8ecd2 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Fri, 4 Oct 2024 16:02:53 +0100 Subject: [PATCH 02/23] Valid code --- .../locals-hub-and-spoke-vnet.tf | 17 +++---- .../locals-private-dns.tf | 8 +-- .../locals-resource-groups.tf | 27 ++++++++++ .../locals-resource-names.tf | 4 ++ .../locals-virtual-wan.tf | 37 ++++++++++++-- templates/complete_multi_region/locals.tf | 15 ++++++ .../management-groups.tf | 47 ++--------------- .../modules/hub-and-spoke-vnet/terraform.tf | 14 ++++++ .../management-groups-and-resources/data.tf | 1 + .../management-groups-and-resources/main.tf | 50 +++++++++++++++++++ .../outputs.tf | 0 .../terraform.tf | 18 +++++++ .../variables.tf | 17 +++++++ .../modules/private-dns/terraform.tf | 14 ++++++ .../modules/virtual-wan/terraform.tf | 14 ++++++ .../modules/virtual-wan/variables.tf | 8 +-- .../networking-hub-and-spoke-vnet.tf | 1 - .../networking-virtual-wan.tf | 8 +-- templates/complete_multi_region/outputs.tf | 12 ----- .../complete_multi_region/resource-groups.tf | 25 ++-------- .../variables-hub-and-spoke-vnet.tf | 8 +-- .../variables-virtual-wan.tf | 20 ++++---- .../variables.management.tf | 28 +++++++++++ 23 files changed, 278 insertions(+), 115 deletions(-) create mode 100644 templates/complete_multi_region/locals-resource-groups.tf create mode 100644 templates/complete_multi_region/locals.tf create mode 100644 templates/complete_multi_region/modules/hub-and-spoke-vnet/terraform.tf create mode 100644 templates/complete_multi_region/modules/management-groups-and-resources/data.tf create mode 100644 templates/complete_multi_region/modules/management-groups-and-resources/main.tf create mode 100644 templates/complete_multi_region/modules/management-groups-and-resources/outputs.tf create mode 100644 templates/complete_multi_region/modules/management-groups-and-resources/terraform.tf create mode 100644 templates/complete_multi_region/modules/management-groups-and-resources/variables.tf create mode 100644 templates/complete_multi_region/modules/private-dns/terraform.tf create mode 100644 templates/complete_multi_region/modules/virtual-wan/terraform.tf create mode 100644 templates/complete_multi_region/variables.management.tf diff --git a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf index 40aecd7a..178d4817 100644 --- a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf @@ -1,5 +1,5 @@ locals { - vnet_gateway_default_skus = { for key, value in var.hub_and_spoke_vnet_virtual_networks : key => length(local.regions[value.location].zones) == 0 ? { + hub_and_spoke_vnet_gateway_default_skus = { for key, value in var.hub_and_spoke_vnet_virtual_networks : key => length(local.regions[value.location].zones) == 0 ? { express_route = "Standard" vpn = "VpnGw1" } : { @@ -12,21 +12,20 @@ locals { for key, value in var.hub_and_spoke_vnet_virtual_networks : key => { name = templatestring(value.name, { location = value.location }) location = value.location - resource_group_name = module.resource_group_connectivity.name + resource_group_name = templatestring(value.resource_group_name, { location = value.location }) settings = value.settings virtual_network_gateways = { - express_route = try(value.virtual_network_gateways.express_route, { + express_route = try({ name = templatestring(value.virtual_network_gateways.express_route.name, { location = value.location }) - sku = value.virtual_network_gateways.express_route.sku == null ? vnet_gateway_default_skus[key].express_route : value.virtual_network_gateways.express_route.sku + sku = value.virtual_network_gateways.express_route.sku == null ? local.hub_and_spoke_vnet_gateway_default_skus[key].express_route : value.virtual_network_gateways.express_route.sku settings = value.virtual_network_gateways.express_route.settings - }) - vpn = try(value.virtual_network_gateways.vpn, { + }, null) + vpn = try({ name = templatestring(value.virtual_network_gateways.vpn.name, { location = value.location }) - sku = value.virtual_network_gateways.vpn.sku == null ? vnet_gateway_default_skus[key].vpn : value.virtual_network_gateways.vpn.sku + sku = value.virtual_network_gateways.vpn.sku == null ? local.hub_and_spoke_vnet_gateway_default_skus[key].vpn : value.virtual_network_gateways.vpn.sku settings = value.virtual_network_gateways.vpn.settings - }) + }, null) } } } - } diff --git a/templates/complete_multi_region/locals-private-dns.tf b/templates/complete_multi_region/locals-private-dns.tf index 53b9d12e..a307423c 100644 --- a/templates/complete_multi_region/locals-private-dns.tf +++ b/templates/complete_multi_region/locals-private-dns.tf @@ -1,20 +1,20 @@ locals { - private_dns_zones_locations_hub_and_spoke_vnet = var.connectity_type == "hub_and_spoke_vnet" ? { + private_dns_zones_locations_hub_and_spoke_vnet = local.connectivity_hub_and_spoke_vnet_enabled ? { for key, value in var.hub_and_spoke_vnet_virtual_networks : key => { location = value.location is_primary = value.location == var.location } } : {} - private_dns_zones_locations_virtual_wan = var.connectity_type == "virtual_wan" ? {} : {} + private_dns_zones_locations_virtual_wan = local.connectivity_virtual_wan_enabled ? {} : {} private_dns_zone_locations = merge(local.private_dns_zones_locations_hub_and_spoke_vnet, local.private_dns_zones_locations_virtual_wan) } locals { - private_dns_zones_virtual_networks_hub_and_spoke_vnet = var.connectity_type == "hub_and_spoke_vnet" ? { + private_dns_zones_virtual_networks_hub_and_spoke_vnet = local.connectivity_hub_and_spoke_vnet_enabled ? { for key, value in try(local.module_hub_and_spoke_vnet.hub_virtual_networks, {}) : key => { vnet_resource_id = module.hub_and_spoke_vnet[0].virtual_networks[key].resource_id } } : {} - private_dns_zones_virtual_networks_virtual_wan = var.connectity_type == "virtual_wan" ? {} : {} + private_dns_zones_virtual_networks_virtual_wan = local.connectivity_virtual_wan_enabled ? {} : {} private_dns_zones_virtual_networks = merge(local.private_dns_zones_virtual_networks_hub_and_spoke_vnet, local.private_dns_zones_virtual_networks_virtual_wan) } diff --git a/templates/complete_multi_region/locals-resource-groups.tf b/templates/complete_multi_region/locals-resource-groups.tf new file mode 100644 index 00000000..e4d74605 --- /dev/null +++ b/templates/complete_multi_region/locals-resource-groups.tf @@ -0,0 +1,27 @@ +locals { + resource_groups_hub_and_spoke_vnet = { + for key, value in local.hub_and_spoke_vnet_virtual_networks : key => { + name = value.resource_group_name + location = value.location + } + } + + resource_groups_virtual_wan = merge({ core = { + name = local.virtual_wan_resource_group_name + location = var.location + }},{ + for key, value in local.virtual_wan_virtual_hubs : key => { + name = value.resource_group_name + location = value.location + } if value.resource_group_name != local.var.virtual_wan_resource_group_name + }) + + resource_groups_private_dns_zones = !local.connectivity_none_enabled && var.private_dns_zones_enabled ? { + dns = { + name = local.private_dns_zones_resource_group_name + location = value.location + } + } : {} + + resource_groups = merge(local.resource_groups_hub_and_spoke_vnet, local.resource_groups_virtual_wan, local.resource_groups_private_dns_zones) +} \ No newline at end of file diff --git a/templates/complete_multi_region/locals-resource-names.tf b/templates/complete_multi_region/locals-resource-names.tf index 7f2c2100..58c861eb 100644 --- a/templates/complete_multi_region/locals-resource-names.tf +++ b/templates/complete_multi_region/locals-resource-names.tf @@ -2,4 +2,8 @@ locals { private_dns_zones_resource_group_name = templatestring(var.private_dns_zones_resource_group_name, { location = var.location }) ddos_protection_plan_resource_group_name = templatestring(var.ddos_protection_plan_resource_group_name, { location = var.location }) ddos_protection_plan_name = templatestring(var.ddos_protection_plan_name, { location = var.location }) + virtual_wan_resource_group_name = templatestring(var.virtual_wan_resource_group_name, { location = var.location }) + management_resource_group_name = templatestring(var.management_resource_group_name, { location = var.location }) + management_log_analytics_workspace_name = templatestring(var.management_log_analytics_workspace_name, { location = var.location }) + management_automation_account_name = templatestring(var.management_automation_account_name, { location = var.location }) } \ No newline at end of file diff --git a/templates/complete_multi_region/locals-virtual-wan.tf b/templates/complete_multi_region/locals-virtual-wan.tf index 2945c1cf..a963d532 100644 --- a/templates/complete_multi_region/locals-virtual-wan.tf +++ b/templates/complete_multi_region/locals-virtual-wan.tf @@ -1,8 +1,35 @@ locals { virtual_wan_virtual_hubs = { for key, value in var.virtual_wan_virtual_hubs : key => { - location = value.location - sku = value.sku - tags = value.tags - firewall = value.firewall - } } + name = templatestring(value.name, { location = value.location }) + location = value.location + resource_group_name = try(templatestring(value.resource_group_name, { location = value.location }), local.virtual_wan_resource_group_name) + virtual_network_connections = value.virtual_network_connections + firewall = try({ + name = templatestring(value.firewall.name, { location = value.location }) + sku_name = try(value.firewall.sku_name, "AZFW_Hub") + sku_tier = try(value.firewall.sku_tier, "Standard") + zones = try(value.firewall.zones, local.regions[value.location].zones) + firewall_policy ={ + name = templatestring(value.firewall.firewall_policy.name, { location = value.location }) + settings = value.firewall.firewall_policy.settings + } + settings = value.settings + }, null) + address_prefix = value.address_prefix + tags = try(value.tags, null) + hub_routing_preference = try(value.hub_routing_preference, null) + private_dns_zone_networking = try({ + virtual_network = { + name = templatestring(value.private_dns_zone_networking.virtual_network.name, { location = value.location }) + address_space = value.private_dns_zone_networking.virtual_network.address_space + private_dns_resolver_subnet = { + name = templatestring(value.private_dns_zone_networking.virtual_network.private_dns_resolver_subnet.name, { location = value.location }) + address_prefix = value.private_dns_zone_networking.virtual_network.private_dns_resolver_subnet.address_prefix + } + } + private_dns_resolver = { + name = templatestring(value.private_dns_zone_networking.private_dns_resolver.name, { location = value.location }) + } + }, null) + }} } diff --git a/templates/complete_multi_region/locals.tf b/templates/complete_multi_region/locals.tf new file mode 100644 index 00000000..e1c426e4 --- /dev/null +++ b/templates/complete_multi_region/locals.tf @@ -0,0 +1,15 @@ +locals { + const = { + connectivity = { + virtual_wan = "virtual_wan" + hub_and_spoke_vnet = "hub_and_spoke_vnet" + none = "none" + } + } +} + +locals { + connectivity_virtual_wan_enabled = var.connectivity_type == const.connectivity.virtual_wan + connectivity_hub_and_spoke_vnet_enabled = var.connectivity_type == const.connectivity.hub_and_spoke_vnet + connectivity_none_enabled = var.connectivity_type == const.connectivity.none +} diff --git a/templates/complete_multi_region/management-groups.tf b/templates/complete_multi_region/management-groups.tf index b9469992..5c68b13a 100644 --- a/templates/complete_multi_region/management-groups.tf +++ b/templates/complete_multi_region/management-groups.tf @@ -1,48 +1,9 @@ module "management_groups" { - source = "Azure/caf-enterprise-scale/azurerm" - version = "6.1.0" + source = "./modules/management-groups-and-resources" - count = local.management_groups_enabled ? 1 : 0 - - disable_telemetry = try(local.management_groups.disable_telemetry, !local.enable_telemetry) - default_location = try(local.management_groups.default_location, var.starter_locations[0]) - root_parent_id = try(local.management_groups.root_parent_id, data.azurerm_client_config.current.tenant_id) - archetype_config_overrides = try(local.management_groups.archetype_config_overrides, {}) - configure_connectivity_resources = try(local.management_groups.configure_connectivity_resources, {}) - configure_identity_resources = try(local.management_groups.configure_identity_resources, {}) - configure_management_resources = try(local.management_groups.configure_management_resources, {}) - create_duration_delay = try(local.management_groups.create_duration_delay, {}) - custom_landing_zones = try(local.management_groups.custom_landing_zones, {}) - custom_policy_roles = try(local.management_groups.custom_policy_roles, {}) - default_tags = try(local.management_groups.default_tags, {}) - deploy_connectivity_resources = try(local.management_groups.deploy_connectivity_resources, true) - deploy_core_landing_zones = try(local.management_groups.deploy_core_landing_zones, true) - deploy_corp_landing_zones = try(local.management_groups.deploy_corp_landing_zones, false) - deploy_demo_landing_zones = try(local.management_groups.deploy_demo_landing_zones, false) - deploy_diagnostics_for_mg = try(local.management_groups.deploy_diagnostics_for_mg, false) - deploy_identity_resources = try(local.management_groups.deploy_identity_resources, false) - deploy_management_resources = try(local.management_groups.deploy_management_resources, false) - deploy_online_landing_zones = try(local.management_groups.deploy_online_landing_zones, false) - deploy_sap_landing_zones = try(local.management_groups.deploy_sap_landing_zones, false) - destroy_duration_delay = try(local.management_groups.destroy_duration_delay, {}) - disable_base_module_tags = try(local.management_groups.disable_base_module_tags, false) - library_path = try(local.management_groups.library_path, "") - policy_non_compliance_message_default = try(local.management_groups.policy_non_compliance_message_default, "This resource {enforcementMode} be compliant with the assigned policy.") - policy_non_compliance_message_default_enabled = try(local.management_groups.policy_non_compliance_message_default_enabled, true) - policy_non_compliance_message_enabled = try(local.management_groups.policy_non_compliance_message_enabled, true) - policy_non_compliance_message_enforced_replacement = try(local.management_groups.policy_non_compliance_message_enforced_replacement, "must") - policy_non_compliance_message_enforcement_placeholder = try(local.management_groups.policy_non_compliance_message_enforcement_placeholder, "{enforcementMode}") - policy_non_compliance_message_not_enforced_replacement = try(local.management_groups.policy_non_compliance_message_not_enforced_replacement, "should") - policy_non_compliance_message_not_supported_definitions = try(local.management_groups.policy_non_compliance_message_not_supported_definitions, ["/providers/Microsoft.Authorization/policyDefinitions/1c6e92c9-99f0-4e55-9cf2-0c234dc48f99", "/providers/Microsoft.Authorization/policyDefinitions/1a5b4dca-0b6f-4cf5-907c-56316bc1bf3d", "/providers/Microsoft.Authorization/policyDefinitions/95edb821-ddaf-4404-9732-666045e056b4"]) - resource_custom_timeouts = try(local.management_groups.resource_custom_timeouts, {}) - root_id = try(local.management_groups.root_id, "alz") - root_name = try(local.management_groups.root_name, "Azure-Landing-Zones") - strict_subscription_association = try(local.management_groups.strict_subscription_association, true) - subscription_id_connectivity = try(local.management_groups.subscription_id_connectivity, var.subscription_id_connectivity) - subscription_id_identity = try(local.management_groups.subscription_id_identity, var.subscription_id_identity) - subscription_id_management = try(local.management_groups.subscription_id_management, var.subscription_id_management) - subscription_id_overrides = try(local.management_groups.subscription_id_overrides, {}) - template_file_variables = try(local.management_groups.template_file_variables, {}) + enable_telemetry = var.enable_telemetry + location = var.location + settings = local.management_groups.settings providers = { azurerm = azurerm diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/terraform.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/terraform.tf new file mode 100644 index 00000000..4619009c --- /dev/null +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/terraform.tf @@ -0,0 +1,14 @@ +terraform { + required_version = "~> 1.9" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.107" + } + azapi = { + source = "Azure/azapi" + version = "~> 1.13" + } + } + # backend "azurerm" {} +} diff --git a/templates/complete_multi_region/modules/management-groups-and-resources/data.tf b/templates/complete_multi_region/modules/management-groups-and-resources/data.tf new file mode 100644 index 00000000..cee07df2 --- /dev/null +++ b/templates/complete_multi_region/modules/management-groups-and-resources/data.tf @@ -0,0 +1 @@ +data "azurerm_client_config" "current" {} diff --git a/templates/complete_multi_region/modules/management-groups-and-resources/main.tf b/templates/complete_multi_region/modules/management-groups-and-resources/main.tf new file mode 100644 index 00000000..8da3959e --- /dev/null +++ b/templates/complete_multi_region/modules/management-groups-and-resources/main.tf @@ -0,0 +1,50 @@ +module "management_groups" { + source = "Azure/caf-enterprise-scale/azurerm" + version = "6.1.0" + + disable_telemetry = !var.enable_telemetry + default_location = var.location + root_parent_id = try(var.settings.root_parent_id, data.azurerm_client_config.current.tenant_id) + archetype_config_overrides = try(var.settings.archetype_config_overrides, {}) + configure_connectivity_resources = try(var.settings.configure_connectivity_resources, {}) + configure_identity_resources = try(var.settings.configure_identity_resources, {}) + configure_management_resources = try(var.settings.configure_management_resources, {}) + create_duration_delay = try(var.settings.create_duration_delay, {}) + custom_landing_zones = try(var.settings.custom_landing_zones, {}) + custom_policy_roles = try(var.settings.custom_policy_roles, {}) + default_tags = try(var.settings.default_tags, {}) + deploy_connectivity_resources = false + deploy_core_landing_zones = try(var.settings.deploy_core_landing_zones, true) + deploy_corp_landing_zones = try(var.settings.deploy_corp_landing_zones, false) + deploy_demo_landing_zones = try(var.settings.deploy_demo_landing_zones, false) + deploy_diagnostics_for_mg = try(var.settings.deploy_diagnostics_for_mg, false) + deploy_identity_resources = try(var.settings.deploy_identity_resources, false) + deploy_management_resources = try(var.settings.deploy_management_resources, false) + deploy_online_landing_zones = try(var.settings.deploy_online_landing_zones, false) + deploy_sap_landing_zones = try(var.settings.deploy_sap_landing_zones, false) + destroy_duration_delay = try(var.settings.destroy_duration_delay, {}) + disable_base_module_tags = try(var.settings.disable_base_module_tags, false) + library_path = try(var.settings.library_path, "") + policy_non_compliance_message_default = try(var.settings.policy_non_compliance_message_default, "This resource {enforcementMode} be compliant with the assigned policy.") + policy_non_compliance_message_default_enabled = try(var.settings.policy_non_compliance_message_default_enabled, true) + policy_non_compliance_message_enabled = try(var.settings.policy_non_compliance_message_enabled, true) + policy_non_compliance_message_enforced_replacement = try(var.settings.policy_non_compliance_message_enforced_replacement, "must") + policy_non_compliance_message_enforcement_placeholder = try(var.settings.policy_non_compliance_message_enforcement_placeholder, "{enforcementMode}") + policy_non_compliance_message_not_enforced_replacement = try(var.settings.policy_non_compliance_message_not_enforced_replacement, "should") + policy_non_compliance_message_not_supported_definitions = try(var.settings.policy_non_compliance_message_not_supported_definitions, ["/providers/Microsoft.Authorization/policyDefinitions/1c6e92c9-99f0-4e55-9cf2-0c234dc48f99", "/providers/Microsoft.Authorization/policyDefinitions/1a5b4dca-0b6f-4cf5-907c-56316bc1bf3d", "/providers/Microsoft.Authorization/policyDefinitions/95edb821-ddaf-4404-9732-666045e056b4"]) + resource_custom_timeouts = try(var.settings.resource_custom_timeouts, {}) + root_id = try(var.settings.root_id, "alz") + root_name = try(var.settings.root_name, "Azure-Landing-Zones") + strict_subscription_association = try(var.settings.strict_subscription_association, true) + subscription_id_connectivity = var.settings.subscription_id_connectivity + subscription_id_identity = var.settings.subscription_id_identity + subscription_id_management = var.settings.subscription_id_management + subscription_id_overrides = try(var.settings.subscription_id_overrides, {}) + template_file_variables = try(var.settings.template_file_variables, {}) + + providers = { + azurerm = azurerm + azurerm.connectivity = azurerm.connectivity + azurerm.management = azurerm.management + } +} diff --git a/templates/complete_multi_region/modules/management-groups-and-resources/outputs.tf b/templates/complete_multi_region/modules/management-groups-and-resources/outputs.tf new file mode 100644 index 00000000..e69de29b diff --git a/templates/complete_multi_region/modules/management-groups-and-resources/terraform.tf b/templates/complete_multi_region/modules/management-groups-and-resources/terraform.tf new file mode 100644 index 00000000..d2e2fb37 --- /dev/null +++ b/templates/complete_multi_region/modules/management-groups-and-resources/terraform.tf @@ -0,0 +1,18 @@ +terraform { + required_version = "~> 1.9" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.107" + configuration_aliases = [ + azurerm.connectivity, + azurerm.management, + ] + } + azapi = { + source = "Azure/azapi" + version = "~> 1.13" + } + } + # backend "azurerm" {} +} diff --git a/templates/complete_multi_region/modules/management-groups-and-resources/variables.tf b/templates/complete_multi_region/modules/management-groups-and-resources/variables.tf new file mode 100644 index 00000000..e1b060c5 --- /dev/null +++ b/templates/complete_multi_region/modules/management-groups-and-resources/variables.tf @@ -0,0 +1,17 @@ +variable "location" { + type = string + description = "The location of the resource group" + nullable = false +} + +variable "settings" { + type = any + description = "The settings for the management groups and resources" + default = null +} + +variable "enable_telemetry" { + type = bool + default = true + description = "Flag to enable/disable telemetry" +} diff --git a/templates/complete_multi_region/modules/private-dns/terraform.tf b/templates/complete_multi_region/modules/private-dns/terraform.tf new file mode 100644 index 00000000..28d0feae --- /dev/null +++ b/templates/complete_multi_region/modules/private-dns/terraform.tf @@ -0,0 +1,14 @@ +terraform { + required_version = "~> 1.8" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.107" + } + azapi = { + source = "Azure/azapi" + version = "~> 1.13" + } + } + # backend "azurerm" {} +} diff --git a/templates/complete_multi_region/modules/virtual-wan/terraform.tf b/templates/complete_multi_region/modules/virtual-wan/terraform.tf new file mode 100644 index 00000000..28d0feae --- /dev/null +++ b/templates/complete_multi_region/modules/virtual-wan/terraform.tf @@ -0,0 +1,14 @@ +terraform { + required_version = "~> 1.8" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.107" + } + azapi = { + source = "Azure/azapi" + version = "~> 1.13" + } + } + # backend "azurerm" {} +} diff --git a/templates/complete_multi_region/modules/virtual-wan/variables.tf b/templates/complete_multi_region/modules/virtual-wan/variables.tf index e7999198..add2a53d 100644 --- a/templates/complete_multi_region/modules/virtual-wan/variables.tf +++ b/templates/complete_multi_region/modules/virtual-wan/variables.tf @@ -23,7 +23,7 @@ variable "private_dns_zones_enabled" { } variable "settings" { - type = object + type = any description = "The settings for the virtual WAN" default = null } @@ -33,7 +33,7 @@ variable "virtual_hubs" { name = string location = string resource_group_name = string - virtual_network_connections = optional(object) + virtual_network_connections = optional(map(any)) firewall = optional(object({ name = string sku_name = string @@ -41,9 +41,9 @@ variable "virtual_hubs" { zones = optional(list(string)) firewall_policy = object({ name = string - settings = object + settings = optional(any) }) - settings = object + settings = optional(any) })) address_prefix = string tags = optional(map(string)) diff --git a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf index b4f8b7a3..50938e62 100644 --- a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf @@ -1,6 +1,5 @@ module "hub_and_spoke_vnet" { source = "./modules/hub-and-spoke-vnet" - version = "0.1.0" count = var.connectivity_type == "hub_and_spoke_vnet" ? 1 : 0 diff --git a/templates/complete_multi_region/networking-virtual-wan.tf b/templates/complete_multi_region/networking-virtual-wan.tf index c52348ab..b8106ae4 100644 --- a/templates/complete_multi_region/networking-virtual-wan.tf +++ b/templates/complete_multi_region/networking-virtual-wan.tf @@ -1,11 +1,13 @@ module "virtual_wan" { source = "./modules/virtual-wan" - count = var.connectity_type == "virtual_wan" ? 1 : 0 + count = local.connectivity_virtual_wan_enabled ? 1 : 0 - virtual_hubs = var.virtual_hubs + name = templatestring(var.virtual_wan_name, { location = var.location }) + location = var.location + resource_group_name = module.resource_group_connectivity.name + virtual_hubs = local.virtual_wan_virtual_hubs - providers = { azurerm = azurerm.connectivity } diff --git a/templates/complete_multi_region/outputs.tf b/templates/complete_multi_region/outputs.tf index 2d69b0d6..e69de29b 100644 --- a/templates/complete_multi_region/outputs.tf +++ b/templates/complete_multi_region/outputs.tf @@ -1,12 +0,0 @@ -# output "transformed_config_file" { -# value = local.config_file_content -# } - -output "firewall_ip_addresses" { - value = (local.hub_networking_enabled ? - { for key, value in try(module.hub_and_spoke_vnet[0].firewalls, {}) : key => value.private_ip_address } : - (local.virtual_wan_enabled ? - { for key, value in try(module.virtual_wan[0].fw, {}) : key => value.name } : {} - ) - ) # TODO: Output vWAN firewall IP addresses -} diff --git a/templates/complete_multi_region/resource-groups.tf b/templates/complete_multi_region/resource-groups.tf index b5c1d904..fa02fd1a 100644 --- a/templates/complete_multi_region/resource-groups.tf +++ b/templates/complete_multi_region/resource-groups.tf @@ -1,27 +1,12 @@ -module "resource_group_private_dns_zones" { +module "resource_groups" { source = "Azure/avm-res-resources-resourcegroup/azurerm" version = "0.1.0" - count = local.private_dns_enabled ? 1 : 0 + for_each = local.resource_groups - name = try(local.module_private_dns.resource_group_name, "rg-private-dns-${var.starter_locations[0]}") - location = try(local.module_private_dns.location, [for location in local.module_private_dns.locations : location if location.is_primary][0].location) - enable_telemetry = try(local.module_private_dns.enable_telemetry, local.enable_telemetry) - - providers = { - azurerm = azurerm.connectivity - } -} - -module "resource_group_connectivity" { - source = "Azure/avm-res-resources-resourcegroup/azurerm" - version = "0.1.0" - - count = var.connectity_type != "none" ? 1 : 0 - - name = try(local.module_private_dns.resource_group_name, "rg-private-dns-${var.starter_locations[0]}") - location = try(local.module_private_dns.location, [for location in local.module_private_dns.locations : location if location.is_primary][0].location) - enable_telemetry = try(local.module_private_dns.enable_telemetry, local.enable_telemetry) + name = each.value.name + location = each.value.location + enable_telemetry = var.enable_telemetry providers = { azurerm = azurerm.connectivity diff --git a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf index 9b54e967..2159827b 100644 --- a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf @@ -3,20 +3,20 @@ variable "hub_and_spoke_vnet_virtual_networks" { name = optional(string, "vnet-hub-$${location}") location = string resource_group_name = optional(string, "rg-hub-$${location}") - settings = object + settings = optional(any) virtual_network_gateways = optional(object({ express_route = optional(object({ name = optional(string, "vgw-hub-expressroute-$${location}") sku = optional(string) - settings = object + settings = optional(any) })) vpn = optional(object({ name = optional(string, "vgw-hub-vpn-$${location}") sku = optional(string) - settings = object + settings = optional(any) })) })) })) - default = {} description = "A map of hub networks to create. Detailed information about the hub network can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-hubnetworking" + default = {} } diff --git a/templates/complete_multi_region/variables-virtual-wan.tf b/templates/complete_multi_region/variables-virtual-wan.tf index b0e0d003..2de9fcae 100644 --- a/templates/complete_multi_region/variables-virtual-wan.tf +++ b/templates/complete_multi_region/variables-virtual-wan.tf @@ -4,8 +4,14 @@ variable "virtual_wan_name" { nullable = false } +variable "virtual_wan_resource_group_name" { + type = string + description = "The name of the resource group for the virtual WAN" + default = "rg-connectivity-$${location}" +} + variable "virtual_wan_settings" { - type = object + type = any description = "The settings for the virtual WAN" default = null } @@ -15,7 +21,7 @@ variable "virtual_wan_virtual_hubs" { name = optional(string, "vwan-hub-$${location}") location = string resource_group_name = optional(string, "rg-vwan-hub-$${location}") - virtual_network_connections = optional(object) + virtual_network_connections = optional(map(any)) firewall = optional(object({ name = optional(string, "fw-hub-$${location}") sku_name = string @@ -23,9 +29,9 @@ variable "virtual_wan_virtual_hubs" { zones = optional(list(string)) firewall_policy = object({ name = optional(string, "fwp-hub-$${location}") - settings = object + settings = optional(any) }) - settings = object + settings = optional(any) })) address_prefix = string tags = optional(map(string)) @@ -47,9 +53,3 @@ variable "virtual_wan_virtual_hubs" { default = {} description = "A map of virtual hubs to create. Detailed information about the virtual hub can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-virtualhub" } - -variable "enable_telemetry" { - type = bool - default = true - description = "Flag to enable/disable telemetry" -} \ No newline at end of file diff --git a/templates/complete_multi_region/variables.management.tf b/templates/complete_multi_region/variables.management.tf new file mode 100644 index 00000000..f3c52706 --- /dev/null +++ b/templates/complete_multi_region/variables.management.tf @@ -0,0 +1,28 @@ +variable "management_use_vnext" { + type = bool + default = false + description = "Flag to enable/disable the use of the next version of the management module" +} + +variable "management_resource_group_name" { + type = string + description = "The name of the resource group for the management resources" + default = "rg-management-$${location}" +} + +variable "management_log_analytics_workspace_name" { + type = string + description = "The name of the Log Analytics workspace for the management resources" + default = "law-management-$${location}" +} + +variable "management_automation_account_name" { + type = string + description = "The SKU of the Log Analytics workspace for the management resources" + default = "aa-management-$${location}" +} + +variable "management_settings" { + type = any + default = null +} \ No newline at end of file From 31e0ee5360075b9e30a69341f304b8262fdc8fba Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Fri, 4 Oct 2024 19:13:36 +0100 Subject: [PATCH 03/23] save changes --- .../locals-hub-and-spoke-vnet.tf | 56 +++++++++---- .../locals-management.tf | 46 +++++++++++ .../locals-private-dns.tf | 12 +-- .../locals-resource-groups.tf | 14 ++-- .../locals-resource-names.tf | 16 ++-- .../locals-virtual-wan.tf | 18 ++--- templates/complete_multi_region/locals.tf | 10 +-- .../management-groups.tf | 13 --- .../main.tf => management.tf} | 74 ++++++++--------- .../modules/hub-and-spoke-vnet/locals.tf | 23 +++--- .../modules/hub-and-spoke-vnet/main.tf | 48 +++++------ .../modules/hub-and-spoke-vnet/outputs.tf | 2 +- .../modules/hub-and-spoke-vnet/variables.tf | 16 +--- .../management-groups-and-resources/data.tf | 1 - .../outputs.tf | 0 .../terraform.tf | 18 ----- .../variables.tf | 17 ---- .../modules/virtual-wan/locals.tf | 52 ++++++------ .../modules/virtual-wan/main.tf | 43 ++++------ .../modules/virtual-wan/variables.tf | 24 +++--- .../networking-hub-and-spoke-vnet.tf | 5 +- .../networking-private-dns.tf | 14 ++-- .../networking-virtual-wan.tf | 13 +-- .../variables-hub-and-spoke-vnet.tf | 80 ++++++++++++++++--- .../variables-virtual-wan.tf | 30 +++---- .../variables.management.tf | 17 ++-- 26 files changed, 365 insertions(+), 297 deletions(-) create mode 100644 templates/complete_multi_region/locals-management.tf delete mode 100644 templates/complete_multi_region/management-groups.tf rename templates/complete_multi_region/{modules/management-groups-and-resources/main.tf => management.tf} (52%) delete mode 100644 templates/complete_multi_region/modules/management-groups-and-resources/data.tf delete mode 100644 templates/complete_multi_region/modules/management-groups-and-resources/outputs.tf delete mode 100644 templates/complete_multi_region/modules/management-groups-and-resources/terraform.tf delete mode 100644 templates/complete_multi_region/modules/management-groups-and-resources/variables.tf diff --git a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf index 178d4817..a517c50b 100644 --- a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf @@ -1,31 +1,55 @@ +output "debug" { + value = local.hub_and_spoke_vnet_virtual_networks +} + locals { hub_and_spoke_vnet_gateway_default_skus = { for key, value in var.hub_and_spoke_vnet_virtual_networks : key => length(local.regions[value.location].zones) == 0 ? { - express_route = "Standard" - vpn = "VpnGw1" + express_route = "Standard" + vpn = "VpnGw1" } : { - express_route = "ErGw1AZ" - vpn = "VpnGw1AZ" - } + express_route = "ErGw1AZ" + vpn = "VpnGw1AZ" + } } - - hub_and_spoke_vnet_virtual_networks = { + + hub_and_spoke_vnet_virtual_networks_template = { for key, value in var.hub_and_spoke_vnet_virtual_networks : key => { - name = templatestring(value.name, { location = value.location }) - location = value.location - resource_group_name = templatestring(value.resource_group_name, { location = value.location }) - settings = value.settings + hub_virtual_network = { + name = templatestring(value.name, { location = value.location }) + resource_group_name = templatestring(value.resource_group_name, { location = value.location }) + location = value.location + firewall = try({ + name = templatestring(value.firewall.name, { location = value.location }) + sku_name = "AZFW_VNet" + sku_tier = "Standard" + zones = local.regions[value.location].zones + default_ip_configuration = try({ + public_ip_config = { + name = templatestring(value.firewall.default_ip_configuration.public_ip_config.name, { location = value.location }) + zones = local.regions[value.location].zones + } + }) + firewall_policy = { + name = templatestring(value.firewall.firewall_policy.name, { location = value.location }) + } + }, null) + } virtual_network_gateways = { express_route = try({ name = templatestring(value.virtual_network_gateways.express_route.name, { location = value.location }) - sku = value.virtual_network_gateways.express_route.sku == null ? local.hub_and_spoke_vnet_gateway_default_skus[key].express_route : value.virtual_network_gateways.express_route.sku - settings = value.virtual_network_gateways.express_route.settings + sku = local.hub_and_spoke_vnet_gateway_default_skus[key].express_route + type = "ExpressRoute" + location = value.location }, null) vpn = try({ - name = templatestring(value.virtual_network_gateways.vpn.name, { location = value.location }) - sku = value.virtual_network_gateways.vpn.sku == null ? local.hub_and_spoke_vnet_gateway_default_skus[key].vpn : value.virtual_network_gateways.vpn.sku - settings = value.virtual_network_gateways.vpn.settings + name = templatestring(value.virtual_network_gateways.vpn.name, { location = value.location }) + sku = local.hub_and_spoke_vnet_gateway_default_skus[key].vpn + type = "Vpn" + location = value.location }, null) } } } + + hub_and_spoke_vnet_virtual_networks = merge(local.hub_and_spoke_vnet_virtual_networks_template, var.hub_and_spoke_vnet_virtual_networks, var.hub_and_spoke_vnet_virtual_networks_overrides) } diff --git a/templates/complete_multi_region/locals-management.tf b/templates/complete_multi_region/locals-management.tf new file mode 100644 index 00000000..42b3194d --- /dev/null +++ b/templates/complete_multi_region/locals-management.tf @@ -0,0 +1,46 @@ +locals { + management_settings = merge(local.management_settings_custom, var.management_settings) + management_settings_custom = { + configure_connectivity_resources = { + settings = { + dns = { + config = { + location = var.location + } + } + } + advanced = { + custom_settings_by_resource_type = { + azurerm_resource_group = { + dns = { + name = local.private_dns_zones_resource_group_name + } + } + } + } + } + configure_management_resources = { + location = var.location + advanced = { + asc_export_resource_group_name = local.management_asc_export_resource_group_name + custom_settings_by_resource_type = { + azurerm_resource_group = { + management = { + name = local.management_resource_group_name + } + } + } + azurerm_log_analytics_workspace = { + management = { + name = local.management_log_analytics_workspace_name + } + } + azurerm_automation_account = { + management = { + name = local.management_automation_account_name + } + } + } + } + } +} \ No newline at end of file diff --git a/templates/complete_multi_region/locals-private-dns.tf b/templates/complete_multi_region/locals-private-dns.tf index a307423c..715559f7 100644 --- a/templates/complete_multi_region/locals-private-dns.tf +++ b/templates/complete_multi_region/locals-private-dns.tf @@ -6,15 +6,15 @@ locals { } } : {} private_dns_zones_locations_virtual_wan = local.connectivity_virtual_wan_enabled ? {} : {} - private_dns_zone_locations = merge(local.private_dns_zones_locations_hub_and_spoke_vnet, local.private_dns_zones_locations_virtual_wan) + private_dns_zone_locations = merge(local.private_dns_zones_locations_hub_and_spoke_vnet, local.private_dns_zones_locations_virtual_wan) } locals { - private_dns_zones_virtual_networks_hub_and_spoke_vnet = local.connectivity_hub_and_spoke_vnet_enabled ? { - for key, value in try(local.module_hub_and_spoke_vnet.hub_virtual_networks, {}) : key => { - vnet_resource_id = module.hub_and_spoke_vnet[0].virtual_networks[key].resource_id - } + private_dns_zones_virtual_networks_hub_and_spoke_vnet = local.connectivity_hub_and_spoke_vnet_enabled ? { + for key, value in local.hub_and_spoke_vnet_virtual_networks : key => { + vnet_resource_id = module.hub_and_spoke_vnet[0].virtual_networks[key].resource_id + } } : {} private_dns_zones_virtual_networks_virtual_wan = local.connectivity_virtual_wan_enabled ? {} : {} - private_dns_zones_virtual_networks = merge(local.private_dns_zones_virtual_networks_hub_and_spoke_vnet, local.private_dns_zones_virtual_networks_virtual_wan) + private_dns_zones_virtual_networks = merge(local.private_dns_zones_virtual_networks_hub_and_spoke_vnet, local.private_dns_zones_virtual_networks_virtual_wan) } diff --git a/templates/complete_multi_region/locals-resource-groups.tf b/templates/complete_multi_region/locals-resource-groups.tf index e4d74605..2f9e62f6 100644 --- a/templates/complete_multi_region/locals-resource-groups.tf +++ b/templates/complete_multi_region/locals-resource-groups.tf @@ -1,25 +1,25 @@ locals { resource_groups_hub_and_spoke_vnet = { for key, value in local.hub_and_spoke_vnet_virtual_networks : key => { - name = value.resource_group_name + name = value.resource_group_name location = value.location } } resource_groups_virtual_wan = merge({ core = { - name = local.virtual_wan_resource_group_name + name = local.virtual_wan_resource_group_name location = var.location - }},{ + } }, { for key, value in local.virtual_wan_virtual_hubs : key => { - name = value.resource_group_name + name = value.resource_group_name location = value.location - } if value.resource_group_name != local.var.virtual_wan_resource_group_name + } if value.resource_group_name != local.virtual_wan_resource_group_name }) resource_groups_private_dns_zones = !local.connectivity_none_enabled && var.private_dns_zones_enabled ? { dns = { - name = local.private_dns_zones_resource_group_name - location = value.location + name = local.private_dns_zones_resource_group_name + location = var.location } } : {} diff --git a/templates/complete_multi_region/locals-resource-names.tf b/templates/complete_multi_region/locals-resource-names.tf index 58c861eb..9d64317f 100644 --- a/templates/complete_multi_region/locals-resource-names.tf +++ b/templates/complete_multi_region/locals-resource-names.tf @@ -1,9 +1,11 @@ locals { - private_dns_zones_resource_group_name = templatestring(var.private_dns_zones_resource_group_name, { location = var.location }) - ddos_protection_plan_resource_group_name = templatestring(var.ddos_protection_plan_resource_group_name, { location = var.location }) - ddos_protection_plan_name = templatestring(var.ddos_protection_plan_name, { location = var.location }) - virtual_wan_resource_group_name = templatestring(var.virtual_wan_resource_group_name, { location = var.location }) - management_resource_group_name = templatestring(var.management_resource_group_name, { location = var.location }) - management_log_analytics_workspace_name = templatestring(var.management_log_analytics_workspace_name, { location = var.location }) - management_automation_account_name = templatestring(var.management_automation_account_name, { location = var.location }) + private_dns_zones_resource_group_name = templatestring(var.private_dns_zones_resource_group_name, { location = var.location }) + ddos_protection_plan_resource_group_name = templatestring(var.ddos_protection_plan_resource_group_name, { location = var.location }) + ddos_protection_plan_name = templatestring(var.ddos_protection_plan_name, { location = var.location }) + virtual_wan_resource_group_name = templatestring(var.virtual_wan_resource_group_name, { location = var.location }) + virtual_wan_name = templatestring(var.virtual_wan_name, { location = var.location }) + management_resource_group_name = templatestring(var.management_resource_group_name, { location = var.location }) + management_log_analytics_workspace_name = templatestring(var.management_log_analytics_workspace_name, { location = var.location }) + management_automation_account_name = templatestring(var.management_automation_account_name, { location = var.location }) + management_asc_export_resource_group_name = templatestring(var.management_asc_export_resource_group_name, { location = var.location }) } \ No newline at end of file diff --git a/templates/complete_multi_region/locals-virtual-wan.tf b/templates/complete_multi_region/locals-virtual-wan.tf index a963d532..a1c5c9fd 100644 --- a/templates/complete_multi_region/locals-virtual-wan.tf +++ b/templates/complete_multi_region/locals-virtual-wan.tf @@ -1,29 +1,29 @@ locals { virtual_wan_virtual_hubs = { for key, value in var.virtual_wan_virtual_hubs : key => { - name = templatestring(value.name, { location = value.location }) - location = value.location - resource_group_name = try(templatestring(value.resource_group_name, { location = value.location }), local.virtual_wan_resource_group_name) + name = templatestring(value.name, { location = value.location }) + location = value.location + resource_group_name = try(templatestring(value.resource_group_name, { location = value.location }), local.virtual_wan_resource_group_name) virtual_network_connections = value.virtual_network_connections firewall = try({ name = templatestring(value.firewall.name, { location = value.location }) sku_name = try(value.firewall.sku_name, "AZFW_Hub") sku_tier = try(value.firewall.sku_tier, "Standard") zones = try(value.firewall.zones, local.regions[value.location].zones) - firewall_policy ={ + firewall_policy = { name = templatestring(value.firewall.firewall_policy.name, { location = value.location }) settings = value.firewall.firewall_policy.settings } settings = value.settings }, null) - address_prefix = value.address_prefix - tags = try(value.tags, null) + address_prefix = value.address_prefix + tags = try(value.tags, null) hub_routing_preference = try(value.hub_routing_preference, null) private_dns_zone_networking = try({ virtual_network = { - name = templatestring(value.private_dns_zone_networking.virtual_network.name, { location = value.location }) + name = templatestring(value.private_dns_zone_networking.virtual_network.name, { location = value.location }) address_space = value.private_dns_zone_networking.virtual_network.address_space private_dns_resolver_subnet = { - name = templatestring(value.private_dns_zone_networking.virtual_network.private_dns_resolver_subnet.name, { location = value.location }) + name = templatestring(value.private_dns_zone_networking.virtual_network.private_dns_resolver_subnet.name, { location = value.location }) address_prefix = value.private_dns_zone_networking.virtual_network.private_dns_resolver_subnet.address_prefix } } @@ -31,5 +31,5 @@ locals { name = templatestring(value.private_dns_zone_networking.private_dns_resolver.name, { location = value.location }) } }, null) - }} + } } } diff --git a/templates/complete_multi_region/locals.tf b/templates/complete_multi_region/locals.tf index e1c426e4..3a7dc480 100644 --- a/templates/complete_multi_region/locals.tf +++ b/templates/complete_multi_region/locals.tf @@ -1,15 +1,15 @@ locals { const = { connectivity = { - virtual_wan = "virtual_wan" + virtual_wan = "virtual_wan" hub_and_spoke_vnet = "hub_and_spoke_vnet" - none = "none" + none = "none" } } } locals { - connectivity_virtual_wan_enabled = var.connectivity_type == const.connectivity.virtual_wan - connectivity_hub_and_spoke_vnet_enabled = var.connectivity_type == const.connectivity.hub_and_spoke_vnet - connectivity_none_enabled = var.connectivity_type == const.connectivity.none + connectivity_virtual_wan_enabled = var.connectivity_type == local.const.connectivity.virtual_wan + connectivity_hub_and_spoke_vnet_enabled = var.connectivity_type == local.const.connectivity.hub_and_spoke_vnet + connectivity_none_enabled = var.connectivity_type == local.const.connectivity.none } diff --git a/templates/complete_multi_region/management-groups.tf b/templates/complete_multi_region/management-groups.tf deleted file mode 100644 index 5c68b13a..00000000 --- a/templates/complete_multi_region/management-groups.tf +++ /dev/null @@ -1,13 +0,0 @@ -module "management_groups" { - source = "./modules/management-groups-and-resources" - - enable_telemetry = var.enable_telemetry - location = var.location - settings = local.management_groups.settings - - providers = { - azurerm = azurerm - azurerm.connectivity = azurerm.connectivity - azurerm.management = azurerm.management - } -} diff --git a/templates/complete_multi_region/modules/management-groups-and-resources/main.tf b/templates/complete_multi_region/management.tf similarity index 52% rename from templates/complete_multi_region/modules/management-groups-and-resources/main.tf rename to templates/complete_multi_region/management.tf index 8da3959e..fefc4bfd 100644 --- a/templates/complete_multi_region/modules/management-groups-and-resources/main.tf +++ b/templates/complete_multi_region/management.tf @@ -4,47 +4,47 @@ module "management_groups" { disable_telemetry = !var.enable_telemetry default_location = var.location - root_parent_id = try(var.settings.root_parent_id, data.azurerm_client_config.current.tenant_id) - archetype_config_overrides = try(var.settings.archetype_config_overrides, {}) - configure_connectivity_resources = try(var.settings.configure_connectivity_resources, {}) - configure_identity_resources = try(var.settings.configure_identity_resources, {}) - configure_management_resources = try(var.settings.configure_management_resources, {}) - create_duration_delay = try(var.settings.create_duration_delay, {}) - custom_landing_zones = try(var.settings.custom_landing_zones, {}) - custom_policy_roles = try(var.settings.custom_policy_roles, {}) - default_tags = try(var.settings.default_tags, {}) + root_parent_id = try(local.management_settings.root_parent_id, data.azurerm_client_config.current.tenant_id) + archetype_config_overrides = try(local.management_settings.archetype_config_overrides, {}) + configure_connectivity_resources = try(local.management_settings.configure_connectivity_resources, {}) + configure_identity_resources = try(local.management_settings.configure_identity_resources, {}) + configure_management_resources = try(local.management_settings.configure_management_resources, {}) + create_duration_delay = try(local.management_settings.create_duration_delay, {}) + custom_landing_zones = try(local.management_settings.custom_landing_zones, {}) + custom_policy_roles = try(local.management_settings.custom_policy_roles, {}) + default_tags = try(local.management_settings.default_tags, {}) deploy_connectivity_resources = false - deploy_core_landing_zones = try(var.settings.deploy_core_landing_zones, true) - deploy_corp_landing_zones = try(var.settings.deploy_corp_landing_zones, false) - deploy_demo_landing_zones = try(var.settings.deploy_demo_landing_zones, false) - deploy_diagnostics_for_mg = try(var.settings.deploy_diagnostics_for_mg, false) - deploy_identity_resources = try(var.settings.deploy_identity_resources, false) - deploy_management_resources = try(var.settings.deploy_management_resources, false) - deploy_online_landing_zones = try(var.settings.deploy_online_landing_zones, false) - deploy_sap_landing_zones = try(var.settings.deploy_sap_landing_zones, false) - destroy_duration_delay = try(var.settings.destroy_duration_delay, {}) - disable_base_module_tags = try(var.settings.disable_base_module_tags, false) - library_path = try(var.settings.library_path, "") - policy_non_compliance_message_default = try(var.settings.policy_non_compliance_message_default, "This resource {enforcementMode} be compliant with the assigned policy.") - policy_non_compliance_message_default_enabled = try(var.settings.policy_non_compliance_message_default_enabled, true) - policy_non_compliance_message_enabled = try(var.settings.policy_non_compliance_message_enabled, true) - policy_non_compliance_message_enforced_replacement = try(var.settings.policy_non_compliance_message_enforced_replacement, "must") - policy_non_compliance_message_enforcement_placeholder = try(var.settings.policy_non_compliance_message_enforcement_placeholder, "{enforcementMode}") - policy_non_compliance_message_not_enforced_replacement = try(var.settings.policy_non_compliance_message_not_enforced_replacement, "should") - policy_non_compliance_message_not_supported_definitions = try(var.settings.policy_non_compliance_message_not_supported_definitions, ["/providers/Microsoft.Authorization/policyDefinitions/1c6e92c9-99f0-4e55-9cf2-0c234dc48f99", "/providers/Microsoft.Authorization/policyDefinitions/1a5b4dca-0b6f-4cf5-907c-56316bc1bf3d", "/providers/Microsoft.Authorization/policyDefinitions/95edb821-ddaf-4404-9732-666045e056b4"]) - resource_custom_timeouts = try(var.settings.resource_custom_timeouts, {}) - root_id = try(var.settings.root_id, "alz") - root_name = try(var.settings.root_name, "Azure-Landing-Zones") - strict_subscription_association = try(var.settings.strict_subscription_association, true) - subscription_id_connectivity = var.settings.subscription_id_connectivity - subscription_id_identity = var.settings.subscription_id_identity - subscription_id_management = var.settings.subscription_id_management - subscription_id_overrides = try(var.settings.subscription_id_overrides, {}) - template_file_variables = try(var.settings.template_file_variables, {}) + deploy_core_landing_zones = try(local.management_settings.deploy_core_landing_zones, true) + deploy_corp_landing_zones = try(local.management_settings.deploy_corp_landing_zones, false) + deploy_demo_landing_zones = try(local.management_settings.deploy_demo_landing_zones, false) + deploy_diagnostics_for_mg = try(local.management_settings.deploy_diagnostics_for_mg, false) + deploy_identity_resources = try(local.management_settings.deploy_identity_resources, false) + deploy_management_resources = try(local.management_settings.deploy_management_resources, false) + deploy_online_landing_zones = try(local.management_settings.deploy_online_landing_zones, false) + deploy_sap_landing_zones = try(local.management_settings.deploy_sap_landing_zones, false) + destroy_duration_delay = try(local.management_settings.destroy_duration_delay, {}) + disable_base_module_tags = try(local.management_settings.disable_base_module_tags, false) + library_path = try(local.management_settings.library_path, "") + policy_non_compliance_message_default = try(local.management_settings.policy_non_compliance_message_default, "This resource {enforcementMode} be compliant with the assigned policy.") + policy_non_compliance_message_default_enabled = try(local.management_settings.policy_non_compliance_message_default_enabled, true) + policy_non_compliance_message_enabled = try(local.management_settings.policy_non_compliance_message_enabled, true) + policy_non_compliance_message_enforced_replacement = try(local.management_settings.policy_non_compliance_message_enforced_replacement, "must") + policy_non_compliance_message_enforcement_placeholder = try(local.management_settings.policy_non_compliance_message_enforcement_placeholder, "{enforcementMode}") + policy_non_compliance_message_not_enforced_replacement = try(local.management_settings.policy_non_compliance_message_not_enforced_replacement, "should") + policy_non_compliance_message_not_supported_definitions = try(local.management_settings.policy_non_compliance_message_not_supported_definitions, ["/providers/Microsoft.Authorization/policyDefinitions/1c6e92c9-99f0-4e55-9cf2-0c234dc48f99", "/providers/Microsoft.Authorization/policyDefinitions/1a5b4dca-0b6f-4cf5-907c-56316bc1bf3d", "/providers/Microsoft.Authorization/policyDefinitions/95edb821-ddaf-4404-9732-666045e056b4"]) + resource_custom_timeouts = try(local.management_settings.resource_custom_timeouts, {}) + root_id = try(local.management_settings.root_id, "alz") + root_name = try(local.management_settings.root_name, "Azure-Landing-Zones") + strict_subscription_association = try(local.management_settings.strict_subscription_association, true) + subscription_id_connectivity = var.subscription_id_connectivity + subscription_id_identity = var.subscription_id_identity + subscription_id_management = var.subscription_id_management + subscription_id_overrides = try(local.management_settings.subscription_id_overrides, {}) + template_file_variables = try(local.management_settings.template_file_variables, {}) providers = { azurerm = azurerm azurerm.connectivity = azurerm.connectivity azurerm.management = azurerm.management } -} +} \ No newline at end of file diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf index de1916a3..100936da 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf @@ -1,23 +1,18 @@ locals { + hub_virtual_networks = { + for key, value in var.hub_virtual_networks : key => value.hub_virtual_network + } virtual_network_gateways_express_route = { for hub_network_key, hub_network_value in var.hub_virtual_networks : "${hub_network_key}-express-route" => { - name = hub_network_value.virtual_network_gateways.express_route.settings.name - type = "ExpressRoute" - sku = hub_network_value.sku - location = hub_network_value.location - virtual_network_id = module.hub_module.hub_and_spoke_vnet.virtual_networks[hub_network_key].id - settings = hub_network_value.virtual_network_gateways.express_route.settings + hub_network_key = hub_network_key + virtual_network_gateway = hub_network_value.virtual_network_gateways.express_route } if can(hub_network_value.virtual_network_gateways.express_route) } virtual_network_gateways_vpn = { for hub_network_key, hub_network_value in var.hub_virtual_networks : "${hub_network_key}-vpn" => { - name = hub_network_value.virtual_network_gateways.vpn.settings.name - type = "Vpn" - sku = hub_network_value.sku - location = hub_network_value.location - virtual_network_id = module.hub_module.hub_and_spoke_vnet.virtual_networks[hub_network_key].id - settings = hub_network_value.virtual_network_gateways.vpn.settings - } if can(hub_network_value.virtual_network_gateways.vpn) + hub_network_key = hub_network_key + virtual_network_gateway = hub_network_value.virtual_network_gateways.vpn + } if can(hub_network_value.virtual_network_gateways.vpn) } virtual_network_gateways = merge(local.virtual_network_gateways_express_route, local.virtual_network_gateways_vpn) -} +} \ No newline at end of file diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf index 9ae20232..f86a056d 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf @@ -2,7 +2,7 @@ module "hub_and_spoke_vnet" { source = "Azure/avm-ptn-hubnetworking/azurerm" version = "0.1.0" - hub_virtual_networks = var.hub_virtual_networks + hub_virtual_networks = local.hub_virtual_networks enable_telemetry = var.enable_telemetry } @@ -12,30 +12,30 @@ module "virtual_network_gateway" { for_each = local.virtual_network_gateways - location = each.value.location - name = each.value.name - sku = each.value.sku - type = each.value.type - virtual_network_id = each.value.virtual_network_id + location = each.value.virtual_network_gateway.location + name = each.value.virtual_network_gateway.name + sku = each.value.virtual_network_gateway.sku + type = each.value.virtual_network_gateway.type + virtual_network_id = module.hub_and_spoke_vnet.virtual_networks[each.value.hub_network_key].id default_tags = var.tags - subnet_creation_enabled = try(each.value.settings.subnet_creation_enabled, null) - edge_zone = try(each.value.settings.edge_zone, null) - express_route_circuits = try(each.value.settings.express_route_circuits, null) - ip_configurations = try(each.value.settings.ip_configurations, null) - local_network_gateways = try(each.value.settings.local_network_gateways, null) - subnet_address_prefix = try(each.value.subnet_address_prefix, null) - tags = try(each.value.settings.tags, null) - vpn_active_active_enabled = try(each.value.settings.vpn_active_active_enabled, null) - vpn_bgp_enabled = try(each.value.settings.vpn_bgp_enabled, null) - vpn_bgp_settings = try(each.value.settings.vpn_bgp_settings, null) - vpn_generation = try(each.value.settings.vpn_generation, null) - vpn_point_to_site = try(each.value.settings.vpn_point_to_site, null) - vpn_type = try(each.value.settings.vpn_type, null) - vpn_private_ip_address_enabled = try(each.value.settings.vpn_private_ip_address_enabled, null) - route_table_bgp_route_propagation_enabled = try(each.value.settings.route_table_bgp_route_propagation_enabled, null) - route_table_creation_enabled = try(each.value.route_table_creation_enabled, null) - route_table_name = try(each.value.settings.route_table_name, null) - route_table_tags = try(each.value.settings.route_table_tags, null) + subnet_creation_enabled = try(each.value.virtual_network_gateway.settings.subnet_creation_enabled, null) + edge_zone = try(each.value.virtual_network_gateway.settings.edge_zone, null) + express_route_circuits = try(each.value.virtual_network_gateway.settings.express_route_circuits, null) + ip_configurations = try(each.value.virtual_network_gateway.settings.ip_configurations, null) + local_network_gateways = try(each.value.virtual_network_gateway.settings.local_network_gateways, null) + subnet_address_prefix = each.value.virtual_network_gateway.subnet_address_prefix + tags = try(each.value.virtual_network_gateway.settings.tags, null) + vpn_active_active_enabled = try(each.value.virtual_network_gateway.settings.vpn_active_active_enabled, null) + vpn_bgp_enabled = try(each.value.virtual_network_gateway.settings.vpn_bgp_enabled, null) + vpn_bgp_settings = try(each.value.virtual_network_gateway.settings.vpn_bgp_settings, null) + vpn_generation = try(each.value.virtual_network_gateway.settings.vpn_generation, null) + vpn_point_to_site = try(each.value.virtual_network_gateway.settings.vpn_point_to_site, null) + vpn_type = try(each.value.virtual_network_gateway.settings.vpn_type, null) + vpn_private_ip_address_enabled = try(each.value.virtual_network_gateway.settings.vpn_private_ip_address_enabled, null) + route_table_bgp_route_propagation_enabled = try(each.value.virtual_network_gateway.settings.route_table_bgp_route_propagation_enabled, null) + route_table_creation_enabled = try(each.value.virtual_network_gateway.route_table_creation_enabled, null) + route_table_name = try(each.value.virtual_network_gateway.settings.route_table_name, null) + route_table_tags = try(each.value.virtual_network_gateway.settings.route_table_tags, null) enable_telemetry = var.enable_telemetry depends_on = [ diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/outputs.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/outputs.tf index 04eefe68..7a7fd518 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/outputs.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/outputs.tf @@ -1,6 +1,6 @@ output "virtual_networks" { value = { - for key, value in module.module.hub_and_spoke_vnet.virtual_networks : key => { + for key, value in module.hub_and_spoke_vnet.virtual_networks : key => { resource_id = value.id } } diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf index c8940d14..e37e27f4 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf @@ -1,20 +1,10 @@ variable "hub_virtual_networks" { type = map(object({ - name = string location = string - resource_group_name = string - settings = object + hub_virtual_network = any virtual_network_gateways = optional(object({ - express_route = optional(object({ - name = string - sku = string - settings = object - })) - vpn = optional(object({ - name = string - sku = string - settings = object - })) + express_route = optional(any) + vpn = optional(any) })) })) default = {} diff --git a/templates/complete_multi_region/modules/management-groups-and-resources/data.tf b/templates/complete_multi_region/modules/management-groups-and-resources/data.tf deleted file mode 100644 index cee07df2..00000000 --- a/templates/complete_multi_region/modules/management-groups-and-resources/data.tf +++ /dev/null @@ -1 +0,0 @@ -data "azurerm_client_config" "current" {} diff --git a/templates/complete_multi_region/modules/management-groups-and-resources/outputs.tf b/templates/complete_multi_region/modules/management-groups-and-resources/outputs.tf deleted file mode 100644 index e69de29b..00000000 diff --git a/templates/complete_multi_region/modules/management-groups-and-resources/terraform.tf b/templates/complete_multi_region/modules/management-groups-and-resources/terraform.tf deleted file mode 100644 index d2e2fb37..00000000 --- a/templates/complete_multi_region/modules/management-groups-and-resources/terraform.tf +++ /dev/null @@ -1,18 +0,0 @@ -terraform { - required_version = "~> 1.9" - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "~> 3.107" - configuration_aliases = [ - azurerm.connectivity, - azurerm.management, - ] - } - azapi = { - source = "Azure/azapi" - version = "~> 1.13" - } - } - # backend "azurerm" {} -} diff --git a/templates/complete_multi_region/modules/management-groups-and-resources/variables.tf b/templates/complete_multi_region/modules/management-groups-and-resources/variables.tf deleted file mode 100644 index e1b060c5..00000000 --- a/templates/complete_multi_region/modules/management-groups-and-resources/variables.tf +++ /dev/null @@ -1,17 +0,0 @@ -variable "location" { - type = string - description = "The location of the resource group" - nullable = false -} - -variable "settings" { - type = any - description = "The settings for the management groups and resources" - default = null -} - -variable "enable_telemetry" { - type = bool - default = true - description = "Flag to enable/disable telemetry" -} diff --git a/templates/complete_multi_region/modules/virtual-wan/locals.tf b/templates/complete_multi_region/modules/virtual-wan/locals.tf index d51e8bb1..210b451f 100644 --- a/templates/complete_multi_region/modules/virtual-wan/locals.tf +++ b/templates/complete_multi_region/modules/virtual-wan/locals.tf @@ -1,20 +1,20 @@ locals { - virtual_network_connections_input = { for virtual_network_connection in flatten([ for virtual_hub_key, virtual_hub_value in var.virtual_hubs : - [ for virtual_network_connection_key, virtual_network_connection_value in value.virtual_network_connections : { + virtual_network_connections_input = { for virtual_network_connection in flatten([for virtual_hub_key, virtual_hub_value in var.virtual_hubs : + [for virtual_network_connection_key, virtual_network_connection_value in virtual_hub_value.virtual_network_connections : { unique_key = "${virtual_hub_key}-${virtual_network_connection_key}" name = virtual_network_connection_value.settings.name virtual_hub_key = virtual_hub_key remote_virtual_network_id = virtual_network_connection_value.remote_virtual_network_id settings = virtual_network_connection_value.settings - } ] - ]) : virtual_network_connection.unique_key => { + }] + ]) : virtual_network_connection.unique_key => { name = virtual_network_connection.name virtual_hub_key = virtual_network_connection.virtual_hub_key remote_virtual_network_id = virtual_network_connection.remote_virtual_network_id settings = virtual_network_connection.settings } } - - virtual_network_connections_private_dns = var.private_dns_zones_enabled ? { for key, value in try(local.module_virtual_wan.virtual_hubs, {}) : "private_dns_vnet_${key}" => { + + virtual_network_connections_private_dns = var.private_dns_zones_enabled ? { for key, value in var.virtual_hubs : "private_dns_vnet_${key}" => { name = "private_dns_vnet_${key}" virtual_hub_key = key remote_virtual_network_id = module.virtual_network_private_dns[key].resource_id @@ -22,32 +22,32 @@ locals { virtual_network_connections = merge(local.virtual_network_connections_input, local.virtual_network_connections_private_dns) } - + locals { firewall_policies = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => { - virtual_hub_key = virtual_hub_value.firewall.virtual_hub_key - name = virtual_hub_value.firewall.firewall_policy.name - location = virtual_hub_value.location - resource_group_name = virtual_hub_value.resource_group == null ? var.resource_group_name : virtual_hub_value.resource_group - settings = virtual_hub_value.firewall.firewall_policysettings + virtual_hub_key = virtual_hub_value.firewall.virtual_hub_key + name = virtual_hub_value.firewall.firewall_policy.name + location = virtual_hub_value.location + resource_group_name = virtual_hub_value.resource_group == null ? var.resource_group_name : virtual_hub_value.resource_group + settings = virtual_hub_value.firewall.firewall_policysettings } if can(virtual_hub_value.firewall.firewall_policy) } firewalls = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => { - virtual_hub_key = virtual_hub_value.firewall.virtual_hub_key - name = virtual_hub_value.firewall.name - sku_name = virtual_hub_value.firewall.sku_name - sku_tier = virtual_hub_value.firewall.sku_tier - dns_servers = try(virtual_hub_value.firewall.settings.dns_servers, null) - private_ip_ranges = try(virtual_hub_value.firewall.settings.private_ip_ranges, null) - threat_intel_mode = try(virtual_hub_value.firewall.settings.threat_intel_mode, null) - zones = virtual_hub_value.firewall.zones - vhub_public_ip_count = try(virtual_hub_value.firewall.settings.vhub_public_ip_count, null) - tags = try(virtual_hub_value.firewall.settings.tags, null) - default_ip_configuration = try(virtual_hub_value.firewall.default_ip_configuration, null) - management_ip_configuration = try(virtual_hub_value.firewall.management_ip_configuration, null) - ip_configuration = try(virtual_hub_value.firewall.ip_configuration, null) - firewall_policy_id = module.firewall_policy[virtual_hub_key].resource_id + virtual_hub_key = virtual_hub_value.firewall.virtual_hub_key + name = virtual_hub_value.firewall.name + sku_name = virtual_hub_value.firewall.sku_name + sku_tier = virtual_hub_value.firewall.sku_tier + dns_servers = try(virtual_hub_value.firewall.settings.dns_servers, null) + private_ip_ranges = try(virtual_hub_value.firewall.settings.private_ip_ranges, null) + threat_intel_mode = try(virtual_hub_value.firewall.settings.threat_intel_mode, null) + zones = virtual_hub_value.firewall.zones + vhub_public_ip_count = try(virtual_hub_value.firewall.settings.vhub_public_ip_count, null) + tags = try(virtual_hub_value.firewall.settings.tags, null) + default_ip_configuration = try(virtual_hub_value.firewall.default_ip_configuration, null) + management_ip_configuration = try(virtual_hub_value.firewall.management_ip_configuration, null) + ip_configuration = try(virtual_hub_value.firewall.ip_configuration, null) + firewall_policy_id = module.firewall_policy[virtual_hub_key].resource_id } if can(virtual_hub_value.firewall) } } diff --git a/templates/complete_multi_region/modules/virtual-wan/main.tf b/templates/complete_multi_region/modules/virtual-wan/main.tf index 936fee6b..ab43cd93 100644 --- a/templates/complete_multi_region/modules/virtual-wan/main.tf +++ b/templates/complete_multi_region/modules/virtual-wan/main.tf @@ -25,41 +25,36 @@ module "virtual_wan" { source = "Azure/avm-ptn-virtualwan/azurerm" version = "0.5.0" - allow_branch_to_branch_traffic = try(local.module_virtual_wan.allow_branch_to_branch_traffic, null) - disable_vpn_encryption = try(local.module_virtual_wan.disable_vpn_encryption, false) - er_circuit_connections = try(local.module_virtual_wan.er_circuit_connections, {}) - expressroute_gateways = try(local.module_virtual_wan.expressroute_gateways, {}) + allow_branch_to_branch_traffic = try(var.settings.allow_branch_to_branch_traffic, null) + disable_vpn_encryption = try(var.settings.disable_vpn_encryption, false) + er_circuit_connections = try(var.settings.er_circuit_connections, {}) + expressroute_gateways = try(var.settings.expressroute_gateways, {}) firewalls = local.firewalls - office365_local_breakout_category = try(local.module_virtual_wan.office365_local_breakout_category, null) + office365_local_breakout_category = try(var.settings.office365_local_breakout_category, null) location = var.location - p2s_gateway_vpn_server_configurations = try(local.module_virtual_wan.p2s_gateway_vpn_server_configurations, {}) - p2s_gateways = try(local.module_virtual_wan.p2s_gateways, {}) + p2s_gateway_vpn_server_configurations = try(var.settings.p2s_gateway_vpn_server_configurations, {}) + p2s_gateways = try(var.settings.p2s_gateways, {}) resource_group_name = var.resource_group_name create_resource_group = false virtual_hubs = var.virtual_hubs virtual_network_connections = local.virtual_network_connections virtual_wan_name = var.name - type = try(local.module_virtual_wan.type, null) - routing_intents = try(local.module_virtual_wan.routing_intents, null) - resource_group_tags = try(local.module_virtual_wan.resource_group_tags, null) - virtual_wan_tags = try(local.module_virtual_wan.virtual_wan_tags, null) - vpn_gateways = try(local.module_virtual_wan.vpn_gateways, {}) - vpn_site_connections = try(local.module_virtual_wan.vpn_site_connections, {}) - vpn_sites = try(local.module_virtual_wan.vpn_sites, null) - tags = try(local.module_virtual_wan.tags, null) + type = try(var.settings.type, null) + routing_intents = try(var.settings.routing_intents, null) + resource_group_tags = try(var.settings.resource_group_tags, null) + virtual_wan_tags = try(var.settings.virtual_wan_tags, null) + vpn_gateways = try(var.settings.vpn_gateways, {}) + vpn_site_connections = try(var.settings.vpn_site_connections, {}) + vpn_sites = try(var.settings.vpn_sites, null) + tags = try(var.settings.tags, null) enable_telemetry = var.enable_telemetry - - depends_on = [ - module.management_groups, - module.virtual_wan_resource_group - ] } module "virtual_network_private_dns" { source = "Azure/avm-res-network-virtualnetwork/azurerm" version = "0.4.0" - for_each = var.private_dns_zones_enabled ? var.virtual_hubs : {} + for_each = var.private_dns_zones_enabled ? var.virtual_hubs : {} address_space = each.value.private_dns_zones_networking.virtual_network.address_space location = each.value.location @@ -79,15 +74,13 @@ module "virtual_network_private_dns" { }] } } - - depends_on = [module.virtual_wan_resource_group] } module "dns_resolver" { source = "Azure/avm-res-network-dnsresolver/azurerm" version = "0.2.1" - for_each = var.private_dns_zones_enabled ? var.virtual_hubs : {} + for_each = var.private_dns_zones_enabled ? var.virtual_hubs : {} location = each.value.location name = each.value.private_dns_zones_networking.private_dns_resolver.name @@ -100,6 +93,4 @@ module "dns_resolver" { subnet_name = module.virtual_network_private_dns[each.key].subnets.dns.name } } - - depends_on = [module.virtual_wan_resource_group] } diff --git a/templates/complete_multi_region/modules/virtual-wan/variables.tf b/templates/complete_multi_region/modules/virtual-wan/variables.tf index add2a53d..b743e23d 100644 --- a/templates/complete_multi_region/modules/virtual-wan/variables.tf +++ b/templates/complete_multi_region/modules/virtual-wan/variables.tf @@ -7,13 +7,13 @@ variable "name" { variable "resource_group_name" { type = string description = "The name of the resource group for the virtual WAN" - nullable = false + nullable = false } variable "location" { - type = string + type = string description = "A map of locations to create the virtual WAN" - nullable = false + nullable = false } variable "private_dns_zones_enabled" { @@ -23,16 +23,16 @@ variable "private_dns_zones_enabled" { } variable "settings" { - type = any + type = any description = "The settings for the virtual WAN" - default = null + default = null } variable "virtual_hubs" { type = map(object({ - name = string - location = string - resource_group_name = string + name = string + location = string + resource_group_name = string virtual_network_connections = optional(map(any)) firewall = optional(object({ name = string @@ -45,15 +45,15 @@ variable "virtual_hubs" { }) settings = optional(any) })) - address_prefix = string - tags = optional(map(string)) + address_prefix = string + tags = optional(map(string)) hub_routing_preference = optional(string) private_dns_zone_networking = optional(object({ virtual_network = object({ - name = string + name = string address_space = string private_dns_resolver_subnet = object({ - name = string + name = string address_prefix = string }) }) diff --git a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf index 50938e62..bed0c148 100644 --- a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf @@ -1,5 +1,5 @@ module "hub_and_spoke_vnet" { - source = "./modules/hub-and-spoke-vnet" + source = "./modules/hub-and-spoke-vnet" count = var.connectivity_type == "hub_and_spoke_vnet" ? 1 : 0 @@ -11,6 +11,7 @@ module "hub_and_spoke_vnet" { } depends_on = [ - module.management_groups + module.management_groups, + module.resource_groups ] } diff --git a/templates/complete_multi_region/networking-private-dns.tf b/templates/complete_multi_region/networking-private-dns.tf index 65b9770a..32cbfc9e 100644 --- a/templates/complete_multi_region/networking-private-dns.tf +++ b/templates/complete_multi_region/networking-private-dns.tf @@ -3,15 +3,17 @@ module "private_dns_zones" { count = var.private_dns_zones_enabled ? 1 : 0 - locations = local.private_dns_zone_locations - resource_group_name = module.resource_group_private_dns_zones.name + locations = local.private_dns_zone_locations + resource_group_name = local.private_dns_zones_resource_group_name connected_virtual_networks = local.private_dns_zones_virtual_networks - enable_telemetry = var.enable_telemetry - tags = var.private_dns_zones_tags + enable_telemetry = var.enable_telemetry + tags = var.private_dns_zones_tags - depends_on = [module.private_dns_zones_resource_group] + depends_on = [ + module.resource_groups + ] providers = { - azurerm = azurerm.connectivity + azurerm = azurerm.connectivity, } } diff --git a/templates/complete_multi_region/networking-virtual-wan.tf b/templates/complete_multi_region/networking-virtual-wan.tf index b8106ae4..6166990b 100644 --- a/templates/complete_multi_region/networking-virtual-wan.tf +++ b/templates/complete_multi_region/networking-virtual-wan.tf @@ -3,16 +3,17 @@ module "virtual_wan" { count = local.connectivity_virtual_wan_enabled ? 1 : 0 - name = templatestring(var.virtual_wan_name, { location = var.location }) - location = var.location - resource_group_name = module.resource_group_connectivity.name - virtual_hubs = local.virtual_wan_virtual_hubs - + name = local.virtual_wan_name + location = var.location + resource_group_name = local.virtual_wan_resource_group_name + virtual_hubs = local.virtual_wan_virtual_hubs + providers = { azurerm = azurerm.connectivity } depends_on = [ - module.management_groups + module.management_groups, + module.resource_groups ] } \ No newline at end of file diff --git a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf index 2159827b..75102242 100644 --- a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf @@ -1,22 +1,80 @@ variable "hub_and_spoke_vnet_virtual_networks" { type = map(object({ - name = optional(string, "vnet-hub-$${location}") - location = string - resource_group_name = optional(string, "rg-hub-$${location}") - settings = optional(any) + location = string + hub_virtual_network = object({ + name = optional(string, "vnet-hub-$${location}") + resource_group_name = optional(string, "rg-hub-$${location}") + address_space = list(string) + firewall = optional(object({ + name = optional(string, "fw-hub-$${location}") + subnet_address_prefix = string + default_ip_configuration = optional(object({ + public_ip_config = optional(object({ + name = optional(string, "pip-fw-hub-$${location}") + })) + })) + firewall_policy = optional(object({ + name = optional(string, "fwp-hub-$${location}") + })) + })) + }) virtual_network_gateways = optional(object({ express_route = optional(object({ - name = optional(string, "vgw-hub-expressroute-$${location}") - sku = optional(string) - settings = optional(any) + subnet_address_prefix = string + name = optional(string, "vgw-hub-expressroute-$${location}") })) vpn = optional(object({ - name = optional(string, "vgw-hub-vpn-$${location}") - sku = optional(string) - settings = optional(any) + subnet_address_prefix = string + name = optional(string, "vgw-hub-vpn-$${location}") })) })) })) description = "A map of hub networks to create. Detailed information about the hub network can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-hubnetworking" - default = {} + default = { + primary = { + location = "uksouth" + hub_virtual_network = { + address_space = ["10.0.0.0/16"] + firewall = { + subnet_address_prefix = "10.0.0.0/24" + } + } + virtual_network_gateways = { + express_route = { + subnet_address_prefix = "10.0.1.0/24" + } + vpn = { + subnet_address_prefix = "10.0.2.0/24" + } + } + } + secondary = { + location = "ukwest" + hub_virtual_network = { + address_space = ["10.1.0.0/16"] + firewall = { + subnet_address_prefix = "10.1.0.0/24" + } + } + virtual_network_gateways = { + express_route = { + subnet_address_prefix = "10.1.1.0/24" + } + vpn = { + subnet_address_prefix = "10.1.2.0/24" + } + } + } + } +} + +variable "hub_and_spoke_vnet_virtual_networks_overrides" { + type = map(object({ + hub_virtual_network = any + virtual_network_gateways = optional(object({ + express_route = optional(any) + vpn = optional(any) + })) + })) + default = {} } diff --git a/templates/complete_multi_region/variables-virtual-wan.tf b/templates/complete_multi_region/variables-virtual-wan.tf index 2de9fcae..42f69f37 100644 --- a/templates/complete_multi_region/variables-virtual-wan.tf +++ b/templates/complete_multi_region/variables-virtual-wan.tf @@ -1,47 +1,47 @@ variable "virtual_wan_name" { type = string description = "The name of the virtual WAN" - nullable = false + default = "vwan-$${location}" } variable "virtual_wan_resource_group_name" { type = string description = "The name of the resource group for the virtual WAN" - default = "rg-connectivity-$${location}" + default = "rg-connectivity-$${location}" } variable "virtual_wan_settings" { - type = any + type = any description = "The settings for the virtual WAN" - default = null + default = null } variable "virtual_wan_virtual_hubs" { type = map(object({ - name = optional(string, "vwan-hub-$${location}") - location = string - resource_group_name = optional(string, "rg-vwan-hub-$${location}") + name = optional(string, "vwan-hub-$${location}") + location = string + resource_group_name = optional(string, "rg-vwan-hub-$${location}") virtual_network_connections = optional(map(any)) firewall = optional(object({ name = optional(string, "fw-hub-$${location}") - sku_name = string - sku_tier = string + sku_name = optional(string, null) + sku_tier = optional(string, null) zones = optional(list(string)) - firewall_policy = object({ + firewall_policy = optional(object({ name = optional(string, "fwp-hub-$${location}") settings = optional(any) - }) + })) settings = optional(any) })) - address_prefix = string - tags = optional(map(string)) + address_prefix = string + tags = optional(map(string)) hub_routing_preference = optional(string) private_dns_zone_networking = optional(object({ virtual_network = object({ - name = optional(string, "vnet-hub-dns-$${location}") + name = optional(string, "vnet-hub-dns-$${location}") address_space = string private_dns_resolver_subnet = object({ - name = optional(string, "subnet-hub-dns-$${location}") + name = optional(string, "subnet-hub-dns-$${location}") address_prefix = string }) }) diff --git a/templates/complete_multi_region/variables.management.tf b/templates/complete_multi_region/variables.management.tf index f3c52706..2d66766d 100644 --- a/templates/complete_multi_region/variables.management.tf +++ b/templates/complete_multi_region/variables.management.tf @@ -1,28 +1,35 @@ variable "management_use_vnext" { type = bool default = false - description = "Flag to enable/disable the use of the next version of the management module" + description = "Flag to enable/disable the use of the next version of the management module" } variable "management_resource_group_name" { type = string description = "The name of the resource group for the management resources" - default = "rg-management-$${location}" + default = "rg-management-$${location}" +} + +variable "management_asc_export_resource_group_name" { + type = string + description = "The name of the resource group for the management ASC export resources" + default = "rg-management-asc-export-$${location}" + } variable "management_log_analytics_workspace_name" { type = string description = "The name of the Log Analytics workspace for the management resources" - default = "law-management-$${location}" + default = "law-management-$${location}" } variable "management_automation_account_name" { type = string description = "The SKU of the Log Analytics workspace for the management resources" - default = "aa-management-$${location}" + default = "aa-management-$${location}" } variable "management_settings" { - type = any + type = any default = null } \ No newline at end of file From 480f7ba287f9392f864fc86040f353c400e713d3 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Sat, 5 Oct 2024 14:07:17 +0100 Subject: [PATCH 04/23] Save hub and spoke vnets --- .../complete_multi_region/locals-config.tf | 39 ++++++++ .../locals-hub-and-spoke-vnet.tf | 48 ++-------- .../modules/hub-and-spoke-vnet/variables.tf | 1 - .../variables-hub-and-spoke-vnet.tf | 90 +++++++++++-------- templates/complete_multi_region/variables.tf | 4 +- 5 files changed, 99 insertions(+), 83 deletions(-) create mode 100644 templates/complete_multi_region/locals-config.tf diff --git a/templates/complete_multi_region/locals-config.tf b/templates/complete_multi_region/locals-config.tf new file mode 100644 index 00000000..f4aaec23 --- /dev/null +++ b/templates/complete_multi_region/locals-config.tf @@ -0,0 +1,39 @@ +locals { + config_template_file_variables = { + starter_location_01 = var.starter_locations[0] + starter_location_02 = try(var.starter_locations[1], null) + starter_location_03 = try(var.starter_locations[2], null) + starter_location_04 = try(var.starter_locations[3], null) + starter_location_05 = try(var.starter_locations[4], null) + starter_location_06 = try(var.starter_locations[5], null) + starter_location_07 = try(var.starter_locations[6], null) + starter_location_08 = try(var.starter_locations[7], null) + starter_location_09 = try(var.starter_locations[8], null) + starter_location_10 = try(var.starter_locations[9], null) + starter_location_01_availability_zones = jsonencode(local.regions[var.starter_locations[0]].zones) + starter_location_02_availability_zones = jsonencode(try(local.regions[var.starter_locations[1]].zones, null)) + starter_location_03_availability_zones = jsonencode(try(local.regions[var.starter_locations[2]].zones, null)) + starter_location_04_availability_zones = jsonencode(try(local.regions[var.starter_locations[3]].zones, null)) + starter_location_05_availability_zones = jsonencode(try(local.regions[var.starter_locations[4]].zones, null)) + starter_location_06_availability_zones = jsonencode(try(local.regions[var.starter_locations[5]].zones, null)) + starter_location_07_availability_zones = jsonencode(try(local.regions[var.starter_locations[6]].zones, null)) + starter_location_08_availability_zones = jsonencode(try(local.regions[var.starter_locations[7]].zones, null)) + starter_location_09_availability_zones = jsonencode(try(local.regions[var.starter_locations[8]].zones, null)) + starter_location_10_availability_zones = jsonencode(try(local.regions[var.starter_locations[9]].zones, null)) + starter_location_01_virtual_network_gateway_sku = local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[0]].express_route + starter_location_02_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[1]].express_route, null) + starter_location_03_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[2]].express_route, null) + starter_location_04_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[3]].express_route, null) + starter_location_05_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[4]].express_route, null) + starter_location_06_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[5]].express_route, null) + starter_location_07_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[6]].express_route, null) + starter_location_08_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[7]].express_route, null) + starter_location_09_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[8]].express_route, null) + starter_location_10_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[9]].express_route, null) + default_postfix = var.default_postfix + root_parent_management_group_id = var.root_parent_management_group_id == "" ? data.azapi_client_config.current.tenant_id : var.root_parent_management_group_id + subscription_id_connectivity = var.subscription_id_connectivity + subscription_id_identity = var.subscription_id_identity + subscription_id_management = var.subscription_id_management + } +} \ No newline at end of file diff --git a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf index a517c50b..62b25b88 100644 --- a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf @@ -3,7 +3,7 @@ output "debug" { } locals { - hub_and_spoke_vnet_gateway_default_skus = { for key, value in var.hub_and_spoke_vnet_virtual_networks : key => length(local.regions[value.location].zones) == 0 ? { + hub_and_spoke_vnet_gateway_default_skus = { for key, value in local.regions : key => length(value.zones) == 0 ? { express_route = "Standard" vpn = "VpnGw1" } : { @@ -11,45 +11,11 @@ locals { vpn = "VpnGw1AZ" } } +} - hub_and_spoke_vnet_virtual_networks_template = { - for key, value in var.hub_and_spoke_vnet_virtual_networks : key => { - hub_virtual_network = { - name = templatestring(value.name, { location = value.location }) - resource_group_name = templatestring(value.resource_group_name, { location = value.location }) - location = value.location - firewall = try({ - name = templatestring(value.firewall.name, { location = value.location }) - sku_name = "AZFW_VNet" - sku_tier = "Standard" - zones = local.regions[value.location].zones - default_ip_configuration = try({ - public_ip_config = { - name = templatestring(value.firewall.default_ip_configuration.public_ip_config.name, { location = value.location }) - zones = local.regions[value.location].zones - } - }) - firewall_policy = { - name = templatestring(value.firewall.firewall_policy.name, { location = value.location }) - } - }, null) - } - virtual_network_gateways = { - express_route = try({ - name = templatestring(value.virtual_network_gateways.express_route.name, { location = value.location }) - sku = local.hub_and_spoke_vnet_gateway_default_skus[key].express_route - type = "ExpressRoute" - location = value.location - }, null) - vpn = try({ - name = templatestring(value.virtual_network_gateways.vpn.name, { location = value.location }) - sku = local.hub_and_spoke_vnet_gateway_default_skus[key].vpn - type = "Vpn" - location = value.location - }, null) - } - } - } - - hub_and_spoke_vnet_virtual_networks = merge(local.hub_and_spoke_vnet_virtual_networks_template, var.hub_and_spoke_vnet_virtual_networks, var.hub_and_spoke_vnet_virtual_networks_overrides) +locals { + hub_and_spoke_vnet_virtual_json = tostring(jsonencode(var.hub_and_spoke_vnet_virtual_networks)) + hub_and_spoke_vnet_virtual_json_templated = templatestring(local.hub_and_spoke_vnet_virtual_json_templated, local.config_template_file_variables) + hub_and_spoke_vnet_virtual_json_final = replace(replace(local.hub_and_spoke_vnet_virtual_json_templated, "\"[", "["), "]\"", "]") + hub_and_spoke_vnet_virtual_networks = jsondecode(local.hub_and_spoke_vnet_virtual_json_final) } diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf index e37e27f4..3b015c7e 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf @@ -1,6 +1,5 @@ variable "hub_virtual_networks" { type = map(object({ - location = string hub_virtual_network = any virtual_network_gateways = optional(object({ express_route = optional(any) diff --git a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf index 75102242..edefabca 100644 --- a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf @@ -1,80 +1,92 @@ variable "hub_and_spoke_vnet_virtual_networks" { type = map(object({ - location = string - hub_virtual_network = object({ - name = optional(string, "vnet-hub-$${location}") - resource_group_name = optional(string, "rg-hub-$${location}") - address_space = list(string) - firewall = optional(object({ - name = optional(string, "fw-hub-$${location}") - subnet_address_prefix = string - default_ip_configuration = optional(object({ - public_ip_config = optional(object({ - name = optional(string, "pip-fw-hub-$${location}") - })) - })) - firewall_policy = optional(object({ - name = optional(string, "fwp-hub-$${location}") - })) - })) - }) + hub_virtual_network = any virtual_network_gateways = optional(object({ - express_route = optional(object({ - subnet_address_prefix = string - name = optional(string, "vgw-hub-expressroute-$${location}") - })) - vpn = optional(object({ - subnet_address_prefix = string - name = optional(string, "vgw-hub-vpn-$${location}") - })) + express_route = optional(any) + vpn = optional(any) })) })) description = "A map of hub networks to create. Detailed information about the hub network can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-hubnetworking" default = { primary = { - location = "uksouth" hub_virtual_network = { + name = "vnet-hub-$${starter_location_01}" + resource_group_name = "rg-hub-$${starter_location_01}" + location = "$${starter_location_01}" address_space = ["10.0.0.0/16"] firewall = { subnet_address_prefix = "10.0.0.0/24" + name = "fw-hub-$${starter_location_01}" + sku_name = "AZFW_VNet" + sku_tier = "Standard" + zones = "$${starter_location_01_availability_zones}" + default_ip_configuration = { + public_ip_config = { + name = "pip-fw-hub-$${starter_location_01}" + zones = "$${starter_location_01_availability_zones}" + } + } + firewall_policy = { + name = "fwp-hub-$${starter_location_01}" + } } } virtual_network_gateways = { express_route = { + location = "$${starter_location_01}" subnet_address_prefix = "10.0.1.0/24" + name = "vgw-hub-expressroute-$${starter_location_01}" + type = "ExpressRoute" + sku = "$${starter_location_01_virtual_network_gateway_sku}" } vpn = { + location = "$${starter_location_01}" subnet_address_prefix = "10.0.2.0/24" + name = "vgw-hub-vpn-$${starter_location_01}" + type = "Vpn" + sku = "$${starter_location_01_virtual_network_gateway_sku}" } } } secondary = { - location = "ukwest" hub_virtual_network = { + name = "vnet-hub-$${starter_location_02}" + resource_group_name = "rg-hub-$${starter_location_02}" + location = "$${starter_location_02}" address_space = ["10.1.0.0/16"] firewall = { subnet_address_prefix = "10.1.0.0/24" + name = "fw-hub-$${starter_location_02}" + sku_name = "AZFW_VNet" + sku_tier = "Standard" + zones = "$${starter_location_02_availability_zones}" + default_ip_configuration = { + public_ip_config = { + name = "pip-fw-hub-$${starter_location_02}" + zones = "$${starter_location_02_availability_zones}" + } + } + firewall_policy = { + name = "fwp-hub-$${starter_location_01}" + } } } virtual_network_gateways = { express_route = { + location = "$${starter_location_02}" subnet_address_prefix = "10.1.1.0/24" + name = "vgw-hub-expressroute-$${starter_location_02}" + type = "ExpressRoute" + sku = "$${starter_location_02_virtual_network_gateway_sku}" } vpn = { + location = "$${starter_location_02}" subnet_address_prefix = "10.1.2.0/24" + name = "vgw-hub-vpn-$${starter_location_02}" + type = "Vpn" + sku = "$${starter_location_02_virtual_network_gateway_sku}" } } } } } - -variable "hub_and_spoke_vnet_virtual_networks_overrides" { - type = map(object({ - hub_virtual_network = any - virtual_network_gateways = optional(object({ - express_route = optional(any) - vpn = optional(any) - })) - })) - default = {} -} diff --git a/templates/complete_multi_region/variables.tf b/templates/complete_multi_region/variables.tf index 2cd1e2f1..7aa7e27f 100644 --- a/templates/complete_multi_region/variables.tf +++ b/templates/complete_multi_region/variables.tf @@ -1,5 +1,5 @@ -variable "location" { - type = string +variable "starter_locations" { + type = list(string) description = "The default for Azure resources. (e.g 'uksouth')|azure_location" } From 49ae6f01db601ba658c642014565ef2d475eba97 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Mon, 7 Oct 2024 09:52:46 +0100 Subject: [PATCH 05/23] Save updates --- .../complete_multi_region/locals-config.tf | 2 +- .../locals-hub-and-spoke-vnet.tf | 4 - .../locals-management.tf | 57 +++------- .../locals-private-dns.tf | 20 ---- .../locals-resource-groups.tf | 38 ++++--- .../locals-resource-names.tf | 11 +- .../locals-virtual-wan.tf | 42 ++------ templates/complete_multi_region/management.tf | 48 ++------- .../modules/hub-and-spoke-vnet/locals.tf | 41 ++++++- .../modules/hub-and-spoke-vnet/main.tf | 58 +++++++--- .../modules/hub-and-spoke-vnet/variables.tf | 9 ++ .../modules/management/main.tf | 50 +++++++++ .../modules/management/variables.tf | 8 ++ .../modules/private-dns/locals.tf | 22 ---- .../modules/private-dns/main.tf | 14 --- .../modules/private-dns/outputs.tf | 0 .../modules/private-dns/terraform.tf | 14 --- .../modules/private-dns/variables.tf | 34 ------ .../modules/virtual-wan/locals.tf | 80 +++++++++----- .../modules/virtual-wan/main.tf | 101 +++++++++++------- .../modules/virtual-wan/variables.tf | 86 +++++---------- .../networking-private-dns.tf | 19 ---- .../networking-virtual-wan.tf | 5 +- .../variables-connectivity.tf | 28 ----- .../variables-hub-and-spoke-vnet.tf | 20 ++++ .../variables-virtual-wan.tf | 100 +++++++++-------- .../variables.management.tf | 83 +++++++++----- templates/complete_multi_region/variables.tf | 6 -- 28 files changed, 478 insertions(+), 522 deletions(-) delete mode 100644 templates/complete_multi_region/locals-private-dns.tf create mode 100644 templates/complete_multi_region/modules/management/main.tf create mode 100644 templates/complete_multi_region/modules/management/variables.tf delete mode 100644 templates/complete_multi_region/modules/private-dns/locals.tf delete mode 100644 templates/complete_multi_region/modules/private-dns/main.tf delete mode 100644 templates/complete_multi_region/modules/private-dns/outputs.tf delete mode 100644 templates/complete_multi_region/modules/private-dns/terraform.tf delete mode 100644 templates/complete_multi_region/modules/private-dns/variables.tf delete mode 100644 templates/complete_multi_region/networking-private-dns.tf diff --git a/templates/complete_multi_region/locals-config.tf b/templates/complete_multi_region/locals-config.tf index f4aaec23..7ecbb2d4 100644 --- a/templates/complete_multi_region/locals-config.tf +++ b/templates/complete_multi_region/locals-config.tf @@ -1,4 +1,5 @@ locals { + primary_location = var.starter_locations[0] config_template_file_variables = { starter_location_01 = var.starter_locations[0] starter_location_02 = try(var.starter_locations[1], null) @@ -30,7 +31,6 @@ locals { starter_location_08_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[7]].express_route, null) starter_location_09_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[8]].express_route, null) starter_location_10_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[9]].express_route, null) - default_postfix = var.default_postfix root_parent_management_group_id = var.root_parent_management_group_id == "" ? data.azapi_client_config.current.tenant_id : var.root_parent_management_group_id subscription_id_connectivity = var.subscription_id_connectivity subscription_id_identity = var.subscription_id_identity diff --git a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf index 62b25b88..78804d59 100644 --- a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf @@ -1,7 +1,3 @@ -output "debug" { - value = local.hub_and_spoke_vnet_virtual_networks -} - locals { hub_and_spoke_vnet_gateway_default_skus = { for key, value in local.regions : key => length(value.zones) == 0 ? { express_route = "Standard" diff --git a/templates/complete_multi_region/locals-management.tf b/templates/complete_multi_region/locals-management.tf index 42b3194d..57ec315d 100644 --- a/templates/complete_multi_region/locals-management.tf +++ b/templates/complete_multi_region/locals-management.tf @@ -1,46 +1,13 @@ locals { - management_settings = merge(local.management_settings_custom, var.management_settings) - management_settings_custom = { - configure_connectivity_resources = { - settings = { - dns = { - config = { - location = var.location - } - } - } - advanced = { - custom_settings_by_resource_type = { - azurerm_resource_group = { - dns = { - name = local.private_dns_zones_resource_group_name - } - } - } - } - } - configure_management_resources = { - location = var.location - advanced = { - asc_export_resource_group_name = local.management_asc_export_resource_group_name - custom_settings_by_resource_type = { - azurerm_resource_group = { - management = { - name = local.management_resource_group_name - } - } - } - azurerm_log_analytics_workspace = { - management = { - name = local.management_log_analytics_workspace_name - } - } - azurerm_automation_account = { - management = { - name = local.management_automation_account_name - } - } - } - } - } -} \ No newline at end of file + management_settings_es_json = tostring(jsonencode(var.management_settings_es)) + management_settings_es_json_templated = templatestring(local.management_settings_es_json, local.config_template_file_variables) + management_settings_es_json_final = replace(replace(local.management_settings_es_json_templated, "\"[", "["), "]\"", "]") + management_settings_es = jsondecode(local.management_settings_es_json_final) +} + +locals { + management_settings_avm_json = tostring(jsonencode(var.management_settings_avm)) + management_settings_avm_json_templated = templatestring(local.management_settings_avm_json, local.config_template_file_variables) + management_settings_avm_json_final = replace(replace(local.management_settings_avm_json_templated, "\"[", "["), "]\"", "]") + management_settings_avm = jsondecode(local.management_settings_avm_json_final) +} diff --git a/templates/complete_multi_region/locals-private-dns.tf b/templates/complete_multi_region/locals-private-dns.tf deleted file mode 100644 index 715559f7..00000000 --- a/templates/complete_multi_region/locals-private-dns.tf +++ /dev/null @@ -1,20 +0,0 @@ -locals { - private_dns_zones_locations_hub_and_spoke_vnet = local.connectivity_hub_and_spoke_vnet_enabled ? { - for key, value in var.hub_and_spoke_vnet_virtual_networks : key => { - location = value.location - is_primary = value.location == var.location - } - } : {} - private_dns_zones_locations_virtual_wan = local.connectivity_virtual_wan_enabled ? {} : {} - private_dns_zone_locations = merge(local.private_dns_zones_locations_hub_and_spoke_vnet, local.private_dns_zones_locations_virtual_wan) -} - -locals { - private_dns_zones_virtual_networks_hub_and_spoke_vnet = local.connectivity_hub_and_spoke_vnet_enabled ? { - for key, value in local.hub_and_spoke_vnet_virtual_networks : key => { - vnet_resource_id = module.hub_and_spoke_vnet[0].virtual_networks[key].resource_id - } - } : {} - private_dns_zones_virtual_networks_virtual_wan = local.connectivity_virtual_wan_enabled ? {} : {} - private_dns_zones_virtual_networks = merge(local.private_dns_zones_virtual_networks_hub_and_spoke_vnet, local.private_dns_zones_virtual_networks_virtual_wan) -} diff --git a/templates/complete_multi_region/locals-resource-groups.tf b/templates/complete_multi_region/locals-resource-groups.tf index 2f9e62f6..ae99a43a 100644 --- a/templates/complete_multi_region/locals-resource-groups.tf +++ b/templates/complete_multi_region/locals-resource-groups.tf @@ -1,27 +1,31 @@ locals { - resource_groups_hub_and_spoke_vnet = { + resource_groups_hub_and_spoke_vnet = local.connectivity_hub_and_spoke_vnet_enabled ? merge({ for key, value in local.hub_and_spoke_vnet_virtual_networks : key => { name = value.resource_group_name location = value.location + }},{ + for key, value in local.virtual_wan_virtual_hubs : key => { + name = value.private_dns_zones.resource_group_name + location = value.location + } if can(value.private_dns_zones.resource_group_name) } - } + ) : {} - resource_groups_virtual_wan = merge({ core = { - name = local.virtual_wan_resource_group_name - location = var.location + resource_groups_virtual_wan = local.connectivity_virtual_wan_enabled ? merge({ core = { + name = local.virtual_wan_settings.resource_group_name + location = local.primary_location } }, { - for key, value in local.virtual_wan_virtual_hubs : key => { - name = value.resource_group_name - location = value.location - } if value.resource_group_name != local.virtual_wan_resource_group_name - }) - - resource_groups_private_dns_zones = !local.connectivity_none_enabled && var.private_dns_zones_enabled ? { - dns = { - name = local.private_dns_zones_resource_group_name - location = var.location + for key, value in local.virtual_wan_virtual_hubs : key => { + name = value.resource_group_name + location = value.location + } if value.resource_group_name != local.virtual_wan_settings.resource_group_name + } ,{ + for key, value in local.virtual_wan_virtual_hubs : key => { + name = value.private_dns_zones.resource_group_name + location = value.location + } if can(value.private_dns_zones.resource_group_name) } - } : {} + ) : {} - resource_groups = merge(local.resource_groups_hub_and_spoke_vnet, local.resource_groups_virtual_wan, local.resource_groups_private_dns_zones) + resource_groups = merge(local.resource_groups_hub_and_spoke_vnet, local.resource_groups_virtual_wan) } \ No newline at end of file diff --git a/templates/complete_multi_region/locals-resource-names.tf b/templates/complete_multi_region/locals-resource-names.tf index 9d64317f..d0d895ba 100644 --- a/templates/complete_multi_region/locals-resource-names.tf +++ b/templates/complete_multi_region/locals-resource-names.tf @@ -1,11 +1,4 @@ locals { - private_dns_zones_resource_group_name = templatestring(var.private_dns_zones_resource_group_name, { location = var.location }) - ddos_protection_plan_resource_group_name = templatestring(var.ddos_protection_plan_resource_group_name, { location = var.location }) - ddos_protection_plan_name = templatestring(var.ddos_protection_plan_name, { location = var.location }) - virtual_wan_resource_group_name = templatestring(var.virtual_wan_resource_group_name, { location = var.location }) - virtual_wan_name = templatestring(var.virtual_wan_name, { location = var.location }) - management_resource_group_name = templatestring(var.management_resource_group_name, { location = var.location }) - management_log_analytics_workspace_name = templatestring(var.management_log_analytics_workspace_name, { location = var.location }) - management_automation_account_name = templatestring(var.management_automation_account_name, { location = var.location }) - management_asc_export_resource_group_name = templatestring(var.management_asc_export_resource_group_name, { location = var.location }) + ddos_protection_plan_resource_group_name = templatestring(var.ddos_protection_plan_resource_group_name, { location = local.primary_location }) + ddos_protection_plan_name = templatestring(var.ddos_protection_plan_name, { location = local.primary_location }) } \ No newline at end of file diff --git a/templates/complete_multi_region/locals-virtual-wan.tf b/templates/complete_multi_region/locals-virtual-wan.tf index a1c5c9fd..1a2ca93c 100644 --- a/templates/complete_multi_region/locals-virtual-wan.tf +++ b/templates/complete_multi_region/locals-virtual-wan.tf @@ -1,35 +1,11 @@ locals { - virtual_wan_virtual_hubs = { for key, value in var.virtual_wan_virtual_hubs : key => { - name = templatestring(value.name, { location = value.location }) - location = value.location - resource_group_name = try(templatestring(value.resource_group_name, { location = value.location }), local.virtual_wan_resource_group_name) - virtual_network_connections = value.virtual_network_connections - firewall = try({ - name = templatestring(value.firewall.name, { location = value.location }) - sku_name = try(value.firewall.sku_name, "AZFW_Hub") - sku_tier = try(value.firewall.sku_tier, "Standard") - zones = try(value.firewall.zones, local.regions[value.location].zones) - firewall_policy = { - name = templatestring(value.firewall.firewall_policy.name, { location = value.location }) - settings = value.firewall.firewall_policy.settings - } - settings = value.settings - }, null) - address_prefix = value.address_prefix - tags = try(value.tags, null) - hub_routing_preference = try(value.hub_routing_preference, null) - private_dns_zone_networking = try({ - virtual_network = { - name = templatestring(value.private_dns_zone_networking.virtual_network.name, { location = value.location }) - address_space = value.private_dns_zone_networking.virtual_network.address_space - private_dns_resolver_subnet = { - name = templatestring(value.private_dns_zone_networking.virtual_network.private_dns_resolver_subnet.name, { location = value.location }) - address_prefix = value.private_dns_zone_networking.virtual_network.private_dns_resolver_subnet.address_prefix - } - } - private_dns_resolver = { - name = templatestring(value.private_dns_zone_networking.private_dns_resolver.name, { location = value.location }) - } - }, null) - } } + virtual_wan_settings_json = tostring(jsonencode(var.virtual_wan_settings)) + virtual_wan_settings_json_templated = templatestring(local.virtual_wan_settings_json, local.config_template_file_variables) + virtual_wan_settings_json_final = replace(replace(local.virtual_wan_settings_json_templated, "\"[", "["), "]\"", "]") + virtual_wan_settings = jsondecode(local.virtual_wan_settings_json_final) + + virtual_wan_virtual_hubs_json = tostring(jsonencode(var.virtual_wan_virtual_hubs)) + virtual_wan_virtual_hubs_json_templated = templatestring(local.virtual_wan_virtual_hubs_json_templated, local.config_template_file_variables) + virtual_wan_virtual_hubs_json_final = replace(replace(local.virtual_wan_virtual_hubs_json_templated, "\"[", "["), "]\"", "]") + virtual_wan_virtual_hubs = jsondecode(local.virtual_wan_virtual_hubs_json_final) } diff --git a/templates/complete_multi_region/management.tf b/templates/complete_multi_region/management.tf index fefc4bfd..2a77d447 100644 --- a/templates/complete_multi_region/management.tf +++ b/templates/complete_multi_region/management.tf @@ -1,50 +1,14 @@ module "management_groups" { - source = "Azure/caf-enterprise-scale/azurerm" - version = "6.1.0" + source = "./modules/management" - disable_telemetry = !var.enable_telemetry - default_location = var.location - root_parent_id = try(local.management_settings.root_parent_id, data.azurerm_client_config.current.tenant_id) - archetype_config_overrides = try(local.management_settings.archetype_config_overrides, {}) - configure_connectivity_resources = try(local.management_settings.configure_connectivity_resources, {}) - configure_identity_resources = try(local.management_settings.configure_identity_resources, {}) - configure_management_resources = try(local.management_settings.configure_management_resources, {}) - create_duration_delay = try(local.management_settings.create_duration_delay, {}) - custom_landing_zones = try(local.management_settings.custom_landing_zones, {}) - custom_policy_roles = try(local.management_settings.custom_policy_roles, {}) - default_tags = try(local.management_settings.default_tags, {}) - deploy_connectivity_resources = false - deploy_core_landing_zones = try(local.management_settings.deploy_core_landing_zones, true) - deploy_corp_landing_zones = try(local.management_settings.deploy_corp_landing_zones, false) - deploy_demo_landing_zones = try(local.management_settings.deploy_demo_landing_zones, false) - deploy_diagnostics_for_mg = try(local.management_settings.deploy_diagnostics_for_mg, false) - deploy_identity_resources = try(local.management_settings.deploy_identity_resources, false) - deploy_management_resources = try(local.management_settings.deploy_management_resources, false) - deploy_online_landing_zones = try(local.management_settings.deploy_online_landing_zones, false) - deploy_sap_landing_zones = try(local.management_settings.deploy_sap_landing_zones, false) - destroy_duration_delay = try(local.management_settings.destroy_duration_delay, {}) - disable_base_module_tags = try(local.management_settings.disable_base_module_tags, false) - library_path = try(local.management_settings.library_path, "") - policy_non_compliance_message_default = try(local.management_settings.policy_non_compliance_message_default, "This resource {enforcementMode} be compliant with the assigned policy.") - policy_non_compliance_message_default_enabled = try(local.management_settings.policy_non_compliance_message_default_enabled, true) - policy_non_compliance_message_enabled = try(local.management_settings.policy_non_compliance_message_enabled, true) - policy_non_compliance_message_enforced_replacement = try(local.management_settings.policy_non_compliance_message_enforced_replacement, "must") - policy_non_compliance_message_enforcement_placeholder = try(local.management_settings.policy_non_compliance_message_enforcement_placeholder, "{enforcementMode}") - policy_non_compliance_message_not_enforced_replacement = try(local.management_settings.policy_non_compliance_message_not_enforced_replacement, "should") - policy_non_compliance_message_not_supported_definitions = try(local.management_settings.policy_non_compliance_message_not_supported_definitions, ["/providers/Microsoft.Authorization/policyDefinitions/1c6e92c9-99f0-4e55-9cf2-0c234dc48f99", "/providers/Microsoft.Authorization/policyDefinitions/1a5b4dca-0b6f-4cf5-907c-56316bc1bf3d", "/providers/Microsoft.Authorization/policyDefinitions/95edb821-ddaf-4404-9732-666045e056b4"]) - resource_custom_timeouts = try(local.management_settings.resource_custom_timeouts, {}) - root_id = try(local.management_settings.root_id, "alz") - root_name = try(local.management_settings.root_name, "Azure-Landing-Zones") - strict_subscription_association = try(local.management_settings.strict_subscription_association, true) - subscription_id_connectivity = var.subscription_id_connectivity - subscription_id_identity = var.subscription_id_identity - subscription_id_management = var.subscription_id_management - subscription_id_overrides = try(local.management_settings.subscription_id_overrides, {}) - template_file_variables = try(local.management_settings.template_file_variables, {}) + count = var.management_use_avm ? 0 : 1 + + enable_telemetry = var.enable_telemetry + settings = local.management_settings_es providers = { azurerm = azurerm azurerm.connectivity = azurerm.connectivity azurerm.management = azurerm.management } -} \ No newline at end of file +} diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf index 100936da..3335bfa6 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf @@ -1,6 +1,8 @@ locals { hub_virtual_networks = { - for key, value in var.hub_virtual_networks : key => value.hub_virtual_network + for key, value in var.hub_virtual_networks : key => merge(value.hub_virtual_network, { + ddos_protection_plan_id = local.ddos_protection_plan_enabled ? module.ddos_protection_plan[0].resource.id : null + }) } virtual_network_gateways_express_route = { for hub_network_key, hub_network_value in var.hub_virtual_networks : "${hub_network_key}-express-route" => { @@ -15,4 +17,39 @@ locals { } if can(hub_network_value.virtual_network_gateways.vpn) } virtual_network_gateways = merge(local.virtual_network_gateways_express_route, local.virtual_network_gateways_vpn) -} \ No newline at end of file +} + +locals { + private_dns_zones = { for key, value in var.hub_virtual_networks : key => value if can(value.private_dns_zones) } + + private_dns_zones_virtual_network_links = { + for key, value in module.hub_and_spoke_vnet.virtual_networks : key => { + vnet_resource_id = value.id + } + } + private_dns_zones_secondary_zones = { + azure_data_explorer = { + zone_name = "privatelink.{regionName}.kusto.windows.net" + } + azure_batch_account = { + zone_name = "{regionName}.privatelink.batch.azure.com" + } + azure_batch_node_mgmt = { + zone_name = "{regionName}.service.privatelink.batch.azure.com" + } + azure_aks_mgmt = { + zone_name = "privatelink.{regionName}.azmk8s.io" + } + azure_acr_data = { + zone_name = "{regionName}.data.privatelink.azurecr.io" + } + azure_backup = { + zone_name = "privatelink.{regionCode}.backup.windowsazure.com" + } + } +} + +locals { + ddos_protection_plan = can(var.hub_and_spoke_networks_settings.ddos_protection_plan) ? var.hub_and_spoke_networks_settings.ddos_protection_plan : null + ddos_protection_plan_enabled = local.ddos_protection_plan != null +} diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf index f86a056d..c5507132 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf @@ -18,27 +18,53 @@ module "virtual_network_gateway" { type = each.value.virtual_network_gateway.type virtual_network_id = module.hub_and_spoke_vnet.virtual_networks[each.value.hub_network_key].id default_tags = var.tags - subnet_creation_enabled = try(each.value.virtual_network_gateway.settings.subnet_creation_enabled, null) - edge_zone = try(each.value.virtual_network_gateway.settings.edge_zone, null) - express_route_circuits = try(each.value.virtual_network_gateway.settings.express_route_circuits, null) - ip_configurations = try(each.value.virtual_network_gateway.settings.ip_configurations, null) - local_network_gateways = try(each.value.virtual_network_gateway.settings.local_network_gateways, null) + subnet_creation_enabled = try(each.value.virtual_network_gateway.subnet_creation_enabled, null) + edge_zone = try(each.value.virtual_network_gateway.edge_zone, null) + express_route_circuits = try(each.value.virtual_network_gateway.express_route_circuits, null) + ip_configurations = try(each.value.virtual_network_gateway.ip_configurations, null) + local_network_gateways = try(each.value.virtual_network_gateway.local_network_gateways, null) subnet_address_prefix = each.value.virtual_network_gateway.subnet_address_prefix - tags = try(each.value.virtual_network_gateway.settings.tags, null) - vpn_active_active_enabled = try(each.value.virtual_network_gateway.settings.vpn_active_active_enabled, null) - vpn_bgp_enabled = try(each.value.virtual_network_gateway.settings.vpn_bgp_enabled, null) - vpn_bgp_settings = try(each.value.virtual_network_gateway.settings.vpn_bgp_settings, null) - vpn_generation = try(each.value.virtual_network_gateway.settings.vpn_generation, null) - vpn_point_to_site = try(each.value.virtual_network_gateway.settings.vpn_point_to_site, null) - vpn_type = try(each.value.virtual_network_gateway.settings.vpn_type, null) - vpn_private_ip_address_enabled = try(each.value.virtual_network_gateway.settings.vpn_private_ip_address_enabled, null) - route_table_bgp_route_propagation_enabled = try(each.value.virtual_network_gateway.settings.route_table_bgp_route_propagation_enabled, null) + tags = try(each.value.virtual_network_gateway.tags, null) + vpn_active_active_enabled = try(each.value.virtual_network_gateway.vpn_active_active_enabled, null) + vpn_bgp_enabled = try(each.value.virtual_network_gateway.vpn_bgp_enabled, null) + vpn_bgp_settings = try(each.value.virtual_network_gateway.vpn_bgp_settings, null) + vpn_generation = try(each.value.virtual_network_gateway.vpn_generation, null) + vpn_point_to_site = try(each.value.virtual_network_gateway.vpn_point_to_site, null) + vpn_type = try(each.value.virtual_network_gateway.vpn_type, null) + vpn_private_ip_address_enabled = try(each.value.virtual_network_gateway.vpn_private_ip_address_enabled, null) + route_table_bgp_route_propagation_enabled = try(each.value.virtual_network_gateway.route_table_bgp_route_propagation_enabled, null) route_table_creation_enabled = try(each.value.virtual_network_gateway.route_table_creation_enabled, null) - route_table_name = try(each.value.virtual_network_gateway.settings.route_table_name, null) - route_table_tags = try(each.value.virtual_network_gateway.settings.route_table_tags, null) + route_table_name = try(each.value.virtual_network_gateway.route_table_name, null) + route_table_tags = try(each.value.virtual_network_gateway.route_table_tags, null) enable_telemetry = var.enable_telemetry depends_on = [ module.hub_and_spoke_vnet ] } + +module "private_dns_zones" { + source = "Azure/avm-ptn-network-private-link-private-dns-zones/azurerm" + version = "0.4.0" + + for_each = local.private_dns_zones + + location = each.value.location + resource_group_name = each.value.private_dns_zones.resource_group_name + resource_group_creation_enabled = false + virtual_network_resource_ids_to_link_to = local.private_dns_zones_virtual_network_links + private_link_private_dns_zones = try(each.value.private_dns_zones.is_primary, false) ? null : local.private_dns_zones_secondary_zones + enable_telemetry = var.enable_telemetry + tags = var.tags +} + +module "ddos_protection_plan" { + source = "Azure/avm-res-network-ddosprotectionplan/azurerm" + version = "0.2.0" + + count = local.ddos_protection_plan_enabled ? 1 : 0 + + name = local.ddos_protection_plan.name + resource_group_name = local.ddos_protection_plan.resource_group_name + location = local.ddos_protection_plan.location +} diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf index 3b015c7e..4f375e4a 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf @@ -1,3 +1,7 @@ +variable "hub_and_spoke_networks_settings" { + type = any +} + variable "hub_virtual_networks" { type = map(object({ hub_virtual_network = any @@ -5,6 +9,11 @@ variable "hub_virtual_networks" { express_route = optional(any) vpn = optional(any) })) + private_dns_zones = object({ + resource_group_name = string + is_primary = optional(bool, false) + }) + ddos_protection_plan = any })) default = {} description = "A map of hub networks to create. Detailed information about the hub network can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-hubnetworking" diff --git a/templates/complete_multi_region/modules/management/main.tf b/templates/complete_multi_region/modules/management/main.tf new file mode 100644 index 00000000..6c7d9ff4 --- /dev/null +++ b/templates/complete_multi_region/modules/management/main.tf @@ -0,0 +1,50 @@ +module "management_groups" { + source = "Azure/caf-enterprise-scale/azurerm" + version = "6.1.0" + + disable_telemetry = !var.enable_telemetry + default_location = var.settings.default_location + root_parent_id = try(var.settings.root_parent_id, data.azurerm_client_config.current.tenant_id) + archetype_config_overrides = try(var.settings.archetype_config_overrides, {}) + configure_connectivity_resources = try(var.settings.configure_connectivity_resources, {}) + configure_identity_resources = try(var.settings.configure_identity_resources, {}) + configure_management_resources = try(var.settings.configure_management_resources, {}) + create_duration_delay = try(var.settings.create_duration_delay, {}) + custom_landing_zones = try(var.settings.custom_landing_zones, {}) + custom_policy_roles = try(var.settings.custom_policy_roles, {}) + default_tags = try(var.settings.default_tags, {}) + deploy_connectivity_resources = try(var.settings.deploy_connectivity_resources, false) + deploy_core_landing_zones = try(var.settings.deploy_core_landing_zones, true) + deploy_corp_landing_zones = try(var.settings.deploy_corp_landing_zones, false) + deploy_demo_landing_zones = try(var.settings.deploy_demo_landing_zones, false) + deploy_diagnostics_for_mg = try(var.settings.deploy_diagnostics_for_mg, false) + deploy_identity_resources = try(var.settings.deploy_identity_resources, false) + deploy_management_resources = try(var.settings.deploy_management_resources, false) + deploy_online_landing_zones = try(var.settings.deploy_online_landing_zones, false) + deploy_sap_landing_zones = try(var.settings.deploy_sap_landing_zones, false) + destroy_duration_delay = try(var.settings.destroy_duration_delay, {}) + disable_base_module_tags = try(var.settings.disable_base_module_tags, false) + library_path = try(var.settings.library_path, "") + policy_non_compliance_message_default = try(var.settings.policy_non_compliance_message_default, "This resource {enforcementMode} be compliant with the assigned policy.") + policy_non_compliance_message_default_enabled = try(var.settings.policy_non_compliance_message_default_enabled, true) + policy_non_compliance_message_enabled = try(var.settings.policy_non_compliance_message_enabled, true) + policy_non_compliance_message_enforced_replacement = try(var.settings.policy_non_compliance_message_enforced_replacement, "must") + policy_non_compliance_message_enforcement_placeholder = try(var.settings.policy_non_compliance_message_enforcement_placeholder, "{enforcementMode}") + policy_non_compliance_message_not_enforced_replacement = try(var.settings.policy_non_compliance_message_not_enforced_replacement, "should") + policy_non_compliance_message_not_supported_definitions = try(var.settings.policy_non_compliance_message_not_supported_definitions, ["/providers/Microsoft.Authorization/policyDefinitions/1c6e92c9-99f0-4e55-9cf2-0c234dc48f99", "/providers/Microsoft.Authorization/policyDefinitions/1a5b4dca-0b6f-4cf5-907c-56316bc1bf3d", "/providers/Microsoft.Authorization/policyDefinitions/95edb821-ddaf-4404-9732-666045e056b4"]) + resource_custom_timeouts = try(var.settings.resource_custom_timeouts, {}) + root_id = try(var.settings.root_id, "alz") + root_name = try(var.settings.root_name, "Azure-Landing-Zones") + strict_subscription_association = try(var.settings.strict_subscription_association, true) + subscription_id_connectivity = var.settings.subscription_id_connectivity + subscription_id_identity = var.settings.subscription_id_identity + subscription_id_management = var.settings.subscription_id_management + subscription_id_overrides = try(var.settings.subscription_id_overrides, {}) + template_file_variables = try(var.settings.template_file_variables, {}) + + providers = { + azurerm = azurerm + azurerm.connectivity = azurerm.connectivity + azurerm.management = azurerm.management + } +} \ No newline at end of file diff --git a/templates/complete_multi_region/modules/management/variables.tf b/templates/complete_multi_region/modules/management/variables.tf new file mode 100644 index 00000000..cd630d30 --- /dev/null +++ b/templates/complete_multi_region/modules/management/variables.tf @@ -0,0 +1,8 @@ +variable "settings" { + type = any +} + +variable "enable_telemetry" { + type = bool + default = true +} \ No newline at end of file diff --git a/templates/complete_multi_region/modules/private-dns/locals.tf b/templates/complete_multi_region/modules/private-dns/locals.tf deleted file mode 100644 index ed1afee1..00000000 --- a/templates/complete_multi_region/modules/private-dns/locals.tf +++ /dev/null @@ -1,22 +0,0 @@ -locals { - private_dns_secondary_zones = { - azure_data_explorer = { - zone_name = "privatelink.{regionName}.kusto.windows.net" - } - azure_batch_account = { - zone_name = "{regionName}.privatelink.batch.azure.com" - } - azure_batch_node_mgmt = { - zone_name = "{regionName}.service.privatelink.batch.azure.com" - } - azure_aks_mgmt = { - zone_name = "privatelink.{regionName}.azmk8s.io" - } - azure_acr_data = { - zone_name = "{regionName}.data.privatelink.azurecr.io" - } - azure_backup = { - zone_name = "privatelink.{regionCode}.backup.windowsazure.com" - } - } -} diff --git a/templates/complete_multi_region/modules/private-dns/main.tf b/templates/complete_multi_region/modules/private-dns/main.tf deleted file mode 100644 index 5cd519f4..00000000 --- a/templates/complete_multi_region/modules/private-dns/main.tf +++ /dev/null @@ -1,14 +0,0 @@ -module "private_dns_zones" { - source = "Azure/avm-ptn-network-private-link-private-dns-zones/azurerm" - version = "0.4.0" - - for_each = var.locations - - location = each.value.location - resource_group_name = var.resource_group_name - resource_group_creation_enabled = false - virtual_network_resource_ids_to_link_to = var.connected_virtual_networks - private_link_private_dns_zones = each.value.is_primary ? null : local.private_dns_secondary_zones - enable_telemetry = var.enable_telemetry - tags = var.tags -} diff --git a/templates/complete_multi_region/modules/private-dns/outputs.tf b/templates/complete_multi_region/modules/private-dns/outputs.tf deleted file mode 100644 index e69de29b..00000000 diff --git a/templates/complete_multi_region/modules/private-dns/terraform.tf b/templates/complete_multi_region/modules/private-dns/terraform.tf deleted file mode 100644 index 28d0feae..00000000 --- a/templates/complete_multi_region/modules/private-dns/terraform.tf +++ /dev/null @@ -1,14 +0,0 @@ -terraform { - required_version = "~> 1.8" - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "~> 3.107" - } - azapi = { - source = "Azure/azapi" - version = "~> 1.13" - } - } - # backend "azurerm" {} -} diff --git a/templates/complete_multi_region/modules/private-dns/variables.tf b/templates/complete_multi_region/modules/private-dns/variables.tf deleted file mode 100644 index cfea1d88..00000000 --- a/templates/complete_multi_region/modules/private-dns/variables.tf +++ /dev/null @@ -1,34 +0,0 @@ -variable "resource_group_name" { - type = string - nullable = false - description = "The name of the resource group for private DNS zones" -} - -variable "locations" { - type = map(object({ - location = string - is_primary = optional(bool, false) - })) - nullable = false - description = "A map of locations to create private DNS zones" -} - -variable "connected_virtual_networks" { - type = map(object({ - vnet_resource_id = string - })) - nullable = false - description = "A map of virtual networks to attach the private DNS zones to" -} - -variable "enable_telemetry" { - type = bool - default = true - description = "Flag to enable/disable telemetry" -} - -variable "tags" { - type = map(string) - default = {} - description = "A map of tags to add to the private DNS zones" -} diff --git a/templates/complete_multi_region/modules/virtual-wan/locals.tf b/templates/complete_multi_region/modules/virtual-wan/locals.tf index 210b451f..aace5ff5 100644 --- a/templates/complete_multi_region/modules/virtual-wan/locals.tf +++ b/templates/complete_multi_region/modules/virtual-wan/locals.tf @@ -1,3 +1,7 @@ +locals { + virtual_hubs = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => virtual_hub_value.hub } +} + locals { virtual_network_connections_input = { for virtual_network_connection in flatten([for virtual_hub_key, virtual_hub_value in var.virtual_hubs : [for virtual_network_connection_key, virtual_network_connection_value in virtual_hub_value.virtual_network_connections : { @@ -14,40 +18,66 @@ locals { settings = virtual_network_connection.settings } } - virtual_network_connections_private_dns = var.private_dns_zones_enabled ? { for key, value in var.virtual_hubs : "private_dns_vnet_${key}" => { + virtual_network_connections_private_dns = { for key, value in local.private_dns_zones : "private_dns_vnet_${key}" => { name = "private_dns_vnet_${key}" virtual_hub_key = key remote_virtual_network_id = module.virtual_network_private_dns[key].resource_id - } } : {} + }} virtual_network_connections = merge(local.virtual_network_connections_input, local.virtual_network_connections_private_dns) } locals { - firewall_policies = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => { - virtual_hub_key = virtual_hub_value.firewall.virtual_hub_key - name = virtual_hub_value.firewall.firewall_policy.name - location = virtual_hub_value.location - resource_group_name = virtual_hub_value.resource_group == null ? var.resource_group_name : virtual_hub_value.resource_group - settings = virtual_hub_value.firewall.firewall_policysettings - } if can(virtual_hub_value.firewall.firewall_policy) + firewall_policies = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => merge({ + location = virtual_hub_value.location + resource_group_name = virtual_hub_value.resource_group_name + firewall_policy_dns = { + servers = [module.dns_resolver[each.value.virtual_hub_key].inbound_endpoint_ips["dns"]] + proxy_enabled = true + } + }, virtual_hub_value) if can(virtual_hub_value.firewall_policy) } + + firewalls = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => merge( + { + virtual_hub_key = virtual_hub_key + location = virtual_hub_value.location + firewall_policy_id = module.firewall_policy[virtual_hub_key].resource_id + }, virtual_hub_value.firewall) + if can(virtual_hub_value.firewall) } +} - firewalls = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => { - virtual_hub_key = virtual_hub_value.firewall.virtual_hub_key - name = virtual_hub_value.firewall.name - sku_name = virtual_hub_value.firewall.sku_name - sku_tier = virtual_hub_value.firewall.sku_tier - dns_servers = try(virtual_hub_value.firewall.settings.dns_servers, null) - private_ip_ranges = try(virtual_hub_value.firewall.settings.private_ip_ranges, null) - threat_intel_mode = try(virtual_hub_value.firewall.settings.threat_intel_mode, null) - zones = virtual_hub_value.firewall.zones - vhub_public_ip_count = try(virtual_hub_value.firewall.settings.vhub_public_ip_count, null) - tags = try(virtual_hub_value.firewall.settings.tags, null) - default_ip_configuration = try(virtual_hub_value.firewall.default_ip_configuration, null) - management_ip_configuration = try(virtual_hub_value.firewall.management_ip_configuration, null) - ip_configuration = try(virtual_hub_value.firewall.ip_configuration, null) - firewall_policy_id = module.firewall_policy[virtual_hub_key].resource_id - } if can(virtual_hub_value.firewall) +locals { + private_dns_zones = { for key, value in var.virtual_hubs : key => value if can(value.private_dns_zones) } + + private_dns_zones_virtual_network_links = { + for key, value in module.virtual_network_private_dns : key => { + vnet_resource_id = value.resource_id + } } + private_dns_zones_secondary_zones = { + azure_data_explorer = { + zone_name = "privatelink.{regionName}.kusto.windows.net" + } + azure_batch_account = { + zone_name = "{regionName}.privatelink.batch.azure.com" + } + azure_batch_node_mgmt = { + zone_name = "{regionName}.service.privatelink.batch.azure.com" + } + azure_aks_mgmt = { + zone_name = "privatelink.{regionName}.azmk8s.io" + } + azure_acr_data = { + zone_name = "{regionName}.data.privatelink.azurecr.io" + } + azure_backup = { + zone_name = "privatelink.{regionCode}.backup.windowsazure.com" + } + } +} + +locals { + ddos_protection_plan = can(var.virtual_wan_settings.ddos_protection_plan) ? var.virtual_wan_settings.ddos_protection_plan : null + ddos_protection_plan_enabled = local.ddos_protection_plan != null } diff --git a/templates/complete_multi_region/modules/virtual-wan/main.tf b/templates/complete_multi_region/modules/virtual-wan/main.tf index ab43cd93..8100fa8a 100644 --- a/templates/complete_multi_region/modules/virtual-wan/main.tf +++ b/templates/complete_multi_region/modules/virtual-wan/main.tf @@ -7,17 +7,14 @@ module "firewall_policy" { name = each.value.name location = each.value.location resource_group_name = each.value.resource_group_name - firewall_policy_sku = try(each.value.settings.sku, "Standard") - firewall_policy_auto_learn_private_ranges_enabled = try(each.value.settings.auto_learn_private_ranges_enabled, null) - firewall_policy_base_policy_id = try(each.value.settings.base_policy_id, null) - firewall_policy_dns = try(each.value.settings.dns, { - servers = [module.dns_resolver[each.value.virtual_hub_key].inbound_endpoint_ips["dns"]] - proxy_enabled = true - }) - firewall_policy_threat_intelligence_mode = try(each.value.settings.threat_intelligence_mode, "Alert") - firewall_policy_private_ip_ranges = try(each.value.settings.private_ip_ranges, null) - firewall_policy_threat_intelligence_allowlist = try(each.value.settings.threat_intelligence_allowlist, null) - tags = try(each.value.settings.tags, null) + firewall_policy_sku = try(each.value.sku, "Standard") + firewall_policy_auto_learn_private_ranges_enabled = try(each.value.auto_learn_private_ranges_enabled, null) + firewall_policy_base_policy_id = try(each.value.base_policy_id, null) + firewall_policy_dns = each.value.settings.dns + firewall_policy_threat_intelligence_mode = try(each.value.threat_intelligence_mode, "Alert") + firewall_policy_private_ip_ranges = try(each.value.private_ip_ranges, null) + firewall_policy_threat_intelligence_allowlist = try(each.value.threat_intelligence_allowlist, null) + tags = try(each.value.tags, null) enable_telemetry = var.enable_telemetry } @@ -25,28 +22,28 @@ module "virtual_wan" { source = "Azure/avm-ptn-virtualwan/azurerm" version = "0.5.0" - allow_branch_to_branch_traffic = try(var.settings.allow_branch_to_branch_traffic, null) - disable_vpn_encryption = try(var.settings.disable_vpn_encryption, false) - er_circuit_connections = try(var.settings.er_circuit_connections, {}) - expressroute_gateways = try(var.settings.expressroute_gateways, {}) + allow_branch_to_branch_traffic = try(var.virtual_wan_settings.allow_branch_to_branch_traffic, null) + disable_vpn_encryption = try(var.virtual_wan_settings.disable_vpn_encryption, false) + er_circuit_connections = try(var.virtual_wan_settings.er_circuit_connections, {}) + expressroute_gateways = try(var.virtual_wan_settings.expressroute_gateways, {}) firewalls = local.firewalls - office365_local_breakout_category = try(var.settings.office365_local_breakout_category, null) - location = var.location - p2s_gateway_vpn_server_configurations = try(var.settings.p2s_gateway_vpn_server_configurations, {}) - p2s_gateways = try(var.settings.p2s_gateways, {}) - resource_group_name = var.resource_group_name + office365_local_breakout_category = try(var.virtual_wan_settings.office365_local_breakout_category, null) + location = var.virtual_wan_settings.location + p2s_gateway_vpn_server_configurations = try(var.virtual_wan_settings.p2s_gateway_vpn_server_configurations, {}) + p2s_gateways = try(var.virtual_wan_settings.p2s_gateways, {}) + resource_group_name = var.virtual_wan_settings.resource_group_name create_resource_group = false - virtual_hubs = var.virtual_hubs + virtual_hubs = local.virtual_hubs virtual_network_connections = local.virtual_network_connections - virtual_wan_name = var.name - type = try(var.settings.type, null) - routing_intents = try(var.settings.routing_intents, null) - resource_group_tags = try(var.settings.resource_group_tags, null) - virtual_wan_tags = try(var.settings.virtual_wan_tags, null) - vpn_gateways = try(var.settings.vpn_gateways, {}) - vpn_site_connections = try(var.settings.vpn_site_connections, {}) - vpn_sites = try(var.settings.vpn_sites, null) - tags = try(var.settings.tags, null) + virtual_wan_name = var.virtual_wan_settings.name + type = try(var.virtual_wan_settings.type, null) + routing_intents = try(var.virtual_wan_settings.routing_intents, null) + resource_group_tags = try(var.virtual_wan_settings.resource_group_tags, null) + virtual_wan_tags = try(var.virtual_wan_settings.virtual_wan_tags, null) + vpn_gateways = try(var.virtual_wan_settings.vpn_gateways, {}) + vpn_site_connections = try(var.virtual_wan_settings.vpn_site_connections, {}) + vpn_sites = try(var.virtual_wan_settings.vpn_sites, null) + tags = try(var.virtual_wan_settings.tags, null) enable_telemetry = var.enable_telemetry } @@ -54,17 +51,21 @@ module "virtual_network_private_dns" { source = "Azure/avm-res-network-virtualnetwork/azurerm" version = "0.4.0" - for_each = var.private_dns_zones_enabled ? var.virtual_hubs : {} + for_each = local.private_dns_zones - address_space = each.value.private_dns_zones_networking.virtual_network.address_space + address_space = each.value.private_dns_zones.networking.virtual_network.address_space location = each.value.location - name = each.value.private_dns_zones_networking.virtual_network.name + name = each.value.private_dns_zones.networking.virtual_network.name resource_group_name = each.value.resource_group_name enable_telemetry = var.enable_telemetry + ddos_protection_plan = local.ddos_protection_plan_enabled ? { + id = module.ddos_protection_plan[0].resource.id + enable = true + } : null subnets = { dns = { - address_prefix = each.value.private_dns_zones_networking.virtual_network.private_dns_resolver_subnet.address_prefix - name = each.value.private_dns_zones_networking.virtual_network.private_dns_resolver_subnet.name + address_prefix = each.value.private_dns_zones.networking.virtual_network.private_dns_resolver_subnet.address_prefix + name = each.value.private_dns_zones.networking.virtual_network.private_dns_resolver_subnet.name delegation = [{ name = "Microsoft.Network.dnsResolvers" service_delegation = { @@ -80,10 +81,10 @@ module "dns_resolver" { source = "Azure/avm-res-network-dnsresolver/azurerm" version = "0.2.1" - for_each = var.private_dns_zones_enabled ? var.virtual_hubs : {} + for_each = local.private_dns_zones location = each.value.location - name = each.value.private_dns_zones_networking.private_dns_resolver.name + name = each.value.private_dns_zones.networking.private_dns_resolver.name resource_group_name = each.value.resource_group_name virtual_network_resource_id = module.virtual_network_private_dns[each.key].resource_id enable_telemetry = var.enable_telemetry @@ -94,3 +95,29 @@ module "dns_resolver" { } } } + +module "private_dns_zones" { + source = "Azure/avm-ptn-network-private-link-private-dns-zones/azurerm" + version = "0.4.0" + + for_each = local.private_dns_zones + + location = each.value.location + resource_group_name = each.value.private_dns_zones.resource_group_name + resource_group_creation_enabled = false + virtual_network_resource_ids_to_link_to = local.private_dns_zones_virtual_network_links + private_link_private_dns_zones = try(each.value.private_dns_zones.is_primary, false) ? null : local.private_dns_zones_secondary_zones + enable_telemetry = var.enable_telemetry + tags = var.tags +} + +module "ddos_protection_plan" { + source = "Azure/avm-res-network-ddosprotectionplan/azurerm" + version = "0.2.0" + + count = local.ddos_protection_plan_enabled ? 1 : 0 + + name = local.ddos_protection_plan.name + resource_group_name = local.ddos_protection_plan.resource_group_name + location = local.ddos_protection_plan.location +} diff --git a/templates/complete_multi_region/modules/virtual-wan/variables.tf b/templates/complete_multi_region/modules/virtual-wan/variables.tf index b743e23d..1de7d362 100644 --- a/templates/complete_multi_region/modules/virtual-wan/variables.tf +++ b/templates/complete_multi_region/modules/virtual-wan/variables.tf @@ -1,67 +1,33 @@ -variable "name" { - type = string - description = "The name of the virtual WAN" - nullable = false -} - -variable "resource_group_name" { - type = string - description = "The name of the resource group for the virtual WAN" - nullable = false -} - -variable "location" { - type = string - description = "A map of locations to create the virtual WAN" - nullable = false -} - -variable "private_dns_zones_enabled" { - type = bool - description = "Flag to enable/disable private DNS zones" - default = true -} - -variable "settings" { - type = any - description = "The settings for the virtual WAN" - default = null +variable "virtual_wan_settings" { + type = any } variable "virtual_hubs" { type = map(object({ - name = string - location = string - resource_group_name = string - virtual_network_connections = optional(map(any)) - firewall = optional(object({ - name = string - sku_name = string - sku_tier = string - zones = optional(list(string)) - firewall_policy = object({ - name = string - settings = optional(any) - }) - settings = optional(any) - })) - address_prefix = string - tags = optional(map(string)) - hub_routing_preference = optional(string) - private_dns_zone_networking = optional(object({ - virtual_network = object({ - name = string - address_space = string - private_dns_resolver_subnet = object({ - name = string - address_prefix = string + hub = any + firewall = optional(any) + firewall_policy = optional(any) + private_dns_zones = optional(object({ + resource_group_name = string + is_primary = optional(bool, false) + networking = object({ + virtual_network = object({ + name = string + address_space = string + private_dns_resolver_subnet = object({ + name = string + address_prefix = string + }) + }) + private_dns_resolver = object({ + name = string }) - }) - private_dns_resolver = object({ - name = string }) })) + ddos_protection_plan = any })) + + default = {} description = "A map of virtual hubs to create. Detailed information about the virtual hub can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-virtualhub" } @@ -70,4 +36,10 @@ variable "enable_telemetry" { type = bool default = true description = "Flag to enable/disable telemetry" -} \ No newline at end of file +} + +variable "tags" { + default = {} + type = map(string) + description = "A map of tags to add to the private DNS zones" +} diff --git a/templates/complete_multi_region/networking-private-dns.tf b/templates/complete_multi_region/networking-private-dns.tf deleted file mode 100644 index 32cbfc9e..00000000 --- a/templates/complete_multi_region/networking-private-dns.tf +++ /dev/null @@ -1,19 +0,0 @@ -module "private_dns_zones" { - source = "./modules/private-dns" - - count = var.private_dns_zones_enabled ? 1 : 0 - - locations = local.private_dns_zone_locations - resource_group_name = local.private_dns_zones_resource_group_name - connected_virtual_networks = local.private_dns_zones_virtual_networks - enable_telemetry = var.enable_telemetry - tags = var.private_dns_zones_tags - - depends_on = [ - module.resource_groups - ] - - providers = { - azurerm = azurerm.connectivity, - } -} diff --git a/templates/complete_multi_region/networking-virtual-wan.tf b/templates/complete_multi_region/networking-virtual-wan.tf index 6166990b..a22640bd 100644 --- a/templates/complete_multi_region/networking-virtual-wan.tf +++ b/templates/complete_multi_region/networking-virtual-wan.tf @@ -3,10 +3,9 @@ module "virtual_wan" { count = local.connectivity_virtual_wan_enabled ? 1 : 0 - name = local.virtual_wan_name - location = var.location - resource_group_name = local.virtual_wan_resource_group_name + virtual_wan_settings = local.virtual_wan_settings virtual_hubs = local.virtual_wan_virtual_hubs + enable_telemetry = var.enable_telemetry providers = { azurerm = azurerm.connectivity diff --git a/templates/complete_multi_region/variables-connectivity.tf b/templates/complete_multi_region/variables-connectivity.tf index 66ac2915..254babc5 100644 --- a/templates/complete_multi_region/variables-connectivity.tf +++ b/templates/complete_multi_region/variables-connectivity.tf @@ -8,35 +8,7 @@ variable "connectivity_type" { } } -variable "private_dns_zones_enabled" { - type = bool - description = "Flag to enable/disable private DNS zones" - default = true -} - -variable "private_dns_zones_resource_group_name" { - type = string - description = "The name of the resource group for private DNS zones" - default = "rg-private-dns-$${location}" -} -variable "private_dns_zones_resource_group_location" { - type = string - description = "The location of the resource group for private DNS zones" - default = null -} - -variable "private_dns_zones_tags" { - type = map(string) - description = "A map of tags to add to the private DNS zones" - default = {} -} - -variable "ddos_protection_plan_enabled" { - type = bool - description = "Flag to enable/disable DDoS protection plan" - default = true -} variable "ddos_protection_plan_resource_group_name" { type = string diff --git a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf index edefabca..952c10a0 100644 --- a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf @@ -1,3 +1,14 @@ +variable "hub_and_spoke_vnet_virtual_networks_settings" { + type = any + default = { + ddos_protection_plan = { + name = "ddos-$${starter_location_01}" + resource_group_name = "rg-ddos-$${starter_location_01}" + location = "$${starter_location_01}" + } + } +} + variable "hub_and_spoke_vnet_virtual_networks" { type = map(object({ hub_virtual_network = any @@ -5,6 +16,8 @@ variable "hub_and_spoke_vnet_virtual_networks" { express_route = optional(any) vpn = optional(any) })) + private_dns_zones = any + ddos_protection_plan = any })) description = "A map of hub networks to create. Detailed information about the hub network can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-hubnetworking" default = { @@ -47,6 +60,10 @@ variable "hub_and_spoke_vnet_virtual_networks" { sku = "$${starter_location_01_virtual_network_gateway_sku}" } } + private_dns_zones = { + resource_group_name = "rg-hub-dns-$${starter_location_01}" + is_primary = true + } } secondary = { hub_virtual_network = { @@ -87,6 +104,9 @@ variable "hub_and_spoke_vnet_virtual_networks" { sku = "$${starter_location_02_virtual_network_gateway_sku}" } } + private_dns_zones = { + resource_group_name = "rg-hub-dns-$${starter_location_01}" + } } } } diff --git a/templates/complete_multi_region/variables-virtual-wan.tf b/templates/complete_multi_region/variables-virtual-wan.tf index 42f69f37..1f6c6561 100644 --- a/templates/complete_multi_region/variables-virtual-wan.tf +++ b/templates/complete_multi_region/variables-virtual-wan.tf @@ -1,55 +1,61 @@ -variable "virtual_wan_name" { - type = string - description = "The name of the virtual WAN" - default = "vwan-$${location}" -} - -variable "virtual_wan_resource_group_name" { - type = string - description = "The name of the resource group for the virtual WAN" - default = "rg-connectivity-$${location}" -} - variable "virtual_wan_settings" { - type = any - description = "The settings for the virtual WAN" - default = null + type = any + default = { + name = "vwan-$${starter_location_01}" + resource_group_name = "rg-vwan-$${starter_location_01}" + location = "$${starter_location_01}" + ddos_protection_plan = { + name = "ddos-$${starter_location_01}" + resource_group_name = "rg-ddos-$${starter_location_01}" + location = "$${starter_location_01}" + } + } } variable "virtual_wan_virtual_hubs" { type = map(object({ - name = optional(string, "vwan-hub-$${location}") - location = string - resource_group_name = optional(string, "rg-vwan-hub-$${location}") - virtual_network_connections = optional(map(any)) - firewall = optional(object({ - name = optional(string, "fw-hub-$${location}") - sku_name = optional(string, null) - sku_tier = optional(string, null) - zones = optional(list(string)) - firewall_policy = optional(object({ - name = optional(string, "fwp-hub-$${location}") - settings = optional(any) - })) - settings = optional(any) - })) - address_prefix = string - tags = optional(map(string)) - hub_routing_preference = optional(string) - private_dns_zone_networking = optional(object({ - virtual_network = object({ - name = optional(string, "vnet-hub-dns-$${location}") - address_space = string - private_dns_resolver_subnet = object({ - name = optional(string, "subnet-hub-dns-$${location}") - address_prefix = string - }) - }) - private_dns_resolver = object({ - name = optional(string, "pdr-hub-dns-$${location}") - }) - })) + hub = any + firewall = any + private_dns_zones = any })) - default = {} + default = { + primary = { + hub = { + name = "vwan-hub-$${starter_location_01}" + resource_group_name = "rg-vwan-hub-$${starter_location_01}" + location = "$${starter_location_01}" + address_prefix = "10.0.0.0/16" + } + firewall = { + name = "fw-hub-$${starter_location_01}" + sku_name = "AZFW_Hub" + sku_tier = "Standard" + zones = "$${starter_location_01_availability_zones}" + firewall_policy = { + name = "fwp-hub-$${starter_location_01}" + } + } + private_dns_zones = { + resource_group_name = "rg-vwan-dns-$${starter_location_01}" + is_primary = true + networking = { + virtual_network = { + name = "vnet-hub-dns-$${starter_location_01}" + address_space = "10.10.0.0/24" + private_dns_resolver_subnet = object({ + name = "subnet-hub-dns-$${starter_location_01}" + address_prefix = "10.10.0.0/28" + }) + } + private_dns_resolver = object({ + name = "pdr-hub-dns-$${starter_location_01}" + }) + } + } + ddos_protection_plan = { + name = "ddos-$${starter_location_01}" + } + } + } description = "A map of virtual hubs to create. Detailed information about the virtual hub can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-virtualhub" } diff --git a/templates/complete_multi_region/variables.management.tf b/templates/complete_multi_region/variables.management.tf index 2d66766d..76b4910f 100644 --- a/templates/complete_multi_region/variables.management.tf +++ b/templates/complete_multi_region/variables.management.tf @@ -1,35 +1,64 @@ -variable "management_use_vnext" { +variable "management_use_avm" { type = bool default = false - description = "Flag to enable/disable the use of the next version of the management module" + description = "Flag to enable/disable the use of the AVM version of the management modules" } -variable "management_resource_group_name" { - type = string - description = "The name of the resource group for the management resources" - default = "rg-management-$${location}" -} - -variable "management_asc_export_resource_group_name" { - type = string - description = "The name of the resource group for the management ASC export resources" - default = "rg-management-asc-export-$${location}" - -} - -variable "management_log_analytics_workspace_name" { - type = string - description = "The name of the Log Analytics workspace for the management resources" - default = "law-management-$${location}" -} - -variable "management_automation_account_name" { - type = string - description = "The SKU of the Log Analytics workspace for the management resources" - default = "aa-management-$${location}" +variable "management_settings_avm" { + type = any + default = {} } -variable "management_settings" { +variable "management_settings_es" { type = any - default = null + default = { + default_location = "$${starter_location_01}" + root_parent_id = "$${root_parent_management_group_id}" + root_id = "alz" + root_name = "Azure-Landing-Zones" + subscription_id_connectivity = "$${subscription_id_connectivity}" + subscription_id_identity = "$${subscription_id_identity}" + subscription_id_management = "$${subscription_id_management}" + configure_connectivity_resources = { + settings = { + dns = { + config = { + location = "$${starter_location_01}" + } + } + } + advanced = { + custom_settings_by_resource_type = { + azurerm_resource_group = { + dns = { + name = "rg-private-dns-$${starter_location_01}" + } + } + } + } + } + configure_management_resources = { + location = "$${starter_location_01}" + advanced = { + asc_export_resource_group_name = "rg-management-asc-export-$${starter_location_01}" + custom_settings_by_resource_type = { + azurerm_resource_group = { + management = { + name = "rg-management-$${starter_location_01}" + } + } + } + azurerm_log_analytics_workspace = { + management = { + name = "law-management-$${starter_location_01}" + } + } + azurerm_automation_account = { + management = { + name = "aa-management-$${starter_location_01}" + } + } + } + } + } } \ No newline at end of file diff --git a/templates/complete_multi_region/variables.tf b/templates/complete_multi_region/variables.tf index 7aa7e27f..c4503363 100644 --- a/templates/complete_multi_region/variables.tf +++ b/templates/complete_multi_region/variables.tf @@ -24,12 +24,6 @@ variable "configuration_file_path" { description = "The path of the configuration file|configuration_file_path" } -variable "default_postfix" { - type = string - default = "landing-zone" - description = "The default postfix for Azure resources. (e.g 'landing-zone')|azure_name" -} - variable "root_parent_management_group_id" { type = string default = "" From 6adcb1270c6d0ff7d8772bfad3677593eb247c42 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Mon, 7 Oct 2024 10:12:26 +0100 Subject: [PATCH 06/23] Bug fixes --- .../complete_multi_region/locals-config.tf | 2 +- .../locals-hub-and-spoke-vnet.tf | 4 +- .../locals-resource-groups.tf | 6 +-- .../locals-virtual-wan.tf | 6 +-- .../modules/management/main.tf | 2 +- .../modules/management/terraform.tf | 12 +++++ .../modules/virtual-wan/locals.tf | 2 +- .../networking-hub-and-spoke-vnet.tf | 3 +- .../variables-hub-and-spoke-vnet.tf | 3 +- .../variables-virtual-wan.tf | 49 +++++++++++++++---- 10 files changed, 66 insertions(+), 23 deletions(-) create mode 100644 templates/complete_multi_region/modules/management/terraform.tf diff --git a/templates/complete_multi_region/locals-config.tf b/templates/complete_multi_region/locals-config.tf index 7ecbb2d4..d15633b0 100644 --- a/templates/complete_multi_region/locals-config.tf +++ b/templates/complete_multi_region/locals-config.tf @@ -31,7 +31,7 @@ locals { starter_location_08_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[7]].express_route, null) starter_location_09_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[8]].express_route, null) starter_location_10_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[9]].express_route, null) - root_parent_management_group_id = var.root_parent_management_group_id == "" ? data.azapi_client_config.current.tenant_id : var.root_parent_management_group_id + root_parent_management_group_id = var.root_parent_management_group_id == "" ? data.azurerm_client_config.current.tenant_id : var.root_parent_management_group_id subscription_id_connectivity = var.subscription_id_connectivity subscription_id_identity = var.subscription_id_identity subscription_id_management = var.subscription_id_management diff --git a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf index 78804d59..56d318f0 100644 --- a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf @@ -11,7 +11,7 @@ locals { locals { hub_and_spoke_vnet_virtual_json = tostring(jsonencode(var.hub_and_spoke_vnet_virtual_networks)) - hub_and_spoke_vnet_virtual_json_templated = templatestring(local.hub_and_spoke_vnet_virtual_json_templated, local.config_template_file_variables) + hub_and_spoke_vnet_virtual_json_templated = templatestring(local.hub_and_spoke_vnet_virtual_json, local.config_template_file_variables) hub_and_spoke_vnet_virtual_json_final = replace(replace(local.hub_and_spoke_vnet_virtual_json_templated, "\"[", "["), "]\"", "]") - hub_and_spoke_vnet_virtual_networks = jsondecode(local.hub_and_spoke_vnet_virtual_json_final) + hub_and_spoke_vnet_virtual_networks = local.connectivity_hub_and_spoke_vnet_enabled ? jsondecode(local.hub_and_spoke_vnet_virtual_json_final) : {} } diff --git a/templates/complete_multi_region/locals-resource-groups.tf b/templates/complete_multi_region/locals-resource-groups.tf index ae99a43a..dbc2ec7a 100644 --- a/templates/complete_multi_region/locals-resource-groups.tf +++ b/templates/complete_multi_region/locals-resource-groups.tf @@ -1,12 +1,12 @@ locals { resource_groups_hub_and_spoke_vnet = local.connectivity_hub_and_spoke_vnet_enabled ? merge({ for key, value in local.hub_and_spoke_vnet_virtual_networks : key => { - name = value.resource_group_name - location = value.location + name = value.hub_virtual_network.resource_group_name + location = value.hub_virtual_network.location }},{ for key, value in local.virtual_wan_virtual_hubs : key => { name = value.private_dns_zones.resource_group_name - location = value.location + location = value.hub_virtual_network.location } if can(value.private_dns_zones.resource_group_name) } ) : {} diff --git a/templates/complete_multi_region/locals-virtual-wan.tf b/templates/complete_multi_region/locals-virtual-wan.tf index 1a2ca93c..57f07a74 100644 --- a/templates/complete_multi_region/locals-virtual-wan.tf +++ b/templates/complete_multi_region/locals-virtual-wan.tf @@ -2,10 +2,10 @@ locals { virtual_wan_settings_json = tostring(jsonencode(var.virtual_wan_settings)) virtual_wan_settings_json_templated = templatestring(local.virtual_wan_settings_json, local.config_template_file_variables) virtual_wan_settings_json_final = replace(replace(local.virtual_wan_settings_json_templated, "\"[", "["), "]\"", "]") - virtual_wan_settings = jsondecode(local.virtual_wan_settings_json_final) + virtual_wan_settings = local.connectivity_virtual_wan_enabled ? jsondecode(local.virtual_wan_settings_json_final) : null virtual_wan_virtual_hubs_json = tostring(jsonencode(var.virtual_wan_virtual_hubs)) - virtual_wan_virtual_hubs_json_templated = templatestring(local.virtual_wan_virtual_hubs_json_templated, local.config_template_file_variables) + virtual_wan_virtual_hubs_json_templated = templatestring(local.virtual_wan_virtual_hubs_json, local.config_template_file_variables) virtual_wan_virtual_hubs_json_final = replace(replace(local.virtual_wan_virtual_hubs_json_templated, "\"[", "["), "]\"", "]") - virtual_wan_virtual_hubs = jsondecode(local.virtual_wan_virtual_hubs_json_final) + virtual_wan_virtual_hubs = local.connectivity_virtual_wan_enabled ? jsondecode(local.virtual_wan_virtual_hubs_json_final) : {} } diff --git a/templates/complete_multi_region/modules/management/main.tf b/templates/complete_multi_region/modules/management/main.tf index 6c7d9ff4..4c7694a9 100644 --- a/templates/complete_multi_region/modules/management/main.tf +++ b/templates/complete_multi_region/modules/management/main.tf @@ -4,7 +4,7 @@ module "management_groups" { disable_telemetry = !var.enable_telemetry default_location = var.settings.default_location - root_parent_id = try(var.settings.root_parent_id, data.azurerm_client_config.current.tenant_id) + root_parent_id = var.settings.root_parent_id archetype_config_overrides = try(var.settings.archetype_config_overrides, {}) configure_connectivity_resources = try(var.settings.configure_connectivity_resources, {}) configure_identity_resources = try(var.settings.configure_identity_resources, {}) diff --git a/templates/complete_multi_region/modules/management/terraform.tf b/templates/complete_multi_region/modules/management/terraform.tf new file mode 100644 index 00000000..0417ea7c --- /dev/null +++ b/templates/complete_multi_region/modules/management/terraform.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.107" + configuration_aliases = [ + azurerm.connectivity, + azurerm.management, + ] + } + } +} \ No newline at end of file diff --git a/templates/complete_multi_region/modules/virtual-wan/locals.tf b/templates/complete_multi_region/modules/virtual-wan/locals.tf index aace5ff5..f9c7d80d 100644 --- a/templates/complete_multi_region/modules/virtual-wan/locals.tf +++ b/templates/complete_multi_region/modules/virtual-wan/locals.tf @@ -32,7 +32,7 @@ locals { location = virtual_hub_value.location resource_group_name = virtual_hub_value.resource_group_name firewall_policy_dns = { - servers = [module.dns_resolver[each.value.virtual_hub_key].inbound_endpoint_ips["dns"]] + servers = [module.dns_resolver[virtual_hub_key].inbound_endpoint_ips["dns"]] proxy_enabled = true } }, virtual_hub_value) if can(virtual_hub_value.firewall_policy) } diff --git a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf index bed0c148..242d53e7 100644 --- a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf @@ -1,8 +1,9 @@ module "hub_and_spoke_vnet" { source = "./modules/hub-and-spoke-vnet" - count = var.connectivity_type == "hub_and_spoke_vnet" ? 1 : 0 + count = local.connectivity_hub_and_spoke_vnet_enabled ? 1 : 0 + hub_and_spoke_networks_settings = var.hub_and_spoke_vnet_virtual_networks_settings hub_virtual_networks = local.hub_and_spoke_vnet_virtual_networks enable_telemetry = var.enable_telemetry diff --git a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf index 952c10a0..3670170d 100644 --- a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf @@ -16,8 +16,7 @@ variable "hub_and_spoke_vnet_virtual_networks" { express_route = optional(any) vpn = optional(any) })) - private_dns_zones = any - ddos_protection_plan = any + private_dns_zones = optional(any) })) description = "A map of hub networks to create. Detailed information about the hub network can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-hubnetworking" default = { diff --git a/templates/complete_multi_region/variables-virtual-wan.tf b/templates/complete_multi_region/variables-virtual-wan.tf index 1f6c6561..40648075 100644 --- a/templates/complete_multi_region/variables-virtual-wan.tf +++ b/templates/complete_multi_region/variables-virtual-wan.tf @@ -15,10 +15,10 @@ variable "virtual_wan_settings" { variable "virtual_wan_virtual_hubs" { type = map(object({ hub = any - firewall = any - private_dns_zones = any + firewall = optional(any) + private_dns_zones = optional(any) })) - default = { + default = { primary = { hub = { name = "vwan-hub-$${starter_location_01}" @@ -42,18 +42,49 @@ variable "virtual_wan_virtual_hubs" { virtual_network = { name = "vnet-hub-dns-$${starter_location_01}" address_space = "10.10.0.0/24" - private_dns_resolver_subnet = object({ + private_dns_resolver_subnet = { name = "subnet-hub-dns-$${starter_location_01}" address_prefix = "10.10.0.0/28" - }) + } } - private_dns_resolver = object({ + private_dns_resolver = { name = "pdr-hub-dns-$${starter_location_01}" - }) + } + } + } + } + secondary = { + hub = { + name = "vwan-hub-$${starter_location_02}" + resource_group_name = "rg-vwan-hub-$${starter_location_02}" + location = "$${starter_location_02}" + address_prefix = "10.1.0.0/16" + } + firewall = { + name = "fw-hub-$${starter_location_02}" + sku_name = "AZFW_Hub" + sku_tier = "Standard" + zones = "$${starter_location_02_availability_zones}" + firewall_policy = { + name = "fwp-hub-$${starter_location_02}" } } - ddos_protection_plan = { - name = "ddos-$${starter_location_01}" + private_dns_zones = { + resource_group_name = "rg-vwan-dns-$${starter_location_01}" + is_primary = false + networking = { + virtual_network = { + name = "vnet-hub-dns-$${starter_location_02}" + address_space = "10.11.0.0/24" + private_dns_resolver_subnet = { + name = "subnet-hub-dns-$${starter_location_02}" + address_prefix = "10.11.0.0/28" + } + } + private_dns_resolver = { + name = "pdr-hub-dns-$${starter_location_02}" + } + } } } } From 2357b4a583c567760dd04db06e4a820f9be51699 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Mon, 7 Oct 2024 11:17:09 +0100 Subject: [PATCH 07/23] Bug fixes and improvements --- .../locals-hub-and-spoke-vnet.tf | 5 ++++ .../locals-resource-names.tf | 4 ---- templates/complete_multi_region/management.tf | 2 +- .../modules/hub-and-spoke-vnet/locals.tf | 4 +++- .../modules/hub-and-spoke-vnet/main.tf | 4 ++-- .../modules/hub-and-spoke-vnet/variables.tf | 5 ++-- .../{management => management-es}/main.tf | 0 .../terraform.tf | 0 .../variables.tf | 0 .../modules/virtual-wan/locals.tf | 6 +++-- .../modules/virtual-wan/main.tf | 14 +++++------ .../modules/virtual-wan/variables.tf | 2 -- .../networking-hub-and-spoke-vnet.tf | 2 +- .../variables-connectivity.tf | 22 +---------------- .../variables-hub-and-spoke-vnet.tf | 4 +++- .../variables.management.tf | 24 +++++++++++++++++-- 16 files changed, 51 insertions(+), 47 deletions(-) delete mode 100644 templates/complete_multi_region/locals-resource-names.tf rename templates/complete_multi_region/modules/{management => management-es}/main.tf (100%) rename templates/complete_multi_region/modules/{management => management-es}/terraform.tf (100%) rename templates/complete_multi_region/modules/{management => management-es}/variables.tf (100%) diff --git a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf index 56d318f0..a4f04d55 100644 --- a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf @@ -10,6 +10,11 @@ locals { } locals { + hub_and_spoke_vnet_settings_json = tostring(jsonencode(var.hub_and_spoke_vnet_settings)) + hub_and_spoke_vnet_settings_json_templated = templatestring(local.hub_and_spoke_vnet_settings_json, local.config_template_file_variables) + hub_and_spoke_vnet_settings_json_final = replace(replace(local.hub_and_spoke_vnet_settings_json_templated, "\"[", "["), "]\"", "]") + hub_and_spoke_vnet_settings = jsondecode(local.hub_and_spoke_vnet_settings_json_final) + hub_and_spoke_vnet_virtual_json = tostring(jsonencode(var.hub_and_spoke_vnet_virtual_networks)) hub_and_spoke_vnet_virtual_json_templated = templatestring(local.hub_and_spoke_vnet_virtual_json, local.config_template_file_variables) hub_and_spoke_vnet_virtual_json_final = replace(replace(local.hub_and_spoke_vnet_virtual_json_templated, "\"[", "["), "]\"", "]") diff --git a/templates/complete_multi_region/locals-resource-names.tf b/templates/complete_multi_region/locals-resource-names.tf deleted file mode 100644 index d0d895ba..00000000 --- a/templates/complete_multi_region/locals-resource-names.tf +++ /dev/null @@ -1,4 +0,0 @@ -locals { - ddos_protection_plan_resource_group_name = templatestring(var.ddos_protection_plan_resource_group_name, { location = local.primary_location }) - ddos_protection_plan_name = templatestring(var.ddos_protection_plan_name, { location = local.primary_location }) -} \ No newline at end of file diff --git a/templates/complete_multi_region/management.tf b/templates/complete_multi_region/management.tf index 2a77d447..71c782f2 100644 --- a/templates/complete_multi_region/management.tf +++ b/templates/complete_multi_region/management.tf @@ -1,5 +1,5 @@ module "management_groups" { - source = "./modules/management" + source = "./modules/management-es" count = var.management_use_avm ? 0 : 1 diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf index 3335bfa6..551007a3 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf @@ -20,7 +20,9 @@ locals { } locals { - private_dns_zones = { for key, value in var.hub_virtual_networks : key => value if can(value.private_dns_zones) } + private_dns_zones = { for key, value in var.hub_virtual_networks : key => merge({ + location = value.hub_virtual_network.location + }, value.private_dns_zones) if can(value.private_dns_zones) } private_dns_zones_virtual_network_links = { for key, value in module.hub_and_spoke_vnet.virtual_networks : key => { diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf index c5507132..d42beebf 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf @@ -50,10 +50,10 @@ module "private_dns_zones" { for_each = local.private_dns_zones location = each.value.location - resource_group_name = each.value.private_dns_zones.resource_group_name + resource_group_name = each.value.resource_group_name resource_group_creation_enabled = false virtual_network_resource_ids_to_link_to = local.private_dns_zones_virtual_network_links - private_link_private_dns_zones = try(each.value.private_dns_zones.is_primary, false) ? null : local.private_dns_zones_secondary_zones + private_link_private_dns_zones = try(each.value.is_primary, false) ? null : local.private_dns_zones_secondary_zones enable_telemetry = var.enable_telemetry tags = var.tags } diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf index 4f375e4a..1dd560fe 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf @@ -9,11 +9,10 @@ variable "hub_virtual_networks" { express_route = optional(any) vpn = optional(any) })) - private_dns_zones = object({ + private_dns_zones = optional(object({ resource_group_name = string is_primary = optional(bool, false) - }) - ddos_protection_plan = any + })) })) default = {} description = "A map of hub networks to create. Detailed information about the hub network can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-hubnetworking" diff --git a/templates/complete_multi_region/modules/management/main.tf b/templates/complete_multi_region/modules/management-es/main.tf similarity index 100% rename from templates/complete_multi_region/modules/management/main.tf rename to templates/complete_multi_region/modules/management-es/main.tf diff --git a/templates/complete_multi_region/modules/management/terraform.tf b/templates/complete_multi_region/modules/management-es/terraform.tf similarity index 100% rename from templates/complete_multi_region/modules/management/terraform.tf rename to templates/complete_multi_region/modules/management-es/terraform.tf diff --git a/templates/complete_multi_region/modules/management/variables.tf b/templates/complete_multi_region/modules/management-es/variables.tf similarity index 100% rename from templates/complete_multi_region/modules/management/variables.tf rename to templates/complete_multi_region/modules/management-es/variables.tf diff --git a/templates/complete_multi_region/modules/virtual-wan/locals.tf b/templates/complete_multi_region/modules/virtual-wan/locals.tf index f9c7d80d..4ec01c75 100644 --- a/templates/complete_multi_region/modules/virtual-wan/locals.tf +++ b/templates/complete_multi_region/modules/virtual-wan/locals.tf @@ -48,8 +48,10 @@ locals { } locals { - private_dns_zones = { for key, value in var.virtual_hubs : key => value if can(value.private_dns_zones) } - + private_dns_zones = { for key, value in var.virtual_hubs : key => merge({ + location = value.hub.location + }, value.private_dns_zones) if can(value.private_dns_zones) } + private_dns_zones_virtual_network_links = { for key, value in module.virtual_network_private_dns : key => { vnet_resource_id = value.resource_id diff --git a/templates/complete_multi_region/modules/virtual-wan/main.tf b/templates/complete_multi_region/modules/virtual-wan/main.tf index 8100fa8a..63e3eb23 100644 --- a/templates/complete_multi_region/modules/virtual-wan/main.tf +++ b/templates/complete_multi_region/modules/virtual-wan/main.tf @@ -53,9 +53,9 @@ module "virtual_network_private_dns" { for_each = local.private_dns_zones - address_space = each.value.private_dns_zones.networking.virtual_network.address_space + address_space = each.value.networking.virtual_network.address_space location = each.value.location - name = each.value.private_dns_zones.networking.virtual_network.name + name = each.value.networking.virtual_network.name resource_group_name = each.value.resource_group_name enable_telemetry = var.enable_telemetry ddos_protection_plan = local.ddos_protection_plan_enabled ? { @@ -64,8 +64,8 @@ module "virtual_network_private_dns" { } : null subnets = { dns = { - address_prefix = each.value.private_dns_zones.networking.virtual_network.private_dns_resolver_subnet.address_prefix - name = each.value.private_dns_zones.networking.virtual_network.private_dns_resolver_subnet.name + address_prefix = each.value.networking.virtual_network.private_dns_resolver_subnet.address_prefix + name = each.value.networking.virtual_network.private_dns_resolver_subnet.name delegation = [{ name = "Microsoft.Network.dnsResolvers" service_delegation = { @@ -84,7 +84,7 @@ module "dns_resolver" { for_each = local.private_dns_zones location = each.value.location - name = each.value.private_dns_zones.networking.private_dns_resolver.name + name = each.value.networking.private_dns_resolver.name resource_group_name = each.value.resource_group_name virtual_network_resource_id = module.virtual_network_private_dns[each.key].resource_id enable_telemetry = var.enable_telemetry @@ -103,10 +103,10 @@ module "private_dns_zones" { for_each = local.private_dns_zones location = each.value.location - resource_group_name = each.value.private_dns_zones.resource_group_name + resource_group_name = each.value.resource_group_name resource_group_creation_enabled = false virtual_network_resource_ids_to_link_to = local.private_dns_zones_virtual_network_links - private_link_private_dns_zones = try(each.value.private_dns_zones.is_primary, false) ? null : local.private_dns_zones_secondary_zones + private_link_private_dns_zones = try(each.value.is_primary, false) ? null : local.private_dns_zones_secondary_zones enable_telemetry = var.enable_telemetry tags = var.tags } diff --git a/templates/complete_multi_region/modules/virtual-wan/variables.tf b/templates/complete_multi_region/modules/virtual-wan/variables.tf index 1de7d362..5c3a4ad2 100644 --- a/templates/complete_multi_region/modules/virtual-wan/variables.tf +++ b/templates/complete_multi_region/modules/virtual-wan/variables.tf @@ -24,10 +24,8 @@ variable "virtual_hubs" { }) }) })) - ddos_protection_plan = any })) - default = {} description = "A map of virtual hubs to create. Detailed information about the virtual hub can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-virtualhub" } diff --git a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf index 242d53e7..a9b8b27d 100644 --- a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf @@ -3,7 +3,7 @@ module "hub_and_spoke_vnet" { count = local.connectivity_hub_and_spoke_vnet_enabled ? 1 : 0 - hub_and_spoke_networks_settings = var.hub_and_spoke_vnet_virtual_networks_settings + hub_and_spoke_networks_settings = local.hub_and_spoke_vnet_settings hub_virtual_networks = local.hub_and_spoke_vnet_virtual_networks enable_telemetry = var.enable_telemetry diff --git a/templates/complete_multi_region/variables-connectivity.tf b/templates/complete_multi_region/variables-connectivity.tf index 254babc5..08e47b1d 100644 --- a/templates/complete_multi_region/variables-connectivity.tf +++ b/templates/complete_multi_region/variables-connectivity.tf @@ -3,27 +3,7 @@ variable "connectivity_type" { description = "The type of connectivity to use for the private DNS zones" default = "hub_and_spoke_vnet" validation { - condition = contains(["hub_and_spoke_vnet", "virtual_wan", "none"], var.connectivity_type) + condition = contains(values(local.const.connectivity), var.connectivity_type) error_message = "The connectivity type must be either 'hub_and_spoke_vnet', 'virtual_wan' or 'none'" } } - - - -variable "ddos_protection_plan_resource_group_name" { - type = string - description = "The name of the resource group for DDoS protection plan" - default = "rg-ddos-$${location}" -} - -variable "ddos_protection_plan_resource_group_location" { - type = string - description = "The location of the resource group for DDoS protection plan" - default = null -} - -variable "ddos_protection_plan_name" { - type = string - description = "The name of the DDoS protection plan" - default = "ddos-$${location}" -} diff --git a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf index 3670170d..8adeacf5 100644 --- a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf @@ -1,4 +1,4 @@ -variable "hub_and_spoke_vnet_virtual_networks_settings" { +variable "hub_and_spoke_vnet_settings" { type = any default = { ddos_protection_plan = { @@ -36,6 +36,7 @@ variable "hub_and_spoke_vnet_virtual_networks" { public_ip_config = { name = "pip-fw-hub-$${starter_location_01}" zones = "$${starter_location_01_availability_zones}" + ip_version = "IPv4" } } firewall_policy = { @@ -80,6 +81,7 @@ variable "hub_and_spoke_vnet_virtual_networks" { public_ip_config = { name = "pip-fw-hub-$${starter_location_02}" zones = "$${starter_location_02_availability_zones}" + ip_version = "IPv4" } } firewall_policy = { diff --git a/templates/complete_multi_region/variables.management.tf b/templates/complete_multi_region/variables.management.tf index 76b4910f..e8369ddf 100644 --- a/templates/complete_multi_region/variables.management.tf +++ b/templates/complete_multi_region/variables.management.tf @@ -19,19 +19,39 @@ variable "management_settings_es" { subscription_id_connectivity = "$${subscription_id_connectivity}" subscription_id_identity = "$${subscription_id_identity}" subscription_id_management = "$${subscription_id_management}" - configure_connectivity_resources = { + deploy_connectivity_resources = false + configure_connectivity_resources = { settings = { dns = { config = { location = "$${starter_location_01}" } } + ddos_protection_plan = { + config = { + location = "$${starter_location_01}" + } + } } advanced = { custom_settings_by_resource_type = { azurerm_resource_group = { dns = { - name = "rg-private-dns-$${starter_location_01}" + ("$${starter_location_01}") = { + name = "rg-dns-$${starter_location_01}" + } + } + ddos = { + ("$${starter_location_01}") = { + name = "rg-ddos-$${starter_location_01}" + } + } + } + azurerm_network_ddos_protection_plan = { + ddos = { + ("$${starter_location_01}") = { + name = "ddos-$${starter_location_01}" + } } } } From c88f3a33933d791faece4d93888065e24b5caeea Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Mon, 7 Oct 2024 12:25:34 +0100 Subject: [PATCH 08/23] Bug fixes and improvements --- templates/complete_multi_region/README.md | 28 ++++ ...onfig-hub-and-spoke-vnet-multi-region.yaml | 158 ------------------ ...nfig-hub-and-spoke-vnet-single-region.yaml | 129 -------------- .../config-virtual-wan-multi-region.yaml | 141 ---------------- .../config-virtual-wan-single-region.yaml | 120 ------------- .../complete_multi_region/locals-config.tf | 48 +++--- .../locals-hub-and-spoke-vnet.tf | 12 +- .../locals-management.tf | 12 +- .../locals-resource-groups.tf | 33 +--- .../locals-virtual-wan.tf | 12 +- templates/complete_multi_region/management.tf | 4 +- .../modules/hub-and-spoke-vnet/locals.tf | 10 +- .../modules/hub-and-spoke-vnet/main.tf | 6 +- .../modules/hub-and-spoke-vnet/variables.tf | 2 +- .../modules/virtual-wan/locals.tf | 16 +- .../modules/virtual-wan/main.tf | 20 +-- .../modules/virtual-wan/variables.tf | 6 +- .../networking-hub-and-spoke-vnet.tf | 4 +- .../networking-virtual-wan.tf | 4 +- templates/complete_multi_region/outputs.tf | 12 ++ .../complete_multi_region/resource-groups.tf | 2 +- .../variables-connectivity.tf | 8 + .../variables-hub-and-spoke-vnet.tf | 104 +----------- .../variables-virtual-wan.tf | 88 +--------- .../variables.management.tf | 71 +------- 25 files changed, 141 insertions(+), 909 deletions(-) create mode 100644 templates/complete_multi_region/README.md delete mode 100644 templates/complete_multi_region/config-hub-and-spoke-vnet-multi-region.yaml delete mode 100644 templates/complete_multi_region/config-hub-and-spoke-vnet-single-region.yaml delete mode 100644 templates/complete_multi_region/config-virtual-wan-multi-region.yaml delete mode 100644 templates/complete_multi_region/config-virtual-wan-single-region.yaml diff --git a/templates/complete_multi_region/README.md b/templates/complete_multi_region/README.md new file mode 100644 index 00000000..8aaf2162 --- /dev/null +++ b/templates/complete_multi_region/README.md @@ -0,0 +1,28 @@ +# Azure Landing Zones Accelerator Starter Module for Terraform - Complete Multi-Region + +## Contributing + +### Run the local examples + +Create a `terraform.tfvars` file in the root of the module directory with the following content, replacing the placeholders with the actual values: + +```hcl +starter_locations = ["uksouth", "ukwest"] +subscription_id_connectivity = "00000000-0000-0000-0000-000000000000" +subscription_id_identity = "00000000-0000-0000-0000-000000000000" +subscription_id_management = "00000000-0000-0000-0000-000000000000" +``` + +#### Hub and Spoke Virtual Networks Multi Region + +```powershell +terraform init +terraform apply -var-file ./examples/config-hub-and-spoke-virtual-networks-multi-region.tfvars +``` + +#### Virtual WAN Multi Region + +```powershell +terraform init +terraform apply -var-file ./examples/config-virtual-wan-multi-region.tfvars +``` diff --git a/templates/complete_multi_region/config-hub-and-spoke-vnet-multi-region.yaml b/templates/complete_multi_region/config-hub-and-spoke-vnet-multi-region.yaml deleted file mode 100644 index 5d6fc00a..00000000 --- a/templates/complete_multi_region/config-hub-and-spoke-vnet-multi-region.yaml +++ /dev/null @@ -1,158 +0,0 @@ -# This file contains templated variables to avoid repeating the same hard-coded values. -# Templated variables are denoted by the dollar curly braces token. The following details each templated variable that you can use: -# `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. -# `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. -# `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. -# `default_postfix`: This is a string sourced from the variable `default_postfix`. This can be used to append to resource names for consistency. -# `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. -# `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. -# `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. -# `subscription_id_management`: The subscription ID of the subscription to deploy the management resources to, sourced from the variable `subscription_id_management`. ---- -management_groups: # `caf-enterprise-scale` module, add inputs as listed on the module registry where necessary. - - # Base variables - root_name: alz - root_id: Azure-Landing-Zones - default_location: ${starter_location_01} - subscription_id_connectivity: ${subscription_id_connectivity} - subscription_id_identity: ${subscription_id_identity} - subscription_id_management: ${subscription_id_management} - root_parent_id: ${root_parent_management_group_id} - deploy_core_landing_zones: true - deploy_corp_landing_zones: true - deploy_online_landing_zones: true - deploy_management_resources: true - deploy_connectivity_resources: false # We are using the AVM patterns for connectivity - deploy_identity_resources: true - - # Management resource settings - configure_management_resources: - location: ${starter_location_01} - settings: - log_analytics: - enabled: true - config: - retention_in_days: 50 - enable_monitoring_for_vm: true - enable_monitoring_for_vmss: true - enabled_sentinel: true - enable_solution_for_change_tracking: true - enable_solution_for_vm_insights: true - enable_solution_for_container_insights: true - enable_sentinel: true - security_center: - config: - email_security_contact: "security_contact@replace_me" - enable_defender_for_app_services: true - enable_defender_for_arm: true - enable_defender_for_containers: true - enable_defender_for_cosmosdbs: true - enable_defender_for_cspm: true - enable_defender_for_key_vault: true - enable_defender_for_oss_databases: true - enable_defender_for_servers: true - enable_defender_for_servers_vulnerability_assessments: true - enable_defender_for_sql_servers: true - enable_defender_for_sql_server_vms: true - enable_defender_for_storage: true - advanced: - asc_export_resource_group_name: rg-asc-export-${starter_location_01} - custom_settings_by_resource_type: - azurerm_resource_group: - management: - name: rg-management-${starter_location_01} - azurerm_log_analytics_workspace: - management: - name: law-management-${starter_location_01} - azurerm_automation_account: - management: - name: aa-management-${starter_location_01} - - # Configure Private DNS Zone Resource Ids for Policy Assignments - configure_connectivity_resources: - settings: - dns: - config: - location: ${starter_location_01} - advanced: - custom_settings_by_resource_type: - azurerm_resource_group: - dns: - ${starter_location_01}: - name: rg-private-dns-${starter_location_01} - -# Connectivity settings -connectivity: - enable_private_dns_zones: true - enable_ddos_protection_plan: true - private_dns_zone_resource_group_name: rg-private-dns-${starter_location_01} - private_dns_zone_resource_group_location: ${starter_location_01} - hub_and_spoke_vnet: # `avm-ptn-hubnetworking` module, add inputs as listed on the module registry where necessary. - hub_virtual_networks: - # Primary hub - primary: - name: vnet-hub-${starter_location_01} - resource_group_name: rg-connectivity-${starter_location_01} - location: ${starter_location_01} - address_space: - - 10.0.0.0/16 - firewall: - name: fw-hub-${starter_location_01} - sku_name: AZFW_VNet - sku_tier: Standard - subnet_address_prefix: 10.0.1.0/24 - zones: ${starter_location_01_availability_zones} - firewall_policy: - name: fwp-hub-${starter_location_01} - dns: - proxy_enabled: true - default_ip_configuration: - public_ip_config: - zones: ${starter_location_01_availability_zones} - name: pip-hub-fw-${starter_location_01} - ip_version: "IPv4" - virtual_network_gateway: # `avm-ptn-vnetgateway` module, add inputs as listed on the module registry where necessary. - name: vgw-hub-${starter_location_01} - subnet_address_prefix: 10.0.2.0/24 - ip_configurations: - default: - name: default - public_ip: - name: pip-hub-vgw-${starter_location_01} - zones: ${starter_location_01_availability_zones} - - # Secondary hub - secondary: - name: vnet-hub-${starter_location_02} - resource_group_name: rg-connectivity-${starter_location_02} - location: ${starter_location_02} - address_space: - - 10.1.0.0/16 - firewall: - name: fw-hub-${starter_location_02} - sku_name: AZFW_VNet - sku_tier: Standard - subnet_address_prefix: 10.1.1.0/24 - zones: ${starter_location_02_availability_zones} - firewall_policy: - name: fwp-hub-${starter_location_02} - dns: - proxy_enabled: true - default_ip_configuration: - public_ip_config: - zones: ${starter_location_02_availability_zones} - name: pip-hub-fw-${starter_location_02} - ip_version: "IPv4" - virtual_network_gateway: # `avm-ptn-vnetgateway` module, add inputs as listed on the module registry where necessary. - name: vgw-hub-${starter_location_02} - subnet_address_prefix: 10.1.2.0/24 - ip_configurations: - ipconfig1: - name: ipconfig1 - public_ip: - name: pip-hub-vgw-${starter_location_02} - zones: ${starter_location_02_availability_zones} - -# Configure root module settings -enable_telemetry: true diff --git a/templates/complete_multi_region/config-hub-and-spoke-vnet-single-region.yaml b/templates/complete_multi_region/config-hub-and-spoke-vnet-single-region.yaml deleted file mode 100644 index 7294d268..00000000 --- a/templates/complete_multi_region/config-hub-and-spoke-vnet-single-region.yaml +++ /dev/null @@ -1,129 +0,0 @@ -# This file contains templated variables to avoid repeating the same hard-coded values. -# Templated variables are denoted by the dollar curly braces token. The following details each templated variable that you can use: -# `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. -# `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. -# `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. -# `default_postfix`: This is a string sourced from the variable `default_postfix`. This can be used to append to resource names for consistency. -# `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. -# `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. -# `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. -# `subscription_id_management`: The subscription ID of the subscription to deploy the management resources to, sourced from the variable `subscription_id_management`. ---- -management_groups: # `caf-enterprise-scale` module, add inputs as listed on the module registry where necessary. - - # Base variables - root_name: alz - root_id: Azure-Landing-Zones - default_location: ${starter_location_01} - subscription_id_connectivity: ${subscription_id_connectivity} - subscription_id_identity: ${subscription_id_identity} - subscription_id_management: ${subscription_id_management} - root_parent_id: ${root_parent_management_group_id} - deploy_core_landing_zones: true - deploy_corp_landing_zones: true - deploy_online_landing_zones: true - deploy_management_resources: true - deploy_connectivity_resources: false # We are using the AVM patterns for connectivity - deploy_identity_resources: true - - # Management resource settings - configure_management_resources: - location: ${starter_location_01} - settings: - log_analytics: - enabled: true - config: - retention_in_days: 50 - enable_monitoring_for_vm: true - enable_monitoring_for_vmss: true - enabled_sentinel: true - enable_solution_for_change_tracking: true - enable_solution_for_vm_insights: true - enable_solution_for_container_insights: true - enable_sentinel: true - security_center: - config: - email_security_contact: "security_contact@replace_me" - enable_defender_for_app_services: true - enable_defender_for_arm: true - enable_defender_for_containers: true - enable_defender_for_cosmosdbs: true - enable_defender_for_cspm: true - enable_defender_for_key_vault: true - enable_defender_for_oss_databases: true - enable_defender_for_servers: true - enable_defender_for_servers_vulnerability_assessments: true - enable_defender_for_sql_servers: true - enable_defender_for_sql_server_vms: true - enable_defender_for_storage: true - advanced: - asc_export_resource_group_name: rg-asc-export-${starter_location_01} - custom_settings_by_resource_type: - azurerm_resource_group: - management: - name: rg-management-${starter_location_01} - azurerm_log_analytics_workspace: - management: - name: law-management-${starter_location_01} - azurerm_automation_account: - management: - name: aa-management-${starter_location_01} - - # Configure Private DNS Zone Resource Ids for Policy Assignments - configure_connectivity_resources: - settings: - dns: - config: - location: ${starter_location_01} - advanced: - custom_settings_by_resource_type: - azurerm_resource_group: - dns: - ${starter_location_01}: - name: rg-private-dns-${starter_location_01} - -# Connectivity settings -connectivity: - hub_and_spoke_vnet: # `avm-ptn-hubnetworking` module, add inputs as listed on the module registry where necessary. - hub_virtual_networks: - # Primary hub - primary: - name: vnet-hub-${starter_location_01} - resource_group_name: rg-connectivity-${starter_location_01} - location: ${starter_location_01} - address_space: - - 10.0.0.0/16 - firewall: - name: fw-hub-${starter_location_01} - sku_name: AZFW_VNet - sku_tier: Standard - subnet_address_prefix: 10.0.1.0/24 - zones: ${starter_location_01_availability_zones} - firewall_policy: - name: fwp-hub-${starter_location_01} - dns: - proxy_enabled: true - default_ip_configuration: - public_ip_config: - zones: ${starter_location_01_availability_zones} - name: pip-hub-fw-${starter_location_01} - ip_version: "IPv4" - virtual_network_gateway: # `avm-ptn-vnetgateway` module, add inputs as listed on the module registry where necessary. - name: vgw-hub-${starter_location_01} - subnet_address_prefix: 10.0.2.0/24 - ip_configurations: - default: - name: default - public_ip: - name: pip-hub-vgw-${starter_location_01} - zones: ${starter_location_01_availability_zones} - - private_dns: - resource_group_name: rg-private-dns-${starter_location_01} - locations: - primary: - location: ${starter_location_01} - is_primary: true # Deploys all zones - -# Configure root module settings -enable_telemetry: true diff --git a/templates/complete_multi_region/config-virtual-wan-multi-region.yaml b/templates/complete_multi_region/config-virtual-wan-multi-region.yaml deleted file mode 100644 index b65f3352..00000000 --- a/templates/complete_multi_region/config-virtual-wan-multi-region.yaml +++ /dev/null @@ -1,141 +0,0 @@ -# This file contains templated variables to avoid repeating the same hard-coded values. -# Templated variables are denoted by the dollar curly braces token. The following details each templated variable that you can use: -# `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. -# `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. -# `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. -# `default_postfix`: This is a string sourced from the variable `default_postfix`. This can be used to append to resource names for consistency. -# `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. -# `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. -# `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. -# `subscription_id_management`: The subscription ID of the subscription to deploy the management resources to, sourced from the variable `subscription_id_management`. ---- -management_groups: # `caf-enterprise-scale` module, add inputs as listed on the module registry where necessary. - - # Base variables - root_name: alz - root_id: Azure-Landing-Zones - default_location: ${starter_location_01} - subscription_id_connectivity: ${subscription_id_connectivity} - subscription_id_identity: ${subscription_id_identity} - subscription_id_management: ${subscription_id_management} - root_parent_id: ${root_parent_management_group_id} - deploy_core_landing_zones: true - deploy_corp_landing_zones: true - deploy_online_landing_zones: true - deploy_management_resources: true - deploy_connectivity_resources: false # We are using the AVM patterns for connectivity - deploy_identity_resources: true - - # Management resource settings - configure_management_resources: - location: ${starter_location_01} - settings: - log_analytics: - enabled: true - config: - retention_in_days: 50 - enable_monitoring_for_vm: true - enable_monitoring_for_vmss: true - enabled_sentinel: true - enable_solution_for_change_tracking: true - enable_solution_for_vm_insights: true - enable_solution_for_container_insights: true - enable_sentinel: true - security_center: - config: - email_security_contact: "security_contact@replace_me" - enable_defender_for_app_services: true - enable_defender_for_arm: true - enable_defender_for_containers: true - enable_defender_for_cosmosdbs: true - enable_defender_for_cspm: true - enable_defender_for_key_vault: true - enable_defender_for_oss_databases: true - enable_defender_for_servers: true - enable_defender_for_servers_vulnerability_assessments: true - enable_defender_for_sql_servers: true - enable_defender_for_sql_server_vms: true - enable_defender_for_storage: true - advanced: - asc_export_resource_group_name: rg-asc-export-${starter_location_01} - custom_settings_by_resource_type: - azurerm_resource_group: - management: - name: rg-management-${starter_location_01} - azurerm_log_analytics_workspace: - management: - name: law-management-${starter_location_01} - azurerm_automation_account: - management: - name: aa-management-${starter_location_01} - - # Configure Private DNS Zone Resource Ids for Policy Assignments - configure_connectivity_resources: - settings: - dns: - config: - location: ${starter_location_01} - advanced: - custom_settings_by_resource_type: - azurerm_resource_group: - dns: - ${starter_location_01}: - name: rg-private-dns-${starter_location_01} - -# Connectivity settings -connectivity: - virtual_wan: # `avm-ptn-vwan` module, add inputs as listed on the module registry where necessary. - virtual_wan_name: vwan-hub-${starter_location_01} - resource_group_name: rg-connectivity-${starter_location_01} - location: ${starter_location_01} - - virtual_hubs: - primary: - name: vnet-hub-${starter_location_01} - location: ${starter_location_01} - address_prefix: 10.0.0.0/16 - private_dns_virtual_network_name: vnet-hub-private-dns-${starter_location_01} - private_dns_virtual_network_address_space: 10.2.0.0/24 - private_dns_virtual_network_subnet_address_space: 10.2.0.0/28 - dns_resolver_name: dpr-hub-${starter_location_01} - - secondary: - name: vnet-hub-${starter_location_02} - location: ${starter_location_02} - address_prefix: 10.1.0.0/16 - private_dns_virtual_network_name: vnet-hub-private-dns-${starter_location_02} - private_dns_virtual_network_address_space: 10.3.0.0/24 - private_dns_virtual_network_subnet_address_space: 10.3.0.0/28 - dns_resolver_name: dpr-hub-${starter_location_02} - - firewalls: - primary: - virtual_hub_key: primary - name: fw-hub-${starter_location_01} - sku_name: AZFW_Hub - sku_tier: Standard - zones: ${starter_location_01_availability_zones} - firewall_policy: - name: fwp-hub-${starter_location_01} - - secondary: - virtual_hub_key: secondary - name: fw-hub-${starter_location_02} - sku_name: AZFW_Hub - sku_tier: Standard - zones: ${starter_location_02_availability_zones} - firewall_policy: - name: fwp-hub-${starter_location_02} - - private_dns: - resource_group_name: rg-private-dns-${starter_location_01} - locations: - primary: - location: ${starter_location_01} - is_primary: true # Deploys all zones - secondary: - location: ${starter_location_02} - is_primary: false # Only deploys regional zones - -# Configure root module settings -enable_telemetry: true diff --git a/templates/complete_multi_region/config-virtual-wan-single-region.yaml b/templates/complete_multi_region/config-virtual-wan-single-region.yaml deleted file mode 100644 index 9584e748..00000000 --- a/templates/complete_multi_region/config-virtual-wan-single-region.yaml +++ /dev/null @@ -1,120 +0,0 @@ -# This file contains templated variables to avoid repeating the same hard-coded values. -# Templated variables are denoted by the dollar curly braces token. The following details each templated variable that you can use: -# `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. -# `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. -# `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. -# `default_postfix`: This is a string sourced from the variable `default_postfix`. This can be used to append to resource names for consistency. -# `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. -# `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. -# `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. -# `subscription_id_management`: The subscription ID of the subscription to deploy the management resources to, sourced from the variable `subscription_id_management`. ---- -management_groups: # `caf-enterprise-scale` module, add inputs as listed on the module registry where necessary. - - # Base variables - root_name: alz - root_id: Azure-Landing-Zones - default_location: ${starter_location_01} - subscription_id_connectivity: ${subscription_id_connectivity} - subscription_id_identity: ${subscription_id_identity} - subscription_id_management: ${subscription_id_management} - root_parent_id: ${root_parent_management_group_id} - deploy_core_landing_zones: true - deploy_corp_landing_zones: true - deploy_online_landing_zones: true - deploy_management_resources: true - deploy_connectivity_resources: false # We are using the AVM patterns for connectivity - deploy_identity_resources: true - - # Management resource settings - configure_management_resources: - location: ${starter_location_01} - settings: - log_analytics: - enabled: true - config: - retention_in_days: 50 - enable_monitoring_for_vm: true - enable_monitoring_for_vmss: true - enabled_sentinel: true - enable_solution_for_change_tracking: true - enable_solution_for_vm_insights: true - enable_solution_for_container_insights: true - enable_sentinel: true - security_center: - config: - email_security_contact: "security_contact@replace_me" - enable_defender_for_app_services: true - enable_defender_for_arm: true - enable_defender_for_containers: true - enable_defender_for_cosmosdbs: true - enable_defender_for_cspm: true - enable_defender_for_key_vault: true - enable_defender_for_oss_databases: true - enable_defender_for_servers: true - enable_defender_for_servers_vulnerability_assessments: true - enable_defender_for_sql_servers: true - enable_defender_for_sql_server_vms: true - enable_defender_for_storage: true - advanced: - asc_export_resource_group_name: rg-asc-export-${starter_location_01} - custom_settings_by_resource_type: - azurerm_resource_group: - management: - name: rg-management-${starter_location_01} - azurerm_log_analytics_workspace: - management: - name: law-management-${starter_location_01} - azurerm_automation_account: - management: - name: aa-management-${starter_location_01} - - # Configure Private DNS Zone Resource Ids for Policy Assignments - configure_connectivity_resources: - settings: - dns: - config: - location: ${starter_location_01} - advanced: - custom_settings_by_resource_type: - azurerm_resource_group: - dns: - ${starter_location_01}: - name: rg-private-dns-${starter_location_01} - -# Connectivity settings -connectivity: - virtual_wan: # `avm-ptn-vwan` module, add inputs as listed on the module registry where necessary. - virtual_wan_name: vwan-hub-${starter_location_01} - resource_group_name: rg-connectivity-${starter_location_01} - location: ${starter_location_01} - - virtual_hubs: - primary: - name: vnet-hub-${starter_location_01} - location: ${starter_location_01} - address_prefix: 10.0.0.0/16 - private_dns_virtual_network_name: vnet-hub-private-dns-${starter_location_01} - private_dns_virtual_network_address_space: 10.2.0.0/24 - private_dns_virtual_network_subnet_address_space: 10.2.0.0/28 - dns_resolver_name: dpr-hub-${starter_location_01} - - firewalls: - primary: - virtual_hub_key: primary - name: fw-hub-${starter_location_01} - sku_name: AZFW_Hub - sku_tier: Standard - zones: ${starter_location_01_availability_zones} - firewall_policy: - name: fwp-hub-${starter_location_01} - - private_dns: - resource_group_name: rg-private-dns-${starter_location_01} - locations: - primary: - location: ${starter_location_01} - is_primary: true # Deploys all zones - -# Configure root module settings -enable_telemetry: true diff --git a/templates/complete_multi_region/locals-config.tf b/templates/complete_multi_region/locals-config.tf index d15633b0..1666305e 100644 --- a/templates/complete_multi_region/locals-config.tf +++ b/templates/complete_multi_region/locals-config.tf @@ -1,26 +1,26 @@ locals { primary_location = var.starter_locations[0] config_template_file_variables = { - starter_location_01 = var.starter_locations[0] - starter_location_02 = try(var.starter_locations[1], null) - starter_location_03 = try(var.starter_locations[2], null) - starter_location_04 = try(var.starter_locations[3], null) - starter_location_05 = try(var.starter_locations[4], null) - starter_location_06 = try(var.starter_locations[5], null) - starter_location_07 = try(var.starter_locations[6], null) - starter_location_08 = try(var.starter_locations[7], null) - starter_location_09 = try(var.starter_locations[8], null) - starter_location_10 = try(var.starter_locations[9], null) - starter_location_01_availability_zones = jsonencode(local.regions[var.starter_locations[0]].zones) - starter_location_02_availability_zones = jsonencode(try(local.regions[var.starter_locations[1]].zones, null)) - starter_location_03_availability_zones = jsonencode(try(local.regions[var.starter_locations[2]].zones, null)) - starter_location_04_availability_zones = jsonencode(try(local.regions[var.starter_locations[3]].zones, null)) - starter_location_05_availability_zones = jsonencode(try(local.regions[var.starter_locations[4]].zones, null)) - starter_location_06_availability_zones = jsonencode(try(local.regions[var.starter_locations[5]].zones, null)) - starter_location_07_availability_zones = jsonencode(try(local.regions[var.starter_locations[6]].zones, null)) - starter_location_08_availability_zones = jsonencode(try(local.regions[var.starter_locations[7]].zones, null)) - starter_location_09_availability_zones = jsonencode(try(local.regions[var.starter_locations[8]].zones, null)) - starter_location_10_availability_zones = jsonencode(try(local.regions[var.starter_locations[9]].zones, null)) + starter_location_01 = var.starter_locations[0] + starter_location_02 = try(var.starter_locations[1], null) + starter_location_03 = try(var.starter_locations[2], null) + starter_location_04 = try(var.starter_locations[3], null) + starter_location_05 = try(var.starter_locations[4], null) + starter_location_06 = try(var.starter_locations[5], null) + starter_location_07 = try(var.starter_locations[6], null) + starter_location_08 = try(var.starter_locations[7], null) + starter_location_09 = try(var.starter_locations[8], null) + starter_location_10 = try(var.starter_locations[9], null) + starter_location_01_availability_zones = jsonencode(local.regions[var.starter_locations[0]].zones) + starter_location_02_availability_zones = jsonencode(try(local.regions[var.starter_locations[1]].zones, null)) + starter_location_03_availability_zones = jsonencode(try(local.regions[var.starter_locations[2]].zones, null)) + starter_location_04_availability_zones = jsonencode(try(local.regions[var.starter_locations[3]].zones, null)) + starter_location_05_availability_zones = jsonencode(try(local.regions[var.starter_locations[4]].zones, null)) + starter_location_06_availability_zones = jsonencode(try(local.regions[var.starter_locations[5]].zones, null)) + starter_location_07_availability_zones = jsonencode(try(local.regions[var.starter_locations[6]].zones, null)) + starter_location_08_availability_zones = jsonencode(try(local.regions[var.starter_locations[7]].zones, null)) + starter_location_09_availability_zones = jsonencode(try(local.regions[var.starter_locations[8]].zones, null)) + starter_location_10_availability_zones = jsonencode(try(local.regions[var.starter_locations[9]].zones, null)) starter_location_01_virtual_network_gateway_sku = local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[0]].express_route starter_location_02_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[1]].express_route, null) starter_location_03_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[2]].express_route, null) @@ -31,9 +31,9 @@ locals { starter_location_08_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[7]].express_route, null) starter_location_09_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[8]].express_route, null) starter_location_10_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[9]].express_route, null) - root_parent_management_group_id = var.root_parent_management_group_id == "" ? data.azurerm_client_config.current.tenant_id : var.root_parent_management_group_id - subscription_id_connectivity = var.subscription_id_connectivity - subscription_id_identity = var.subscription_id_identity - subscription_id_management = var.subscription_id_management + root_parent_management_group_id = var.root_parent_management_group_id == "" ? data.azurerm_client_config.current.tenant_id : var.root_parent_management_group_id + subscription_id_connectivity = var.subscription_id_connectivity + subscription_id_identity = var.subscription_id_identity + subscription_id_management = var.subscription_id_management } } \ No newline at end of file diff --git a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf index a4f04d55..d2b7c024 100644 --- a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf @@ -10,13 +10,13 @@ locals { } locals { - hub_and_spoke_vnet_settings_json = tostring(jsonencode(var.hub_and_spoke_vnet_settings)) + hub_and_spoke_vnet_settings_json = tostring(jsonencode(var.hub_and_spoke_vnet_settings)) hub_and_spoke_vnet_settings_json_templated = templatestring(local.hub_and_spoke_vnet_settings_json, local.config_template_file_variables) - hub_and_spoke_vnet_settings_json_final = replace(replace(local.hub_and_spoke_vnet_settings_json_templated, "\"[", "["), "]\"", "]") - hub_and_spoke_vnet_settings = jsondecode(local.hub_and_spoke_vnet_settings_json_final) + hub_and_spoke_vnet_settings_json_final = replace(replace(local.hub_and_spoke_vnet_settings_json_templated, "\"[", "["), "]\"", "]") + hub_and_spoke_vnet_settings = jsondecode(local.hub_and_spoke_vnet_settings_json_final) - hub_and_spoke_vnet_virtual_json = tostring(jsonencode(var.hub_and_spoke_vnet_virtual_networks)) + hub_and_spoke_vnet_virtual_json = tostring(jsonencode(var.hub_and_spoke_vnet_virtual_networks)) hub_and_spoke_vnet_virtual_json_templated = templatestring(local.hub_and_spoke_vnet_virtual_json, local.config_template_file_variables) - hub_and_spoke_vnet_virtual_json_final = replace(replace(local.hub_and_spoke_vnet_virtual_json_templated, "\"[", "["), "]\"", "]") - hub_and_spoke_vnet_virtual_networks = local.connectivity_hub_and_spoke_vnet_enabled ? jsondecode(local.hub_and_spoke_vnet_virtual_json_final) : {} + hub_and_spoke_vnet_virtual_json_final = replace(replace(local.hub_and_spoke_vnet_virtual_json_templated, "\"[", "["), "]\"", "]") + hub_and_spoke_vnet_virtual_networks = local.connectivity_hub_and_spoke_vnet_enabled ? jsondecode(local.hub_and_spoke_vnet_virtual_json_final) : {} } diff --git a/templates/complete_multi_region/locals-management.tf b/templates/complete_multi_region/locals-management.tf index 57ec315d..9c7bf230 100644 --- a/templates/complete_multi_region/locals-management.tf +++ b/templates/complete_multi_region/locals-management.tf @@ -1,13 +1,13 @@ locals { - management_settings_es_json = tostring(jsonencode(var.management_settings_es)) + management_settings_es_json = tostring(jsonencode(var.management_settings_es)) management_settings_es_json_templated = templatestring(local.management_settings_es_json, local.config_template_file_variables) - management_settings_es_json_final = replace(replace(local.management_settings_es_json_templated, "\"[", "["), "]\"", "]") - management_settings_es = jsondecode(local.management_settings_es_json_final) + management_settings_es_json_final = replace(replace(local.management_settings_es_json_templated, "\"[", "["), "]\"", "]") + management_settings_es = jsondecode(local.management_settings_es_json_final) } locals { - management_settings_avm_json = tostring(jsonencode(var.management_settings_avm)) + management_settings_avm_json = tostring(jsonencode(var.management_settings_avm)) management_settings_avm_json_templated = templatestring(local.management_settings_avm_json, local.config_template_file_variables) - management_settings_avm_json_final = replace(replace(local.management_settings_avm_json_templated, "\"[", "["), "]\"", "]") - management_settings_avm = jsondecode(local.management_settings_avm_json_final) + management_settings_avm_json_final = replace(replace(local.management_settings_avm_json_templated, "\"[", "["), "]\"", "]") + management_settings_avm = jsondecode(local.management_settings_avm_json_final) } diff --git a/templates/complete_multi_region/locals-resource-groups.tf b/templates/complete_multi_region/locals-resource-groups.tf index dbc2ec7a..d71ca86a 100644 --- a/templates/complete_multi_region/locals-resource-groups.tf +++ b/templates/complete_multi_region/locals-resource-groups.tf @@ -1,31 +1,6 @@ locals { - resource_groups_hub_and_spoke_vnet = local.connectivity_hub_and_spoke_vnet_enabled ? merge({ - for key, value in local.hub_and_spoke_vnet_virtual_networks : key => { - name = value.hub_virtual_network.resource_group_name - location = value.hub_virtual_network.location - }},{ - for key, value in local.virtual_wan_virtual_hubs : key => { - name = value.private_dns_zones.resource_group_name - location = value.hub_virtual_network.location - } if can(value.private_dns_zones.resource_group_name) - } - ) : {} - - resource_groups_virtual_wan = local.connectivity_virtual_wan_enabled ? merge({ core = { - name = local.virtual_wan_settings.resource_group_name - location = local.primary_location - } }, { - for key, value in local.virtual_wan_virtual_hubs : key => { - name = value.resource_group_name - location = value.location - } if value.resource_group_name != local.virtual_wan_settings.resource_group_name - } ,{ - for key, value in local.virtual_wan_virtual_hubs : key => { - name = value.private_dns_zones.resource_group_name - location = value.location - } if can(value.private_dns_zones.resource_group_name) - } - ) : {} - - resource_groups = merge(local.resource_groups_hub_and_spoke_vnet, local.resource_groups_virtual_wan) + connectivity_resource_groups_json = tostring(jsonencode(var.connectivity_resource_groups)) + connectivity_resource_groups_json_templated = templatestring(local.connectivity_resource_groups_json, local.config_template_file_variables) + connectivity_resource_groups_json_final = replace(replace(local.connectivity_resource_groups_json_templated, "\"[", "["), "]\"", "]") + connectivity_resource_groups = jsondecode(local.connectivity_resource_groups_json_final) } \ No newline at end of file diff --git a/templates/complete_multi_region/locals-virtual-wan.tf b/templates/complete_multi_region/locals-virtual-wan.tf index 57f07a74..83aa993d 100644 --- a/templates/complete_multi_region/locals-virtual-wan.tf +++ b/templates/complete_multi_region/locals-virtual-wan.tf @@ -1,11 +1,11 @@ locals { - virtual_wan_settings_json = tostring(jsonencode(var.virtual_wan_settings)) + virtual_wan_settings_json = tostring(jsonencode(var.virtual_wan_settings)) virtual_wan_settings_json_templated = templatestring(local.virtual_wan_settings_json, local.config_template_file_variables) - virtual_wan_settings_json_final = replace(replace(local.virtual_wan_settings_json_templated, "\"[", "["), "]\"", "]") - virtual_wan_settings = local.connectivity_virtual_wan_enabled ? jsondecode(local.virtual_wan_settings_json_final) : null + virtual_wan_settings_json_final = replace(replace(local.virtual_wan_settings_json_templated, "\"[", "["), "]\"", "]") + virtual_wan_settings = local.connectivity_virtual_wan_enabled ? jsondecode(local.virtual_wan_settings_json_final) : null - virtual_wan_virtual_hubs_json = tostring(jsonencode(var.virtual_wan_virtual_hubs)) + virtual_wan_virtual_hubs_json = tostring(jsonencode(var.virtual_wan_virtual_hubs)) virtual_wan_virtual_hubs_json_templated = templatestring(local.virtual_wan_virtual_hubs_json, local.config_template_file_variables) - virtual_wan_virtual_hubs_json_final = replace(replace(local.virtual_wan_virtual_hubs_json_templated, "\"[", "["), "]\"", "]") - virtual_wan_virtual_hubs = local.connectivity_virtual_wan_enabled ? jsondecode(local.virtual_wan_virtual_hubs_json_final) : {} + virtual_wan_virtual_hubs_json_final = replace(replace(local.virtual_wan_virtual_hubs_json_templated, "\"[", "["), "]\"", "]") + virtual_wan_virtual_hubs = local.connectivity_virtual_wan_enabled ? jsondecode(local.virtual_wan_virtual_hubs_json_final) : {} } diff --git a/templates/complete_multi_region/management.tf b/templates/complete_multi_region/management.tf index 71c782f2..5b0c7c4f 100644 --- a/templates/complete_multi_region/management.tf +++ b/templates/complete_multi_region/management.tf @@ -1,10 +1,10 @@ module "management_groups" { - source = "./modules/management-es" + source = "./modules/management-es" count = var.management_use_avm ? 0 : 1 enable_telemetry = var.enable_telemetry - settings = local.management_settings_es + settings = local.management_settings_es providers = { azurerm = azurerm diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf index 551007a3..450e52bc 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf @@ -6,15 +6,15 @@ locals { } virtual_network_gateways_express_route = { for hub_network_key, hub_network_value in var.hub_virtual_networks : "${hub_network_key}-express-route" => { - hub_network_key = hub_network_key + hub_network_key = hub_network_key virtual_network_gateway = hub_network_value.virtual_network_gateways.express_route } if can(hub_network_value.virtual_network_gateways.express_route) } virtual_network_gateways_vpn = { for hub_network_key, hub_network_value in var.hub_virtual_networks : "${hub_network_key}-vpn" => { - hub_network_key = hub_network_key + hub_network_key = hub_network_key virtual_network_gateway = hub_network_value.virtual_network_gateways.vpn - } if can(hub_network_value.virtual_network_gateways.vpn) + } if can(hub_network_value.virtual_network_gateways.vpn) } virtual_network_gateways = merge(local.virtual_network_gateways_express_route, local.virtual_network_gateways_vpn) } @@ -23,7 +23,7 @@ locals { private_dns_zones = { for key, value in var.hub_virtual_networks : key => merge({ location = value.hub_virtual_network.location }, value.private_dns_zones) if can(value.private_dns_zones) } - + private_dns_zones_virtual_network_links = { for key, value in module.hub_and_spoke_vnet.virtual_networks : key => { vnet_resource_id = value.id @@ -52,6 +52,6 @@ locals { } locals { - ddos_protection_plan = can(var.hub_and_spoke_networks_settings.ddos_protection_plan) ? var.hub_and_spoke_networks_settings.ddos_protection_plan : null + ddos_protection_plan = can(var.hub_and_spoke_networks_settings.ddos_protection_plan) ? var.hub_and_spoke_networks_settings.ddos_protection_plan : null ddos_protection_plan_enabled = local.ddos_protection_plan != null } diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf index d42beebf..f8a12655 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf @@ -61,10 +61,10 @@ module "private_dns_zones" { module "ddos_protection_plan" { source = "Azure/avm-res-network-ddosprotectionplan/azurerm" version = "0.2.0" - + count = local.ddos_protection_plan_enabled ? 1 : 0 - name = local.ddos_protection_plan.name + name = local.ddos_protection_plan.name resource_group_name = local.ddos_protection_plan.resource_group_name - location = local.ddos_protection_plan.location + location = local.ddos_protection_plan.location } diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf index 1dd560fe..792bff94 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf @@ -7,7 +7,7 @@ variable "hub_virtual_networks" { hub_virtual_network = any virtual_network_gateways = optional(object({ express_route = optional(any) - vpn = optional(any) + vpn = optional(any) })) private_dns_zones = optional(object({ resource_group_name = string diff --git a/templates/complete_multi_region/modules/virtual-wan/locals.tf b/templates/complete_multi_region/modules/virtual-wan/locals.tf index 4ec01c75..78e2f6e8 100644 --- a/templates/complete_multi_region/modules/virtual-wan/locals.tf +++ b/templates/complete_multi_region/modules/virtual-wan/locals.tf @@ -22,26 +22,26 @@ locals { name = "private_dns_vnet_${key}" virtual_hub_key = key remote_virtual_network_id = module.virtual_network_private_dns[key].resource_id - }} + } } virtual_network_connections = merge(local.virtual_network_connections_input, local.virtual_network_connections_private_dns) } locals { firewall_policies = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => merge({ - location = virtual_hub_value.location + location = virtual_hub_value.location resource_group_name = virtual_hub_value.resource_group_name firewall_policy_dns = { servers = [module.dns_resolver[virtual_hub_key].inbound_endpoint_ips["dns"]] proxy_enabled = true } - }, virtual_hub_value) if can(virtual_hub_value.firewall_policy) } - + }, virtual_hub_value) if can(virtual_hub_value.firewall_policy) } + firewalls = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => merge( { - virtual_hub_key = virtual_hub_key - location = virtual_hub_value.location - firewall_policy_id = module.firewall_policy[virtual_hub_key].resource_id + virtual_hub_key = virtual_hub_key + location = virtual_hub_value.location + firewall_policy_id = module.firewall_policy[virtual_hub_key].resource_id }, virtual_hub_value.firewall) if can(virtual_hub_value.firewall) } @@ -80,6 +80,6 @@ locals { } locals { - ddos_protection_plan = can(var.virtual_wan_settings.ddos_protection_plan) ? var.virtual_wan_settings.ddos_protection_plan : null + ddos_protection_plan = can(var.virtual_wan_settings.ddos_protection_plan) ? var.virtual_wan_settings.ddos_protection_plan : null ddos_protection_plan_enabled = local.ddos_protection_plan != null } diff --git a/templates/complete_multi_region/modules/virtual-wan/main.tf b/templates/complete_multi_region/modules/virtual-wan/main.tf index 63e3eb23..35c6789b 100644 --- a/templates/complete_multi_region/modules/virtual-wan/main.tf +++ b/templates/complete_multi_region/modules/virtual-wan/main.tf @@ -10,12 +10,12 @@ module "firewall_policy" { firewall_policy_sku = try(each.value.sku, "Standard") firewall_policy_auto_learn_private_ranges_enabled = try(each.value.auto_learn_private_ranges_enabled, null) firewall_policy_base_policy_id = try(each.value.base_policy_id, null) - firewall_policy_dns = each.value.settings.dns - firewall_policy_threat_intelligence_mode = try(each.value.threat_intelligence_mode, "Alert") - firewall_policy_private_ip_ranges = try(each.value.private_ip_ranges, null) - firewall_policy_threat_intelligence_allowlist = try(each.value.threat_intelligence_allowlist, null) - tags = try(each.value.tags, null) - enable_telemetry = var.enable_telemetry + firewall_policy_dns = each.value.settings.dns + firewall_policy_threat_intelligence_mode = try(each.value.threat_intelligence_mode, "Alert") + firewall_policy_private_ip_ranges = try(each.value.private_ip_ranges, null) + firewall_policy_threat_intelligence_allowlist = try(each.value.threat_intelligence_allowlist, null) + tags = try(each.value.tags, null) + enable_telemetry = var.enable_telemetry } module "virtual_wan" { @@ -59,7 +59,7 @@ module "virtual_network_private_dns" { resource_group_name = each.value.resource_group_name enable_telemetry = var.enable_telemetry ddos_protection_plan = local.ddos_protection_plan_enabled ? { - id = module.ddos_protection_plan[0].resource.id + id = module.ddos_protection_plan[0].resource.id enable = true } : null subnets = { @@ -114,10 +114,10 @@ module "private_dns_zones" { module "ddos_protection_plan" { source = "Azure/avm-res-network-ddosprotectionplan/azurerm" version = "0.2.0" - + count = local.ddos_protection_plan_enabled ? 1 : 0 - name = local.ddos_protection_plan.name + name = local.ddos_protection_plan.name resource_group_name = local.ddos_protection_plan.resource_group_name - location = local.ddos_protection_plan.location + location = local.ddos_protection_plan.location } diff --git a/templates/complete_multi_region/modules/virtual-wan/variables.tf b/templates/complete_multi_region/modules/virtual-wan/variables.tf index 5c3a4ad2..8ea54fc0 100644 --- a/templates/complete_multi_region/modules/virtual-wan/variables.tf +++ b/templates/complete_multi_region/modules/virtual-wan/variables.tf @@ -4,8 +4,8 @@ variable "virtual_wan_settings" { variable "virtual_hubs" { type = map(object({ - hub = any - firewall = optional(any) + hub = any + firewall = optional(any) firewall_policy = optional(any) private_dns_zones = optional(object({ resource_group_name = string @@ -25,7 +25,7 @@ variable "virtual_hubs" { }) })) })) - + default = {} description = "A map of virtual hubs to create. Detailed information about the virtual hub can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-virtualhub" } diff --git a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf index a9b8b27d..cd9d137d 100644 --- a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf @@ -4,8 +4,8 @@ module "hub_and_spoke_vnet" { count = local.connectivity_hub_and_spoke_vnet_enabled ? 1 : 0 hub_and_spoke_networks_settings = local.hub_and_spoke_vnet_settings - hub_virtual_networks = local.hub_and_spoke_vnet_virtual_networks - enable_telemetry = var.enable_telemetry + hub_virtual_networks = local.hub_and_spoke_vnet_virtual_networks + enable_telemetry = var.enable_telemetry providers = { azurerm = azurerm.connectivity diff --git a/templates/complete_multi_region/networking-virtual-wan.tf b/templates/complete_multi_region/networking-virtual-wan.tf index a22640bd..4bf75949 100644 --- a/templates/complete_multi_region/networking-virtual-wan.tf +++ b/templates/complete_multi_region/networking-virtual-wan.tf @@ -4,8 +4,8 @@ module "virtual_wan" { count = local.connectivity_virtual_wan_enabled ? 1 : 0 virtual_wan_settings = local.virtual_wan_settings - virtual_hubs = local.virtual_wan_virtual_hubs - enable_telemetry = var.enable_telemetry + virtual_hubs = local.virtual_wan_virtual_hubs + enable_telemetry = var.enable_telemetry providers = { azurerm = azurerm.connectivity diff --git a/templates/complete_multi_region/outputs.tf b/templates/complete_multi_region/outputs.tf index e69de29b..f58fcd33 100644 --- a/templates/complete_multi_region/outputs.tf +++ b/templates/complete_multi_region/outputs.tf @@ -0,0 +1,12 @@ +output "yaml" { + value = yamlencode({ + hub_and_spoke_vnet_es = { + management_use_avm = var.management_use_avm + management_settings_es = var.management_settings_es + connectivity_type = var.connectivity_type + connectivity_resource_groups = var.connectivity_resource_groups + hub_and_spoke_vnet_settings = var.hub_and_spoke_vnet_settings + hub_and_spoke_vnet_virtual_networks = var.hub_and_spoke_vnet_virtual_networks + } + }) +} diff --git a/templates/complete_multi_region/resource-groups.tf b/templates/complete_multi_region/resource-groups.tf index fa02fd1a..adaba836 100644 --- a/templates/complete_multi_region/resource-groups.tf +++ b/templates/complete_multi_region/resource-groups.tf @@ -2,7 +2,7 @@ module "resource_groups" { source = "Azure/avm-res-resources-resourcegroup/azurerm" version = "0.1.0" - for_each = local.resource_groups + for_each = local.connectivity_resource_groups name = each.value.name location = each.value.location diff --git a/templates/complete_multi_region/variables-connectivity.tf b/templates/complete_multi_region/variables-connectivity.tf index 08e47b1d..1bc171ee 100644 --- a/templates/complete_multi_region/variables-connectivity.tf +++ b/templates/complete_multi_region/variables-connectivity.tf @@ -7,3 +7,11 @@ variable "connectivity_type" { error_message = "The connectivity type must be either 'hub_and_spoke_vnet', 'virtual_wan' or 'none'" } } + +variable "connectivity_resource_groups" { + type = map(object({ + name = string + location = string + })) + description = "A map of resource groups to create" +} diff --git a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf index 8adeacf5..85eb5189 100644 --- a/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/variables-hub-and-spoke-vnet.tf @@ -1,12 +1,6 @@ variable "hub_and_spoke_vnet_settings" { - type = any - default = { - ddos_protection_plan = { - name = "ddos-$${starter_location_01}" - resource_group_name = "rg-ddos-$${starter_location_01}" - location = "$${starter_location_01}" - } - } + type = any + default = {} } variable "hub_and_spoke_vnet_virtual_networks" { @@ -14,100 +8,10 @@ variable "hub_and_spoke_vnet_virtual_networks" { hub_virtual_network = any virtual_network_gateways = optional(object({ express_route = optional(any) - vpn = optional(any) + vpn = optional(any) })) private_dns_zones = optional(any) })) description = "A map of hub networks to create. Detailed information about the hub network can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-hubnetworking" - default = { - primary = { - hub_virtual_network = { - name = "vnet-hub-$${starter_location_01}" - resource_group_name = "rg-hub-$${starter_location_01}" - location = "$${starter_location_01}" - address_space = ["10.0.0.0/16"] - firewall = { - subnet_address_prefix = "10.0.0.0/24" - name = "fw-hub-$${starter_location_01}" - sku_name = "AZFW_VNet" - sku_tier = "Standard" - zones = "$${starter_location_01_availability_zones}" - default_ip_configuration = { - public_ip_config = { - name = "pip-fw-hub-$${starter_location_01}" - zones = "$${starter_location_01_availability_zones}" - ip_version = "IPv4" - } - } - firewall_policy = { - name = "fwp-hub-$${starter_location_01}" - } - } - } - virtual_network_gateways = { - express_route = { - location = "$${starter_location_01}" - subnet_address_prefix = "10.0.1.0/24" - name = "vgw-hub-expressroute-$${starter_location_01}" - type = "ExpressRoute" - sku = "$${starter_location_01_virtual_network_gateway_sku}" - } - vpn = { - location = "$${starter_location_01}" - subnet_address_prefix = "10.0.2.0/24" - name = "vgw-hub-vpn-$${starter_location_01}" - type = "Vpn" - sku = "$${starter_location_01_virtual_network_gateway_sku}" - } - } - private_dns_zones = { - resource_group_name = "rg-hub-dns-$${starter_location_01}" - is_primary = true - } - } - secondary = { - hub_virtual_network = { - name = "vnet-hub-$${starter_location_02}" - resource_group_name = "rg-hub-$${starter_location_02}" - location = "$${starter_location_02}" - address_space = ["10.1.0.0/16"] - firewall = { - subnet_address_prefix = "10.1.0.0/24" - name = "fw-hub-$${starter_location_02}" - sku_name = "AZFW_VNet" - sku_tier = "Standard" - zones = "$${starter_location_02_availability_zones}" - default_ip_configuration = { - public_ip_config = { - name = "pip-fw-hub-$${starter_location_02}" - zones = "$${starter_location_02_availability_zones}" - ip_version = "IPv4" - } - } - firewall_policy = { - name = "fwp-hub-$${starter_location_01}" - } - } - } - virtual_network_gateways = { - express_route = { - location = "$${starter_location_02}" - subnet_address_prefix = "10.1.1.0/24" - name = "vgw-hub-expressroute-$${starter_location_02}" - type = "ExpressRoute" - sku = "$${starter_location_02_virtual_network_gateway_sku}" - } - vpn = { - location = "$${starter_location_02}" - subnet_address_prefix = "10.1.2.0/24" - name = "vgw-hub-vpn-$${starter_location_02}" - type = "Vpn" - sku = "$${starter_location_02_virtual_network_gateway_sku}" - } - } - private_dns_zones = { - resource_group_name = "rg-hub-dns-$${starter_location_01}" - } - } - } + default = {} } diff --git a/templates/complete_multi_region/variables-virtual-wan.tf b/templates/complete_multi_region/variables-virtual-wan.tf index 40648075..6b36d777 100644 --- a/templates/complete_multi_region/variables-virtual-wan.tf +++ b/templates/complete_multi_region/variables-virtual-wan.tf @@ -1,92 +1,14 @@ variable "virtual_wan_settings" { - type = any - default = { - name = "vwan-$${starter_location_01}" - resource_group_name = "rg-vwan-$${starter_location_01}" - location = "$${starter_location_01}" - ddos_protection_plan = { - name = "ddos-$${starter_location_01}" - resource_group_name = "rg-ddos-$${starter_location_01}" - location = "$${starter_location_01}" - } - } + type = any + default = {} } variable "virtual_wan_virtual_hubs" { type = map(object({ - hub = any - firewall = optional(any) + hub = any + firewall = optional(any) private_dns_zones = optional(any) })) - default = { - primary = { - hub = { - name = "vwan-hub-$${starter_location_01}" - resource_group_name = "rg-vwan-hub-$${starter_location_01}" - location = "$${starter_location_01}" - address_prefix = "10.0.0.0/16" - } - firewall = { - name = "fw-hub-$${starter_location_01}" - sku_name = "AZFW_Hub" - sku_tier = "Standard" - zones = "$${starter_location_01_availability_zones}" - firewall_policy = { - name = "fwp-hub-$${starter_location_01}" - } - } - private_dns_zones = { - resource_group_name = "rg-vwan-dns-$${starter_location_01}" - is_primary = true - networking = { - virtual_network = { - name = "vnet-hub-dns-$${starter_location_01}" - address_space = "10.10.0.0/24" - private_dns_resolver_subnet = { - name = "subnet-hub-dns-$${starter_location_01}" - address_prefix = "10.10.0.0/28" - } - } - private_dns_resolver = { - name = "pdr-hub-dns-$${starter_location_01}" - } - } - } - } - secondary = { - hub = { - name = "vwan-hub-$${starter_location_02}" - resource_group_name = "rg-vwan-hub-$${starter_location_02}" - location = "$${starter_location_02}" - address_prefix = "10.1.0.0/16" - } - firewall = { - name = "fw-hub-$${starter_location_02}" - sku_name = "AZFW_Hub" - sku_tier = "Standard" - zones = "$${starter_location_02_availability_zones}" - firewall_policy = { - name = "fwp-hub-$${starter_location_02}" - } - } - private_dns_zones = { - resource_group_name = "rg-vwan-dns-$${starter_location_01}" - is_primary = false - networking = { - virtual_network = { - name = "vnet-hub-dns-$${starter_location_02}" - address_space = "10.11.0.0/24" - private_dns_resolver_subnet = { - name = "subnet-hub-dns-$${starter_location_02}" - address_prefix = "10.11.0.0/28" - } - } - private_dns_resolver = { - name = "pdr-hub-dns-$${starter_location_02}" - } - } - } - } - } + default = {} description = "A map of virtual hubs to create. Detailed information about the virtual hub can be found in the module's README: https://registry.terraform.io/modules/Azure/avm-ptn-virtualhub" } diff --git a/templates/complete_multi_region/variables.management.tf b/templates/complete_multi_region/variables.management.tf index e8369ddf..630a97fa 100644 --- a/templates/complete_multi_region/variables.management.tf +++ b/templates/complete_multi_region/variables.management.tf @@ -11,74 +11,5 @@ variable "management_settings_avm" { variable "management_settings_es" { type = any - default = { - default_location = "$${starter_location_01}" - root_parent_id = "$${root_parent_management_group_id}" - root_id = "alz" - root_name = "Azure-Landing-Zones" - subscription_id_connectivity = "$${subscription_id_connectivity}" - subscription_id_identity = "$${subscription_id_identity}" - subscription_id_management = "$${subscription_id_management}" - deploy_connectivity_resources = false - configure_connectivity_resources = { - settings = { - dns = { - config = { - location = "$${starter_location_01}" - } - } - ddos_protection_plan = { - config = { - location = "$${starter_location_01}" - } - } - } - advanced = { - custom_settings_by_resource_type = { - azurerm_resource_group = { - dns = { - ("$${starter_location_01}") = { - name = "rg-dns-$${starter_location_01}" - } - } - ddos = { - ("$${starter_location_01}") = { - name = "rg-ddos-$${starter_location_01}" - } - } - } - azurerm_network_ddos_protection_plan = { - ddos = { - ("$${starter_location_01}") = { - name = "ddos-$${starter_location_01}" - } - } - } - } - } - } - configure_management_resources = { - location = "$${starter_location_01}" - advanced = { - asc_export_resource_group_name = "rg-management-asc-export-$${starter_location_01}" - custom_settings_by_resource_type = { - azurerm_resource_group = { - management = { - name = "rg-management-$${starter_location_01}" - } - } - } - azurerm_log_analytics_workspace = { - management = { - name = "law-management-$${starter_location_01}" - } - } - azurerm_automation_account = { - management = { - name = "aa-management-$${starter_location_01}" - } - } - } - } - } + default = {} } \ No newline at end of file From a10456c455a9343e4224d601b4ae40ceb58459ef Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Mon, 7 Oct 2024 15:45:03 +0100 Subject: [PATCH 09/23] Bug fixes and yaml output --- ...onfig-hub-and-spoke-vnet-multi-region.yaml | 180 ++++++++++++++++++ .../modules/hub-and-spoke-vnet/main.tf | 9 +- templates/complete_multi_region/outputs.tf | 12 -- templates/complete_multi_region/yaml.tf | 43 +++++ 4 files changed, 227 insertions(+), 17 deletions(-) create mode 100644 templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml delete mode 100644 templates/complete_multi_region/outputs.tf create mode 100644 templates/complete_multi_region/yaml.tf diff --git a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml new file mode 100644 index 00000000..ad62f4c8 --- /dev/null +++ b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml @@ -0,0 +1,180 @@ +# This file contains templated variables to avoid repeating the same hard-coded values. +# Templated variables are denoted by the dollar curly braces token (e.g. ${starter_location_01}). The following details each templated variable that you can use: +# `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. +# `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. +# `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. +# `starter_location_01_virtual_network_gateway_sku` to `starter_location_10_virtual_network_gateway_sku`: These are the default SKUs for the virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. +# `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. +# `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. +# `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. +# `subscription_id_management`: The subscription ID of the subscription to deploy the management resources to, sourced from the variable `subscription_id_management`. + +connectivity_resource_groups: + ddos: + location: ${starter_location_01} + name: rg-hub-ddos-${starter_location_01} + dns: + location: ${starter_location_01} + name: rg-hub-dns-${starter_location_01} + vnet_primary: + location: ${starter_location_01} + name: rg-hub-${starter_location_01} + vnet_secondary: + location: ${starter_location_02} + name: rg-hub-${starter_location_02} +connectivity_type: hub_and_spoke_vnet +hub_and_spoke_vnet_settings: + ddos_protection_plan: + location: ${starter_location_01} + name: ddos-hub-${starter_location_01} + resource_group_name: rg-hub-ddos-${starter_location_01} +hub_and_spoke_vnet_virtual_networks: + primary: + hub_virtual_network: + address_space: + - 10.0.0.0/16 + firewall: + default_ip_configuration: + public_ip_config: + ip_version: IPv4 + name: pip-fw-hub-${starter_location_01} + zones: ${starter_location_01_availability_zones} + firewall_policy: + name: fwp-hub-${starter_location_01} + name: fw-hub-${starter_location_01} + sku_name: AZFW_VNet + sku_tier: Standard + subnet_address_prefix: 10.0.0.0/24 + zones: ${starter_location_01_availability_zones} + location: ${starter_location_01} + name: vnet-hub-${starter_location_01} + resource_group_creation_enabled: false + resource_group_name: rg-hub-${starter_location_01} + subnets: + virtual_network_gateway: + address_prefixes: + - 10.0.1.0/24 + name: GatewaySubnet + private_dns_zones: + is_primary: true + resource_group_name: rg-hub-dns-${starter_location_01} + virtual_network_gateways: + express_route: + ip_configurations: + default: + name: ipconfig-vgw-hub-expressroute-${starter_location_01} + public_ip: + name: pip-vgw-hub-expressroute-${starter_location_01} + zones: ${starter_location_01_availability_zones} + location: ${starter_location_01} + name: vgw-hub-expressroute-${starter_location_01} + sku: ${starter_location_01_virtual_network_gateway_sku} + type: ExpressRoute + vpn: + ip_configurations: + default: + name: ipconfig-vgw-hub-vpn-${starter_location_01} + public_ip: + name: pip-vgw-hub-vpn-${starter_location_01} + zones: ${starter_location_01_availability_zones} + location: ${starter_location_01} + name: vgw-hub-vpn-${starter_location_01} + sku: ${starter_location_01_virtual_network_gateway_sku} + type: Vpn + secondary: + hub_virtual_network: + address_space: + - 10.1.0.0/16 + firewall: + default_ip_configuration: + public_ip_config: + ip_version: IPv4 + name: pip-fw-hub-${starter_location_02} + zones: ${starter_location_02_availability_zones} + firewall_policy: + name: fwp-hub-${starter_location_01} + name: fw-hub-${starter_location_02} + sku_name: AZFW_VNet + sku_tier: Standard + subnet_address_prefix: 10.1.0.0/24 + zones: ${starter_location_02_availability_zones} + location: ${starter_location_02} + name: vnet-hub-${starter_location_02} + resource_group_creation_enabled: false + resource_group_name: rg-hub-${starter_location_02} + subnets: + virtual_network_gateway: + address_prefixes: + - 10.1.1.0/24 + name: GatewaySubnet + private_dns_zones: + is_primary: false + resource_group_name: rg-hub-dns-${starter_location_01} + virtual_network_gateways: + express_route: + ip_configurations: + default: + name: ipconfig-vgw-hub-expressroute-${starter_location_02} + public_ip: + name: pip-vgw-hub-expressroute-${starter_location_02} + zones: ${starter_location_02_availability_zones} + location: ${starter_location_02} + name: vgw-hub-expressroute-${starter_location_02} + sku: ${starter_location_02_virtual_network_gateway_sku} + type: ExpressRoute + vpn: + ip_configurations: + default: + name: ipconfig-vgw-hub-vpn-${starter_location_02} + public_ip: + name: pip-vgw-hub-vpn-${starter_location_02} + zones: ${starter_location_02_availability_zones} + location: ${starter_location_02} + name: vgw-hub-vpn-${starter_location_02} + sku: ${starter_location_02_virtual_network_gateway_sku} + type: Vpn +management_settings_es: + configure_connectivity_resources: + advanced: + custom_settings_by_resource_type: + azurerm_network_ddos_protection_plan: + ddos: + ${starter_location_01}: + name: ddos-hub-${starter_location_01} + azurerm_resource_group: + ddos: + ${starter_location_01}: + name: rg-hub-ddos-${starter_location_01} + dns: + ${starter_location_01}: + name: rg-hub-dns-${starter_location_01} + settings: + ddos_protection_plan: + config: + location: ${starter_location_01} + dns: + config: + location: ${starter_location_01} + configure_management_resources: + advanced: + asc_export_resource_group_name: rg-management-asc-export-${starter_location_01} + azurerm_automation_account: + management: + name: aa-management-${starter_location_01} + azurerm_log_analytics_workspace: + management: + name: law-management-${starter_location_01} + custom_settings_by_resource_type: + azurerm_resource_group: + management: + name: rg-management-${starter_location_01} + location: ${starter_location_01} + default_location: ${starter_location_01} + deploy_connectivity_resources: false + root_id: alz + root_name: Azure-Landing-Zones + root_parent_id: ${root_parent_management_group_id} + subscription_id_connectivity: ${subscription_id_connectivity} + subscription_id_identity: ${subscription_id_identity} + subscription_id_management: ${subscription_id_management} +management_use_avm: false diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf index f8a12655..bf174af7 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/main.tf @@ -8,7 +8,7 @@ module "hub_and_spoke_vnet" { module "virtual_network_gateway" { source = "Azure/avm-ptn-vnetgateway/azurerm" - version = "0.3.1" + version = "0.5.0" for_each = local.virtual_network_gateways @@ -17,14 +17,13 @@ module "virtual_network_gateway" { sku = each.value.virtual_network_gateway.sku type = each.value.virtual_network_gateway.type virtual_network_id = module.hub_and_spoke_vnet.virtual_networks[each.value.hub_network_key].id - default_tags = var.tags - subnet_creation_enabled = try(each.value.virtual_network_gateway.subnet_creation_enabled, null) + tags = var.tags + subnet_creation_enabled = try(each.value.virtual_network_gateway.subnet_creation_enabled, false) edge_zone = try(each.value.virtual_network_gateway.edge_zone, null) express_route_circuits = try(each.value.virtual_network_gateway.express_route_circuits, null) ip_configurations = try(each.value.virtual_network_gateway.ip_configurations, null) local_network_gateways = try(each.value.virtual_network_gateway.local_network_gateways, null) - subnet_address_prefix = each.value.virtual_network_gateway.subnet_address_prefix - tags = try(each.value.virtual_network_gateway.tags, null) + subnet_address_prefix = try(each.value.virtual_network_gateway.subnet_address_prefix, null) vpn_active_active_enabled = try(each.value.virtual_network_gateway.vpn_active_active_enabled, null) vpn_bgp_enabled = try(each.value.virtual_network_gateway.vpn_bgp_enabled, null) vpn_bgp_settings = try(each.value.virtual_network_gateway.vpn_bgp_settings, null) diff --git a/templates/complete_multi_region/outputs.tf b/templates/complete_multi_region/outputs.tf deleted file mode 100644 index f58fcd33..00000000 --- a/templates/complete_multi_region/outputs.tf +++ /dev/null @@ -1,12 +0,0 @@ -output "yaml" { - value = yamlencode({ - hub_and_spoke_vnet_es = { - management_use_avm = var.management_use_avm - management_settings_es = var.management_settings_es - connectivity_type = var.connectivity_type - connectivity_resource_groups = var.connectivity_resource_groups - hub_and_spoke_vnet_settings = var.hub_and_spoke_vnet_settings - hub_and_spoke_vnet_virtual_networks = var.hub_and_spoke_vnet_virtual_networks - } - }) -} diff --git a/templates/complete_multi_region/yaml.tf b/templates/complete_multi_region/yaml.tf new file mode 100644 index 00000000..8e19519c --- /dev/null +++ b/templates/complete_multi_region/yaml.tf @@ -0,0 +1,43 @@ +locals { + yaml_file_header = < Date: Mon, 7 Oct 2024 16:55:04 +0100 Subject: [PATCH 10/23] Add tfvar files --- .gitignore | 1 - ...fig-hub-and-spoke-vnet-multi-region.tfvars | 252 ++++++++++++++++++ .../config-virtual-wan-multi-region.tfvars | 189 +++++++++++++ 3 files changed, 441 insertions(+), 1 deletion(-) create mode 100644 templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars create mode 100644 templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars diff --git a/.gitignore b/.gitignore index 48c0febe..793d6391 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,6 @@ override.tf.json # example: *tfplan* .terraform.lock.hcl terraform.log -*.tfvars !terraform.tfvars templates/basic/terraform.tfvars templates/test_* diff --git a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars new file mode 100644 index 00000000..582ce8ed --- /dev/null +++ b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars @@ -0,0 +1,252 @@ +# This file contains templated variables to avoid repeating the same hard-coded values. +# Templated variables are denoted by the dollar-dollar curly braces token (e.g. $${starter_location_01}). The following details each templated variable that you can use: +# `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. +# `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. +# `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. +# `starter_location_01_virtual_network_gateway_sku` to `starter_location_10_virtual_network_gateway_sku`: These are the default SKUs for the virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. +# `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. +# `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. +# `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. +# `subscription_id_management`: The subscription ID of the subscription to deploy the management resources to, sourced from the variable `subscription_id_management`. + +management_use_avm = false +management_settings_es = { + default_location = "$${starter_location_01}" + root_parent_id = "$${root_parent_management_group_id}" + root_id = "alz" + root_name = "Azure-Landing-Zones" + subscription_id_connectivity = "$${subscription_id_connectivity}" + subscription_id_identity = "$${subscription_id_identity}" + subscription_id_management = "$${subscription_id_management}" + deploy_connectivity_resources = false + configure_connectivity_resources = { + settings = { + dns = { + config = { + location = "$${starter_location_01}" + } + } + ddos_protection_plan = { + config = { + location = "$${starter_location_01}" + } + } + } + advanced = { + custom_settings_by_resource_type = { + azurerm_resource_group = { + dns = { + ("$${starter_location_01}") = { + name = "rg-hub-dns-$${starter_location_01}" + } + } + ddos = { + ("$${starter_location_01}") = { + name = "rg-hub-ddos-$${starter_location_01}" + } + } + } + azurerm_network_ddos_protection_plan = { + ddos = { + ("$${starter_location_01}") = { + name = "ddos-hub-$${starter_location_01}" + } + } + } + } + } + } + configure_management_resources = { + location = "$${starter_location_01}" + advanced = { + asc_export_resource_group_name = "rg-management-asc-export-$${starter_location_01}" + custom_settings_by_resource_type = { + azurerm_resource_group = { + management = { + name = "rg-management-$${starter_location_01}" + } + } + } + azurerm_log_analytics_workspace = { + management = { + name = "law-management-$${starter_location_01}" + } + } + azurerm_automation_account = { + management = { + name = "aa-management-$${starter_location_01}" + } + } + } + } +} + +connectivity_type = "hub_and_spoke_vnet" + +connectivity_resource_groups = { + ddos = { + name = "rg-hub-ddos-$${starter_location_01}" + location = "$${starter_location_01}" + } + vnet_primary = { + name = "rg-hub-$${starter_location_01}" + location = "$${starter_location_01}" + } + vnet_secondary = { + name = "rg-hub-$${starter_location_02}" + location = "$${starter_location_02}" + } + dns = { + name = "rg-hub-dns-$${starter_location_01}" + location = "$${starter_location_01}" + } +} + +hub_and_spoke_vnet_settings = { + ddos_protection_plan = { + name = "ddos-hub-$${starter_location_01}" + resource_group_name = "rg-hub-ddos-$${starter_location_01}" + location = "$${starter_location_01}" + } +} + +hub_and_spoke_vnet_virtual_networks = { + primary = { + hub_virtual_network = { + name = "vnet-hub-$${starter_location_01}" + resource_group_name = "rg-hub-$${starter_location_01}" + resource_group_creation_enabled = false + location = "$${starter_location_01}" + address_space = ["10.0.0.0/16"] + subnets = { + virtual_network_gateway = { + name = "GatewaySubnet" + address_prefixes = ["10.0.1.0/24"] + assign_generated_route_table = false + } + } + firewall = { + subnet_address_prefix = "10.0.0.0/24" + name = "fw-hub-$${starter_location_01}" + sku_name = "AZFW_VNet" + sku_tier = "Standard" + zones = "$${starter_location_01_availability_zones}" + default_ip_configuration = { + public_ip_config = { + name = "pip-fw-hub-$${starter_location_01}" + zones = "$${starter_location_01_availability_zones}" + ip_version = "IPv4" + } + } + firewall_policy = { + name = "fwp-hub-$${starter_location_01}" + } + } + } + virtual_network_gateways = { + express_route = { + location = "$${starter_location_01}" + name = "vgw-hub-expressroute-$${starter_location_01}" + type = "ExpressRoute" + sku = "$${starter_location_01_virtual_network_gateway_sku}" + ip_configurations = { + default = { + name = "ipconfig-vgw-hub-expressroute-$${starter_location_01}" + public_ip = { + name = "pip-vgw-hub-expressroute-$${starter_location_01}" + zones = "$${starter_location_01_availability_zones}" + } + } + } + } + vpn = { + location = "$${starter_location_01}" + name = "vgw-hub-vpn-$${starter_location_01}" + type = "Vpn" + sku = "$${starter_location_01_virtual_network_gateway_sku}" + ip_configurations = { + default = { + name = "ipconfig-vgw-hub-vpn-$${starter_location_01}" + public_ip = { + name = "pip-vgw-hub-vpn-$${starter_location_01}" + zones = "$${starter_location_01_availability_zones}" + } + } + } + } + } + private_dns_zones = { + resource_group_name = "rg-hub-dns-$${starter_location_01}" + is_primary = true + } + } + secondary = { + hub_virtual_network = { + name = "vnet-hub-$${starter_location_02}" + resource_group_name = "rg-hub-$${starter_location_02}" + resource_group_creation_enabled = false + location = "$${starter_location_02}" + address_space = ["10.1.0.0/16"] + subnets = { + virtual_network_gateway = { + name = "GatewaySubnet" + address_prefixes = ["10.1.1.0/24"] + assign_generated_route_table = false + } + } + firewall = { + subnet_address_prefix = "10.1.0.0/24" + name = "fw-hub-$${starter_location_02}" + sku_name = "AZFW_VNet" + sku_tier = "Standard" + zones = "$${starter_location_02_availability_zones}" + default_ip_configuration = { + public_ip_config = { + name = "pip-fw-hub-$${starter_location_02}" + zones = "$${starter_location_02_availability_zones}" + ip_version = "IPv4" + } + } + firewall_policy = { + name = "fwp-hub-$${starter_location_01}" + } + } + } + virtual_network_gateways = { + express_route = { + location = "$${starter_location_02}" + name = "vgw-hub-expressroute-$${starter_location_02}" + type = "ExpressRoute" + sku = "$${starter_location_02_virtual_network_gateway_sku}" + ip_configurations = { + default = { + name = "ipconfig-vgw-hub-expressroute-$${starter_location_02}" + public_ip = { + name = "pip-vgw-hub-expressroute-$${starter_location_02}" + zones = "$${starter_location_02_availability_zones}" + } + } + } + } + vpn = { + location = "$${starter_location_02}" + name = "vgw-hub-vpn-$${starter_location_02}" + type = "Vpn" + sku = "$${starter_location_02_virtual_network_gateway_sku}" + ip_configurations = { + default = { + name = "ipconfig-vgw-hub-vpn-$${starter_location_02}" + public_ip = { + name = "pip-vgw-hub-vpn-$${starter_location_02}" + zones = "$${starter_location_02_availability_zones}" + } + } + } + } + } + private_dns_zones = { + resource_group_name = "rg-hub-dns-$${starter_location_01}" + is_primary = false + } + } +} diff --git a/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars b/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars new file mode 100644 index 00000000..9b0128f7 --- /dev/null +++ b/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars @@ -0,0 +1,189 @@ +# This file contains templated variables to avoid repeating the same hard-coded values. +# Templated variables are denoted by the dollar-dollar curly braces token (e.g. $${starter_location_01}). The following details each templated variable that you can use: +# `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. +# `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. +# `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. +# `starter_location_01_virtual_network_gateway_sku` to `starter_location_10_virtual_network_gateway_sku`: These are the default SKUs for the virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. +# `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. +# `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. +# `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. +# `subscription_id_management`: The subscription ID of the subscription to deploy the management resources to, sourced from the variable `subscription_id_management`. + +management_use_avm = false +management_settings_es = { + default_location = "$${starter_location_01}" + root_parent_id = "$${root_parent_management_group_id}" + root_id = "alz" + root_name = "Azure-Landing-Zones" + subscription_id_connectivity = "$${subscription_id_connectivity}" + subscription_id_identity = "$${subscription_id_identity}" + subscription_id_management = "$${subscription_id_management}" + deploy_connectivity_resources = false + configure_connectivity_resources = { + settings = { + dns = { + config = { + location = "$${starter_location_01}" + } + } + ddos_protection_plan = { + config = { + location = "$${starter_location_01}" + } + } + } + advanced = { + custom_settings_by_resource_type = { + azurerm_resource_group = { + dns = { + ("$${starter_location_01}") = { + name = "rg-dns-$${starter_location_01}" + } + } + ddos = { + ("$${starter_location_01}") = { + name = "rg-ddos-$${starter_location_01}" + } + } + } + azurerm_network_ddos_protection_plan = { + ddos = { + ("$${starter_location_01}") = { + name = "ddos-$${starter_location_01}" + } + } + } + } + } + } + configure_management_resources = { + location = "$${starter_location_01}" + advanced = { + asc_export_resource_group_name = "rg-management-asc-export-$${starter_location_01}" + custom_settings_by_resource_type = { + azurerm_resource_group = { + management = { + name = "rg-management-$${starter_location_01}" + } + } + } + azurerm_log_analytics_workspace = { + management = { + name = "law-management-$${starter_location_01}" + } + } + azurerm_automation_account = { + management = { + name = "aa-management-$${starter_location_01}" + } + } + } + } +} + +connectivity_type = "virtual_wan" + +connectivity_resource_groups = { + ddos = { + name = "rg-hub-ddos-$${starter_location_01}" + location = "$${starter_location_01}" + } + vwam = { + name = "rg-vwan-$${starter_location_01}" + location = "$${starter_location_01}" + } + vnet_primary = { + name = "rg-vwan-hub-$${starter_location_01}" + location = "$${starter_location_01}" + } + vnet_secondary = { + name = "rg-vwan-hub-$${starter_location_02}" + location = "$${starter_location_02}" + } + dns = { + name = "rg-hub-dns-$${starter_location_01}" + location = "$${starter_location_01}" + } +} + +virtual_wan_settings = { + name = "vwan-hub-$${starter_location_01}" + resource_group_name = "rg-vwan-$${starter_location_01}" + location = "$${starter_location_01}" + ddos_protection_plan = { + name = "ddos-hub-$${starter_location_01}" + resource_group_name = "rg-hub-ddos-$${starter_location_01}" + location = "$${starter_location_01}" + } +} + +virtual_wan_virtual_hubs = { + primary = { + hub = { + name = "vwan-hub-$${starter_location_01}" + resource_group_name = "rg-vwan-hub-$${starter_location_01}" + location = "$${starter_location_01}" + address_prefix = "10.0.0.0/16" + } + firewall = { + name = "fw-hub-$${starter_location_01}" + sku_name = "AZFW_Hub" + sku_tier = "Standard" + zones = "$${starter_location_01_availability_zones}" + firewall_policy = { + name = "fwp-hub-$${starter_location_01}" + } + } + private_dns_zones = { + resource_group_name = "rg-vwan-dns-$${starter_location_01}" + is_primary = true + networking = { + virtual_network = { + name = "vnet-hub-dns-$${starter_location_01}" + address_space = "10.10.0.0/24" + private_dns_resolver_subnet = { + name = "subnet-hub-dns-$${starter_location_01}" + address_prefix = "10.10.0.0/28" + } + } + private_dns_resolver = { + name = "pdr-hub-dns-$${starter_location_01}" + } + } + } + } + secondary = { + hub = { + name = "vwan-hub-$${starter_location_02}" + resource_group_name = "rg-vwan-hub-$${starter_location_02}" + location = "$${starter_location_02}" + address_prefix = "10.1.0.0/16" + } + firewall = { + name = "fw-hub-$${starter_location_02}" + sku_name = "AZFW_Hub" + sku_tier = "Standard" + zones = "$${starter_location_02_availability_zones}" + firewall_policy = { + name = "fwp-hub-$${starter_location_02}" + } + } + private_dns_zones = { + resource_group_name = "rg-vwan-dns-$${starter_location_01}" + is_primary = false + networking = { + virtual_network = { + name = "vnet-hub-dns-$${starter_location_02}" + address_space = "10.11.0.0/24" + private_dns_resolver_subnet = { + name = "subnet-hub-dns-$${starter_location_02}" + address_prefix = "10.11.0.0/28" + } + } + private_dns_resolver = { + name = "pdr-hub-dns-$${starter_location_02}" + } + } + } + } +} From e768dbc48337145cbac63e770b5e71facf958ab8 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Mon, 7 Oct 2024 20:43:57 +0100 Subject: [PATCH 11/23] Bug fixating --- ...fig-hub-and-spoke-vnet-multi-region.tfvars | 1 - ...onfig-hub-and-spoke-vnet-multi-region.yaml | 7 ++---- .../config-virtual-wan-multi-region.tfvars | 1 - .../complete_multi_region/locals-config.tf | 10 -------- .../locals-hub-and-spoke-vnet.tf | 24 +++++++++++++++---- templates/complete_multi_region/yaml.tf | 1 - 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars index 582ce8ed..8571fc7e 100644 --- a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars +++ b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars @@ -3,7 +3,6 @@ # `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. -# `starter_location_01_virtual_network_gateway_sku` to `starter_location_10_virtual_network_gateway_sku`: These are the default SKUs for the virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. # `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. # `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. # `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. diff --git a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml index ad62f4c8..04f7e257 100644 --- a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml +++ b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml @@ -3,7 +3,6 @@ # `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. -# `starter_location_01_virtual_network_gateway_sku` to `starter_location_10_virtual_network_gateway_sku`: These are the default SKUs for the virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. # `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. # `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. # `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. @@ -54,6 +53,7 @@ hub_and_spoke_vnet_virtual_networks: virtual_network_gateway: address_prefixes: - 10.0.1.0/24 + assign_generated_route_table: false name: GatewaySubnet private_dns_zones: is_primary: true @@ -68,7 +68,6 @@ hub_and_spoke_vnet_virtual_networks: zones: ${starter_location_01_availability_zones} location: ${starter_location_01} name: vgw-hub-expressroute-${starter_location_01} - sku: ${starter_location_01_virtual_network_gateway_sku} type: ExpressRoute vpn: ip_configurations: @@ -79,7 +78,6 @@ hub_and_spoke_vnet_virtual_networks: zones: ${starter_location_01_availability_zones} location: ${starter_location_01} name: vgw-hub-vpn-${starter_location_01} - sku: ${starter_location_01_virtual_network_gateway_sku} type: Vpn secondary: hub_virtual_network: @@ -106,6 +104,7 @@ hub_and_spoke_vnet_virtual_networks: virtual_network_gateway: address_prefixes: - 10.1.1.0/24 + assign_generated_route_table: false name: GatewaySubnet private_dns_zones: is_primary: false @@ -120,7 +119,6 @@ hub_and_spoke_vnet_virtual_networks: zones: ${starter_location_02_availability_zones} location: ${starter_location_02} name: vgw-hub-expressroute-${starter_location_02} - sku: ${starter_location_02_virtual_network_gateway_sku} type: ExpressRoute vpn: ip_configurations: @@ -131,7 +129,6 @@ hub_and_spoke_vnet_virtual_networks: zones: ${starter_location_02_availability_zones} location: ${starter_location_02} name: vgw-hub-vpn-${starter_location_02} - sku: ${starter_location_02_virtual_network_gateway_sku} type: Vpn management_settings_es: configure_connectivity_resources: diff --git a/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars b/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars index 9b0128f7..73d5fe91 100644 --- a/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars +++ b/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars @@ -3,7 +3,6 @@ # `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. -# `starter_location_01_virtual_network_gateway_sku` to `starter_location_10_virtual_network_gateway_sku`: These are the default SKUs for the virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. # `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. # `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. # `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. diff --git a/templates/complete_multi_region/locals-config.tf b/templates/complete_multi_region/locals-config.tf index 1666305e..ec406e71 100644 --- a/templates/complete_multi_region/locals-config.tf +++ b/templates/complete_multi_region/locals-config.tf @@ -21,16 +21,6 @@ locals { starter_location_08_availability_zones = jsonencode(try(local.regions[var.starter_locations[7]].zones, null)) starter_location_09_availability_zones = jsonencode(try(local.regions[var.starter_locations[8]].zones, null)) starter_location_10_availability_zones = jsonencode(try(local.regions[var.starter_locations[9]].zones, null)) - starter_location_01_virtual_network_gateway_sku = local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[0]].express_route - starter_location_02_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[1]].express_route, null) - starter_location_03_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[2]].express_route, null) - starter_location_04_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[3]].express_route, null) - starter_location_05_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[4]].express_route, null) - starter_location_06_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[5]].express_route, null) - starter_location_07_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[6]].express_route, null) - starter_location_08_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[7]].express_route, null) - starter_location_09_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[8]].express_route, null) - starter_location_10_virtual_network_gateway_sku = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[9]].express_route, null) root_parent_management_group_id = var.root_parent_management_group_id == "" ? data.azurerm_client_config.current.tenant_id : var.root_parent_management_group_id subscription_id_connectivity = var.subscription_id_connectivity subscription_id_identity = var.subscription_id_identity diff --git a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf index d2b7c024..94d409c6 100644 --- a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf @@ -7,6 +7,22 @@ locals { vpn = "VpnGw1AZ" } } + + hub_and_spoke_vnet_virtual_networks_with_default_gateway_skus = { for key, value in var.hub_and_spoke_vnet_virtual_networks : key => merge( + can(value.virtual_network_gateways.express_route) ? { + virtual_network_gateways = { + express_route = { + sku = local.hub_and_spoke_vnet_gateway_default_skus[key].express_route + } + }}: {}, + can(value.virtual_network_gateways.vpn) ? { + virtual_network_gateways = { + vpn = { + sku = local.hub_and_spoke_vnet_gateway_default_skus[key].vpn + } + }} : {}, + var.hub_and_spoke_vnet_virtual_networks) + } } locals { @@ -15,8 +31,8 @@ locals { hub_and_spoke_vnet_settings_json_final = replace(replace(local.hub_and_spoke_vnet_settings_json_templated, "\"[", "["), "]\"", "]") hub_and_spoke_vnet_settings = jsondecode(local.hub_and_spoke_vnet_settings_json_final) - hub_and_spoke_vnet_virtual_json = tostring(jsonencode(var.hub_and_spoke_vnet_virtual_networks)) - hub_and_spoke_vnet_virtual_json_templated = templatestring(local.hub_and_spoke_vnet_virtual_json, local.config_template_file_variables) - hub_and_spoke_vnet_virtual_json_final = replace(replace(local.hub_and_spoke_vnet_virtual_json_templated, "\"[", "["), "]\"", "]") - hub_and_spoke_vnet_virtual_networks = local.connectivity_hub_and_spoke_vnet_enabled ? jsondecode(local.hub_and_spoke_vnet_virtual_json_final) : {} + hub_and_spoke_vnet_virtual_networks_json = tostring(jsonencode(local.hub_and_spoke_vnet_virtual_networks_with_default_gateway_skus)) + hub_and_spoke_vnet_virtual_networks_json_templated = templatestring(local.hub_and_spoke_vnet_virtual_networks_json, local.config_template_file_variables) + hub_and_spoke_vnet_virtual_networks_json_final = replace(replace(local.hub_and_spoke_vnet_virtual_networks_json_templated, "\"[", "["), "]\"", "]") + hub_and_spoke_vnet_virtual_networks = local.connectivity_hub_and_spoke_vnet_enabled ? jsondecode(local.hub_and_spoke_vnet_virtual_networks_json_final) : {} } diff --git a/templates/complete_multi_region/yaml.tf b/templates/complete_multi_region/yaml.tf index 8e19519c..358d7e98 100644 --- a/templates/complete_multi_region/yaml.tf +++ b/templates/complete_multi_region/yaml.tf @@ -5,7 +5,6 @@ locals { # `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. -# `starter_location_01_virtual_network_gateway_sku` to `starter_location_10_virtual_network_gateway_sku`: These are the default SKUs for the virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. # `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. # `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. # `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. From 367a1ccc2b674c48cef0851ac55630810dfaafa1 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Mon, 7 Oct 2024 21:35:05 +0100 Subject: [PATCH 12/23] Bug fixes --- ...fig-hub-and-spoke-vnet-multi-region.tfvars | 73 ++++++++++--------- ...onfig-hub-and-spoke-vnet-multi-region.yaml | 4 + .../complete_multi_region/locals-config.tf | 68 +++++++++++------ .../locals-hub-and-spoke-vnet.tf | 20 +---- templates/complete_multi_region/yaml.tf | 14 ++-- 5 files changed, 94 insertions(+), 85 deletions(-) diff --git a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars index 8571fc7e..b2d7c5a0 100644 --- a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars +++ b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars @@ -3,6 +3,7 @@ # `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. +# `starter_location_01_virtual_network_gateway_sku` to `starter_location_10_virtual_network_gateway_sku`: These are the default SKUs for the virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. # `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. # `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. # `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. @@ -119,8 +120,8 @@ hub_and_spoke_vnet_virtual_networks = { address_space = ["10.0.0.0/16"] subnets = { virtual_network_gateway = { - name = "GatewaySubnet" - address_prefixes = ["10.0.1.0/24"] + name = "GatewaySubnet" + address_prefixes = ["10.0.1.0/24"] assign_generated_route_table = false } } @@ -144,31 +145,31 @@ hub_and_spoke_vnet_virtual_networks = { } virtual_network_gateways = { express_route = { - location = "$${starter_location_01}" - name = "vgw-hub-expressroute-$${starter_location_01}" - type = "ExpressRoute" - sku = "$${starter_location_01_virtual_network_gateway_sku}" - ip_configurations = { + location = "$${starter_location_01}" + name = "vgw-hub-expressroute-$${starter_location_01}" + type = "ExpressRoute" + sku = "$${starter_location_01_virtual_network_gateway_sku_express_route}" + ip_configurations = { default = { - name = "ipconfig-vgw-hub-expressroute-$${starter_location_01}" + name = "ipconfig-vgw-hub-expressroute-$${starter_location_01}" public_ip = { - name = "pip-vgw-hub-expressroute-$${starter_location_01}" - zones = "$${starter_location_01_availability_zones}" + name = "pip-vgw-hub-expressroute-$${starter_location_01}" + zones = "$${starter_location_01_availability_zones}" } } } } vpn = { - location = "$${starter_location_01}" - name = "vgw-hub-vpn-$${starter_location_01}" - type = "Vpn" - sku = "$${starter_location_01_virtual_network_gateway_sku}" - ip_configurations = { + location = "$${starter_location_01}" + name = "vgw-hub-vpn-$${starter_location_01}" + type = "Vpn" + sku = "$${starter_location_01_virtual_network_gateway_sku_vpn}" + ip_configurations = { default = { - name = "ipconfig-vgw-hub-vpn-$${starter_location_01}" + name = "ipconfig-vgw-hub-vpn-$${starter_location_01}" public_ip = { - name = "pip-vgw-hub-vpn-$${starter_location_01}" - zones = "$${starter_location_01_availability_zones}" + name = "pip-vgw-hub-vpn-$${starter_location_01}" + zones = "$${starter_location_01_availability_zones}" } } } @@ -188,8 +189,8 @@ hub_and_spoke_vnet_virtual_networks = { address_space = ["10.1.0.0/16"] subnets = { virtual_network_gateway = { - name = "GatewaySubnet" - address_prefixes = ["10.1.1.0/24"] + name = "GatewaySubnet" + address_prefixes = ["10.1.1.0/24"] assign_generated_route_table = false } } @@ -213,31 +214,31 @@ hub_and_spoke_vnet_virtual_networks = { } virtual_network_gateways = { express_route = { - location = "$${starter_location_02}" - name = "vgw-hub-expressroute-$${starter_location_02}" - type = "ExpressRoute" - sku = "$${starter_location_02_virtual_network_gateway_sku}" - ip_configurations = { + location = "$${starter_location_02}" + name = "vgw-hub-expressroute-$${starter_location_02}" + type = "ExpressRoute" + sku = "$${starter_location_02_virtual_network_gateway_sku_express_route}" + ip_configurations = { default = { - name = "ipconfig-vgw-hub-expressroute-$${starter_location_02}" + name = "ipconfig-vgw-hub-expressroute-$${starter_location_02}" public_ip = { - name = "pip-vgw-hub-expressroute-$${starter_location_02}" - zones = "$${starter_location_02_availability_zones}" + name = "pip-vgw-hub-expressroute-$${starter_location_02}" + zones = "$${starter_location_02_availability_zones}" } } } } vpn = { - location = "$${starter_location_02}" - name = "vgw-hub-vpn-$${starter_location_02}" - type = "Vpn" - sku = "$${starter_location_02_virtual_network_gateway_sku}" - ip_configurations = { + location = "$${starter_location_02}" + name = "vgw-hub-vpn-$${starter_location_02}" + type = "Vpn" + sku = "$${starter_location_02_virtual_network_gateway_sku_vpn}" + ip_configurations = { default = { - name = "ipconfig-vgw-hub-vpn-$${starter_location_02}" + name = "ipconfig-vgw-hub-vpn-$${starter_location_02}" public_ip = { - name = "pip-vgw-hub-vpn-$${starter_location_02}" - zones = "$${starter_location_02_availability_zones}" + name = "pip-vgw-hub-vpn-$${starter_location_02}" + zones = "$${starter_location_02_availability_zones}" } } } diff --git a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml index 04f7e257..b4062f60 100644 --- a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml +++ b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml @@ -68,6 +68,7 @@ hub_and_spoke_vnet_virtual_networks: zones: ${starter_location_01_availability_zones} location: ${starter_location_01} name: vgw-hub-expressroute-${starter_location_01} + sku: ${starter_location_01_virtual_network_gateway_sku_express_route} type: ExpressRoute vpn: ip_configurations: @@ -78,6 +79,7 @@ hub_and_spoke_vnet_virtual_networks: zones: ${starter_location_01_availability_zones} location: ${starter_location_01} name: vgw-hub-vpn-${starter_location_01} + sku: ${starter_location_01_virtual_network_gateway_sku_vpn} type: Vpn secondary: hub_virtual_network: @@ -119,6 +121,7 @@ hub_and_spoke_vnet_virtual_networks: zones: ${starter_location_02_availability_zones} location: ${starter_location_02} name: vgw-hub-expressroute-${starter_location_02} + sku: ${starter_location_02_virtual_network_gateway_sku_express_route} type: ExpressRoute vpn: ip_configurations: @@ -129,6 +132,7 @@ hub_and_spoke_vnet_virtual_networks: zones: ${starter_location_02_availability_zones} location: ${starter_location_02} name: vgw-hub-vpn-${starter_location_02} + sku: ${starter_location_02_virtual_network_gateway_sku_vpn} type: Vpn management_settings_es: configure_connectivity_resources: diff --git a/templates/complete_multi_region/locals-config.tf b/templates/complete_multi_region/locals-config.tf index ec406e71..5b12b3a4 100644 --- a/templates/complete_multi_region/locals-config.tf +++ b/templates/complete_multi_region/locals-config.tf @@ -1,29 +1,49 @@ locals { primary_location = var.starter_locations[0] config_template_file_variables = { - starter_location_01 = var.starter_locations[0] - starter_location_02 = try(var.starter_locations[1], null) - starter_location_03 = try(var.starter_locations[2], null) - starter_location_04 = try(var.starter_locations[3], null) - starter_location_05 = try(var.starter_locations[4], null) - starter_location_06 = try(var.starter_locations[5], null) - starter_location_07 = try(var.starter_locations[6], null) - starter_location_08 = try(var.starter_locations[7], null) - starter_location_09 = try(var.starter_locations[8], null) - starter_location_10 = try(var.starter_locations[9], null) - starter_location_01_availability_zones = jsonencode(local.regions[var.starter_locations[0]].zones) - starter_location_02_availability_zones = jsonencode(try(local.regions[var.starter_locations[1]].zones, null)) - starter_location_03_availability_zones = jsonencode(try(local.regions[var.starter_locations[2]].zones, null)) - starter_location_04_availability_zones = jsonencode(try(local.regions[var.starter_locations[3]].zones, null)) - starter_location_05_availability_zones = jsonencode(try(local.regions[var.starter_locations[4]].zones, null)) - starter_location_06_availability_zones = jsonencode(try(local.regions[var.starter_locations[5]].zones, null)) - starter_location_07_availability_zones = jsonencode(try(local.regions[var.starter_locations[6]].zones, null)) - starter_location_08_availability_zones = jsonencode(try(local.regions[var.starter_locations[7]].zones, null)) - starter_location_09_availability_zones = jsonencode(try(local.regions[var.starter_locations[8]].zones, null)) - starter_location_10_availability_zones = jsonencode(try(local.regions[var.starter_locations[9]].zones, null)) - root_parent_management_group_id = var.root_parent_management_group_id == "" ? data.azurerm_client_config.current.tenant_id : var.root_parent_management_group_id - subscription_id_connectivity = var.subscription_id_connectivity - subscription_id_identity = var.subscription_id_identity - subscription_id_management = var.subscription_id_management + starter_location_01 = var.starter_locations[0] + starter_location_02 = try(var.starter_locations[1], null) + starter_location_03 = try(var.starter_locations[2], null) + starter_location_04 = try(var.starter_locations[3], null) + starter_location_05 = try(var.starter_locations[4], null) + starter_location_06 = try(var.starter_locations[5], null) + starter_location_07 = try(var.starter_locations[6], null) + starter_location_08 = try(var.starter_locations[7], null) + starter_location_09 = try(var.starter_locations[8], null) + starter_location_10 = try(var.starter_locations[9], null) + starter_location_01_availability_zones = jsonencode(local.regions[var.starter_locations[0]].zones) + starter_location_02_availability_zones = jsonencode(try(local.regions[var.starter_locations[1]].zones, null)) + starter_location_03_availability_zones = jsonencode(try(local.regions[var.starter_locations[2]].zones, null)) + starter_location_04_availability_zones = jsonencode(try(local.regions[var.starter_locations[3]].zones, null)) + starter_location_05_availability_zones = jsonencode(try(local.regions[var.starter_locations[4]].zones, null)) + starter_location_06_availability_zones = jsonencode(try(local.regions[var.starter_locations[5]].zones, null)) + starter_location_07_availability_zones = jsonencode(try(local.regions[var.starter_locations[6]].zones, null)) + starter_location_08_availability_zones = jsonencode(try(local.regions[var.starter_locations[7]].zones, null)) + starter_location_09_availability_zones = jsonencode(try(local.regions[var.starter_locations[8]].zones, null)) + starter_location_10_availability_zones = jsonencode(try(local.regions[var.starter_locations[9]].zones, null)) + starter_location_01_virtual_network_gateway_sku_express_route = local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[0]].express_route + starter_location_02_virtual_network_gateway_sku_express_route = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[1]].express_route, null) + starter_location_03_virtual_network_gateway_sku_express_route = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[2]].express_route, null) + starter_location_04_virtual_network_gateway_sku_express_route = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[3]].express_route, null) + starter_location_05_virtual_network_gateway_sku_express_route = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[4]].express_route, null) + starter_location_06_virtual_network_gateway_sku_express_route = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[5]].express_route, null) + starter_location_07_virtual_network_gateway_sku_express_route = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[6]].express_route, null) + starter_location_08_virtual_network_gateway_sku_express_route = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[7]].express_route, null) + starter_location_09_virtual_network_gateway_sku_express_route = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[8]].express_route, null) + starter_location_10_virtual_network_gateway_sku_express_route = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[9]].express_route, null) + starter_location_01_virtual_network_gateway_sku_vpn = local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[0]].vpn + starter_location_02_virtual_network_gateway_sku_vpn = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[1]].vpn, null) + starter_location_03_virtual_network_gateway_sku_vpn = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[2]].vpn, null) + starter_location_04_virtual_network_gateway_sku_vpn = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[3]].vpn, null) + starter_location_05_virtual_network_gateway_sku_vpn = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[4]].vpn, null) + starter_location_06_virtual_network_gateway_sku_vpn = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[5]].vpn, null) + starter_location_07_virtual_network_gateway_sku_vpn = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[6]].vpn, null) + starter_location_08_virtual_network_gateway_sku_vpn = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[7]].vpn, null) + starter_location_09_virtual_network_gateway_sku_vpn = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[8]].vpn, null) + starter_location_10_virtual_network_gateway_sku_vpn = try(local.hub_and_spoke_vnet_gateway_default_skus[var.starter_locations[9]].vpn, null) + root_parent_management_group_id = var.root_parent_management_group_id == "" ? data.azurerm_client_config.current.tenant_id : var.root_parent_management_group_id + subscription_id_connectivity = var.subscription_id_connectivity + subscription_id_identity = var.subscription_id_identity + subscription_id_management = var.subscription_id_management } } \ No newline at end of file diff --git a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf index 94d409c6..bc6d476f 100644 --- a/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/locals-hub-and-spoke-vnet.tf @@ -7,22 +7,6 @@ locals { vpn = "VpnGw1AZ" } } - - hub_and_spoke_vnet_virtual_networks_with_default_gateway_skus = { for key, value in var.hub_and_spoke_vnet_virtual_networks : key => merge( - can(value.virtual_network_gateways.express_route) ? { - virtual_network_gateways = { - express_route = { - sku = local.hub_and_spoke_vnet_gateway_default_skus[key].express_route - } - }}: {}, - can(value.virtual_network_gateways.vpn) ? { - virtual_network_gateways = { - vpn = { - sku = local.hub_and_spoke_vnet_gateway_default_skus[key].vpn - } - }} : {}, - var.hub_and_spoke_vnet_virtual_networks) - } } locals { @@ -31,8 +15,8 @@ locals { hub_and_spoke_vnet_settings_json_final = replace(replace(local.hub_and_spoke_vnet_settings_json_templated, "\"[", "["), "]\"", "]") hub_and_spoke_vnet_settings = jsondecode(local.hub_and_spoke_vnet_settings_json_final) - hub_and_spoke_vnet_virtual_networks_json = tostring(jsonencode(local.hub_and_spoke_vnet_virtual_networks_with_default_gateway_skus)) + hub_and_spoke_vnet_virtual_networks_json = tostring(jsonencode(var.hub_and_spoke_vnet_virtual_networks)) hub_and_spoke_vnet_virtual_networks_json_templated = templatestring(local.hub_and_spoke_vnet_virtual_networks_json, local.config_template_file_variables) hub_and_spoke_vnet_virtual_networks_json_final = replace(replace(local.hub_and_spoke_vnet_virtual_networks_json_templated, "\"[", "["), "]\"", "]") - hub_and_spoke_vnet_virtual_networks = local.connectivity_hub_and_spoke_vnet_enabled ? jsondecode(local.hub_and_spoke_vnet_virtual_networks_json_final) : {} + hub_and_spoke_vnet_virtual_networks = local.connectivity_hub_and_spoke_vnet_enabled ? jsondecode(local.hub_and_spoke_vnet_virtual_networks_json_final) : {} } diff --git a/templates/complete_multi_region/yaml.tf b/templates/complete_multi_region/yaml.tf index 358d7e98..a5c4da0b 100644 --- a/templates/complete_multi_region/yaml.tf +++ b/templates/complete_multi_region/yaml.tf @@ -22,16 +22,16 @@ YAML }) yaml_file_virtual_wan_es = yamlencode({ - management_use_avm = var.management_use_avm - management_settings_es = var.management_settings_es - connectivity_type = var.connectivity_type - connectivity_resource_groups = var.connectivity_resource_groups - virtual_wan_settings = var.virtual_wan_settings - virtual_wan_virtual_hubs = var.virtual_wan_virtual_hubs + management_use_avm = var.management_use_avm + management_settings_es = var.management_settings_es + connectivity_type = var.connectivity_type + connectivity_resource_groups = var.connectivity_resource_groups + virtual_wan_settings = var.virtual_wan_settings + virtual_wan_virtual_hubs = var.virtual_wan_virtual_hubs }) yaml_file_content = local.connectivity_hub_and_spoke_vnet_enabled ? local.yaml_file_hub_and_spoke_vnet_es : local.yaml_file_virtual_wan_es - yaml_file_final = replace("${local.yaml_file_header}${local.yaml_file_content}", "\"", "") + yaml_file_final = replace("${local.yaml_file_header}${local.yaml_file_content}", "\"", "") yaml_file_name = "config-${replace(var.connectivity_type, "_", "-")}-multi-region.yaml" } From dc353403bd72d43cc92a30dadc1a96519bc00e01 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Mon, 7 Oct 2024 21:43:44 +0100 Subject: [PATCH 13/23] Add missing DNS setting --- .../examples/config-hub-and-spoke-vnet-multi-region.tfvars | 6 ++++++ .../examples/config-hub-and-spoke-vnet-multi-region.yaml | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars index b2d7c5a0..4d3cf6c8 100644 --- a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars +++ b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars @@ -140,6 +140,9 @@ hub_and_spoke_vnet_virtual_networks = { } firewall_policy = { name = "fwp-hub-$${starter_location_01}" + dns = { + proxy_enabled = true + } } } } @@ -209,6 +212,9 @@ hub_and_spoke_vnet_virtual_networks = { } firewall_policy = { name = "fwp-hub-$${starter_location_01}" + dns = { + proxy_enabled = true + } } } } diff --git a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml index b4062f60..d0180668 100644 --- a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml +++ b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml @@ -39,6 +39,8 @@ hub_and_spoke_vnet_virtual_networks: name: pip-fw-hub-${starter_location_01} zones: ${starter_location_01_availability_zones} firewall_policy: + dns: + proxy_enabled: true name: fwp-hub-${starter_location_01} name: fw-hub-${starter_location_01} sku_name: AZFW_VNet @@ -92,6 +94,8 @@ hub_and_spoke_vnet_virtual_networks: name: pip-fw-hub-${starter_location_02} zones: ${starter_location_02_availability_zones} firewall_policy: + dns: + proxy_enabled: true name: fwp-hub-${starter_location_01} name: fw-hub-${starter_location_02} sku_name: AZFW_VNet From 506cdc67ffdbbab30a8e946a66550773afade2a8 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Mon, 7 Oct 2024 21:52:23 +0100 Subject: [PATCH 14/23] Fixes --- ...config-hub-and-spoke-vnet-multi-region.tfvars | 3 ++- .../config-virtual-wan-multi-region.tfvars | 2 ++ .../modules/virtual-wan/locals.tf | 2 +- templates/complete_multi_region/yaml.tf | 16 +++++++++------- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars index 4d3cf6c8..8e382058 100644 --- a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars +++ b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars @@ -3,7 +3,8 @@ # `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. -# `starter_location_01_virtual_network_gateway_sku` to `starter_location_10_virtual_network_gateway_sku`: These are the default SKUs for the virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. +# `starter_location_01_virtual_network_gateway_sku_express_route` to `starter_location_10_virtual_network_gateway_sku_express_route`: These are the default SKUs for the Express Route virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. +# `starter_location_01_virtual_network_gateway_sku_vpn` to `starter_location_10_virtual_network_gateway_sku_vpn`: These are the default SKUs for the VPN virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. # `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. # `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. # `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. diff --git a/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars b/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars index 73d5fe91..16e9bc69 100644 --- a/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars +++ b/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars @@ -3,6 +3,8 @@ # `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. +# `starter_location_01_virtual_network_gateway_sku_express_route` to `starter_location_10_virtual_network_gateway_sku_express_route`: These are the default SKUs for the Express Route virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. +# `starter_location_01_virtual_network_gateway_sku_vpn` to `starter_location_10_virtual_network_gateway_sku_vpn`: These are the default SKUs for the VPN virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. # `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. # `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. # `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. diff --git a/templates/complete_multi_region/modules/virtual-wan/locals.tf b/templates/complete_multi_region/modules/virtual-wan/locals.tf index 78e2f6e8..9cdfafad 100644 --- a/templates/complete_multi_region/modules/virtual-wan/locals.tf +++ b/templates/complete_multi_region/modules/virtual-wan/locals.tf @@ -35,7 +35,7 @@ locals { servers = [module.dns_resolver[virtual_hub_key].inbound_endpoint_ips["dns"]] proxy_enabled = true } - }, virtual_hub_value) if can(virtual_hub_value.firewall_policy) } + }, virtual_hub_value.firewall.firewall_policy) if can(virtual_hub_value.firewall_policy) } firewalls = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => merge( { diff --git a/templates/complete_multi_region/yaml.tf b/templates/complete_multi_region/yaml.tf index a5c4da0b..a1a0428f 100644 --- a/templates/complete_multi_region/yaml.tf +++ b/templates/complete_multi_region/yaml.tf @@ -5,6 +5,8 @@ locals { # `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. # `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. +# `starter_location_01_virtual_network_gateway_sku_express_route` to `starter_location_10_virtual_network_gateway_sku_express_route`: These are the default SKUs for the Express Route virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. +# `starter_location_01_virtual_network_gateway_sku_vpn` to `starter_location_10_virtual_network_gateway_sku_vpn`: These are the default SKUs for the VPN virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways. # `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. # `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. # `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. @@ -22,16 +24,16 @@ YAML }) yaml_file_virtual_wan_es = yamlencode({ - management_use_avm = var.management_use_avm - management_settings_es = var.management_settings_es - connectivity_type = var.connectivity_type - connectivity_resource_groups = var.connectivity_resource_groups - virtual_wan_settings = var.virtual_wan_settings - virtual_wan_virtual_hubs = var.virtual_wan_virtual_hubs + management_use_avm = var.management_use_avm + management_settings_es = var.management_settings_es + connectivity_type = var.connectivity_type + connectivity_resource_groups = var.connectivity_resource_groups + virtual_wan_settings = var.virtual_wan_settings + virtual_wan_virtual_hubs = var.virtual_wan_virtual_hubs }) yaml_file_content = local.connectivity_hub_and_spoke_vnet_enabled ? local.yaml_file_hub_and_spoke_vnet_es : local.yaml_file_virtual_wan_es - yaml_file_final = replace("${local.yaml_file_header}${local.yaml_file_content}", "\"", "") + yaml_file_final = replace("${local.yaml_file_header}${local.yaml_file_content}", "\"", "") yaml_file_name = "config-${replace(var.connectivity_type, "_", "-")}-multi-region.yaml" } From 2723dd1d64c36fbb4888d2cd04ec09a0e7d909bf Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Tue, 8 Oct 2024 10:31:05 +0100 Subject: [PATCH 15/23] Fix VWAN --- ...fig-hub-and-spoke-vnet-multi-region.tfvars | 4 +- ...onfig-hub-and-spoke-vnet-multi-region.yaml | 185 ------------------ .../config-virtual-wan-multi-region.tfvars | 26 +-- .../modules/virtual-wan/locals.tf | 10 +- .../modules/virtual-wan/main.tf | 8 +- .../modules/virtual-wan/variables.tf | 8 +- templates/complete_multi_region/yaml.tf | 14 +- 7 files changed, 38 insertions(+), 217 deletions(-) delete mode 100644 templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml diff --git a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars index 8e382058..fea2c1cb 100644 --- a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars +++ b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.tfvars @@ -141,7 +141,7 @@ hub_and_spoke_vnet_virtual_networks = { } firewall_policy = { name = "fwp-hub-$${starter_location_01}" - dns = { + dns = { proxy_enabled = true } } @@ -213,7 +213,7 @@ hub_and_spoke_vnet_virtual_networks = { } firewall_policy = { name = "fwp-hub-$${starter_location_01}" - dns = { + dns = { proxy_enabled = true } } diff --git a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml b/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml deleted file mode 100644 index d0180668..00000000 --- a/templates/complete_multi_region/examples/config-hub-and-spoke-vnet-multi-region.yaml +++ /dev/null @@ -1,185 +0,0 @@ -# This file contains templated variables to avoid repeating the same hard-coded values. -# Templated variables are denoted by the dollar curly braces token (e.g. ${starter_location_01}). The following details each templated variable that you can use: -# `starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources. -# `starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources. -# `starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources. -# `root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under. -# `subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`. -# `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. -# `subscription_id_management`: The subscription ID of the subscription to deploy the management resources to, sourced from the variable `subscription_id_management`. - -connectivity_resource_groups: - ddos: - location: ${starter_location_01} - name: rg-hub-ddos-${starter_location_01} - dns: - location: ${starter_location_01} - name: rg-hub-dns-${starter_location_01} - vnet_primary: - location: ${starter_location_01} - name: rg-hub-${starter_location_01} - vnet_secondary: - location: ${starter_location_02} - name: rg-hub-${starter_location_02} -connectivity_type: hub_and_spoke_vnet -hub_and_spoke_vnet_settings: - ddos_protection_plan: - location: ${starter_location_01} - name: ddos-hub-${starter_location_01} - resource_group_name: rg-hub-ddos-${starter_location_01} -hub_and_spoke_vnet_virtual_networks: - primary: - hub_virtual_network: - address_space: - - 10.0.0.0/16 - firewall: - default_ip_configuration: - public_ip_config: - ip_version: IPv4 - name: pip-fw-hub-${starter_location_01} - zones: ${starter_location_01_availability_zones} - firewall_policy: - dns: - proxy_enabled: true - name: fwp-hub-${starter_location_01} - name: fw-hub-${starter_location_01} - sku_name: AZFW_VNet - sku_tier: Standard - subnet_address_prefix: 10.0.0.0/24 - zones: ${starter_location_01_availability_zones} - location: ${starter_location_01} - name: vnet-hub-${starter_location_01} - resource_group_creation_enabled: false - resource_group_name: rg-hub-${starter_location_01} - subnets: - virtual_network_gateway: - address_prefixes: - - 10.0.1.0/24 - assign_generated_route_table: false - name: GatewaySubnet - private_dns_zones: - is_primary: true - resource_group_name: rg-hub-dns-${starter_location_01} - virtual_network_gateways: - express_route: - ip_configurations: - default: - name: ipconfig-vgw-hub-expressroute-${starter_location_01} - public_ip: - name: pip-vgw-hub-expressroute-${starter_location_01} - zones: ${starter_location_01_availability_zones} - location: ${starter_location_01} - name: vgw-hub-expressroute-${starter_location_01} - sku: ${starter_location_01_virtual_network_gateway_sku_express_route} - type: ExpressRoute - vpn: - ip_configurations: - default: - name: ipconfig-vgw-hub-vpn-${starter_location_01} - public_ip: - name: pip-vgw-hub-vpn-${starter_location_01} - zones: ${starter_location_01_availability_zones} - location: ${starter_location_01} - name: vgw-hub-vpn-${starter_location_01} - sku: ${starter_location_01_virtual_network_gateway_sku_vpn} - type: Vpn - secondary: - hub_virtual_network: - address_space: - - 10.1.0.0/16 - firewall: - default_ip_configuration: - public_ip_config: - ip_version: IPv4 - name: pip-fw-hub-${starter_location_02} - zones: ${starter_location_02_availability_zones} - firewall_policy: - dns: - proxy_enabled: true - name: fwp-hub-${starter_location_01} - name: fw-hub-${starter_location_02} - sku_name: AZFW_VNet - sku_tier: Standard - subnet_address_prefix: 10.1.0.0/24 - zones: ${starter_location_02_availability_zones} - location: ${starter_location_02} - name: vnet-hub-${starter_location_02} - resource_group_creation_enabled: false - resource_group_name: rg-hub-${starter_location_02} - subnets: - virtual_network_gateway: - address_prefixes: - - 10.1.1.0/24 - assign_generated_route_table: false - name: GatewaySubnet - private_dns_zones: - is_primary: false - resource_group_name: rg-hub-dns-${starter_location_01} - virtual_network_gateways: - express_route: - ip_configurations: - default: - name: ipconfig-vgw-hub-expressroute-${starter_location_02} - public_ip: - name: pip-vgw-hub-expressroute-${starter_location_02} - zones: ${starter_location_02_availability_zones} - location: ${starter_location_02} - name: vgw-hub-expressroute-${starter_location_02} - sku: ${starter_location_02_virtual_network_gateway_sku_express_route} - type: ExpressRoute - vpn: - ip_configurations: - default: - name: ipconfig-vgw-hub-vpn-${starter_location_02} - public_ip: - name: pip-vgw-hub-vpn-${starter_location_02} - zones: ${starter_location_02_availability_zones} - location: ${starter_location_02} - name: vgw-hub-vpn-${starter_location_02} - sku: ${starter_location_02_virtual_network_gateway_sku_vpn} - type: Vpn -management_settings_es: - configure_connectivity_resources: - advanced: - custom_settings_by_resource_type: - azurerm_network_ddos_protection_plan: - ddos: - ${starter_location_01}: - name: ddos-hub-${starter_location_01} - azurerm_resource_group: - ddos: - ${starter_location_01}: - name: rg-hub-ddos-${starter_location_01} - dns: - ${starter_location_01}: - name: rg-hub-dns-${starter_location_01} - settings: - ddos_protection_plan: - config: - location: ${starter_location_01} - dns: - config: - location: ${starter_location_01} - configure_management_resources: - advanced: - asc_export_resource_group_name: rg-management-asc-export-${starter_location_01} - azurerm_automation_account: - management: - name: aa-management-${starter_location_01} - azurerm_log_analytics_workspace: - management: - name: law-management-${starter_location_01} - custom_settings_by_resource_type: - azurerm_resource_group: - management: - name: rg-management-${starter_location_01} - location: ${starter_location_01} - default_location: ${starter_location_01} - deploy_connectivity_resources: false - root_id: alz - root_name: Azure-Landing-Zones - root_parent_id: ${root_parent_management_group_id} - subscription_id_connectivity: ${subscription_id_connectivity} - subscription_id_identity: ${subscription_id_identity} - subscription_id_management: ${subscription_id_management} -management_use_avm: false diff --git a/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars b/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars index 16e9bc69..5114f806 100644 --- a/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars +++ b/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars @@ -89,7 +89,7 @@ connectivity_resource_groups = { name = "rg-hub-ddos-$${starter_location_01}" location = "$${starter_location_01}" } - vwam = { + vwan = { name = "rg-vwan-$${starter_location_01}" location = "$${starter_location_01}" } @@ -136,19 +136,21 @@ virtual_wan_virtual_hubs = { } } private_dns_zones = { - resource_group_name = "rg-vwan-dns-$${starter_location_01}" + resource_group_name = "rg-hub-dns-$${starter_location_01}" is_primary = true networking = { virtual_network = { - name = "vnet-hub-dns-$${starter_location_01}" - address_space = "10.10.0.0/24" + name = "vnet-hub-dns-$${starter_location_01}" + resource_group_name = "rg-vwan-hub-$${starter_location_01}" + address_space = "10.10.0.0/24" private_dns_resolver_subnet = { - name = "subnet-hub-dns-$${starter_location_01}" - address_prefix = "10.10.0.0/28" + name = "subnet-hub-dns-$${starter_location_01}" + address_prefix = "10.10.0.0/28" } } private_dns_resolver = { name = "pdr-hub-dns-$${starter_location_01}" + resource_group_name = "rg-vwan-hub-$${starter_location_01}" } } } @@ -170,19 +172,21 @@ virtual_wan_virtual_hubs = { } } private_dns_zones = { - resource_group_name = "rg-vwan-dns-$${starter_location_01}" + resource_group_name = "rg-hub-dns-$${starter_location_01}" is_primary = false networking = { virtual_network = { - name = "vnet-hub-dns-$${starter_location_02}" - address_space = "10.11.0.0/24" + name = "vnet-hub-dns-$${starter_location_02}" + resource_group_name = "rg-vwan-hub-$${starter_location_02}" + address_space = "10.11.0.0/24" private_dns_resolver_subnet = { - name = "subnet-hub-dns-$${starter_location_02}" - address_prefix = "10.11.0.0/28" + name = "subnet-hub-dns-$${starter_location_02}" + address_prefix = "10.11.0.0/28" } } private_dns_resolver = { name = "pdr-hub-dns-$${starter_location_02}" + resource_group_name = "rg-vwan-hub-$${starter_location_02}" } } } diff --git a/templates/complete_multi_region/modules/virtual-wan/locals.tf b/templates/complete_multi_region/modules/virtual-wan/locals.tf index 9cdfafad..7218f49e 100644 --- a/templates/complete_multi_region/modules/virtual-wan/locals.tf +++ b/templates/complete_multi_region/modules/virtual-wan/locals.tf @@ -4,7 +4,7 @@ locals { locals { virtual_network_connections_input = { for virtual_network_connection in flatten([for virtual_hub_key, virtual_hub_value in var.virtual_hubs : - [for virtual_network_connection_key, virtual_network_connection_value in virtual_hub_value.virtual_network_connections : { + [for virtual_network_connection_key, virtual_network_connection_value in try(virtual_hub_value.virtual_network_connections, {}) : { unique_key = "${virtual_hub_key}-${virtual_network_connection_key}" name = virtual_network_connection_value.settings.name virtual_hub_key = virtual_hub_key @@ -29,9 +29,9 @@ locals { locals { firewall_policies = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => merge({ - location = virtual_hub_value.location - resource_group_name = virtual_hub_value.resource_group_name - firewall_policy_dns = { + location = try(virtual_hub_value.firewall.firewall_policy.location, virtual_hub_value.hub.location) + resource_group_name = try(virtual_hub_value.firewall.firewall_policy.resource_group_name, virtual_hub_value.hub.resource_group_name) + dns = { servers = [module.dns_resolver[virtual_hub_key].inbound_endpoint_ips["dns"]] proxy_enabled = true } @@ -40,7 +40,7 @@ locals { firewalls = { for virtual_hub_key, virtual_hub_value in var.virtual_hubs : virtual_hub_key => merge( { virtual_hub_key = virtual_hub_key - location = virtual_hub_value.location + location = try(virtual_hub_value.firewall.location, virtual_hub_value.hub.location) firewall_policy_id = module.firewall_policy[virtual_hub_key].resource_id }, virtual_hub_value.firewall) if can(virtual_hub_value.firewall) diff --git a/templates/complete_multi_region/modules/virtual-wan/main.tf b/templates/complete_multi_region/modules/virtual-wan/main.tf index 35c6789b..2af39487 100644 --- a/templates/complete_multi_region/modules/virtual-wan/main.tf +++ b/templates/complete_multi_region/modules/virtual-wan/main.tf @@ -10,7 +10,7 @@ module "firewall_policy" { firewall_policy_sku = try(each.value.sku, "Standard") firewall_policy_auto_learn_private_ranges_enabled = try(each.value.auto_learn_private_ranges_enabled, null) firewall_policy_base_policy_id = try(each.value.base_policy_id, null) - firewall_policy_dns = each.value.settings.dns + firewall_policy_dns = each.value.dns firewall_policy_threat_intelligence_mode = try(each.value.threat_intelligence_mode, "Alert") firewall_policy_private_ip_ranges = try(each.value.private_ip_ranges, null) firewall_policy_threat_intelligence_allowlist = try(each.value.threat_intelligence_allowlist, null) @@ -53,10 +53,10 @@ module "virtual_network_private_dns" { for_each = local.private_dns_zones - address_space = each.value.networking.virtual_network.address_space + address_space = [each.value.networking.virtual_network.address_space] location = each.value.location name = each.value.networking.virtual_network.name - resource_group_name = each.value.resource_group_name + resource_group_name = each.value.networking.virtual_network.resource_group_name enable_telemetry = var.enable_telemetry ddos_protection_plan = local.ddos_protection_plan_enabled ? { id = module.ddos_protection_plan[0].resource.id @@ -85,7 +85,7 @@ module "dns_resolver" { location = each.value.location name = each.value.networking.private_dns_resolver.name - resource_group_name = each.value.resource_group_name + resource_group_name = each.value.networking.private_dns_resolver.resource_group_name virtual_network_resource_id = module.virtual_network_private_dns[each.key].resource_id enable_telemetry = var.enable_telemetry inbound_endpoints = { diff --git a/templates/complete_multi_region/modules/virtual-wan/variables.tf b/templates/complete_multi_region/modules/virtual-wan/variables.tf index 8ea54fc0..4671b9bc 100644 --- a/templates/complete_multi_region/modules/virtual-wan/variables.tf +++ b/templates/complete_multi_region/modules/virtual-wan/variables.tf @@ -12,15 +12,17 @@ variable "virtual_hubs" { is_primary = optional(bool, false) networking = object({ virtual_network = object({ - name = string - address_space = string + name = string + address_space = string + resource_group_name = string private_dns_resolver_subnet = object({ name = string address_prefix = string }) }) private_dns_resolver = object({ - name = string + name = string + resource_group_name = string }) }) })) diff --git a/templates/complete_multi_region/yaml.tf b/templates/complete_multi_region/yaml.tf index a1a0428f..b34dc444 100644 --- a/templates/complete_multi_region/yaml.tf +++ b/templates/complete_multi_region/yaml.tf @@ -24,16 +24,16 @@ YAML }) yaml_file_virtual_wan_es = yamlencode({ - management_use_avm = var.management_use_avm - management_settings_es = var.management_settings_es - connectivity_type = var.connectivity_type - connectivity_resource_groups = var.connectivity_resource_groups - virtual_wan_settings = var.virtual_wan_settings - virtual_wan_virtual_hubs = var.virtual_wan_virtual_hubs + management_use_avm = var.management_use_avm + management_settings_es = var.management_settings_es + connectivity_type = var.connectivity_type + connectivity_resource_groups = var.connectivity_resource_groups + virtual_wan_settings = var.virtual_wan_settings + virtual_wan_virtual_hubs = var.virtual_wan_virtual_hubs }) yaml_file_content = local.connectivity_hub_and_spoke_vnet_enabled ? local.yaml_file_hub_and_spoke_vnet_es : local.yaml_file_virtual_wan_es - yaml_file_final = replace("${local.yaml_file_header}${local.yaml_file_content}", "\"", "") + yaml_file_final = replace("${local.yaml_file_header}${local.yaml_file_content}", "\"", "") yaml_file_name = "config-${replace(var.connectivity_type, "_", "-")}-multi-region.yaml" } From 7d2fa28f4785d528c27e5ba4c4be7137ca59a006 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Tue, 8 Oct 2024 11:33:46 +0100 Subject: [PATCH 16/23] Tidy up --- templates/complete_multi_region/locals-config.tf | 2 +- templates/complete_multi_region/locals-resource-groups.tf | 2 +- templates/complete_multi_region/locals.tf | 1 + templates/complete_multi_region/management.tf | 2 +- .../modules/hub-and-spoke-vnet/locals.tf | 4 ++-- .../modules/hub-and-spoke-vnet/outputs.tf | 7 ------- .../modules/hub-and-spoke-vnet/terraform.tf | 1 - .../complete_multi_region/modules/management-es/main.tf | 2 +- .../modules/management-es/terraform.tf | 3 ++- .../modules/management-es/variables.tf | 2 +- .../complete_multi_region/modules/virtual-wan/locals.tf | 4 ++-- .../complete_multi_region/modules/virtual-wan/outputs.tf | 7 ------- .../complete_multi_region/modules/virtual-wan/terraform.tf | 3 +-- .../complete_multi_region/networking-hub-and-spoke-vnet.tf | 2 +- templates/complete_multi_region/networking-virtual-wan.tf | 4 ++-- templates/complete_multi_region/resource-groups.tf | 2 +- templates/complete_multi_region/terraform.tf | 2 +- .../{variables.management.tf => variables-management.tf} | 2 +- templates/complete_multi_region/variables.tf | 6 ++++++ 19 files changed, 25 insertions(+), 33 deletions(-) delete mode 100644 templates/complete_multi_region/modules/hub-and-spoke-vnet/outputs.tf delete mode 100644 templates/complete_multi_region/modules/virtual-wan/outputs.tf rename templates/complete_multi_region/{variables.management.tf => variables-management.tf} (99%) diff --git a/templates/complete_multi_region/locals-config.tf b/templates/complete_multi_region/locals-config.tf index 5b12b3a4..f0e23fe2 100644 --- a/templates/complete_multi_region/locals-config.tf +++ b/templates/complete_multi_region/locals-config.tf @@ -46,4 +46,4 @@ locals { subscription_id_identity = var.subscription_id_identity subscription_id_management = var.subscription_id_management } -} \ No newline at end of file +} diff --git a/templates/complete_multi_region/locals-resource-groups.tf b/templates/complete_multi_region/locals-resource-groups.tf index d71ca86a..7c20cec5 100644 --- a/templates/complete_multi_region/locals-resource-groups.tf +++ b/templates/complete_multi_region/locals-resource-groups.tf @@ -3,4 +3,4 @@ locals { connectivity_resource_groups_json_templated = templatestring(local.connectivity_resource_groups_json, local.config_template_file_variables) connectivity_resource_groups_json_final = replace(replace(local.connectivity_resource_groups_json_templated, "\"[", "["), "]\"", "]") connectivity_resource_groups = jsondecode(local.connectivity_resource_groups_json_final) -} \ No newline at end of file +} diff --git a/templates/complete_multi_region/locals.tf b/templates/complete_multi_region/locals.tf index 3a7dc480..84c2cb0f 100644 --- a/templates/complete_multi_region/locals.tf +++ b/templates/complete_multi_region/locals.tf @@ -9,6 +9,7 @@ locals { } locals { + management_enabled = (var.management_settings_es) > 0 connectivity_virtual_wan_enabled = var.connectivity_type == local.const.connectivity.virtual_wan connectivity_hub_and_spoke_vnet_enabled = var.connectivity_type == local.const.connectivity.hub_and_spoke_vnet connectivity_none_enabled = var.connectivity_type == local.const.connectivity.none diff --git a/templates/complete_multi_region/management.tf b/templates/complete_multi_region/management.tf index 5b0c7c4f..22b1eabb 100644 --- a/templates/complete_multi_region/management.tf +++ b/templates/complete_multi_region/management.tf @@ -1,7 +1,7 @@ module "management_groups" { source = "./modules/management-es" - count = var.management_use_avm ? 0 : 1 + count = !var.skip_deploy && var.management_use_avm ? 0 : 1 enable_telemetry = var.enable_telemetry settings = local.management_settings_es diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf index 450e52bc..83dc56eb 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/locals.tf @@ -22,7 +22,7 @@ locals { locals { private_dns_zones = { for key, value in var.hub_virtual_networks : key => merge({ location = value.hub_virtual_network.location - }, value.private_dns_zones) if can(value.private_dns_zones) } + }, value.private_dns_zones) if can(value.private_dns_zones.resource_group_name) } private_dns_zones_virtual_network_links = { for key, value in module.hub_and_spoke_vnet.virtual_networks : key => { @@ -52,6 +52,6 @@ locals { } locals { - ddos_protection_plan = can(var.hub_and_spoke_networks_settings.ddos_protection_plan) ? var.hub_and_spoke_networks_settings.ddos_protection_plan : null + ddos_protection_plan = can(var.hub_and_spoke_networks_settings.ddos_protection_plan.name) ? var.hub_and_spoke_networks_settings.ddos_protection_plan : null ddos_protection_plan_enabled = local.ddos_protection_plan != null } diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/outputs.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/outputs.tf deleted file mode 100644 index 7a7fd518..00000000 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/outputs.tf +++ /dev/null @@ -1,7 +0,0 @@ -output "virtual_networks" { - value = { - for key, value in module.hub_and_spoke_vnet.virtual_networks : key => { - resource_id = value.id - } - } -} diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/terraform.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/terraform.tf index 4619009c..d6c95626 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/terraform.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/terraform.tf @@ -10,5 +10,4 @@ terraform { version = "~> 1.13" } } - # backend "azurerm" {} } diff --git a/templates/complete_multi_region/modules/management-es/main.tf b/templates/complete_multi_region/modules/management-es/main.tf index 4c7694a9..3ea1a33a 100644 --- a/templates/complete_multi_region/modules/management-es/main.tf +++ b/templates/complete_multi_region/modules/management-es/main.tf @@ -47,4 +47,4 @@ module "management_groups" { azurerm.connectivity = azurerm.connectivity azurerm.management = azurerm.management } -} \ No newline at end of file +} diff --git a/templates/complete_multi_region/modules/management-es/terraform.tf b/templates/complete_multi_region/modules/management-es/terraform.tf index 0417ea7c..f5314d87 100644 --- a/templates/complete_multi_region/modules/management-es/terraform.tf +++ b/templates/complete_multi_region/modules/management-es/terraform.tf @@ -1,4 +1,5 @@ terraform { + required_version = "~> 1.9" required_providers { azurerm = { source = "hashicorp/azurerm" @@ -9,4 +10,4 @@ terraform { ] } } -} \ No newline at end of file +} diff --git a/templates/complete_multi_region/modules/management-es/variables.tf b/templates/complete_multi_region/modules/management-es/variables.tf index cd630d30..bc3fc55b 100644 --- a/templates/complete_multi_region/modules/management-es/variables.tf +++ b/templates/complete_multi_region/modules/management-es/variables.tf @@ -5,4 +5,4 @@ variable "settings" { variable "enable_telemetry" { type = bool default = true -} \ No newline at end of file +} diff --git a/templates/complete_multi_region/modules/virtual-wan/locals.tf b/templates/complete_multi_region/modules/virtual-wan/locals.tf index 7218f49e..cea6ab29 100644 --- a/templates/complete_multi_region/modules/virtual-wan/locals.tf +++ b/templates/complete_multi_region/modules/virtual-wan/locals.tf @@ -50,7 +50,7 @@ locals { locals { private_dns_zones = { for key, value in var.virtual_hubs : key => merge({ location = value.hub.location - }, value.private_dns_zones) if can(value.private_dns_zones) } + }, value.private_dns_zones) if can(value.private_dns_zones.resource_group_name) } private_dns_zones_virtual_network_links = { for key, value in module.virtual_network_private_dns : key => { @@ -80,6 +80,6 @@ locals { } locals { - ddos_protection_plan = can(var.virtual_wan_settings.ddos_protection_plan) ? var.virtual_wan_settings.ddos_protection_plan : null + ddos_protection_plan = can(var.virtual_wan_settings.ddos_protection_plan.name) ? var.virtual_wan_settings.ddos_protection_plan : null ddos_protection_plan_enabled = local.ddos_protection_plan != null } diff --git a/templates/complete_multi_region/modules/virtual-wan/outputs.tf b/templates/complete_multi_region/modules/virtual-wan/outputs.tf deleted file mode 100644 index c6585b91..00000000 --- a/templates/complete_multi_region/modules/virtual-wan/outputs.tf +++ /dev/null @@ -1,7 +0,0 @@ -output "private_dns_zones_virtual_networks" { - value = { - for key, value in module.virtual_network_private_dns : key => { - resource_id = value.resource_id - } - } -} \ No newline at end of file diff --git a/templates/complete_multi_region/modules/virtual-wan/terraform.tf b/templates/complete_multi_region/modules/virtual-wan/terraform.tf index 28d0feae..d6c95626 100644 --- a/templates/complete_multi_region/modules/virtual-wan/terraform.tf +++ b/templates/complete_multi_region/modules/virtual-wan/terraform.tf @@ -1,5 +1,5 @@ terraform { - required_version = "~> 1.8" + required_version = "~> 1.9" required_providers { azurerm = { source = "hashicorp/azurerm" @@ -10,5 +10,4 @@ terraform { version = "~> 1.13" } } - # backend "azurerm" {} } diff --git a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf index cd9d137d..7039a75a 100644 --- a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf @@ -1,7 +1,7 @@ module "hub_and_spoke_vnet" { source = "./modules/hub-and-spoke-vnet" - count = local.connectivity_hub_and_spoke_vnet_enabled ? 1 : 0 + count = !var.skip_deploy && local.connectivity_hub_and_spoke_vnet_enabled ? 1 : 0 hub_and_spoke_networks_settings = local.hub_and_spoke_vnet_settings hub_virtual_networks = local.hub_and_spoke_vnet_virtual_networks diff --git a/templates/complete_multi_region/networking-virtual-wan.tf b/templates/complete_multi_region/networking-virtual-wan.tf index 4bf75949..c5a0fb36 100644 --- a/templates/complete_multi_region/networking-virtual-wan.tf +++ b/templates/complete_multi_region/networking-virtual-wan.tf @@ -1,7 +1,7 @@ module "virtual_wan" { source = "./modules/virtual-wan" - count = local.connectivity_virtual_wan_enabled ? 1 : 0 + count = !var.skip_deploy && local.connectivity_virtual_wan_enabled ? 1 : 0 virtual_wan_settings = local.virtual_wan_settings virtual_hubs = local.virtual_wan_virtual_hubs @@ -15,4 +15,4 @@ module "virtual_wan" { module.management_groups, module.resource_groups ] -} \ No newline at end of file +} diff --git a/templates/complete_multi_region/resource-groups.tf b/templates/complete_multi_region/resource-groups.tf index adaba836..e7698e25 100644 --- a/templates/complete_multi_region/resource-groups.tf +++ b/templates/complete_multi_region/resource-groups.tf @@ -2,7 +2,7 @@ module "resource_groups" { source = "Azure/avm-res-resources-resourcegroup/azurerm" version = "0.1.0" - for_each = local.connectivity_resource_groups + for_each = var.skip_deploy ? {} : local.connectivity_resource_groups name = each.value.name location = each.value.location diff --git a/templates/complete_multi_region/terraform.tf b/templates/complete_multi_region/terraform.tf index 788d0588..c4fe252d 100644 --- a/templates/complete_multi_region/terraform.tf +++ b/templates/complete_multi_region/terraform.tf @@ -1,5 +1,5 @@ terraform { - required_version = "~> 1.8" + required_version = "~> 1.9" required_providers { azurerm = { source = "hashicorp/azurerm" diff --git a/templates/complete_multi_region/variables.management.tf b/templates/complete_multi_region/variables-management.tf similarity index 99% rename from templates/complete_multi_region/variables.management.tf rename to templates/complete_multi_region/variables-management.tf index 630a97fa..5b9e58b9 100644 --- a/templates/complete_multi_region/variables.management.tf +++ b/templates/complete_multi_region/variables-management.tf @@ -12,4 +12,4 @@ variable "management_settings_avm" { variable "management_settings_es" { type = any default = {} -} \ No newline at end of file +} diff --git a/templates/complete_multi_region/variables.tf b/templates/complete_multi_region/variables.tf index c4503363..a4ca2bee 100644 --- a/templates/complete_multi_region/variables.tf +++ b/templates/complete_multi_region/variables.tf @@ -35,3 +35,9 @@ variable "enable_telemetry" { default = true description = "Flag to enable/disable telemetry" } + +variable "skip_deploy" { + type = bool + default = false + description = "Flag to skip deployment. This is used for testing and documentation generation purposes." +} \ No newline at end of file From 94a40ab989a4f92e5d4ccc1c876b363702d79949 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Tue, 8 Oct 2024 11:50:26 +0100 Subject: [PATCH 17/23] Linting --- .../examples/config-virtual-wan-multi-region.tfvars | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars b/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars index 5114f806..8754997b 100644 --- a/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars +++ b/templates/complete_multi_region/examples/config-virtual-wan-multi-region.tfvars @@ -144,12 +144,12 @@ virtual_wan_virtual_hubs = { resource_group_name = "rg-vwan-hub-$${starter_location_01}" address_space = "10.10.0.0/24" private_dns_resolver_subnet = { - name = "subnet-hub-dns-$${starter_location_01}" - address_prefix = "10.10.0.0/28" + name = "subnet-hub-dns-$${starter_location_01}" + address_prefix = "10.10.0.0/28" } } private_dns_resolver = { - name = "pdr-hub-dns-$${starter_location_01}" + name = "pdr-hub-dns-$${starter_location_01}" resource_group_name = "rg-vwan-hub-$${starter_location_01}" } } @@ -180,12 +180,12 @@ virtual_wan_virtual_hubs = { resource_group_name = "rg-vwan-hub-$${starter_location_02}" address_space = "10.11.0.0/24" private_dns_resolver_subnet = { - name = "subnet-hub-dns-$${starter_location_02}" - address_prefix = "10.11.0.0/28" + name = "subnet-hub-dns-$${starter_location_02}" + address_prefix = "10.11.0.0/28" } } private_dns_resolver = { - name = "pdr-hub-dns-$${starter_location_02}" + name = "pdr-hub-dns-$${starter_location_02}" resource_group_name = "rg-vwan-hub-$${starter_location_02}" } } From 38c315ee11388f771e4bd17d9004e647965906bd Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Tue, 8 Oct 2024 12:36:27 +0100 Subject: [PATCH 18/23] linting and bug fix --- templates/complete_multi_region/locals.tf | 2 +- templates/complete_multi_region/management.tf | 2 +- templates/complete_multi_region/variables.tf | 2 +- templates/complete_multi_region/yaml.tf | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/templates/complete_multi_region/locals.tf b/templates/complete_multi_region/locals.tf index 84c2cb0f..c3a88960 100644 --- a/templates/complete_multi_region/locals.tf +++ b/templates/complete_multi_region/locals.tf @@ -9,7 +9,7 @@ locals { } locals { - management_enabled = (var.management_settings_es) > 0 + management_enabled = length(var.management_settings_es) > 0 connectivity_virtual_wan_enabled = var.connectivity_type == local.const.connectivity.virtual_wan connectivity_hub_and_spoke_vnet_enabled = var.connectivity_type == local.const.connectivity.hub_and_spoke_vnet connectivity_none_enabled = var.connectivity_type == local.const.connectivity.none diff --git a/templates/complete_multi_region/management.tf b/templates/complete_multi_region/management.tf index 22b1eabb..f459f0aa 100644 --- a/templates/complete_multi_region/management.tf +++ b/templates/complete_multi_region/management.tf @@ -1,7 +1,7 @@ module "management_groups" { source = "./modules/management-es" - count = !var.skip_deploy && var.management_use_avm ? 0 : 1 + count = var.skip_deploy ? 0 : (var.management_use_avm ? 0 : 1) enable_telemetry = var.enable_telemetry settings = local.management_settings_es diff --git a/templates/complete_multi_region/variables.tf b/templates/complete_multi_region/variables.tf index a4ca2bee..52bee8f4 100644 --- a/templates/complete_multi_region/variables.tf +++ b/templates/complete_multi_region/variables.tf @@ -40,4 +40,4 @@ variable "skip_deploy" { type = bool default = false description = "Flag to skip deployment. This is used for testing and documentation generation purposes." -} \ No newline at end of file +} diff --git a/templates/complete_multi_region/yaml.tf b/templates/complete_multi_region/yaml.tf index b34dc444..59452edc 100644 --- a/templates/complete_multi_region/yaml.tf +++ b/templates/complete_multi_region/yaml.tf @@ -12,6 +12,7 @@ locals { # `subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`. # `subscription_id_management`: The subscription ID of the subscription to deploy the management resources to, sourced from the variable `subscription_id_management`. +--- YAML yaml_file_hub_and_spoke_vnet_es = yamlencode({ @@ -33,7 +34,7 @@ YAML }) yaml_file_content = local.connectivity_hub_and_spoke_vnet_enabled ? local.yaml_file_hub_and_spoke_vnet_es : local.yaml_file_virtual_wan_es - yaml_file_final = replace("${local.yaml_file_header}${local.yaml_file_content}", "\"", "") + yaml_file_final = replace(replace("${local.yaml_file_header}${local.yaml_file_content}", "\"", ""), " - ", " - ") yaml_file_name = "config-${replace(var.connectivity_type, "_", "-")}-multi-region.yaml" } From 78ec91fd1d80af47174469f92d150cd5f75df9ce Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Tue, 8 Oct 2024 12:42:00 +0100 Subject: [PATCH 19/23] linting --- templates/complete_multi_region/terraform.tf | 4 ++++ templates/complete_multi_region/variables.tf | 6 ------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/templates/complete_multi_region/terraform.tf b/templates/complete_multi_region/terraform.tf index c4fe252d..79898cab 100644 --- a/templates/complete_multi_region/terraform.tf +++ b/templates/complete_multi_region/terraform.tf @@ -9,6 +9,10 @@ terraform { source = "Azure/azapi" version = "~> 1.13" } + local = { + source = "hashicorp/local" + version = "~> 2.5" + } } # backend "azurerm" {} } diff --git a/templates/complete_multi_region/variables.tf b/templates/complete_multi_region/variables.tf index 52bee8f4..eb771b6b 100644 --- a/templates/complete_multi_region/variables.tf +++ b/templates/complete_multi_region/variables.tf @@ -18,12 +18,6 @@ variable "subscription_id_management" { description = "value of the subscription id for the Management subscription|azure_subscription_id" } -variable "configuration_file_path" { - type = string - default = "config-hub-and-spoke-vnet-multi-region.yaml" - description = "The path of the configuration file|configuration_file_path" -} - variable "root_parent_management_group_id" { type = string default = "" From c2ca8f19621d350bc8fc0fdee8a856c66ee15639 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Tue, 8 Oct 2024 12:50:54 +0100 Subject: [PATCH 20/23] linting --- templates/complete_multi_region/locals.tf | 2 -- templates/complete_multi_region/management.tf | 17 ++++++++++++++++- .../modules/management-avm/main.tf | 1 + .../modules/management-avm/terraform.tf | 13 +++++++++++++ .../modules/management-avm/variables.tf | 8 ++++++++ 5 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 templates/complete_multi_region/modules/management-avm/main.tf create mode 100644 templates/complete_multi_region/modules/management-avm/terraform.tf create mode 100644 templates/complete_multi_region/modules/management-avm/variables.tf diff --git a/templates/complete_multi_region/locals.tf b/templates/complete_multi_region/locals.tf index c3a88960..07b83c35 100644 --- a/templates/complete_multi_region/locals.tf +++ b/templates/complete_multi_region/locals.tf @@ -9,8 +9,6 @@ locals { } locals { - management_enabled = length(var.management_settings_es) > 0 connectivity_virtual_wan_enabled = var.connectivity_type == local.const.connectivity.virtual_wan connectivity_hub_and_spoke_vnet_enabled = var.connectivity_type == local.const.connectivity.hub_and_spoke_vnet - connectivity_none_enabled = var.connectivity_type == local.const.connectivity.none } diff --git a/templates/complete_multi_region/management.tf b/templates/complete_multi_region/management.tf index f459f0aa..abeada5d 100644 --- a/templates/complete_multi_region/management.tf +++ b/templates/complete_multi_region/management.tf @@ -1,4 +1,4 @@ -module "management_groups" { +module "management_es" { source = "./modules/management-es" count = var.skip_deploy ? 0 : (var.management_use_avm ? 0 : 1) @@ -12,3 +12,18 @@ module "management_groups" { azurerm.management = azurerm.management } } + +module "management_avm" { + source = "./modules/management-avm" + + count = var.skip_deploy ? 0 : (var.management_use_avm ? 1 : 0) + + enable_telemetry = var.enable_telemetry + settings = local.management_settings_es + + providers = { + azurerm = azurerm + azurerm.connectivity = azurerm.connectivity + azurerm.management = azurerm.management + } +} diff --git a/templates/complete_multi_region/modules/management-avm/main.tf b/templates/complete_multi_region/modules/management-avm/main.tf new file mode 100644 index 00000000..a9d9f297 --- /dev/null +++ b/templates/complete_multi_region/modules/management-avm/main.tf @@ -0,0 +1 @@ +# Not implemented yet diff --git a/templates/complete_multi_region/modules/management-avm/terraform.tf b/templates/complete_multi_region/modules/management-avm/terraform.tf new file mode 100644 index 00000000..f5314d87 --- /dev/null +++ b/templates/complete_multi_region/modules/management-avm/terraform.tf @@ -0,0 +1,13 @@ +terraform { + required_version = "~> 1.9" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.107" + configuration_aliases = [ + azurerm.connectivity, + azurerm.management, + ] + } + } +} diff --git a/templates/complete_multi_region/modules/management-avm/variables.tf b/templates/complete_multi_region/modules/management-avm/variables.tf new file mode 100644 index 00000000..bc3fc55b --- /dev/null +++ b/templates/complete_multi_region/modules/management-avm/variables.tf @@ -0,0 +1,8 @@ +variable "settings" { + type = any +} + +variable "enable_telemetry" { + type = bool + default = true +} From f71c8d71a6ee0fe43b66ba95708f3ded472a79fd Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Tue, 8 Oct 2024 12:55:47 +0100 Subject: [PATCH 21/23] linting --- templates/complete_multi_region/locals-config.tf | 1 - templates/complete_multi_region/management.tf | 2 +- .../complete_multi_region/modules/management-avm/main.tf | 6 ++++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/templates/complete_multi_region/locals-config.tf b/templates/complete_multi_region/locals-config.tf index f0e23fe2..cd0f310b 100644 --- a/templates/complete_multi_region/locals-config.tf +++ b/templates/complete_multi_region/locals-config.tf @@ -1,5 +1,4 @@ locals { - primary_location = var.starter_locations[0] config_template_file_variables = { starter_location_01 = var.starter_locations[0] starter_location_02 = try(var.starter_locations[1], null) diff --git a/templates/complete_multi_region/management.tf b/templates/complete_multi_region/management.tf index abeada5d..4f41b4f1 100644 --- a/templates/complete_multi_region/management.tf +++ b/templates/complete_multi_region/management.tf @@ -19,7 +19,7 @@ module "management_avm" { count = var.skip_deploy ? 0 : (var.management_use_avm ? 1 : 0) enable_telemetry = var.enable_telemetry - settings = local.management_settings_es + settings = local.management_settings_avm providers = { azurerm = azurerm diff --git a/templates/complete_multi_region/modules/management-avm/main.tf b/templates/complete_multi_region/modules/management-avm/main.tf index a9d9f297..3c7a73e8 100644 --- a/templates/complete_multi_region/modules/management-avm/main.tf +++ b/templates/complete_multi_region/modules/management-avm/main.tf @@ -1 +1,7 @@ # Not implemented yet +output "temp_for_linting" { + value = { + settings = var.settings + enable_telemetry = var.enable_telemetry + } +} From 24d059c0bec56a6a28db8815fac0d812711ac66e Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Tue, 8 Oct 2024 15:38:31 +0100 Subject: [PATCH 22/23] Update docs --- templates/complete_multi_region/README.md | 28 +++++++++-- .../modules/hub-and-spoke-vnet/variables.tf | 35 ++++++++++--- .../modules/management-avm/variables.tf | 16 ++++-- .../modules/management-es/variables.tf | 16 ++++-- .../modules/virtual-wan/variables.tf | 49 +++++++++++++++++-- .../variables-connectivity.tf | 12 ++++- .../variables-hub-and-spoke-vnet.tf | 23 +++++++-- .../variables-management.tf | 14 ++++-- .../variables-virtual-wan.tf | 39 +++++++++++++-- templates/complete_multi_region/yaml.tf | 3 ++ 10 files changed, 202 insertions(+), 33 deletions(-) diff --git a/templates/complete_multi_region/README.md b/templates/complete_multi_region/README.md index 8aaf2162..cabb486a 100644 --- a/templates/complete_multi_region/README.md +++ b/templates/complete_multi_region/README.md @@ -1,8 +1,28 @@ # Azure Landing Zones Accelerator Starter Module for Terraform - Complete Multi-Region -## Contributing +This module is part of the Azure Landing Zones Accelerator solution. It is a complete multi-region implementation of the Azure Landing Zones Platform Landing Zone for Terraform. -### Run the local examples +It deploys a hub and spoke virtual network or Virtual WAN architecture across multiple regions. + +The module deploys the following resources: + +- Management group hierarchy +- Azure Policy definitions and assignments +- Role definitions +- Management resources, including Log Analytics workspace and Automation account +- Hub and spoke virtual network or Virtual WAN architecture across multiple regions +- DDOS protection plan +- Private DNS zones + +## Usage + +The module is intended to be used with the [Azure Landing Zones Accelerator](https://aka.ms/alz/accelerator/docs). Head over there to get started. + +>NOTE: The module can be used independently if needed. Example tfvars files can be found in the `examples` directory for that use case. + +### Running Directly + +#### Run the local examples Create a `terraform.tfvars` file in the root of the module directory with the following content, replacing the placeholders with the actual values: @@ -13,14 +33,14 @@ subscription_id_identity = "00000000-0000-0000-0000-000000000000" subscription_id_management = "00000000-0000-0000-0000-000000000000" ``` -#### Hub and Spoke Virtual Networks Multi Region +##### Hub and Spoke Virtual Networks Multi Region ```powershell terraform init terraform apply -var-file ./examples/config-hub-and-spoke-virtual-networks-multi-region.tfvars ``` -#### Virtual WAN Multi Region +##### Virtual WAN Multi Region ```powershell terraform init diff --git a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf index 792bff94..0ac361f7 100644 --- a/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf +++ b/templates/complete_multi_region/modules/hub-and-spoke-vnet/variables.tf @@ -1,5 +1,14 @@ variable "hub_and_spoke_networks_settings" { - type = any + type = any + default = {} + description = <. +If it is set to false, then no telemetry will be collected. +DESCRIPTION + nullable = false } variable "tags" { - default = {} type = map(string) - description = "A map of tags to add to the private DNS zones" + default = null + description = "(Optional) Tags of the resource." } diff --git a/templates/complete_multi_region/modules/management-avm/variables.tf b/templates/complete_multi_region/modules/management-avm/variables.tf index bc3fc55b..06e3c150 100644 --- a/templates/complete_multi_region/modules/management-avm/variables.tf +++ b/templates/complete_multi_region/modules/management-avm/variables.tf @@ -1,8 +1,18 @@ variable "settings" { - type = any + type = any + default = {} + description = <. +If it is set to false, then no telemetry will be collected. +DESCRIPTION + nullable = false } diff --git a/templates/complete_multi_region/modules/management-es/variables.tf b/templates/complete_multi_region/modules/management-es/variables.tf index bc3fc55b..d97c443e 100644 --- a/templates/complete_multi_region/modules/management-es/variables.tf +++ b/templates/complete_multi_region/modules/management-es/variables.tf @@ -1,8 +1,18 @@ variable "settings" { - type = any + type = any + default = {} + description = <. +If it is set to false, then no telemetry will be collected. +DESCRIPTION + nullable = false } diff --git a/templates/complete_multi_region/modules/virtual-wan/variables.tf b/templates/complete_multi_region/modules/virtual-wan/variables.tf index 4671b9bc..e7f861f7 100644 --- a/templates/complete_multi_region/modules/virtual-wan/variables.tf +++ b/templates/complete_multi_region/modules/virtual-wan/variables.tf @@ -1,5 +1,16 @@ variable "virtual_wan_settings" { - type = any + type = any + default = {} + description = <. +If it is set to false, then no telemetry will be collected. +DESCRIPTION + nullable = false } variable "tags" { - default = {} type = map(string) - description = "A map of tags to add to the private DNS zones" + default = null + description = "(Optional) Tags of the resource." } diff --git a/templates/complete_multi_region/variables-connectivity.tf b/templates/complete_multi_region/variables-connectivity.tf index 1bc171ee..e3c4afdd 100644 --- a/templates/complete_multi_region/variables-connectivity.tf +++ b/templates/complete_multi_region/variables-connectivity.tf @@ -1,6 +1,6 @@ variable "connectivity_type" { type = string - description = "The type of connectivity to use for the private DNS zones" + description = "The type of network connectivity technology to use for the private DNS zones" default = "hub_and_spoke_vnet" validation { condition = contains(values(local.const.connectivity), var.connectivity_type) @@ -13,5 +13,13 @@ variable "connectivity_resource_groups" { name = string location = string })) - description = "A map of resource groups to create" + description = < Date: Tue, 8 Oct 2024 16:13:08 +0100 Subject: [PATCH 23/23] Bug fix --- .../complete_multi_region/networking-hub-and-spoke-vnet.tf | 3 ++- templates/complete_multi_region/networking-virtual-wan.tf | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf index 7039a75a..dee3d4ab 100644 --- a/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf +++ b/templates/complete_multi_region/networking-hub-and-spoke-vnet.tf @@ -12,7 +12,8 @@ module "hub_and_spoke_vnet" { } depends_on = [ - module.management_groups, + module.management_es, + module.management_avm, module.resource_groups ] } diff --git a/templates/complete_multi_region/networking-virtual-wan.tf b/templates/complete_multi_region/networking-virtual-wan.tf index c5a0fb36..cb6392ac 100644 --- a/templates/complete_multi_region/networking-virtual-wan.tf +++ b/templates/complete_multi_region/networking-virtual-wan.tf @@ -12,7 +12,8 @@ module "virtual_wan" { } depends_on = [ - module.management_groups, + module.management_es, + module.management_avm, module.resource_groups ] }