From 5acc2e9c8aa241ea1f1245a24fb709706fceb85c Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Fri, 12 Sep 2025 13:17:45 +0100 Subject: [PATCH 1/5] feat: handle map inputs --- ...evops-terraform-complete-multi-region.yaml | 47 ----- ...ithub-terraform-complete-multi-region.yaml | 44 ---- ...local-terraform-complete-multi-region.yaml | 38 ---- ...onfig-hub-and-spoke-vnet-multi-region.yaml | 197 ------------------ ...nfig-hub-and-spoke-vnet-single-region.yaml | 136 ------------ .../config-virtual-wan-multi-region.yaml | 141 ------------- .../config-virtual-wan-single-region.yaml | 111 ---------- src/ALZ/Private/Config-Helpers/Set-Config.ps1 | 49 +++-- 8 files changed, 36 insertions(+), 727 deletions(-) delete mode 100644 docs/wiki/examples/powershell-inputs/inputs-azure-devops-terraform-complete-multi-region.yaml delete mode 100644 docs/wiki/examples/powershell-inputs/inputs-github-terraform-complete-multi-region.yaml delete mode 100644 docs/wiki/examples/powershell-inputs/inputs-local-terraform-complete-multi-region.yaml delete mode 100644 docs/wiki/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-multi-region.yaml delete mode 100644 docs/wiki/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-single-region.yaml delete mode 100644 docs/wiki/examples/starter-module-config/complete-multi-region/config-virtual-wan-multi-region.yaml delete mode 100644 docs/wiki/examples/starter-module-config/complete-multi-region/config-virtual-wan-single-region.yaml diff --git a/docs/wiki/examples/powershell-inputs/inputs-azure-devops-terraform-complete-multi-region.yaml b/docs/wiki/examples/powershell-inputs/inputs-azure-devops-terraform-complete-multi-region.yaml deleted file mode 100644 index 5a3fbc7..0000000 --- a/docs/wiki/examples/powershell-inputs/inputs-azure-devops-terraform-complete-multi-region.yaml +++ /dev/null @@ -1,47 +0,0 @@ ---- -# For detailed instructions on using this file, visit: -# https://github.com/Azure/ALZ-PowerShell-Module/wiki/%5BUser-Guide%5D-Quick-Start-Phase-2-Azure-DevOps#2212-azure-devops-with-terraform - -# Basic Inputs -iac_type: "terraform" -bootstrap_module_name: "alz_azuredevops" -starter_module_name: "complete_multi_region" - -# Shared Interface Inputs -bootstrap_location: "" -starter_locations: ["", ""] -root_parent_management_group_id: "" -subscription_id_management: "" -subscription_id_identity: "" -subscription_id_connectivity: "" - -# Bootstrap Inputs -azure_devops_personal_access_token: "" -azure_devops_agents_personal_access_token: "" -azure_devops_organization_name: "" -use_separate_repository_for_templates: true -bootstrap_subscription_id: "" -service_name: "alz" -environment_name: "mgmt" -postfix_number: 1 -azure_devops_use_organisation_legacy_url: false -azure_devops_create_project: true -azure_devops_project_name: "" -use_self_hosted_agents: true -use_private_networking: true -allow_storage_access_from_my_ip: false -apply_approvers: [""] -create_branch_policies: true - -# Complete Multi Region Starter Module Specific Variables -# (Details: https://github.com/Azure/ALZ-PowerShell-Module/wiki/%5BUser-Guide%5D-Starter-Module-Terraform-Complete-Multi-Region) -# The detailed configuration can be supplied in a separate file or combined in this file. Examples can be seen here: -# Hub and Spoke Virtual Network Multi Region: https://raw.githubusercontent.com/wiki/Azure/ALZ-PowerShell-Module/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-multi-region.yaml -# Virtual WAN Multi Region: https://raw.githubusercontent.com/wiki/Azure/ALZ-PowerShell-Module/examples/starter-module-config/complete-multi-region/config-virtual-wan-multi-region.yaml -# Hub and Spoke Virtual Network Single Region: https://raw.githubusercontent.com/wiki/Azure/ALZ-PowerShell-Module/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-single-region.yaml -# Virtual WAN Single Region: https://raw.githubusercontent.com/wiki/Azure/ALZ-PowerShell-Module/examples/starter-module-config/complete-multi-region/config-virtual-wan-single-region.yaml - -# Advanced Inputs -bootstrap_module_version: "latest" -starter_module_version: "latest" -#output_folder_path: "/accelerator/output" diff --git a/docs/wiki/examples/powershell-inputs/inputs-github-terraform-complete-multi-region.yaml b/docs/wiki/examples/powershell-inputs/inputs-github-terraform-complete-multi-region.yaml deleted file mode 100644 index cd1b4f2..0000000 --- a/docs/wiki/examples/powershell-inputs/inputs-github-terraform-complete-multi-region.yaml +++ /dev/null @@ -1,44 +0,0 @@ ---- -# For detailed instructions on using this file, visit: -# https://github.com/Azure/ALZ-PowerShell-Module/wiki/%5BUser-Guide%5D-Quick-Start-Phase-2-GitHub#2222-github-with-terraform - -# Basic Inputs -iac_type: "terraform" -bootstrap_module_name: "alz_github" -starter_module_name: "complete_multi_region" - -# Shared Interface Inputs -bootstrap_location: "" -starter_locations: ["", ""] -root_parent_management_group_id: "" -subscription_id_management: "" -subscription_id_identity: "" -subscription_id_connectivity: "" - -# Bootstrap Inputs -github_personal_access_token: "" -github_runners_personal_access_token: "" -github_organization_name: "" -use_separate_repository_for_templates: true -bootstrap_subscription_id: "" -service_name: "alz" -environment_name: "mgmt" -postfix_number: 1 -use_self_hosted_runners: true -use_private_networking: true -allow_storage_access_from_my_ip: false -apply_approvers: [""] -create_branch_policies: true - -# Complete Multi Region Starter Module Specific Variables -# (Details: https://github.com/Azure/ALZ-PowerShell-Module/wiki/%5BUser-Guide%5D-Starter-Module-Terraform-Complete-Multi-Region) -# The detailed configuration can be supplied in a separate file or combined in this file. Examples can be seen here: -# Hub and Spoke Virtual Network Multi Region: https://raw.githubusercontent.com/wiki/Azure/ALZ-PowerShell-Module/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-multi-region.yaml -# Virtual WAN Multi Region: https://raw.githubusercontent.com/wiki/Azure/ALZ-PowerShell-Module/examples/starter-module-config/complete-multi-region/config-virtual-wan-multi-region.yaml -# Hub and Spoke Virtual Network Single Region: https://raw.githubusercontent.com/wiki/Azure/ALZ-PowerShell-Module/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-single-region.yaml -# Virtual WAN Single Region: https://raw.githubusercontent.com/wiki/Azure/ALZ-PowerShell-Module/examples/starter-module-config/complete-multi-region/config-virtual-wan-single-region.yaml - -# Advanced Inputs -bootstrap_module_version: "latest" -starter_module_version: "latest" -#output_folder_path: "/accelerator/output" diff --git a/docs/wiki/examples/powershell-inputs/inputs-local-terraform-complete-multi-region.yaml b/docs/wiki/examples/powershell-inputs/inputs-local-terraform-complete-multi-region.yaml deleted file mode 100644 index d3932d9..0000000 --- a/docs/wiki/examples/powershell-inputs/inputs-local-terraform-complete-multi-region.yaml +++ /dev/null @@ -1,38 +0,0 @@ ---- -# For detailed instructions on using this file, visit: -# https://github.com/Azure/ALZ-PowerShell-Module/wiki/%5BUser-Guide%5D-Quick-Start-Phase-2-Local#2232-local-file-system-with-terraform - -# Basic Inputs -iac_type: "terraform" -bootstrap_module_name: "alz_local" -starter_module_name: "complete_multi_region" - -# Shared Interface Inputs -bootstrap_location: "" -starter_locations: ["", ""] -root_parent_management_group_id: "" -subscription_id_management: "" -subscription_id_identity: "" -subscription_id_connectivity: "" - -# Bootstrap Inputs -target_directory: "" -create_bootstrap_resources_in_azure: true -bootstrap_subscription_id: "" -service_name: "alz" -environment_name: "mgmt" -postfix_number: 1 -grant_permissions_to_current_user: true - -# Complete Multi Region Starter Module Specific Variables -# (Details: https://github.com/Azure/ALZ-PowerShell-Module/wiki/%5BUser-Guide%5D-Starter-Module-Terraform-Complete-Multi-Region) -# The detailed configuration can be supplied in a separate file or combined in this file. Examples can be seen here: -# Hub and Spoke Virtual Network Multi Region: https://raw.githubusercontent.com/wiki/Azure/ALZ-PowerShell-Module/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-multi-region.yaml -# Virtual WAN Multi Region: https://raw.githubusercontent.com/wiki/Azure/ALZ-PowerShell-Module/examples/starter-module-config/complete-multi-region/config-virtual-wan-multi-region.yaml -# Hub and Spoke Virtual Network Single Region: https://raw.githubusercontent.com/wiki/Azure/ALZ-PowerShell-Module/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-single-region.yaml -# Virtual WAN Single Region: https://raw.githubusercontent.com/wiki/Azure/ALZ-PowerShell-Module/examples/starter-module-config/complete-multi-region/config-virtual-wan-single-region.yaml - -# Advanced Inputs -bootstrap_module_version: "latest" -starter_module_version: "latest" -#output_folder_path: "/accelerator/output" diff --git a/docs/wiki/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-multi-region.yaml b/docs/wiki/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-multi-region.yaml deleted file mode 100644 index f7be4e7..0000000 --- a/docs/wiki/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-multi-region.yaml +++ /dev/null @@ -1,197 +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. -# `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`. -# `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: ${connectivity_resource_group_ddos} -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: ${connectivity_resource_group_vnet_primary} - subnets: - virtual_network_gateway: - address_prefixes: - - 10.0.1.0/24 - assign_generated_route_table: false - name: GatewaySubnet - tags: - deployment: terraform - source: Azure Landing Zones Accelerator - private_dns_zones: - is_primary: true - resource_group_name: ${connectivity_resource_group_dns} - 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: ${connectivity_resource_group_vnet_secondary} - subnets: - virtual_network_gateway: - address_prefixes: - - 10.1.1.0/24 - assign_generated_route_table: false - name: GatewaySubnet - tags: - deployment: terraform - source: Azure Landing Zones Accelerator - private_dns_zones: - is_primary: false - resource_group_name: ${connectivity_resource_group_dns} - 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: ${connectivity_resource_group_ddos} - dns: - ${starter_location_01}: - name: ${connectivity_resource_group_dns} - 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 - deploy_management_resources: true - deploy_core_landing_zones: true - deploy_corp_landing_zones: true - deploy_online_landing_zones: true - 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} diff --git a/docs/wiki/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-single-region.yaml b/docs/wiki/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-single-region.yaml deleted file mode 100644 index 5cfd57b..0000000 --- a/docs/wiki/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-single-region.yaml +++ /dev/null @@ -1,136 +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. -# `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`. -# `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} -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: ${connectivity_resource_group_ddos} -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: ${connectivity_resource_group_vnet_primary} - subnets: - virtual_network_gateway: - address_prefixes: - - 10.0.1.0/24 - assign_generated_route_table: false - name: GatewaySubnet - tags: - deployment: terraform - source: Azure Landing Zones Accelerator - private_dns_zones: - is_primary: true - resource_group_name: ${connectivity_resource_group_dns} - 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 -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: ${connectivity_resource_group_ddos} - dns: - ${starter_location_01}: - name: ${connectivity_resource_group_dns} - 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 - deploy_management_resources: true - deploy_core_landing_zones: true - deploy_corp_landing_zones: true - deploy_online_landing_zones: true - 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} diff --git a/docs/wiki/examples/starter-module-config/complete-multi-region/config-virtual-wan-multi-region.yaml b/docs/wiki/examples/starter-module-config/complete-multi-region/config-virtual-wan-multi-region.yaml deleted file mode 100644 index 4f8ce3d..0000000 --- a/docs/wiki/examples/starter-module-config/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 (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_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`. -# `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-vwan-hub-${starter_location_01} - vnet_secondary: - location: ${starter_location_02} - name: rg-vwan-hub-${starter_location_02} - vwan: - location: ${starter_location_01} - name: rg-vwan-${starter_location_01} -connectivity_type: virtual_wan -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: ${connectivity_resource_group_ddos} - dns: - ${starter_location_01}: - name: ${connectivity_resource_group_dns} - 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 - deploy_management_resources: true - deploy_core_landing_zones: true - deploy_corp_landing_zones: true - deploy_online_landing_zones: true - 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} -virtual_wan_settings: - ddos_protection_plan: - location: ${starter_location_01} - name: ddos-hub-${starter_location_01} - resource_group_name: ${connectivity_resource_group_ddos} - location: ${starter_location_01} - name: vwan-hub-${starter_location_01} - resource_group_name: ${connectivity_resource_group_vwan} -virtual_wan_virtual_hubs: - primary: - firewall: - firewall_policy: - name: fwp-hub-${starter_location_01} - name: fw-hub-${starter_location_01} - sku_name: AZFW_Hub - sku_tier: Standard - zones: ${starter_location_01_availability_zones} - hub: - address_prefix: 10.0.0.0/16 - location: ${starter_location_01} - name: vwan-hub-${starter_location_01} - resource_group_name: ${connectivity_resource_group_vnet_primary} - private_dns_zones: - is_primary: true - networking: - private_dns_resolver: - name: pdr-hub-dns-${starter_location_01} - resource_group_name: ${connectivity_resource_group_vnet_primary} - virtual_network: - address_space: 10.10.0.0/24 - name: vnet-hub-dns-${starter_location_01} - private_dns_resolver_subnet: - address_prefix: 10.10.0.0/28 - name: subnet-hub-dns-${starter_location_01} - resource_group_name: ${connectivity_resource_group_vnet_primary} - resource_group_name: ${connectivity_resource_group_dns} - secondary: - firewall: - firewall_policy: - name: fwp-hub-${starter_location_02} - name: fw-hub-${starter_location_02} - sku_name: AZFW_Hub - sku_tier: Standard - zones: ${starter_location_02_availability_zones} - hub: - address_prefix: 10.1.0.0/16 - location: ${starter_location_02} - name: vwan-hub-${starter_location_02} - resource_group_name: ${connectivity_resource_group_vnet_secondary} - private_dns_zones: - is_primary: false - networking: - private_dns_resolver: - name: pdr-hub-dns-${starter_location_02} - resource_group_name: ${connectivity_resource_group_vnet_secondary} - virtual_network: - address_space: 10.11.0.0/24 - name: vnet-hub-dns-${starter_location_02} - private_dns_resolver_subnet: - address_prefix: 10.11.0.0/28 - name: subnet-hub-dns-${starter_location_02} - resource_group_name: ${connectivity_resource_group_vnet_secondary} - resource_group_name: ${connectivity_resource_group_dns} diff --git a/docs/wiki/examples/starter-module-config/complete-multi-region/config-virtual-wan-single-region.yaml b/docs/wiki/examples/starter-module-config/complete-multi-region/config-virtual-wan-single-region.yaml deleted file mode 100644 index 6d90fa7..0000000 --- a/docs/wiki/examples/starter-module-config/complete-multi-region/config-virtual-wan-single-region.yaml +++ /dev/null @@ -1,111 +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. -# `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`. -# `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-vwan-hub-${starter_location_01} - vwan: - location: ${starter_location_01} - name: rg-vwan-${starter_location_01} -connectivity_type: virtual_wan -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: ${connectivity_resource_group_ddos} - dns: - ${starter_location_01}: - name: ${connectivity_resource_group_dns} - 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 - deploy_management_resources: true - deploy_core_landing_zones: true - deploy_corp_landing_zones: true - deploy_online_landing_zones: true - 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} -virtual_wan_settings: - ddos_protection_plan: - location: ${starter_location_01} - name: ddos-hub-${starter_location_01} - resource_group_name: ${connectivity_resource_group_ddos} - location: ${starter_location_01} - name: vwan-hub-${starter_location_01} - resource_group_name: ${connectivity_resource_group_vwan} -virtual_wan_virtual_hubs: - primary: - firewall: - firewall_policy: - name: fwp-hub-${starter_location_01} - name: fw-hub-${starter_location_01} - sku_name: AZFW_Hub - sku_tier: Standard - zones: ${starter_location_01_availability_zones} - hub: - address_prefix: 10.0.0.0/16 - location: ${starter_location_01} - name: vwan-hub-${starter_location_01} - resource_group_name: ${connectivity_resource_group_vnet_primary} - private_dns_zones: - is_primary: true - networking: - private_dns_resolver: - name: pdr-hub-dns-${starter_location_01} - resource_group_name: ${connectivity_resource_group_vnet_primary} - virtual_network: - address_space: 10.10.0.0/24 - name: vnet-hub-dns-${starter_location_01} - private_dns_resolver_subnet: - address_prefix: 10.10.0.0/28 - name: subnet-hub-dns-${starter_location_01} - resource_group_name: ${connectivity_resource_group_vnet_primary} - resource_group_name: ${connectivity_resource_group_dns} diff --git a/src/ALZ/Private/Config-Helpers/Set-Config.ps1 b/src/ALZ/Private/Config-Helpers/Set-Config.ps1 index 4494010..05e1bc4 100644 --- a/src/ALZ/Private/Config-Helpers/Set-Config.ps1 +++ b/src/ALZ/Private/Config-Helpers/Set-Config.ps1 @@ -52,24 +52,47 @@ function Set-Config { Write-Error "Input config item $($inputConfigName) is not an array, but an index was specified." throw "Input config item $($inputConfigName) is not an array, but an index was specified." } - $index = [int]$indexSplit[1] - if($inputConfigItemValue.Length -le $index) { - Write-Verbose "Input config item $($inputConfigName) does not have an index of $index." - if($index -eq 0) { - Write-Error "At least one value is required for input config item $($inputConfigName)." - throw "At least one value is required for input config item $($inputConfigName)." + + $indexString = $indexSplit[1].Replace("`"", "").Replace("'", "") + + if($indexString -as [int]) { + # Handle integer index for arrays + $index = [int]$indexString + if($inputConfigItemValue.Length -le $index) { + Write-Verbose "Input config item $($inputConfigName) does not have an index of $index." + if($index -eq 0) { + Write-Error "At least one value is required for input config item $($inputConfigName)." + throw "At least one value is required for input config item $($inputConfigName)." + } + } else { + $inputConfigItemIndexValue = $inputConfigItemValue[$index] + if($null -ne $inputConfigItemIndexValue) { + $configurationValue.Value.Value = $inputConfigItemIndexValue + continue + } else { + Write-Verbose "Input config item $($inputConfigName) with index $index is null." + if($index -eq 0) { + Write-Error "At least one value is required for input config item $($inputConfigName)." + throw "At least one value is required for input config item $($inputConfigName)." + } + } } } else { - $inputConfigItemIndexValue = $inputConfigItemValue[$index] - if($null -ne $inputConfigItemIndexValue) { - $configurationValue.Value.Value = $inputConfigItemIndexValue - continue - } else { - Write-Verbose "Input config item $($inputConfigName) with index $index is null." - if($index -eq 0) { + # Handle string index for maps + if($inputConfigItemValue.ContainsKey($indexString)) { + $inputConfigItemIndexValue = $inputConfigItemValue[$indexString] + if($null -ne $inputConfigItemIndexValue) { + $configurationValue.Value.Value = $inputConfigItemIndexValue + continue + } else { + Write-Verbose "Input config item $($inputConfigName) with index $indexString is null." Write-Error "At least one value is required for input config item $($inputConfigName)." throw "At least one value is required for input config item $($inputConfigName)." } + } else { + Write-Verbose "Input config item $($inputConfigName) does not have an index of $indexString." + Write-Error "At least one value is required for input config item $($inputConfigName)." + throw "At least one value is required for input config item $($inputConfigName)." } } } else { From a5e6203fd30e0e47e38d334c7651b78405e26b8e Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Fri, 12 Sep 2025 13:30:20 +0100 Subject: [PATCH 2/5] add logging --- src/ALZ/Private/Config-Helpers/Set-Config.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ALZ/Private/Config-Helpers/Set-Config.ps1 b/src/ALZ/Private/Config-Helpers/Set-Config.ps1 index 05e1bc4..9b950f6 100644 --- a/src/ALZ/Private/Config-Helpers/Set-Config.ps1 +++ b/src/ALZ/Private/Config-Helpers/Set-Config.ps1 @@ -42,11 +42,13 @@ function Set-Config { continue } - # Look for array config match + # Look for collection config match if($inputConfigName.EndsWith("]")) { + Write-Verbose "Looking for collection input config match for $inputConfigName" $indexSplit = $inputConfigName.Split([char[]]@('[', ']'), [System.StringSplitOptions]::RemoveEmptyEntries) $inputConfigItem = $inputConfig.PsObject.Properties | Where-Object { $_.Name -eq $indexSplit[0] } if($null -ne $inputConfigItem) { + Write-Verbose "Found collection input config match for $inputConfigName" $inputConfigItemValue = $inputConfigItem.Value.Value if(!$inputConfigItemValue.GetType().ImplementedInterfaces.Contains([System.Collections.ICollection])) { Write-Error "Input config item $($inputConfigName) is not an array, but an index was specified." @@ -54,9 +56,11 @@ function Set-Config { } $indexString = $indexSplit[1].Replace("`"", "").Replace("'", "") + Write-Verbose "Using index $indexString for input config item $inputConfigName" if($indexString -as [int]) { # Handle integer index for arrays + Write-Verbose "Handling integer index for array" $index = [int]$indexString if($inputConfigItemValue.Length -le $index) { Write-Verbose "Input config item $($inputConfigName) does not have an index of $index." @@ -79,6 +83,7 @@ function Set-Config { } } else { # Handle string index for maps + Write-Verbose "Handling string index for map" if($inputConfigItemValue.ContainsKey($indexString)) { $inputConfigItemIndexValue = $inputConfigItemValue[$indexString] if($null -ne $inputConfigItemIndexValue) { From 21df6a3d84ad33313fa403df4a0916d10cce8e38 Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Fri, 12 Sep 2025 13:39:37 +0100 Subject: [PATCH 3/5] parse int --- src/ALZ/Private/Config-Helpers/Set-Config.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ALZ/Private/Config-Helpers/Set-Config.ps1 b/src/ALZ/Private/Config-Helpers/Set-Config.ps1 index 9b950f6..f641d61 100644 --- a/src/ALZ/Private/Config-Helpers/Set-Config.ps1 +++ b/src/ALZ/Private/Config-Helpers/Set-Config.ps1 @@ -58,7 +58,7 @@ function Set-Config { $indexString = $indexSplit[1].Replace("`"", "").Replace("'", "") Write-Verbose "Using index $indexString for input config item $inputConfigName" - if($indexString -as [int]) { + if([int]::TryParse($indexString, [ref]$null)) { # Handle integer index for arrays Write-Verbose "Handling integer index for array" $index = [int]$indexString From 5eb54230d9bb75c9ad86c46213a29bff7429217e Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Fri, 12 Sep 2025 13:46:29 +0100 Subject: [PATCH 4/5] add mor debugging --- src/ALZ/Private/Config-Helpers/Set-Config.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ALZ/Private/Config-Helpers/Set-Config.ps1 b/src/ALZ/Private/Config-Helpers/Set-Config.ps1 index f641d61..7c84f83 100644 --- a/src/ALZ/Private/Config-Helpers/Set-Config.ps1 +++ b/src/ALZ/Private/Config-Helpers/Set-Config.ps1 @@ -50,7 +50,10 @@ function Set-Config { if($null -ne $inputConfigItem) { Write-Verbose "Found collection input config match for $inputConfigName" $inputConfigItemValue = $inputConfigItem.Value.Value - if(!$inputConfigItemValue.GetType().ImplementedInterfaces.Contains([System.Collections.ICollection])) { + Write-Verbose "Input config item value type: $($inputConfigItemValue.GetType().FullName)" + $interfaces = $inputConfigItemValue.GetType().ImplementedInterfaces + Write-Verbose "Input config item interfaces: $interfaces" + if(!$interfaces.Contains([System.Collections.ICollection])) { Write-Error "Input config item $($inputConfigName) is not an array, but an index was specified." throw "Input config item $($inputConfigName) is not an array, but an index was specified." } From 5c2b87186400f20bd8aa2995e6620f358a0632ab Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Fri, 12 Sep 2025 14:02:20 +0100 Subject: [PATCH 5/5] handle as PSCustomObject --- src/ALZ/Private/Config-Helpers/Set-Config.ps1 | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/ALZ/Private/Config-Helpers/Set-Config.ps1 b/src/ALZ/Private/Config-Helpers/Set-Config.ps1 index 7c84f83..62a046c 100644 --- a/src/ALZ/Private/Config-Helpers/Set-Config.ps1 +++ b/src/ALZ/Private/Config-Helpers/Set-Config.ps1 @@ -50,13 +50,8 @@ function Set-Config { if($null -ne $inputConfigItem) { Write-Verbose "Found collection input config match for $inputConfigName" $inputConfigItemValue = $inputConfigItem.Value.Value - Write-Verbose "Input config item value type: $($inputConfigItemValue.GetType().FullName)" - $interfaces = $inputConfigItemValue.GetType().ImplementedInterfaces - Write-Verbose "Input config item interfaces: $interfaces" - if(!$interfaces.Contains([System.Collections.ICollection])) { - Write-Error "Input config item $($inputConfigName) is not an array, but an index was specified." - throw "Input config item $($inputConfigName) is not an array, but an index was specified." - } + $inputConfigItemValueType = $inputConfigItemValue.GetType().FullName + Write-Verbose "Input config item value type: $inputConfigItemValueType" $indexString = $indexSplit[1].Replace("`"", "").Replace("'", "") Write-Verbose "Using index $indexString for input config item $inputConfigName" @@ -64,6 +59,12 @@ function Set-Config { if([int]::TryParse($indexString, [ref]$null)) { # Handle integer index for arrays Write-Verbose "Handling integer index for array" + + if(!$inputConfigItemValueType.EndsWith("[]")) { + Write-Error "Input config item $($inputConfigName) is not an array, but an index was specified." + throw "Input config item $($inputConfigName) is not an array, but an index was specified." + } + $index = [int]$indexString if($inputConfigItemValue.Length -le $index) { Write-Verbose "Input config item $($inputConfigName) does not have an index of $index." @@ -87,8 +88,15 @@ function Set-Config { } else { # Handle string index for maps Write-Verbose "Handling string index for map" - if($inputConfigItemValue.ContainsKey($indexString)) { - $inputConfigItemIndexValue = $inputConfigItemValue[$indexString] + + if(!$inputConfigItemValueType.EndsWith("PSCustomObject")) { + Write-Error "Input config item $($inputConfigName) is not a map, but a key was specified." + throw "Input config item $($inputConfigName) is not a map, but a key was specified." + } + + $mapItem = $inputConfigItemValue.PsObject.Properties | Where-Object { $_.Name -eq $indexString } + if($null -ne $mapItem) { + $inputConfigItemIndexValue = $mapItem.Value if($null -ne $inputConfigItemIndexValue) { $configurationValue.Value.Value = $inputConfigItemIndexValue continue