From 4f345fa87717d771d1b5d65ee9487dad579106db Mon Sep 17 00:00:00 2001 From: Jared Holgate Date: Fri, 13 Dec 2024 15:33:05 +0000 Subject: [PATCH] feat: azure verified modules for alz platform landing zone starter docs (#7) * stub out AVM starter docs * Save changes * Save changes * Save changes * Save changes * Save changes * Save changes * Save changes * Save changes * save changes * Save changes * save changes * save changes * save changes * Save changes * Save changes * Save changes * save changes * Fixing links * Latest updates and fixes * Minor fixes * Update docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-virtual-wan-with-azure-firewall.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-virtual-wan-with-azure-firewall.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-virtual-wan-with-nva.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-virtual-wan-with-nva.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-hub-and-spoke-vnet-with-azure-firewall.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-hub-and-spoke-vnet-with-azure-firewall.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- DEVELOPER.md | 9 +- docs/content/accelerator/_index.md | 4 +- .../accelerator/startermodules/_index.md | 6 +- .../startermodules/bicepcomplete.md | 2 +- .../terraform-platform-landing-zone/_index.md | 477 ++++++++++++++++++ .../management_only.md | 29 ++ ...-hub-and-spoke-vnet-with-azure-firewall.md | 86 ++++ ...ulti-region-hub-and-spoke-vnet-with-nva.md | 80 +++ ...-region-virtual-wan-with-azure-firewall.md | 83 +++ .../multi-region-virtual-wan-with-nva.md | 77 +++ ...-hub-and-spoke-vnet-with-azure-firewall.md | 89 ++++ ...-region-virtual-wan-with-azure-firewall.md | 87 ++++ .../startermodules/terraformbasic.md | 26 - .../img/starter-module-hubnetworking.png | Bin 65369 -> 0 bytes .../startermodules/terraformcomplete/index.md | 77 --- .../terraformcompletemultiregion.md | 95 ---- .../startermodules/terraformfsi/index.md | 10 +- .../startermodules/terraformhubnetworking.md | 30 -- .../terraformsovereign/index.md | 10 +- .../startermodules/terrafromcompletevnext.md | 74 --- docs/content/accelerator/troubleshooting.md | 45 +- docs/content/accelerator/upgradeguide.md | 4 + .../1_prerequisites/1a_serviceprincipal.md | 3 +- .../userguide/1_prerequisites/_index.md | 7 +- .../userguide/2_start/2a_github.md | 40 +- .../userguide/2_start/2b_azuredevops.md | 41 +- .../accelerator/userguide/2_start/2c_local.md | 41 +- .../accelerator/userguide/2_start/_index.md | 3 +- .../content/accelerator/userguide/3_deploy.md | 3 +- docs/content/accelerator/userguide/_index.md | 10 +- .../userguide/advancedscenarios.md | 60 +-- .../accelerator/yamlschemareference.md | 211 -------- .../connectivity_resource_groups.tfvars | 43 ++ .../config/connectivity_type.tfvars | 8 + ...custom_replacements.names.ip_ranges.tfvars | 70 +++ .../config/custom_replacements.names.tfvars | 29 ++ ...acements.resource_group_identifiers.tfvars | 6 + ...m_replacements.resource_identifiers.tfvars | 10 + .../config/enable_telemetry.tfvars | 1 + .../config/hub_and_spoke_vnet_settings.tfvars | 7 + ...hub_and_spoke_vnet_virtual_networks.tfvars | 92 ++++ .../alz.alz_architecture_definition.json | 96 ++++ .../config/management_group_settings.tfvars | 68 +++ .../management_resource_settings.tfvars | 22 + .../tf/accelerator/config/tags.tfvars | 4 + .../config/virtual_wan_settings.tfvars | 10 + .../config/virtual_wan_virtual_hubs.tfvars | 60 +++ docs/themes/hugo-geekdoc/static/custom.css | 6 + 48 files changed, 1692 insertions(+), 659 deletions(-) create mode 100644 docs/content/accelerator/startermodules/terraform-platform-landing-zone/_index.md create mode 100644 docs/content/accelerator/startermodules/terraform-platform-landing-zone/management_only.md create mode 100644 docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-hub-and-spoke-vnet-with-azure-firewall.md create mode 100644 docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-hub-and-spoke-vnet-with-nva.md create mode 100644 docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-virtual-wan-with-azure-firewall.md create mode 100644 docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-virtual-wan-with-nva.md create mode 100644 docs/content/accelerator/startermodules/terraform-platform-landing-zone/single-region-hub-and-spoke-vnet-with-azure-firewall.md create mode 100644 docs/content/accelerator/startermodules/terraform-platform-landing-zone/single-region-virtual-wan-with-azure-firewall.md delete mode 100644 docs/content/accelerator/startermodules/terraformbasic.md delete mode 100644 docs/content/accelerator/startermodules/terraformcomplete/img/starter-module-hubnetworking.png delete mode 100644 docs/content/accelerator/startermodules/terraformcomplete/index.md delete mode 100644 docs/content/accelerator/startermodules/terraformcompletemultiregion.md delete mode 100644 docs/content/accelerator/startermodules/terraformhubnetworking.md delete mode 100644 docs/content/accelerator/startermodules/terrafromcompletevnext.md delete mode 100644 docs/content/accelerator/yamlschemareference.md create mode 100644 docs/static/examples/tf/accelerator/config/connectivity_resource_groups.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/connectivity_type.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/custom_replacements.names.ip_ranges.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/custom_replacements.names.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/custom_replacements.resource_group_identifiers.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/custom_replacements.resource_identifiers.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/enable_telemetry.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/hub_and_spoke_vnet_settings.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/hub_and_spoke_vnet_virtual_networks.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/lib/architecture_definitions/alz.alz_architecture_definition.json create mode 100644 docs/static/examples/tf/accelerator/config/management_group_settings.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/management_resource_settings.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/tags.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/virtual_wan_settings.tfvars create mode 100644 docs/static/examples/tf/accelerator/config/virtual_wan_virtual_hubs.tfvars diff --git a/DEVELOPER.md b/DEVELOPER.md index d2ada25..1f2c8c6 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -7,19 +7,24 @@ Make sure you install the same version as the one specified in the `.github/work ## Creating a local HTTP server -To create a local HTTP server, if you have GNU make installed, run the following command: +To create a local HTTP server, if you are on Linux and have GNU make installed, run the following command: ```bash make server ``` -Alternatively, you can run the following commands: +Alternatively, you can run the following commands on Linux or Windows: ```bash cd docs hugo server ``` +```pwsh +cd docs +hugo server +``` + The server will start and you can access the documentation at . You can stop the server by pressing `Ctrl+C`. diff --git a/docs/content/accelerator/_index.md b/docs/content/accelerator/_index.md index 73806f4..bc9c073 100644 --- a/docs/content/accelerator/_index.md +++ b/docs/content/accelerator/_index.md @@ -35,7 +35,7 @@ The accelerator follows a 3 phase approach: 1. Pre-requisites: Instructions to configure credentials and subscriptions. 2. Bootstrap: Run the PowerShell module to generate the continuous delivery environment. -3. Run: Update the module (if needed) to suit the needs of your organisation and deploy via continuous delivery. +3. Run: Update the module (if needed) to suit the needs of your organization and deploy via continuous delivery. {{< img name="overview" size="origin" lazy=true >}} @@ -66,7 +66,7 @@ The components of the environment are similar, but differ depending on your choi - Environment for Apply - Action Variables for Backend and Plan / Apply - Team and Members for Apply Approval - - Customised OIDC Token Subject for governed Actions + - Customized OIDC Token Subject for governed Actions - [Optional] Runner Group ### Azure DevOps diff --git a/docs/content/accelerator/startermodules/_index.md b/docs/content/accelerator/startermodules/_index.md index 554b8b9..1238490 100644 --- a/docs/content/accelerator/startermodules/_index.md +++ b/docs/content/accelerator/startermodules/_index.md @@ -1,6 +1,6 @@ --- title: Starter modules -weight: 15 +weight: 10 geekdocCollapseSection: true --- @@ -11,8 +11,6 @@ These are called starter modules because the expectation is you'll update these Each starter module expects different inputs and the following pages detail those inputs. You'll be prompted for these inputs when you run the Accelerator PowerShell module. - [Bicep Complete Starter Module]({{< relref "bicepcomplete" >}}): Management groups, policies and hub networking. -- [Terraform Basic Starter Module]({{< relref "terraformbasic" >}}): Management groups and policies. -- [Terraform Hub Networking Starter Module]({{< relref "terraformhubnetworking" >}}): Management groups, policies and hub networking. -- [Terraform Complete Starter Module]({{< relref "terraformcomplete" >}}): Management groups, policies, hub networking with fully custom configuration. +- [Terraform Azure Verified Modules for Platform Landing Zone (ALZ)]({{< relref "terraform-platform-landing-zone" >}}): Management groups, policies, hub networking with fully custom configuration. - [Terraform FSI Starter Module]({{< relref "terraformfsi" >}}): Management groups, policies, hub networking and financial services industry (FSI) specific configurations. - [Terraform Sovereign Starter Module]({{< relref "terraformsovereign" >}}): Management groups, policies, hub networking and sovereign cloud specific configurations. diff --git a/docs/content/accelerator/startermodules/bicepcomplete.md b/docs/content/accelerator/startermodules/bicepcomplete.md index 9c3b585..70fbae6 100644 --- a/docs/content/accelerator/startermodules/bicepcomplete.md +++ b/docs/content/accelerator/startermodules/bicepcomplete.md @@ -1,5 +1,5 @@ --- -title: Bicep complete +title: Bicep - Complete --- The `complete` starter module is currently the only option available for Bicep. diff --git a/docs/content/accelerator/startermodules/terraform-platform-landing-zone/_index.md b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/_index.md new file mode 100644 index 0000000..c4b4a22 --- /dev/null +++ b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/_index.md @@ -0,0 +1,477 @@ +--- +title: Terraform - Azure Verified Modules for Platform Landing Zone (ALZ) +geekdocCollapseSection: true +--- + +The `platform_landing_zone` starter module deploys the end to end platform landing zone using Azure Verified Modules. It is fully configurable to meet different customer scenarios. + +This documentation covers the top scenarios and documents all available configuration settings for this module. + +We aim to cover 80% of common customer scenarios. If the particular customer scenario is not covered here, it may be possible to adjust the configuration settings to match the customer requirements. If not, then it my be the case the customer needs to adjust their Terraform code post bootstrap. + +This documentation covers the following: + +* [Usage](#usage): How to use this starter module +* [Scenarios](#scenarios): The scenarios supported with example configuration files +* [How To](#how-to): Common customization tasks and how to perform them are documented here +* [Platform landing zone configuration file](#platform-landing-zone-configuration-file): Comprehensive documentation of the available input variables +* [Azure Verified Modules Reference](#azure-verified-modules-reference): A reference list and explanation of the Azure Verified Modules used in this starter module + +## Usage + +To use the module, follow the detailed steps documented in phases 1, 2, and 3 of the Accelerator. Here we cover come specifics to help with understanding. + +There are 3 sets of configuration that can be supplied to the accelerator to pre-configure it. + +### Bootstrap Configuration File + +This is the YAML file used to provide the base configuration required to bootstrap your version control system and Azure. + +Some of this configuration is also fed into this starter module. You will see a `terraform.tfvars.json` file is created to hold these inputs. They include management group ID, subscriptions IDs, starter locations, etc. + +We provide examples of this file for each version control system. These can be found in the [Phase 2]({{< relref "/accelerator/userguide/2_start" >}}) documentation, but are also listed here for convenience: + +* Azure DevOps: [inputs-azure-devops.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/bootstrap/inputs-azure-devops.yaml) +* GitHub: [inputs-github.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/bootstrap/inputs-github.yaml) +* Local: [inputs-local.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/bootstrap/inputs-local.yaml) + +### Platform Landing Zone Configuration File + +This is the `tfvars` file in HCL format that determines which resources are deployed and what type of hub networking connectivity is deployed. + +This file is validated by the accelerator and then directly copied to your repository, so it retains the ordering, comments, etc. You will see the file is renamed to `*.auto.tfvars`, so that it is automatically picked up by Terraform. + +We provide examples of this file for each scenario. These can be found in the [scenarios](#scenarios) documentation. + +### Platform Landing Zone Library (lib) Folder + +This is a folder of configuration files used to customize the management groups and associated policies. This library and its usage is documented alongside the `avm-ptn-alz` module. However, we cover a common customization use case in our [How To](#how-to) section. + +By default we supply an empty `lib` folder. This folder can be overridden with a set of files to customize Management Groups and Policy Assignments. Use cases include: + +* Renaming management groups +* Customizing the management group structure +* Removing policy assignments +* Adding custom policy definitions and assignments + +The detailed documentation for the library and it's usage can be found here: + +* Platform Landing Zone Library Documentation: https://azure.github.io/Azure-Landing-Zones-Library/ +* Azure Verified Module for Management Groups and Policy: https://registry.terraform.io/modules/Azure/avm-ptn-alz/azurerm/0.10.0 + +## Scenarios + +Scenarios are common customer use cases when deploying the platform landing zone. The following section provide a description of the scenario and link to the pre-configured files for that scenario. + +### Multi-Region Hub and Spoke Virtual Network with Azure Firewall + +A full platform landing zone deployment with hub and spoke Virtual Network connectivity using Azure Firewall in multiple regions. + +* Example Platform landing zone configuration file: [full-multi-region/hub-and-spoke-vnet.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/full-multi-region/hub-and-spoke-vnet.tfvars) +* Detailed documentation: [Multi-region hub and spoke virtual network with Azure Firewall]({{< relref "multi-region-hub-and-spoke-vnet-with-azure-firewall" >}}) + +### Multi-Region Virtual WAN with Azure Firewall + +A full platform landing zone deployment with Virtual WAN network connectivity using Azure Firewall in multiple regions. + +* Example platform landing zone configuration file: [full-multi-region/virtual-wan.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/full-multi-region/virtual-wan.tfvars) +* Detailed documentation: [Multi-region virtual wan with Azure Firewall]({{< relref "multi-region-virtual-wan-with-azure-firewall" >}}) + +### Multi-Region Hub and Spoke Virtual Network with Network Virtual Appliance (NVA) + +A full platform landing zone deployment with hub and spoke Virtual Network connectivity in multiple regions, ready for a third party Network Virtual Appliance (NVA). + +* Example platform landing zone configuration file: [full-multi-region-nva/virtual-wan.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/full-multi-region-nva/virtual-wan.tfvars) +* Detailed documentation: [Multi-region virtual wan with Network Virtual Appliance]({{< relref "multi-region-virtual-wan-with-nva" >}}) + +### Multi-Region Virtual WAN with Network Virtual Appliance (NVA) + +A full platform landing zone deployment with Virtual WAN network connectivity in multiple regions, ready for a third party Network Virtual Appliance (NVA). + +* Example platform landing zone configuration file: [full-multi-region-nva/virtual-wan.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/full-multi-region-nva/virtual-wan.tfvars) +* Detailed documentation: [Multi-region virtual wan with Azure Firewall]({{< relref "multi-region-virtual-wan-with-nva" >}}) + +### Single-Region Hub and Spoke Virtual Network with Azure Firewall + +A full platform landing zone deployment with hub and spoke Virtual Network connectivity using Azure Firewall in a single region. + +{{< hint type=warning >}} +The single region option is here for completeness, we recommend always having at least 2 regions to support resiliency. +{{< /hint >}} + +* Example Platform landing zone configuration file: [full-single-region/hub-and-spoke-vnet.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/full-single-region/hub-and-spoke-vnet.tfvars) +* Detailed documentation: [Single-region hub and spoke virtual network with Azure Firewall]({{< relref "multi-region-hub-and-spoke-vnet-with-azure-firewall" >}}) + +### Single-Region Virtual WAN with Azure Firewall + +A full platform landing zone deployment with Virtual WAN network connectivity using Azure Firewall in a single region. + +{{< hint type=warning >}} +The single region option is here for completeness, we recommend always having at least 2 regions to support resiliency. +{{< /hint >}} + +* Example platform landing zone configuration file: [full-single-region/virtual-wan.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/full-single-region/virtual-wan.tfvars) +* Detailed documentation: [Single-region virtual wan with Azure Firewall]({{< relref "multi-region-virtual-wan-with-azure-firewall" >}}) + +### Management Groups, Policy and Management Resources Only + +A platform landing zone deployment without any connectivity resources. + +* Example Platform landing zone configuration file: [management_only/management.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/management_only/management.tfvars) +* Detailed documentation: [Management Only]({{< relref "management_only" >}}) + +## How to + +The how to section details how to make configuration changes that apply to the common scenarios. + +### Customize Management Group Names and IDs + +The customer may want to customize the management groups names and IDs. In order to do this they need to supply a `lib` folder to the accelerator. + +The `lib` folder should contain the following structure (we are showing it nested under the standard accelerator file structure here): + +```plaintext +📂accelerator +┣ 📂config +┃ ┣ 📂lib +┃ ┃ ┗ 📂architecture_definitions +┃ ┃ ┗ 📜alz.alz_architecture_definition.json +┃ ┗ 📜inputs.yaml +┗ 📂output +``` +{{< hint type=warning >}} +The `lib` folder must be named `lib`, any other name will not work +{{< /hint >}} + +The `alz.alz_architecture_definition.json` file content should be copied from [here](https://github.com/Azure/Azure-Landing-Zones-Library/blob/main/platform/alz/architecture_definitions/alz.alz_architecture_definition.json). + +The customer can then edit this configuration file to update the management group names and IDs. + +For example to prefix all the management group display names with `Contoso` and update the management group IDs to have the `contoso-` prefix they can update the file to look like this: + +{{< include file="/static/examples/tf/accelerator/config/lib/architecture_definitions/alz.alz_architecture_definition.json" language="json" >}} + +{{< hint type=tip >}} +When updating the management group `id`, you also need to consider any child management groups that refer to it by the `parent_id` +{{< /hint >}} + +Now, when deploying the accelerator they need to supply their lib folder as an argument with `starterAdditionalFiles`: + +```pwsh +Deploy-Accelerator -inputs "c:\accelerator\config\inputs.yaml", "c:\accelerator\config\networking.yaml" -starterAdditionalFiles "c:\accelerator\config\lib" -output "c:\accelerator\output" +``` + +### Turn off DDOS protection plan + +The customer can choose to not deploy a DDOS protection plan. In order to do that, they need to remove the DDOS protection plan configuration and disable the DINE policy. The customer can either comment out or remove the configuration entirely. + +{{< hint type=warning >}} +DDOS Protection plan is a critical security protection for public facing services. Carefully consider this and be sure to put in place an alternative solution, such as per IP protection. +{{< /hint >}} + +The steps to follow are: + +1. To keep the code tidy remove the follow settings from `custom_replacements.names`: + 1. `ddos_resource_group_name` + 1. `ddos_protection_plan_name` +1. To keep the code tidy remove the follow settings from `custom_replacements.resource_group_identifiers`: + 1. `ddos_protection_plan_resource_group_id` +1. To keep the code tidy remove the follow settings from `custom_replacements.resource_identifiers`: + 1. `ddos_protection_plan_id` +1. Remove the follow configuration settings from `management_group_settings.policy_default_values`: + 1. `ddos_protection_plan_id` +1. Add the follow section to `management_group_settings.policy_assignments_to_modify`: + ```terraform + connectivity = { + policy_assignments = { + Enable-DDoS-VNET = { + enforcement_mode = "DoNotEnforce" + } + } + } + ``` +1. Remove the whole `ddos_protection_plan` section from `hub_and_spoke_vnet_settings` or `virtual_wan_settings` + +### Turn off Bastion host + +The customer can choose to not deploy a Bastion Host. In order to do that, they need to remove the Bastion Host configuration. The customer can either comment out or remove the configuration entirely. + +The steps to follow are: + +1. To keep the code tidy remove the follow settings from `custom_replacements.names`: + 1. `_bastion_subnet_address_prefix` where `` is for each region +1. Remove the whole `bastion` section from each `hub_and_spoke_vnet_virtual_networks` or `virtual_wan_virtual_hubs` region + +### Turn off Private DNS zones and Private DNS resolver + +The customer can choose to not deploy any DNS related resources. In order to do that, they need to remove the DNS configuration and disable the DINE policy. The customer can either comment out or remove the configuration entirely. + +The steps to follow are: + +1. To keep the code tidy remove the follow settings from `custom_replacements.names`: + 1. `dns_resource_group_name` + 1. `_private_dns_resolver_subnet_address_prefix` where `` is for each region +1. Remove the follow configuration settings from `management_group_settings.policy_default_values`: + 1. `private_dns_zone_subscription_id` + 1. `private_dns_zone_region` + 1. `private_dns_zone_resource_group_name` +1. Add the follow section to `management_group_settings.policy_assignments_to_modify`: + ```terraform + corp = { + policy_assignments = { + Deploy-Private-DNS-Zones = { + enforcement_mode = "DoNotEnforce" + } + } + } + ``` +1. Remove the whole `private_dns_zones` section from each `hub_and_spoke_vnet_virtual_networks` or `virtual_wan_virtual_hubs` region + +### Additional Regions + +Additional regions are supported. The custom can add up to 10 regions using the out of the box module. + +{{< hint type=tip >}} +If a customer needs to scale beyond 10 regions, that can be accomodated by adding additional built in replacements [here](https://github.com/Azure/alz-terraform-accelerator/blob/cf0b37351cd4f2dde9d2cf20642d76bacadf923c/templates/platform_landing_zone/locals.config.tf#L2) +{{< /hint >}} + +To add an additional regions, the process is `copy` -> `paste` -> `update`: + +1. Copy, paste and update the regional resource group names in `custom_replacements.names` +1. Copy, paste and update the regional IP Ranges in `custom_replacements.names` +1. Copy, paste and update the regional resource group in `connectivity_resource_groups` +1. Copy, paste and update the region in `hub_and_spoke_vnet_virtual_networks` or `virtual_wan_virtual_hubs` + +### IP Address Ranges + +The example configuration files that include connectivity include an out of the box set of ip address ranges. These ranges have been chosen to support a real world scenario with optimal use to avoid ip exhaustion as a customer scales. However many customers will not want to use these ranges if they may overlap with their existing ranges or they are planning to scale beyond the /16 per region we cater for. + +In order to update the IP ranges, you can update the `custom_replacements.names` section that includes the IP ranges. For example if the customer prefers to use `172.16` or `192.168`, they could update the ranges as follows: + +{{< include file="/static/examples/tf/accelerator/config/custom_replacements.names.ip_ranges.tfvars" language="terraform" >}} + +## Platform landing zone configuration file + +This section details the available configuration settings / variables in this starter module. + +### Custom Replacements (`custom_replacements`) + +The `custom_replacements` variable builds on the built-in replacements to provide user defined replacements that can be used throughout your configuration. This reduces the complexity of the configuration file by allowing re-use of names and other definitions that may be repeated throughout the configuration. + +There are 4 layers of replacements that can be built upon to provide the level of flexibility you need. The order of precendence determines which other replacements can be used to build your replacement. For example a 'Name' replacement can be used to build a 'Resource Group Identifier' replacement, but a 'Resource Group Identifier' replacement cannot be used to build a 'Name' replacement. + +The layers and precedence order is: + +1. Built-in Replacements: These can be found at the top of our example config files and you can also see them in the code base [here](https://github.com/Azure/alz-terraform-accelerator/blob/cf0b37351cd4f2dde9d2cf20642d76bacadf923c/templates/platform_landing_zone/locals.config.tf#L2) +2. Names: This is for resource names and other basic strings +3. Resource Group Identifiers: This is for resource group IDs +4. Resource Identifiers: This is for resource IDs + +#### Names (`custom_replacements.names`) + +Used to define custom names and strings that can be used throughout the configuration file. This can leverage the built-in replacements. + +Exanple usage: + +{{< include file="/static/examples/tf/accelerator/config/custom_replacements.names.tfvars" language="terraform" >}} + +#### Resource Group Identifiers (`custom_replacements.resource_group_identifiers`) + +Used to define resource group IDs that can be used throughout the configuration file. This can leverage the built-in replacements and custom names. + +Exanple usage: + +{{< include file="/static/examples/tf/accelerator/config/custom_replacements.resource_group_identifiers.tfvars" language="terraform" >}} + +#### Resource Identifiers (`custom_replacements.resource_identifiers`) + +Used to define resource IDs that can be used throughout the configuration file. This can leverage the built-in replacements, custom names, and resource group IDs. + +Exanple usage: + +{{< include file="/static/examples/tf/accelerator/config/custom_replacements.resource_identifiers.tfvars" language="terraform" >}} + +### Enable Telemetry (`enable_telemetry`) + +The `enable_telemetry` variable determines whether telemetry about module usage is sent to Microsoft, enabling us to invest in improvements to the Accelerator and Azure Verified Modules. + +Example usage: + +{{< include file="/static/examples/tf/accelerator/config/enable_telemetry.tfvars" language="terraform" >}} + +### Tags (`tags`) + +The `tags` variable is a default set of tags to apply to resources that support them. In many cases, these tags can be overriden on a per resource basis. + +Example usage: + +{{< include file="/static/examples/tf/accelerator/config/tags.tfvars" language="terraform" >}} + +### Management Resource Settings (`management_resource_settings`) + +The `management_resource_settings` variable is used to configure the management resources. This includes the log analytics workspace, automation account, and data collection rules for Azure Monitoring Agent (AMA). + +This variable is of type `any` as it maps directly to the Azure Verified Module variables. To determine what can be supplied to this variable you can refer to the documentation for this module directly: + +Documentation link: [registry.terraform.io/modules/Azure/avm-ptn-alz-management](https://registry.terraform.io/modules/Azure/avm-ptn-alz-management/azurerm/0.4.0?tab=inputs) + +Example usage: + +{{< include file="/static/examples/tf/accelerator/config/management_resource_settings.tfvars" language="terraform" >}} + +### Management Group Settings (`management_group_settings`) + +The `management_group_settings` variable is used to configure the management groups, policies, and policy role assignments. + +This variable is of type `any` as it maps directly to the Azure Verified Module variables. To determine what can be supplied to this variable you can refer to the documentation for this module directly: + +Documentation link: [registry.terraform.io/modules/Azure/avm-ptn-alz](https://registry.terraform.io/modules/Azure/avm-ptn-alz/azurerm/0.10.0?tab=inputs) + +Example usage: + +{{< include file="/static/examples/tf/accelerator/config/management_group_settings.tfvars" language="terraform" >}} + +### Connectivity Type (`connectivity_type`) + +The `connectivity_type` variable is used to choose the type of connectivity to deploy. Supported values are: + +* `hub_and_spoke_vnet`: Deploy hub and spoke networking using Azure Virtual Networks +* `virtual_wan`: Deploy Azure Virtual WAN networking +* `none`: Don't deploy any networking + +Example usage: + +{{< include file="/static/examples/tf/accelerator/config/connectivity_type.tfvars" language="terraform" >}} + +### Connectivity Resource Groups (`connectivity_resource_groups`) + +The `connectivity_resource_groups` variable is used to specify the name and location of the resource groups used for connectivity. + +This variable is a `map(object)` and has two properties: + +* `name`: The resource group name +* `location`: The resource group location + +Example usage: + +{{< include file="/static/examples/tf/accelerator/config/connectivity_resource_groups.tfvars" language="terraform" >}} + +### Hub and Spoke Virtual Network Settings (`hub_and_spoke_vnet_settings`) + +The `hub_and_spoke_vnet_settings` variable is used to set the non-regional settings for the hub and spoke Virtual Network connectivity option. It is only used to set the DDOS Protection Plan at this time. + +This variable is of type `any` as it will be used for other purposes moving forward. + +Example usage: + +{{< include file="/static/examples/tf/accelerator/config/hub_and_spoke_vnet_settings.tfvars" language="terraform" >}} + +### Hub and Spoke Virtual Networks (`hub_and_spoke_vnet_virtual_networks`) + +The `hub_and_spoke_vnet_virtual_networks` variable is used to set the regional settings for the hub and spoke Virtual Network connectivity options. This includes Hub Networks, Peering, Routing, Subnets, Firewalls, Virtual Network Gateways, Bastion Hosts, Private DNS Zones, and Private DNS Resolver + +This variable is of type `map(object)`. Some of the object properties map directly to the Azure Verified Module variables. To determine what can be supplied to these variable you can refer to the documentation for this module directly. + +The `map(object)` definition can be found [here](https://github.com/Azure/alz-terraform-accelerator/blob/cf0b37351cd4f2dde9d2cf20642d76bacadf923c/templates/platform_landing_zone/modules/hub-and-spoke-vnet/variables.tf#L14). + +The supported object properties are: + +* `hub_virtual_network`: This `object` maps directly to the variables of the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-ptn-hubnetworking](https://registry.terraform.io/modules/Azure/avm-ptn-hubnetworking/azurerm/0.4.0?tab=inputs) +* `bastion`: This an `object` to specify the Bastion Host settings (omit this object if you don't want to deploy a Bastion Host) + * `subnet_address_prefix`: The Bastion Host subnet address space + * `bastion_host`: This `object` maps directly to the variables of the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-res-network-bastionhost](https://registry.terraform.io/modules/Azure/avm-res-network-bastionhost/azurerm/0.3.1?tab=inputs) + * `bastion_public_ip`: This `object` maps directly to the variables of the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-res-network-publicipaddress](https://registry.terraform.io/modules/Azure/avm-res-network-publicipaddress/azurerm/0.1.2?tab=inputs) +* `virtual_network_gateways`: This an `object` to specify the Virtual Network Gateways settings (omit this object if you don't want to deploy any Virtual Network Gateways) + * `subnet_address_prefix`: The Virtual Network Gateway subnet address space + * `express_route`: This `object` maps directly to the variables of the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-ptn-vnetgateway](https://registry.terraform.io/modules/Azure/avm-ptn-vnetgateway/azurerm/0.5.0?tab=inputs) + * `vpn`: This `object` maps directly to the variables of the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-ptn-vnetgateway](https://registry.terraform.io/modules/Azure/avm-ptn-vnetgateway/azurerm/0.5.0?tab=inputs) +* `private_dns_zones`: This an `object` to specify the Private DNS Zone settings (omit this object if you don't want to deploy any Private DNS Zones) + * `subnet_address_prefix`: The Private DNS Resolver subnet address space + * `resource_group_name`: The name of the resource group to deploy the Private DNS Zones into + * `is_primary`: Whether this is the primary region. Any non-regional Private Link Private DNS Zones will be deployed into this region. Although the Private DNS Zones are a global resource, their meta-data needs to reside in a specific region. + * `private_link_private_dns_zones`: This is a `map(object)` used to override the Private Link Private DNS Zones that are deployed, leave this empty to deploy the default set of zones specified by ALZ + * `zone_name`: The name of the Private DNS Zone to deploy + * `auto_registration_zone_enabled`: Whether to deploy the Virtual Machine auto-registration Private DNS Zone + * `auto_registration_zone_name`: The name of the Virtual Machine auto-registration Private DNS Zone + * `private_dns_resolver`: This is an `object` to specify the Private DNS Resolver + * `name`: The name of the Private DNS Resolver + * `resource_group_name`: The name of the resource group to deploy the Private DNS Resolver into + * `ip_address`: The static IP Address of the Private DNS Resolver. This will be auto calculated if not supplied + +Example usage: + +{{< include file="/static/examples/tf/accelerator/config/hub_and_spoke_vnet_virtual_networks.tfvars" language="terraform" >}} + +### Virtual WAN Settings (`virtual_wan_settings`) + +The `virtual_wan_settings` variable is used to set the non-regional settings for the Virtual WAN connectivity option. It is used to set the Virtual WAN non-regional properites and the DDOS Protection Plan. + +This variable is of type `any` as it maps directly to the Azure Verified Module variables. To determine what can be supplied to this variable you can refer to the documentation for this module directly: + +Documentation link: [registry.terraform.io/modules/Azure/avm-ptn-virtualwan](https://registry.terraform.io/modules/Azure/avm-ptn-virtualwan/azurerm/0.5.3?tab=inputs) + +Example usage: + +{{< include file="/static/examples/tf/accelerator/config/virtual_wan_settings.tfvars" language="terraform" >}} + +### Virtual WAN Virtual Hubs (`virtual_wan_virtual_hubs`) + +The `hub_and_spoke_vnet_virtual_networks` variable is used to set the regional settings for the Virtual WAN connectivity options. This includes Virtual WAN Hubs, Firewalls, Virtual Network Gateways, Bastion Hosts, Private DNS Zones, and Private DNS Resolver + +This variable is of type `map(object)`. Some of the object properties map directly to the Azure Verified Module variables. To determine what can be supplied to these variable you can refer to the documentation for this module directly. + +The `map(object)` definition can be found [here](https://github.com/Azure/alz-terraform-accelerator/blob/cf0b37351cd4f2dde9d2cf20642d76bacadf923c/templates/platform_landing_zone/modules/hub-and-spoke-vnet/variables.tf#L14). + +The supported object properties are: + +* `hub`: This `object` maps directly to the `virtual_hubs` variable of the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-ptn-virtualwan](https://registry.terraform.io/modules/Azure/avm-ptn-virtualwan/azurerm/0.5.3?tab=inputs) +* `firewall`: This `object` maps directly to the `firewalls` variable of the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-ptn-virtualwan](https://registry.terraform.io/modules/Azure/avm-ptn-virtualwan/azurerm/0.5.3?tab=inputs) +* `firewall_policy`: This `object` maps directly to the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-res-network-firewallpolicy](https://registry.terraform.io/modules/Azure/avm-res-network-firewallpolicy/azurerm/0.2.3?tab=inputs) +* `bastion`: This an `object` to specify the Bastion Host settings (omit this object if you don't want to deploy a Bastion Host) + * `subnet_address_prefix`: The Bastion Host subnet address space + * `bastion_host`: This `object` maps directly to the variables of the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-res-network-bastionhost](https://registry.terraform.io/modules/Azure/avm-res-network-bastionhost/azurerm/0.3.1?tab=inputs) + * `bastion_public_ip`: This `object` maps directly to the variables of the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-res-network-publicipaddress](https://registry.terraform.io/modules/Azure/avm-res-network-publicipaddress/azurerm/0.1.2?tab=inputs) +* `virtual_network_gateways`: This an `object` to specify the Virtual Network Gateways settings (omit this object if you don't want to deploy any Virtual Network Gateways) + * `express_route`: This `object` maps directly to the `expressroute_gateways` variable of the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-ptn-virtualwan](https://registry.terraform.io/modules/Azure/avm-ptn-virtualwan/azurerm/0.5.3?tab=inputs) + * `vpn`: This `object` maps directly to the `vpn_gateways` variable of the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-ptn-virtualwan](https://registry.terraform.io/modules/Azure/avm-ptn-virtualwan/azurerm/0.5.3?tab=inputs) +* `private_dns_zones`: This an `object` to specify the Private DNS Zone settings (omit this object if you don't want to deploy any Private DNS Zones) + * `subnet_address_prefix`: The Private DNS Resolver subnet address space + * `resource_group_name`: The name of the resource group to deploy the Private DNS Zones into + * `is_primary`: Whether this is the primary region. Any non-regional Private Link Private DNS Zones will be deployed into this region. Although the Private DNS Zones are a global resource, their meta-data needs to reside in a specific region. + * `private_link_private_dns_zones`: This is a `map(object)` used to override the Private Link Private DNS Zones that are deployed, leave this empty to deploy the default set of zones specified by ALZ + * `zone_name`: The name of the Private DNS Zone to deploy + * `auto_registration_zone_enabled`: Whether to deploy the Virtual Machine auto-registration Private DNS Zone + * `auto_registration_zone_name`: The name of the Virtual Machine auto-registration Private DNS Zone + * `private_dns_resolver`: This is an `object` to specify the Private DNS Resolver + * `name`: The name of the Private DNS Resolver + * `resource_group_name`: The name of the resource group to deploy the Private DNS Resolver into + * `ip_address`: The static IP Address of the Private DNS Resolver. This will be auto calculated if not supplied +* `side_car_virtual_network`: This `object` maps directly to the variables of the Azure Verified Module, which can be found here: [registry.terraform.io/modules/Azure/avm-res-network-virtualnetwork](https://registry.terraform.io/modules/Azure/avm-res-network-virtualnetwork/azurerm/0.7.1?tab=inputs) + +Example usage: + +{{< include file="/static/examples/tf/accelerator/config/virtual_wan_virtual_hubs.tfvars" language="terraform" >}} + +## Azure Verified Modules Reference + +For reference, the following is a list of the Azure Verified Modules used by this starter module + +### Used and can be configured + +| Applies To | Module Type | Module Name | Description | Link | +| -- | -- | -- | -- | -- | +| All | Pattern | Management Groups and Policy | Used to create the management group structure, deploy policy definitions, assign policies, and create role assignments | https://github.com/Azure/terraform-azurerm-avm-ptn-alz | +| All | Pattern | Management Resources | Used to deploy the management resource, including log analytics workspace and automation account | https://github.com/Azure/terraform-azurerm-avm-ptn-alz-management | +| All | Utility | Regions | Used to lookup the availability zones in the regions selected, so they can be used in the replacements | https://github.com/Azure/terraform-azurerm-avm-utl-regions | +| Both Connectivity | Resource | Resource Group | Used to create the Resource Groups if connectivity is enabled | https://github.com/Azure/terraform-azurerm-avm-res-resources-resourcegroup | +| Both Connectivity | Resource | Private DNS Resolver | Used to deploy the Private DNS Resolver if connectivity is enabled | https://github.com/Azure/terraform-azurerm-avm-res-network-dnsresolver | +| Both Connectivity | Pattern | Private Link Private DNS Zones | Used to deploy the Private Link Private DNS Zones if connectivity is enabled | https://github.com/Azure/terraform-azurerm-avm-ptn-network-private-link-private-dns-zones | +| Both Connectivity | Resource | Private DNS Zone | Used to deploy the Virtual Machine auto-registration DNS Zone if connectivity is enabled | https://github.com/Azure/terraform-azurerm-avm-res-network-privatednszone | +| Both Connectivity | Resource | DDOS Protection Plan | Used to deploy the DDOS Protection Plan if connectivity is enabled | https://github.com/Azure/terraform-azurerm-avm-res-network-ddosprotectionplan | +| Both Connectivity | Resource | Public IP Address | Used to deploy the Public IP Address for the Bastion Host if connectivity is enabled | https://github.com/Azure/terraform-azurerm-avm-res-network-publicipaddress | +| Both Connectivity | Resource | Bastion Host | Used to deploy the Bastion Host if connectivity is enabled | https://github.com/Azure/terraform-azurerm-avm-res-network-bastionhost | +| Hub and Spoke VNET | Pattern | Hub Networking | Used to deploy and configure the Hub and Spoke Virtual Network if that option is selected | https://github.com/Azure/terraform-azurerm-avm-ptn-hubnetworking | +| Hub and Spoke VNET | Pattern | Virtual Network Gateways | Used to deploy the virtual network gateways for the Hub and Spoke Virtual Network options | https://github.com/Azure/terraform-azurerm-avm-ptn-vnetgateway | +| Virtual WAN | Pattern | Virtual WAN | Used to deploy and configure the Virtual WAN if that option is selected | https://github.com/Azure/terraform-azurerm-avm-ptn-virtualwan | +| Virtual WAN | Resource | Firewall Policy | Used to deploy the Firewall Policy if the Virtual WAN option is selected | https://github.com/Azure/terraform-azurerm-avm-res-network-firewallpolicy | +| Virtual WAN | Resource | Virtual Network | Used to deploy the Sidecar Virtual Network and Subnets if the Virtual WAN option is selected | https://github.com/Azure/terraform-azurerm-avm-res-network-virtualnetwork | diff --git a/docs/content/accelerator/startermodules/terraform-platform-landing-zone/management_only.md b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/management_only.md new file mode 100644 index 0000000..ca2784e --- /dev/null +++ b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/management_only.md @@ -0,0 +1,29 @@ +--- +title: Scenario - Management Groups, Policy and Management Resources Only +weight: 20 +--- + +A platform landing zone deployment without any connectivity resources. + +* Example Platform landing zone configuration file: [management_only/management.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/management_only/management.tfvars) + +## Resources + +The following resources are deployed by default in this scenario: + +### Management + +#### Management Groups + +- Management Groups +- Policy Definitions +- Policy Set Definitions +- Policy Assignments (not those related to connectivity) +- Policy Assignment Role Assignments + +#### Management Resources + +- Log Analytics Workspace +- Log Analytics Data Collection Rules for AMA +- User Assigned Managed Identity for AMA +- Automation Account diff --git a/docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-hub-and-spoke-vnet-with-azure-firewall.md b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-hub-and-spoke-vnet-with-azure-firewall.md new file mode 100644 index 0000000..3be859a --- /dev/null +++ b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-hub-and-spoke-vnet-with-azure-firewall.md @@ -0,0 +1,86 @@ +--- +title: Scenario - Multi-Region Hub and Spoke Virtual Network with Azure Firewall +weight: 5 +--- + +A full platform landing zone deployment with hub and spoke Virtual Network connectivity using Azure Firewall in multiple regions. + +* Example Platform landing zone configuration file: [full-multi-region/hub-and-spoke-vnet.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/full-multi-region/hub-and-spoke-vnet.tfvars) + +## Resources + +The following resources are deployed by default in this scenario: + +### Management + +#### Management Groups + +- Management Groups +- Policy Definitions +- Policy Set Definitions +- Policy Assignments +- Policy Assignment Role Assignments + +#### Management Resources + +- Log Analytics Workspace +- Log Analytics Data Collection Rules for AMA +- User Assigned Managed Identity for AMA +- Automation Account + +### Connectivity + +#### Azure DDOS Protection Plan + +- DDOS Protection Plan + +#### Azure Virtual Networks + +- Hub virtual networks in each region +- Hub virtual network peering +- Subnets for Firewall, Gateway, Bastion, and Private DNS Resolver in each region +- Azure Route table for Firewall per region +- Azure Route table for other subnets and spokes per region + +#### Azure Firewall + +- Azure Firewall per region +- Azure Firewall public IP per region +- Azure Firewall policy per region + +#### Azure Bastion + +- Azure Bastion per region +- Azure Bastion public IP per region + +#### Azure Private DNS + +- Azure Private DNS Resolver per region +- Azure non-regional Private Link Private DNS zones in primary region +- Azure regional Private Link Private DNS zones per region +- Azure Virtual Machine auto-registration Private DNS zone per region +- Azure Private Link DNS zone virtual network links per region + +#### Azure Virtual Network Gateways + +- Azure ExpressRoute Virtual Network Gateway per region +- Azure VPN Virtual Network Gateway per region + +## Configuration + +The following relevant configuration is applied: + +### Azure DNS + +Private DNS is configured ready for using Private Link and Virtual Machine Auto-registration. Spoke Virtual Networks should use the Azure Firewall IP Address in the same region as their DNS configuration. + +- Azure Firewall is configured as DNS proxy +- Azure Firewall forwards DNS traffic to the Private DNS resolver +- Azure Private DNS Resolver has an inbound endpoint from the hub network +- Azure Private Link DNS zones are linked to all the hub Virtual Networks + +### Azure Routing + +Route tables are pre-configured for spoke virtual networks in each region. Assign the user subnet route table to any subnets created in spokes. + +- Azure Firewall in relevant region as next hop in Route Table diff --git a/docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-hub-and-spoke-vnet-with-nva.md b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-hub-and-spoke-vnet-with-nva.md new file mode 100644 index 0000000..e78ce42 --- /dev/null +++ b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-hub-and-spoke-vnet-with-nva.md @@ -0,0 +1,80 @@ +--- +title: Scenario - Multi-Region Hub and Spoke Virtual Network with Network Virtual Appliance (NVA) +weight: 7 +--- + +A full platform landing zone deployment with hub and spoke Virtual Network connectivity in multiple regions, ready for a third party Network Virtual Appliance (NVA). + +* Example platform landing zone configuration file: [full-multi-region-nva/virtual-wan.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/full-multi-region-nva/virtual-wan.tfvars) + +## Resources + +The following resources are deployed by default in this scenario: + +### Management + +#### Management Groups + +- Management Groups +- Policy Definitions +- Policy Set Definitions +- Policy Assignments +- Policy Assignment Role Assignments + +#### Management Resources + +- Log Analytics Workspace +- Log Analytics Data Collection Rules for AMA +- User Assigned Managed Identity for AMA +- Automation Account + +### Connectivity + +#### Azure DDOS Protection Plan + +- DDOS Protection Plan + +#### Azure Virtual Networks + +- Hub virtual networks in each region +- Hub virtual network peering +- Subnets for Network Virtual Appliance, Gateway, Bastion, and Private DNS Resolver in each region +- Azure Route table for Network Virtual Appliance per region +- Azure Route table for other subnets and spokes per region + +#### Azure Bastion + +- Azure Bastion per region +- Azure Bastion public ip per region + +#### Azure Private DNS + +- Azure Private DNS Resolver per region +- Azure non-regional Private Link Private DNS zones in primary region +- Azure regional Private Link Private DNS zones per region +- Azure Virtual Machine auto-registration Private DNS zone per region +- Azure Private Link DNS zone virtual network links per region + +#### Azure Virtual Network Gateways + +- Azure ExpressRoute Virtual Network Gateway per region +- Azure VPN Virtual Network Gateway per region + +## Configuration + +The following relevant configuration is applied: + +### Azure DNS + +Private DNS is configured ready for using Private Link and Virtual Machine Auto-registration. Spoke Virtual Networks should use the Network Virtual Appliance IP Address in the same region as their DNS configuration. + +- Network Virtual Appliance should be configured as DNS proxy +- Network Virtual Appliance should be forward DNS traffic to the Private DNS resolver +- Azure Private DNS Resolver has an inbound endpoint from the hub network +- Azure Private Link DNS zones are linked to the all hub Virtual Networks + +### Azure Routing + +Route tables are pre-configured for spoke virtual networks in each region. Assign the user subnet route table to any subnets created in spokes. + +- Network Virtual Appliance in relevant region as next hop in Route Table diff --git a/docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-virtual-wan-with-azure-firewall.md b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-virtual-wan-with-azure-firewall.md new file mode 100644 index 0000000..230e9f3 --- /dev/null +++ b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-virtual-wan-with-azure-firewall.md @@ -0,0 +1,83 @@ +--- +title: Scenario - Multi-Region Virtual WAN with Azure Firewall +weight: 6 +--- + +A full platform landing zone deployment with Virtual WAN network connectivity using Azure Firewall in multiple regions. + +* Example platform landing zone configuration file: [full-multi-region/virtual-wan.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/full-multi-region/virtual-wan.tfvars) + +## Resources + +The following resources are deployed by default in this scenario: + +### Management + +#### Management Groups + +- Management Groups +- Policy Definitions +- Policy Set Definitions +- Policy Assignments +- Policy Assignment Role Assignments + +#### Management Resources + +- Log Analytics Workspace +- Log Analytics Data Collection Rules for AMA +- User Assigned Managed Identity for AMA +- Automation Account + +### Connectivity + +#### Azure DDOS Protection Plan + +- DDOS Protection Plan + +#### Azure Virtual WAN + +- Virtual WAN homed in the primary region +- Virtual Hubs in each region + +#### Azure Virtual Networks + +- Sidecar Virtual Networks +- Sidecar to Virtual Hub peering +- Subnets for Bastion, and Private DNS Resolver in each region + +#### Azure Firewall + +- Azure Firewall per region +- Azure Firewall public IP per region +- Azure Firewall policy per region + +#### Azure Bastion + +- Azure Bastion per region +- Azure Bastion public IP per region + +#### Azure Private DNS + +- Azure Private DNS Resolver per region +- Azure non-regional Private Link Private DNS zones in primary region +- Azure regional Private Link Private DNS zones per region +- Azure Virtual Machine auto-registration Private DNS zone per region +- Azure Private Link DNS zone virtual network links per region + +#### Azure Virtual Network Gateways + +- Azure ExpressRoute Virtual Network Gateway per region +- Azure VPN Virtual Network Gateway per region + +## Configuration + +The following relevant configuration is applied: + +### Azure DNS + +Private DNS is configured ready for using Private Link and Virtual Machine Auto-registration. Spoke Virtual Networks should use the Azure Firewall IP Address in the same region as their DNS configuration. + +- Azure Firewall is configured as DNS proxy +- Azure Firewall forwards DNS traffic to the Private DNS resolver +- Azure Private DNS Resolver has an inbound endpoint from the sidecar network +- Azure Private Link DNS zones are linked to all hub sidecar Virtual Networks diff --git a/docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-virtual-wan-with-nva.md b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-virtual-wan-with-nva.md new file mode 100644 index 0000000..924b4bb --- /dev/null +++ b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/multi-region-virtual-wan-with-nva.md @@ -0,0 +1,77 @@ +--- +title: Scenario - Multi-Region Virtual WAN with Network Virtual Appliance (NVA) +weight: 8 +--- + +A full platform landing zone deployment with Virtual WAN network connectivity in multiple regions, ready for a third party Network Virtual Appliance (NVA). + +* Example platform landing zone configuration file: [full-multi-region-nva/virtual-wan.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/full-multi-region-nva/virtual-wan.tfvars) + +## Resources + +The following resources are deployed by default in this scenario: + +### Management + +#### Management Groups + +- Management Groups +- Policy Definitions +- Policy Set Definitions +- Policy Assignments +- Policy Assignment Role Assignments + +#### Management Resources + +- Log Analytics Workspace +- Log Analytics Data Collection Rules for AMA +- User Assigned Managed Identity for AMA +- Automation Account + +### Connectivity + +#### Azure DDOS Protection Plan + +- DDOS Protection Plan + +#### Azure Virtual WAN + +- Virtual WAN homed in the primary region +- Virtual Hubs in each region + +#### Azure Virtual Networks + +- Sidecar Virtual Networks +- Sidecar to Virtual Hub peering +- Subnets for Bastion, and Private DNS Resolver in each region + +#### Azure Bastion + +- Azure Bastion per region +- Azure Bastion public IP per region + +#### Azure Private DNS + +- Azure Private DNS Resolver per region +- Azure non-regional Private Link Private DNS zones in primary region +- Azure regional Private Link Private DNS zones per region +- Azure Virtual Machine auto-registration Private DNS zone per region +- Azure Private Link DNS zone virtual network links per region + +#### Azure Virtual Network Gateways + +- Azure ExpressRoute Virtual Network Gateway per region +- Azure VPN Virtual Network Gateway per region + +## Configuration + +The following relevant configuration is applied: + +### Azure DNS + +Private DNS is configured ready for using Private Link and Virtual Machine Auto-registration. Spoke Virtual Networks should use the Network Virtual Appliance IP Address in the same region as their DNS configuration. + +- Network Virtual Appliance should be configured as DNS proxy +- Network Virtual Appliance should forward DNS traffic to the Private DNS resolver +- Azure Private DNS Resolver has an inbound endpoint from the sidecar network +- Azure Private Link DNS zones are linked to the all hub sidecar Virtual Networks diff --git a/docs/content/accelerator/startermodules/terraform-platform-landing-zone/single-region-hub-and-spoke-vnet-with-azure-firewall.md b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/single-region-hub-and-spoke-vnet-with-azure-firewall.md new file mode 100644 index 0000000..74f0caf --- /dev/null +++ b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/single-region-hub-and-spoke-vnet-with-azure-firewall.md @@ -0,0 +1,89 @@ +--- +title: Scenario - Single-Region Hub and Spoke Virtual Network with Azure Firewall +weight: 9 +--- + +A full platform landing zone deployment with hub and spoke Virtual Network connectivity using Azure Firewall in a single region. + +{{< hint type=warning >}} +The single region option is here for completeness, we recommend always having at least 2 regions to support resiliency. +{{< /hint >}} + +* Example Platform landing zone configuration file: [full-single-region/hub-and-spoke-vnet.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/full-single-region/hub-and-spoke-vnet.tfvars) + +## Resources + +The following resources are deployed by default in this scenario: + +### Management + +#### Management Groups + +- Management Groups +- Policy Definitions +- Policy Set Definitions +- Policy Assignments +- Policy Assignment Role Assignments + +#### Management Resources + +- Log Analytics Workspace +- Log Analytics Data Collection Rules for AMA +- User Assigned Managed Identity for AMA +- Automation Account + +### Connectivity + +#### Azure DDOS Protection Plan + +- DDOS Protection Plan + +#### Azure Virtual Networks + +- Hub virtual network in one region +- Subnets for Firewall, Gateway, Bastion, and Private DNS Resolver in one region +- Azure Route table for Firewall in one region +- Azure Route table for other subnets and spokes in one region + +#### Azure Firewall + +- Azure Firewall in one region +- Azure Firewall public IP in one region +- Azure Firewall policy in one region + +#### Azure Bastion + +- Azure Bastion in one region +- Azure Bastion public ip in one region + +#### Azure Private DNS + +- Azure Private DNS Resolver in one region +- Azure non-regional Private Link Private DNS zones in one region +- Azure regional Private Link Private DNS zones in one region +- Azure Virtual Machine auto-registration Private DNS zone in one region +- Azure Private Link DNS zone virtual network links in one region + +#### Azure Virtual Network Gateways + +- Azure ExpressRoute Virtual Network Gateway in one region +- Azure VPN Virtual Network Gateway in one region + +## Configuration + +The following relevant configuration is applied: + +### Azure DNS + +Private DNS is configured ready for using Private Link and Virtual Machine Auto-registration. Spoke Virtual Networks should use the Azure Firewall IP Address as their DNS configuration. + +- Azure Firewall is configured as DNS proxy +- Azure Firewall forwards DNS traffic to the Private DNS resolver +- Azure Private DNS Resolver has an inbound endpoint from the hub network +- Azure Private Link DNS zones are linked to the all hub Virtual Networks + +### Azure Routing + +Route tables are pre-configured for spoke virtual networks in one region. Assign the user subnet route table to any subnets created in spokes. + +- Azure Firewall in one region as next hop in Route Table diff --git a/docs/content/accelerator/startermodules/terraform-platform-landing-zone/single-region-virtual-wan-with-azure-firewall.md b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/single-region-virtual-wan-with-azure-firewall.md new file mode 100644 index 0000000..45396c7 --- /dev/null +++ b/docs/content/accelerator/startermodules/terraform-platform-landing-zone/single-region-virtual-wan-with-azure-firewall.md @@ -0,0 +1,87 @@ +--- +title: Scenario - Single-Region Virtual WAN with Azure Firewall +weight: 10 +--- + +A full platform landing zone deployment with Virtual WAN network connectivity using Azure Firewall in a single region. + +{{< hint type=warning >}} +The single region option is here for completeness, we recommend always having at least 2 regions to support resiliency. +{{< /hint >}} + +* Example platform landing zone configuration file: [full-single-region/virtual-wan.tfvars](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/full-single-region/virtual-wan.tfvars) + +## Resources + +The following resources are deployed by default in this scenario: + +### Management + +#### Management Groups + +- Management Groups +- Policy Definitions +- Policy Set Definitions +- Policy Assignments +- Policy Assignment Role Assignments + +#### Management Resources + +- Log Analytics Workspace +- Log Analytics Data Collection Rules for AMA +- User Assigned Managed Identity for AMA +- Automation Account + +### Connectivity + +#### Azure DDOS Protection Plan + +- DDOS Protection Plan + +#### Azure Virtual WAN + +- Virtual WAN +- Virtual Hubs in one region + +#### Azure Virtual Networks + +- Sidecar Virtual Network +- Sidecar to Virtual Hub peering +- Subnets for Bastion, and Private DNS Resolver in one region + +#### Azure Firewall + +- Azure Firewall in one region +- Azure Firewall public IP in one region +- Azure Firewall policy in one region + +#### Azure Bastion + +- Azure Bastion in one region +- Azure Bastion public ip in one region + +#### Azure Private DNS + +- Azure Private DNS Resolver in one region +- Azure non-regional Private Link Private DNS zones in one region +- Azure regional Private Link Private DNS zones in one region +- Azure Virtual Machine auto-registration Private DNS zone in one region +- Azure Private Link DNS zone virtual network links in one region + +#### Azure Virtual Network Gateways + +- Azure ExpressRoute Virtual Network Gateway in one region +- Azure VPN Virtual Network Gateway in one region + +## Configuration + +The following relevant configuration is applied: + +### Azure DNS + +Private DNS is configured ready for using Private Link and Virtual Machine Auto-registration. Spoke Virtual Networks should use the Azure Firewall IP Address as their DNS configuration. + +- Azure Firewall is configured as DNS proxy +- Azure Firewall forwards DNS traffic to the Private DNS resolver +- Azure Private DNS Resolver has an inbound endpoint from the sidecar network +- Azure Private Link DNS zones are linked to the all hub sidecar Virtual Networks diff --git a/docs/content/accelerator/startermodules/terraformbasic.md b/docs/content/accelerator/startermodules/terraformbasic.md deleted file mode 100644 index 937c4a3..0000000 --- a/docs/content/accelerator/startermodules/terraformbasic.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Terraform basic ---- - -The `basic` starter module deploys the management group hierarchy, management resources and policies only. - -Example input files can be found here: - -- [inputs-azure-devops-terraform-basic.yaml][example_powershell_inputs_azure_devops_terraform_basic] -- [inputs-github-terraform-basic.yaml][example_powershell_inputs_github_terraform_basic] -- [inputs-local-terraform-basic.yaml][example_powershell_inputs_local_terraform_basic] - -The following table describes the inputs required for the `basic` starter module. - -| Input | Placeholder | Description | -| - | -- | --- | -| `root_id` | `` | This is the prefix for the ID of management groups. | -| `root_name` | `` | This is the prefix for the name of management groups. | - - [//]: # (************************) - [//]: # (INSERT LINK LABELS BELOW) - [//]: # (************************) - -[example_powershell_inputs_azure_devops_terraform_basic]: https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/powershell-inputs/inputs-azure-devops-terraform-basic.yaml "Example - PowerShell Inputs - Azure DevOps - Terraform - Basic" -[example_powershell_inputs_github_terraform_basic]: https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/powershell-inputs/inputs-github-terraform-basic.yaml "Example - PowerShell Inputs - GitHub - Terraform - Basic" -[example_powershell_inputs_local_terraform_basic]: https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/powershell-inputs/inputs-local-terraform-basic.yaml "Example - PowerShell Inputs - Local - Terraform - Basic" diff --git a/docs/content/accelerator/startermodules/terraformcomplete/img/starter-module-hubnetworking.png b/docs/content/accelerator/startermodules/terraformcomplete/img/starter-module-hubnetworking.png deleted file mode 100644 index a772597c107910a74dba3f923b89718a6fa185f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65369 zcmeFZXHZjZ7d9G1Ku`p!3IY}o5CKJ+v`|Gt2_2=XfP{|HO9)a0MUY;kOPAiH1QY~B zrFSBPUJ@YGB=m1bpXYhYd1ua_GjslYnNgBVviDt9xz=^9JK@?|s>Z&S&N_#G^054A4C}=8xKowDE51&u~uc=)gJaPqr zSa?YP$kcSXH$b4{bv0!LeJ}IXN$U6dM#(29`KfT|DXW*~pQL_LJz?t#2I+{Ln%jDP z_C~;45tz2NCBt3%>#?w}IwJj&Let#eGcB)#U+jL96A*EM{)%q!f$a{YP8EBxOZ z{IwMScZvRgvZ4nD*Z5PYKum@Ep~`%u&G>Fa5HiRDfwUt4SW6SycGmm zD6ojK!=lo(fKTRzJKrX~M|%8!w|gIMzGLbp2SwFbt}gfIT-9^kA*|+SN-j;Ld^M0z?**SUame{e7LkG8pZ_~z^x4XEl_O4$qxoQT5dF)NE}t=2 zYz`Yp-sbvW0V&{o{_~4*k72#sO79uYySuxO^!3pXgFsS@e@7!XzM5y+Mye?u+*~JQ zpuW975lB9KqWp={MQus*`%#=6B@_XJWfc__g16i>M(^U15moaO`5?AvcF z`5CjpnnHyAH(%rPB#``ZkE))9ESNQVsF=({%|r{UZ4~i%lr!A{+82k^i455rE;d4C ztGsSq!hL&pJx2_ro&48eFGYYIv0Y>o<4tm$F57GRGSPW!vz^iPu1lexCy1MKZGNVQ zW7%`W=1o^ya2dh!4V&0aZVmm!^luxE28WUG<`~#^t7n9_8$sV>PhRr43htAkjXlkX3#O8;;`hqHuvps{Vet$_@Jg4P9bnb*{|AV`5wFaxY_pCN@r;(Rz)*q8pu^& zOR+Dlfcnic;*)#*ZZOp!?_*6STdxk*@9xcZb!(V$7WOc{y9x1m6%)6;)JwO$?=aXv zXeJ;v-BXHs_>(Vy-y&|<7Fj#ey`#afgRVwO^ymOib9*xjh(fXq?eAGm_cN;#L-tN~hWs zO%r!CuD-!68aKkJceuNJkz;a=N!#{3hm@6YGcj9CR8(24eiCtVgeM?Q2%6y`l02Mo z!Ss%!Y$Y6AiV6s*k58bUU_H~0(F=ngl~3Cv%8wh-M^1WayecZx1U6{< z?ESFd9Da`p;yQesHR6oDw|#>sg}T_h8xV?zR24CTFwW0W=&^5cyBL?xj)K|DP(`=(79uHwn!ae<~iwZ zR4|JDHpIacFf#bK4DeFBcFdqK5juE)e@Wn1~Bf0_g%ywp}2 zT{~7SK646`7WoI`#7R<&4hGp6<5|d>wZ3@LtqMfrpd&@*C|eB54g(#xlXetNu|w@# zfgg^|qS||fH?dom5f(uidQ8N@Pc%iNgRPLvR|#{*Qh9kdwdO>L_)UAtK5^A3PFia6 zBdwZH%9jbIU6dz>--h?E#tNA=D7*4fy)q0(aJCm31jaB-r9kvR^4Pyn852+BZsrJ; z&-aIu5w{+eUoj@nd*L=|G_a0*~RP?2;+i0}ZET{hP zgJ&WWE?skL#juOmuCIiVIun)Ab zf4S~f#q;dE}h%&T2sHNMO*_h_CM zOdU?ib4m2m3;P(_$p-f-g&;~5bx=T$;twE4S>B!6OrSrf^XPCvI(s6vqj{f46Dx7F zZ=~aBJ&5dslTb)>T8FKqAJL^cE;WYIuCUyGw6tK6y9TzQ93+Duv&>TG;p$X4Fn!U* z^W?;DcXj-33OUH_cmD10a8RcWmh}7j;9wmgdNOzTC7v+;b`7;kYorljM@o2^)^_9Z zP=Xrd;x8X;iTJahNw*CKKYUeZ{t1_k3+Dbxas9rs82?0viFASAR%q0HdtK;}{iF8L zP7@88dP`qDWQ4KdryX~5ec??*mYZ6gqm?n&SFm#j#OGfLo7wPoi`0Zc6L;cn_2gaOBDKhy`T-Gc# zBv8LW%4yu!{N7MTc9q)>=0%%oOF(Yw%| zL$4paZJYW+$mP~NIO{L`p38Z<6llu}$k^0q7o8Ew_#_dYQ%64&r@iU7sQA9*HRam>BKN9sP*iu;zIp zda@@B7rfPpgm1C8-Z>hZ9lg>3PPEv}EBF7Io0#@OHpMP=g!^1I5{775+9aF?)@J#Z zUAN0}Ulxr2t~>mLaw`CS+CY7FxtWC#3}-PnyBN>g)n|SPG#0nYIjT;pjqXMEC2*TR+O?0wMKI>ay8yh(=$Px#rxB`%|pF;OM0F&VF?2W9at zer1zhE^Gw(R1oxse);&$xk6=2boK-4b-3#EV1ek#ATf!(zAsWTMZ zv@}0TCxomlq7S7s0RIT+`Cv#ZNE;2LB|_N98HflB6MniIv3NIwT92z`rl`2|dos*r zLd*XMyNaM905Gw^6UPYvSt)h^gcZX zez?W@1oLuh)Kun%hDta+dNlT0$-DI18aPR7 z_g)BqvrLdi*36{g(NPqDQ?qk_#wlx$swJAI_>`7yPTQYhY)E)sOM16Ya?&y-UJY1~uW^^lEMW{4Ilxe>Z}@;_4~Kw45)@#+?~Bw&Tcl)KVSQ1g247x>s#SPfH`nc4fc$Kno6fV0NppKqbi8 zgs%qnP4srPXT7LR&->_GI*+Ph?=&;yWbFsC#p0?jirMMI9A`Q$TKtiYlMQ0rl%UK3 zeID=`*C-4*NOBE>VPBiBNH{4MHnh8tIgOC{R{FU;wXs%ZV2=r>u^Ag%p-v3X2dc9rW$7=3%wJd=)o4ajy)Pieqm`yaq?C> z_G~{;Dnx%G4Kaoca*J=g+-q~TKztZJh#4+cdit1DPPhlgP-=CN*EDO}2lA*Vj72aD zI80RAK1stB2e*Dui*41np8xjl36kg!anMMU61!}&4P+_W14y1_L~W{svw4!|=59}$ zx1CDXcB5BPZ&}+OcK0CLzHewna-y?$0Yxs~3llTC5DmsicJ`OqwuLULm`VNJ|;i8FLJWR(s z`Ct|GXHl~Fhp@FwABz#jlMr2kn&TxVpRw{M{qM)W#|yL#kz;*gEEEWh>kY-WQyDwx zYFoXeo^)B1oxL6%=Yo3YCd=6g3%8~;Y0pq^D2%TnI=$(evZVxH|Fqhf{-#ocE}EM8 zS9Q^Sdvk(Uz7jY95S?Vl?%Wk^OB(MaADKKg%w7T#hGq2F@rqBIj^zY_-rp#@G|=sD zp)LX86ErLS*`S}gyY?={BjM@VeKoZ}rLglV>h-oL6KA9tH|r3xUu@KLaHsmH)T~i4 zd*=86N4ITEAQd(r?MpBiJ9bf6wEM~cPtiStTBo=nI|V`7A?tTAxwODFlUfJck@$fI zcWi4@;08qe4HvlCw(%3u+qr48qg>Okk+>I6|H?BqZpCYMbjFOGe>`*BW>)PKhd^3u zzzU(=#Pe(KTFDLlEj52oKp&8-zH3{yu7vDUw;0BJRh3e zq}RuxBSF%=oEl^Oj5D2|vJ2UB{rJAz{*8C8DL~hY8@b(6KV)Y%Bp|j^(ZQt&qM<>x zj)IYcE*+O_<~2m;XD8X)sS5B;Z<@UNCL49Pl!H!f(KP#>1yRfmHp&jv&Q9`M&k5cd zN>NzS->~S^6S-nB!RtSHvq3JBH_LvvK_i?B1amf%OZ!8oz_-9MH}{H)p*411>)Nfy zTW&${m37?s$+1Pr?&aHGo11p1@Qo*^Hks|8cY8_yq4~GL#&`-8qJzhABGG#hI(nFf z_WA6wChgQ_*HcwGY%o%s`sl^LjE`GM<+_>FjB?3`5gM9@b;{5s@J^qS2dQ%Y+(gRt zUxSP#3ryXI4a6UR4uEMo0qN=qic{7{S!}#eARmV~Il%9awoFZJCDa8=)!Za@NHkvv z+_|}w=9vy(5U{9dXpr*7`J<!}S!Wfda3zhc z$(l3$^>NC54McZqnlc!VsLS^%p8-nVjp zBU@)WcJWX7W}+XXc31j05!$SPLja5YMohf+@Z^Gf#)s*8W8wL`plZrDhB`(NJL-N0 z9yWkruz~OIgxkINF)|!&d`BZyT+sM?Q<~>A3O!-%^2Ff3Caw(><4Cy-kxex z95Ku8^~C0tS(LY=usJW=vauk~K$-fkR2@Etod?7b0%R;;{M_tsc_n<;AGaQRE>UCs zH>lZ9iiRFr0E5qOdzEE_!pm~AYx`(%pOhXSD@CDtPwGaRWpI-o&u}mms+%KLZF*2y z=5Fi!5ju>bTFH6;{lSbyhvDg=kO5NAZ_sbp?vc)!Satj9$4J|LP45a9=sU9|z$qqg zGQEJqk;ru(ZZ_a%0kwVPbIzOxBEFrdsb4!19=Q;Nk6bJ1iRhOM|R(Knf@H@0s_UIC-Ihf z%lD~)Pw`!z;5$nPvVsyZA}bY8r|28=tO zEJ;U_vf{oJ*A<_+(sYmU5Tt-l0L&H!D@XbgLN}==dEsQrkv zO#z1_u2@7x0s`Edo?YCboZ>9Y!)x!(SOZi;R%s1DpgN*z9bYE|3@DL4Gap9sHvR^k zQy@^t!)CvFLDNsSjYR;Ek{-z}A@tMNo{AYN&sUf^LRU1{1oOs@l!)66@iiXdQK=X| zi?Tt{BQMvb9>=0V8J7l9O0%gW2UVJxNA704`L7(8+wJ6cxv@04TK**t?{ z!w_YF$AuX372bX^|1EEXfyDMLJ!4?OHgKHBOP(`3s2KW`GpG=}u` ztacj!xZU44Y|2FH(;dr>;1v?#Cp!6-L)xL^&87aBaS{XUwmI8=m48O?n#cOD@mt|p z^A!JU;5Rgq=sO%->>M*kC?IFN1jsFV5@YBAHsejgPs1{Eju^J7357}V!riv=Cv6S@ zkXp{Pz-qj(YQ?^iIW|D(RZ zATVk?vosE7(1aFs!z(N?fEEwh-_yYXi}!NlOafCM}p15X7XE>KX zv2hPi0Ok^y@Sm}-Yu1RlS7S^3A--1)%K%{*r{>l7yqqCt7y#_b(3l_41VM z$v}W;lBv;8@)wY{WP^?!0%K{}>B_s>fJ4Ht$3C};1b+f%+v?UH!Q3^+tC%d~T^UKz z39ixPS_1HJYVl|CpqpQs{Vrx$+-GMQCIBjM_QUpz(0R|hdg8?MZ! zKEhQgeALu)ezXoDj4n1Tp&8uUUJ5Jx1?U;w#y7mKDN>UQcA6-{#u=&o-?YDG4J#z& za&FODr%ATASV1mPT&JE6^7W{_G>DJ)zsGMOjZZ7*&2Te_2YQ3*@#R&NIw$iq7KPf`s(jN0!(6 zKVFs@ft~DE1>x7wm*3*;xUQ?deY5xz2oNlJdih$8;%3c$-h+n|HTG>ou~c`T{VXSG zCVPJT{8@%{*-nYd)Ms%RwWU}=liFZ@P~6#nx$^HcSksM%^R70dIV;%_!O2SD+|0!lmEFDXqVm-p&$T7)r%3VeRDZm4vAQ=!%)WK& z)APA(!58dueqN%9$qX!*K($WON-H%zEtA`j=K9g2TPxAk#$?zWc^#Pip4)v^0#d|gR* zEL(@7n3n{vcD&_a&l?{a8VW8nzPtS1?kIDvy%S(Db&cW=1ME*Oc!5A`MWxMmL*@n|tN1#`HqmSh)q`OyS(ZQY z(KkV_=N_0YbJ=6pT#Mq0wV5bh5rbnmap$aP|47ratj6@&d}j8MlDjtiiN~|Gj%m_<*v}b;G1YyD9dH3 zgz~75epBi9k`C$A-o(&AuDl-vLvHPq)V>~wp&9ohypw9=RjQnkEyFtE;BYjIzdeYs zGNgD_&PfT-2FXqUBoYRXb9=z0cXhCNb3TZdJ;v!JN*-BIrap;(V(3e- zYHR3Buj>*nxiKE#G1nDp;&i|&z4Xg9#~75mnw+0ei*l+@M%%mb8H>lUoS0r2cM%!i zSd44a;l%1<7P(G5YLY+*vbcl7d*qt zHr;`ba?>ivSPCScO9CQ10Zwt+=VZp^H^}(74$X7!zPadA>xkZVs1APGxzwr#;GC9W zgq*`k175y54no<4&}e}bt~Dc99*2gz%VqTTHON*f+)g^`QV z-Fj4PtIC#^dbVYq#_sQl&rt_NfQBXs9p8tRoRIva%mV5&L^m%T!_JS3-eAb$dBrMN z7q&B3OV~uEcEGi%u2tKCv|msgDu<_v?$8l@Fpb7XCFo*eCG>N}nzvsy=oGz9&>HZf#reWF-E&T7O1k58nQ5dr zNhp%cQBC~KA54F@i?W(MkWPMYhQOBg(n`s8#&w1pD*lVGu`Rw9nWH8??*fFavB|F4 z()#L_Zmon*BZnCsB}B8d65?86SLjL^)_%~!#E)E=oKGuPhUi~7BlI7*aY)47-c81E zqKZBDpXDF{Wiq#%;HRHs-~PFC)_{rl@@|f6HKF&?B;SJbW|?_454#0`Qx@NFJa!dk zrx(nv&b4ksILTdvG$1~Gvfu+n(;17qasIY`AUzZ5B?~UQ9qBwGPL^I?+iUFZ)m(u6 z=#BK3BRYF_0tgdRZbd%HSF>u*jz^7Jc7;X(7v|#dyk8wR02pK)*S*K+o@fWJllG(4 zqcZ0yO-7KFQf1b*OClL5$LV(JO$X>sQN;5P_MXaZf~bCTk9#CZyX!8TRl3w zQ_dI}t_@6-2mGvw1n`)6e@9#&0*1MpB>KRLDYi>r16IP*<}=}G^WGkTwEYA>N((A+ zjF#&9BgF9Z= z^H>@6nApoeJ+o}C99)#y_;@sUB4bl`{+ zRh^_aso1|}oaAG!lQ`+rGO0T%HddaMwCm!}i2bx~BYqzCSu!gl4K&yvzGoi0jzqB5Tw4+vS_Mx$7OuA}?)IAmH9GzJTp(`U&FGFl0&|=j)G+sVqB|gX zo~uY9Gs|IPVx$;h^fc!bG)O4IB9g_%wF?O!?pihC01Uk>^UL~ARa^(_&!(S$*y0aA zb8%j&>kI|k`#@SLN(J>yw~xj(5$JJ|nJ<3K@I36@hKGE%eJSz{wT?Jta@|lmE~m4s zLg%*AVSP$eG_A$N-tJIZc14i^Y)#~#c#&TARj2VvYfY3rqJIdh-_+CVibE0>k33Z? za@ccQ)B3Ak!w-tCCai20s{z*n!LALedh?{xcrDg z)at4^*r&S$F&oi5rBMnE2C! z_lAoUJNqgC@Tskhjd;4X=DQxXsQv1Bn=h)-LhOq1_tl^>@StID!)HUD9~{p2Mw@p= zs!9-1LjA^>FNlOx){{dg!L_r06zII)0WE8Q|5YYfgqf)?w&%GIW;}?NhKWz|gJT>_ z8>FB>1C@cXC(FTo2IXi>y#l_GvvNM%7@?=pfN^oCE|fN|(_qQ0M$O3-^N(cs3WSE3 zKAY9QuwG`X)Fj{t&Qv_W- zJ;pqzpGkL~6lGimzin7m%MT6=yxPFowd=p+s=0~%wzD1A+w0F0UPs(Od-9yfJY+sO z?or0AbVRbZH8tbr+*(v{IdV#Femr;5@Y@;G6mdIsVg4-NDS$AU2%Xx{0U9h!s%AM& zy)7R4zv#r5e{?jcBsE58-5bfX$Y}locV8!pE$=^TniG7&8Ly7WS#dR>i+IpPk%?$2 z5;D)=zjMJ^Fza+c?Pkkal?-$d6r6zZn~GvD+g1+5VRwy3c2}I4;GV_j7oz^E$`$2y zz7~K(iolOevLC+zMv;obQ6cuXi^ER-DQFF#NLNo@e*LJk=fiX9L~m%_U8ALcpsT% zW$N7nklgGY{IGC^#qnXjq3^Vp-lNK$MoqFkfqZigjL=27Yqyr>fPM};kB@aweRoX!@8Q=o55jtqqGP)!qLSk5yK_z*J?+|Y;6B?{irQf5;kR;O2TgtpYL+% zr>VL(Bai0*LBMjH?1uFPKdq9ypj4c{BiycW!sk6 zqwtLUH~@=1@6$W31X>oT_3}@*ZE+n!lL!f9*{8qOwd~=t3WSW#QsrBA-G!!UJjO^) zVHCQ~=NmE^vpRFU^MAWzcyZH^ai!#@vfBA>`yx2&)Rvm>@{+xxSyM<*>2kGk82fncHTPWQ!>|y;GNceBWj2nzkSVk|J<$i^OX+$#vG0Ejw$;24v%giR404 zFSNtqP?%S1Thto5%jdDYpg_Ax-GL{?O{l>Z9r*wRq&@#f`0ar4*X>hQ!QH9Z|0>zA z?pw~#>YNKoz2{Hr?|Tn&_5NmZvKaISaJ4aPG}kcTpnbZ$TFzH}(ES5CN0GLE!6@O=_7<$LQs3-Ey%@PRWXQMn92)m|l$>{8TJsAW zdJ87Q&2u@fFLFD~AZ`a}^Rjzc+JfB~FTh;^3P>lK8uLy)-Or5eQi%z>nE?y~QVDgC zzMyju5#sZsUlY9P9}|e)?R9Ep!uqub>FW0owJhxGB7bqi^Vy4=Q$C8&?BZN<(6l~) z24zA=-g9+7s^UGEgC5l-)Lqurc?{+ZHY$FFU7Wlun2em898^kUmwRfZ*Jsg1#>2@u zmBfa9fP(L_tG6}rk!7tRTD9MM=yo3uDPerkE zeYGf|tBOR&M;bHjixqsR`|wIn{cMLr!R3D_l`E{W@p-(HO?|&OKq3IvnXRxPl)`!x zb>*$UIA%oIO>}fRXxpFS;T&jW)fE6i@5AI0x5LD^WKQ01r_h;${pOc9*y57<_J#%& zIyG^Ne5^dTW}B>)o3QzA5Fx&jx@{?y@kaL~->pUftvltMluVLjM(*3$e}(Vt-Y?jriLj z?>pL~3h1M##++PyekPKE74w2`J*=3^4&va|^=!0JoI@klK!&mRu=hBqABA#*uOmuQ;+XoW|x3hVd=iH~BDwyHD&Qj|Tz|E0V z$hm_eldB(K=Xkh!$@rLlYbYd%1_WYy>l7Ce)No!mQ&#SQtNPG@yrs}QR?rz?R3#KP zbZz=a-HCcquQJM~_%y}QTnS}0&Ydfrc~M31Mm3U7ajnT(@diYLPhlpGTf6de=i6v! zzlGOX?)OXQyk01b<~$dUc-P>j&mcd!M%3Fa(jzGNT=VbGR=KJ`kARq$Toql68%&}o zGSXEbb3^yoHj#6vy03}(%U8UryAKoOv4qV;;7P|`NTHcjJBE<S4W9KuOVI=AO$@F4&$^JUud`qy4oE-uBF2%!BON%_q1#~Hd+do;18=m)nmbJo|O z(c-U!*V~&c)segxMf<8^*qWXFKv>hA2De+2u}|kG`D}|=Xdo9g(q-!T&&ZLQi#8rLPNf7K{#&@6Vbs7yd-9 zcNE~chjXbg@!YRQb2Eeo@#8)3n#=SUuA1Wx_I5i=_=)1_MEWwla0_VOQJS$g-@O=H zvx-gLH6uWu7*2Bh^{F2y0605b`-rE~lfGGfi@pksVrh~uJjyfEkRCMgM;80nmTI3T zHF&9@LSnomASrg4mXClssX$Ms?t$FH&BMKIC9~S#mki8y=K<|V*8&q*p&CIVWS4Z>t<_M*^-zpgoOOw!) z)K&8(OW_Yu(wRQ!p3b|kM){xXV1}6WYXcBM5K1CweE(2C(V%2OP(!5uAa9=jrk=qT z>+1Xieo#QRz7ZNm6(x3Gy?$6CX{}g&j99!lzQ`$NyQB$Pb`B2%u>wb1lCKwp4yiOH@^l&&BLp7_T|z zzpc?(B`Ajn0yvmi^g(S5Gr${vlj3t%$DVz+*1V+KlTp$h`dhrN<^G2g07#-#*+$QC z)n~nxW$2nAQrH|m#b0}?%=iE+57~&x7f|iPNQ6zCG*Z<`8`0o-7X+Xvd}CQ zsRTB>)-66yL8w{9ilv8~I)dEN0D7f{x|8qna$lV7qU6wiFHMw5 zuJBkhE-oyj-v0N?e^!f(jI70Wt&OjRtPBS#iPd@v|DK4R4*N zUreqL$EazJebYvZdtxt4Sh(AzO_#86`~M;yr_XE8Dhb}IcJ@OK9!uT0N%ybN9j)8w zn=iXF$c4&j@%_rVKVB5=_CQqpzWvKz0H;z}c<`ZOPPoo~(VTtweMB(%%}53oJGFP= z4Z10^z8=-V5WVJ)Q# zR+7y2&Y%ZMPy!`bcl0{Vb-i9kP->ztWjp6y=FySU_Vq(^n=d$XZ%N|pYy4QwiTy#k z??_Q`vEzg8+rC8}p0LTjItzsFUa`4lQ16TlIQPqW-rDj0BI9DHjQwPBPi=bm)saRB zw9`Y)QTGWO!!uP3W9@SzXya<@)c=BUPiNGEd;Ml!Umfq$)%{Xe%&p|K7tgcaBx783 z%V6|mz|Ohxma$Y}3{K7Fn+MvJf2numDXH@pB5x8yJ6D!slWO$Kv=U%Hf2K1FlEq`O zo`O8n;pZ2+C`CJQ<}1?vO;g8PV_c3lLxD5Dt}3lrm-$8Rt`By;<-F&B@IHigwMck` zxcYU)q-xVx=xZBV)(o=dY%|5gcsiV2DVbunw13M2+Nv2pS zy@c?O(|5o=tuT6^WzpewS~nQXOk8SH}CsABZynzWqnhct{xA z7T?Pq=1FsyRzuAy{s`@vBcufIN~Q3!%e`3J#cvrk-z+LIJzS5MjHLOm=gqa#CUqk9&I+6Cpw->R}LwBwx9CS0xX7 zUj;C3;lIbtx9b!a=Wu0A&(zC8iVh&wd8Q%k;zBkXAI&7t_%i5&Yi;js0} z{f?!al+^}f3tzRCal=7Zh`!!2VEgcR#Y%+|=Dg;;h}+#(D_im63nfPP)mbPb)Ativ zUMHj!e-(<4ZduAe*>m}$eOKAh^_@LzqLM`_s(?XxfBFIR$&|LNjKIzVQn(+7oZGi! z!n?4wnO!UVt{hY_+!h=j3mk~>PBZWD z^1?^^-I7Sv+;r61^gFo6>ci~z7t3P`D4%K75m;vqQlPU`wx<8`_hibzo_JVv=P@x1 zCe#iV7O}PUqXO}%{>HfQ^^w%ro%WM9{R z>x_0qh=#q$Wud|O{6H^gh<;-QpN!|N#{=w@K$vL>>jOzpf#~l+?5+y>6!3wH zt4nD%Wj@_l#q2ACW9Le;oZ|NBB(MLBTJfyJen=lS$P&nXvGps9cXh0y!!QvZcFe|+ z_2LgP^x}in=Z}~4Tx)e-ZI94SKufL~V}!zk$paw&!g&FZzP`T4QFKx7zoB?f2uS&a{$m z4i9y!de$VM5$~cM9<@ZD?`p;7!UpPAa-3R!l)({BrH5Q)6# z;~{GF=r`1m4)=ZOC#%A&wLyJzu) zhfU7N-SB~^TV3#EjMvou!{>BXCIw69PlgSTSAzO=kEb@b+C8+;M#}07-Bhpq|3(Vu z=*=>pvR^SSVVDwKpM~)wGKlkF-XDVa_Fgngg8_s~bbtRISNXyEo>sM6j4_z+D%lxw zWltf>SL-sQeK}ptGhY5zypEyGSIDL8(n_qQT=L48p!(8}&&lY591J!AtrYf^FM-+2 z$2v&H9qR1w9}CrP!nPBrEq!mSPTXbtXj5q{$Y!X&`+6iv6MDJ&j)$o6O^Y8V1oGNC zp%bTf`vjTMDMACzI1#h1qv^eE)z)DqyH@tVoLRqerQZ09f zfRInkkz3m$j5_|UmD18Rz^O$+r5MKzRB?Y_n41@?B~U9w95Chm1X^E(1{W3bu1r7 zm|Lm7t@{R9$Q9T2W9*|M7EKVQ#fXsjQZfx2U99?p;+=?K2-09=6$Lc<&M5 z-f*!Fb-ujfq-{0ey(Sz4`CP5_xM(8myWTIL&!WHWp3p7P9VnI_ubquN9ojcm`lvd;%klkC**G9ol>{9pbs;e4e+fq zW>47TWy26oQJfY|KwL*157o5D4ydnlH zcdzz?G8sr({a-D317?z$`H|8&scDja+?L*EEkfeYv~hW4*+%-iRjBNj*(%gw66co< z4TF@xt`0elB_`hAlg^;?+jHHN)F!w99AA#I6Hq#=DRw~B z3L3|b$MNeqw1v`o0HRN*cU%locd%1})kfvoo&^ej)bgfQW4s<5?*LmCnPNDSvmQPITa8$|REsY>G^laJ zO`wi{!~2iy!?Y64?;qXl~t^LK(X5MC}`r zOBpFQlvHlf)c|DMy#%pmXtAj?Z+w5Mc?kj1H zi2bFaMwF%5!8l`QPJ{^1uNu#5(yBnNfc6>Wb(q_?2>p_YGd~=LY0`vKf`FI?NXCVO zKu2F-YI6FSZbP*3o=lqY`5Vx52LYqfHwm|zp2hnGS+{GH<>-@7(_jQ1W63mDRx>(x z4)QY#0&|kzuuJsRI*cSOr~y{Mh93XMGX3}zL=L!%s|tt@=^3*eIX1b2hmUheZc zqRxV=c35aPw-CLDtsYGq*z%)TVHpNY`udix394`S*zIu@hit9vNA*$Z=dI_tBp(aZ z4NaUhdjTzOTmX-lTnTWNR!IQHI;$2&F1#LP2dK^gzjZ_dp-H~>Ah~S$R^WtvTT`IS zf*sKI_D9@RoKoWDY%+eZ7HC>3mtOyLeQ1Tyg^OHQFN7z=$L?De z-l06dikLdyC+2wEW+B=O@>~{jl5tQ?hu^$)^7N#Og;q6($?GAl z&SrY|>Abw>nB!Wo+@MS_#a4H(j#s6gT23xi{XvsdtOaFHWS9)QsuZfM&bwm1j~zYI zpqnZ(KlH~m7ihJ|LMBuXI-;@;a(!1(J*g7H*rU`tmiHwS`R?TszSv50=z;YnpkPLb z%&Sth7I1Rl0H5Rjz5ZV9_X)efEiGuv&bPFBtS8A4h*FGAQ*CW^pkuOmV=AEjCOzAS zYe_t54Zd9hl-_#4F9=wy5WIok*~mJdR%TN+H3O&T;Y|Ov&x)#F3!nGHW|X1{zp85e z*Vud;#CQEiIHB&v^B!EnYYDWymk(cCW2E?z4pW;J_^(y$t1Cy+tuK^5s&u|vzrNZf z$BOEhM|$tMJRg^n|Y5BEY`44il zO%{3@p?&z4{F6LKX6>E)U-2@4+G^JWO3AQzd5=y%uZ0V8ZtotzOkTj;HG}dG+J9ql z*}by%yB*LQe(1l#DK&Y$|7g^A1{a>-Ub;h&V^34X1>yAq6>+vg=|3kvJ-4i~y7E2D z-{VltuivK9|NL&_+RiZ@mz<2TT@TnsrK{EN)OP!|qZ+J@Ss8D-hONM)5|rr8ABKCc zD@OcvRorh!eeI`$O;|7VUik?Hs$!uRzpCfE1(9k>`gIIN5YuEUpCgAkWFAlY?ws3Y z-1n@)EGMPB#iGQ1CKlPyIaTa9#frqYsYXp8qkjFWz6=$Aa567=36+zDaq3zA%q5k^+;fW+9B~oN* zkzHCW$xhj_Zy6yU`(D}io$!g0rL2SO#*{VN3`IiOnQUXvZVbj?821_VxvuMXeZTkp zc-)W2eV>2LnD_g<&-~849W*!TSPwTFSfB#c%qcEH>1R zbgi*Q?c4SKYT5>S45c+~CNra)-Wkj}6@DDDuQNI`GLEOKfhumt9kkScFw*Vz$&h4< z3WEZuyqITyq(E;M8iZlulgs2~_0(+gYEtEQd$8Go!g%A7X;mujkVZ``3i{n@W^~cE zL`W80puXp5L~$b%bn9fO_kZ$}i1GcoS}2m3`_Gdl7iBv3@UmA2_}bT3^y;0v-;AzA z1o$bMUa!v_b3yG6-dJsSHYv@{ZU&_j_+judi*a>7kB>J_En6Q-d{TaEHc+5mc;h}X zeh9is+E1Y8C!St$PBju&%VGK+F=%6%P$N%6t&?N1zB@l0EN=@l2v1KR#p=!#G{>>SgCecI*3J~TPfF}as9Shd&s&kf2BOtGK9IqG(n%v})&M7YVCH*E6HlsVM@50z4DWYrdPk}Fd1@@xBHNGquD%!7 zwM+VUu$g|_7l{+f9M#G}gcs}xt(Uh&uGLN~-(Yv0KYe#MxTP@DbOmnf!O*X}y%K^N znaWiLk+V`sEL1H0&Hj?N!N&Q=Zv~}umBJ1U`GD@u7vuTU)n);DgvK!dk4jIVQ%^xu zX1V-)2#7(q3e`x@#`c4lLFroWcj+1{E|K=TmpR(7`r;*O@-2SpJp9{VEj<-!R2H;( zlLZt*v;(}_t3pf-gP}`RFGGtpwcKK{Jhab!&U_Ec^?hy@qQlM1^t1N@!_sLbtwsLz zT)9$;h1K1y;(k#lGBPvK#BZWM4(2E7^z%bL7j!=`C1I%H#-iF(z>?h_yKd*ZYEL1( zZwGBfF^jghNXD4grm;LIt<{q3sc`8E+Z1VpA$@Om!Ws_d7Wp&w2GY(XYo|g~ zET2@pG}Kt%2&x#>n>Q|;P44W)dLHxyZWO#Rjjei+LYF^UV(wPrQN!DLX7~{yM|$Gw zAZ-gbE9;80a%PRdo)R;+rnCxsk=D;YS>dR0#(LdvKEj_GeE!=2pr7!weqs{|l$Fx{ zx5~@^TB93VY>(_$J?6gng6FBpx#Rp1eyN%3xNwakzH1Uji=ZS$nbaU~tzGF~dE@r; z^`^j46!xwkE+W99w$4#}6e)_YMdzurl+->^Qn__XV&=QHQQ1=5S_NW%+TmW{w2FSe zq;z+ho$bq1Yg>lEmw345%ibQr;inB4ho$%t=JB{u$GW6Ikzt?mDP&YujlJt7jq+@{ zIZ&vR`+NIyx9)E54}5RlzCJBPT|s|`a&KOho?=Q8YGjFJ;RGIeB~PJvZ(T~y#%p?9WF zo1gmG&E(thiF31wksKNWh?zvE&HM?l$Z=vs3H zaTNoA7CHvki6{ZuheMZp{Fe0)!2)%q?mKDtva9L zuKu;&7A(S-`nabbk|KxdFFDs>Y&Px zH>cv2M27}iU&R&7#3Y=i?MP7sy=!(1qr53UpN_~%DBWjCZo9Re4Wlm&3;5!>FPwpg z^+3CZ+k7A|fk>=r5E|=z7#;omgJXC55GMq}Mb@$U!@f*>bHjhFIv?myT=n1HtWkFS z?$E_~{zu-ai;@GGV@PRe$B(epXGX{w)5|*`TH~cwN>%XLpJ=ad|4;j zZfhGUE(xo&M?KGVNl0vp_S=3}kXy^d?UeYbU5Q8}PI2o^=U@5{dS1TcR(s&4t&A&? zfkRaYOkg6PYs48&OL_UNk6LBsRZ0UCt-bZ$nQm+c!pBcg@|%mx&Y;L@Ymxk!_wTqwEQ4HrLrV~o!9 zY`A=ul&kM>|JI~ z_`CskLXHna?sf4W-NL+Nb_s{=+0B>RB@@n76@Hg0X%H99bhRv{t87ya`jus$9PU-Q z4*Mu}$2&Z$!y(-{z=o0@SnnlcA9NUbb9Bs||JYSm)2!S%y|C-JoyXVmU? z#yptp-QrBj)%a!34?=Cq&~7*L!Cx~XzX|)>yAiQStEj9AXCwc~xX`#S{)=5f%hb!O z-)JgOK?goV^(I?Up47{|RULI++1>endF-rP)MJrJp7=p*HK5ok9c^IY&+i{`AmGl! zlc(9$e||h?;F;4RvzRq<@P6F=NBs(&SI|UP314@}3H7sB_4z3?%BDqeudgPhze3M? zZqB3555oG~;kxUx76HEQX6sqWpc`J$+iSLCtWZnF$aBNs?UA~9E_7u+-SsPLen?l* zFDEO{(_vD&zBB?gl3TBxcwLUa`2B@xwo_nTAB}&@t7=>QVdgsUL%Yc2+-i$2k)Td5 z=_wq@E{RktTmA&-v(9T{wY`0+b!A6|EkHg8$Jo(;z46|V3)xNn4iNPK4FZJToSQ?b zbe!j*H7*%&a}>r94rT5Dm98Aof>glM6*6m(_%5(G86Ev>=Ibz^xP6ui-uNRB1~f#D z;|fUg-C3?jtY4@y{J50;>!Q36DA&&3LpZyCfUhIvgz|m&M)hRDk3fM^yb9X0>pqTi z+ga|D{NZS_Dh}BFAAlNCmOvl}N(SETZc2joBbeoI|WmwPtsIDHSPtk$NiaWlinR!BWX zIJR0U$?N8|*z-cP@`sNb*ti*xu@vio7f8Q35=6!sU{=R!EBI8iJ=9LN*dLIkQT+G! zCCeCDMzs39H@MERj}lxpO32Uwf$JU!CULTG2GGOwe!H}Djz{wpI#H`e528tKYJw4b z8sE+)!%Fdu-_rabp-`-K*+7c7OwO$VL)kq-02*WwyF6Y_uGKGNI8EmJKUS_RPd7UX zElVI>zTU$yF3pU#wbmH4dkCUVpk#cAv*PLH=C+sRDJxO+STiREsi)>cw;T;OlaDVZ zN@=UQ^1bSODUSJh$0m$oJx$D+cJm!01*q}TMW2$5S4$sqymTTOivE8EGf?m+5B3N0hnrFK4Dznbh;!Ujn8RiUQTQfo2cWsE z)sq8jipWx15qqB&jWj<})da|tqN{&nOO1gB*lOp*Bi13ud+fJedTm|pB}t01=I0WQ zArIKf-ZGVGByzpIz1+CHtekanIq=h7_A99uv7G8#d*p4^-k4}7)4%*J^7xNM^&W`O zMTw^{dJZWG$HkLs$Gu;f!LK$@g+f^bO@0xM@hsm!O>0y;&d1rc zucXKx+TTHsePKf@yS-ceiTojqob3}iOpVnWcj0}sn%J^FNixBZ%02|7Gtz0cQ*mGO zCzecX%J@C^TY5y6N_#5E&7d@Tit}bUU+@i_Wg~$TVZXgM5_()?l<|&St&T1i#|tBM zO04HM6V5_!Q~$tj}7C=5FoGISqS?K4R zMD2>BPH&%yo>RAJ=+ zb5hNfMW@=j0bRP3t@F2b?Un=W{s?OZpU$-k37sP`)ra;xQ=?u?>v(P9z-!}GlC_OFl zs?6w`%B>sqX{#@Ya&*z? zk=8s$D%f6$OWsfnJpp;u`TZRa_2u~PnnzFntyOVWhfFQ{n?ZtP^m(|>Kr=>>E-cf;zh5P0mWOE*i>Cb$( zqF64fZ4w` zd~!m=S3MpMs^`BCF?Vfb9DJZIHAzuDipW7{4jk*fL*%dmlovOj1I5KMDB$c0fYr*+|zL zrqr(lw=Yoz2^g6VHEd*Nhyy3pdO#!EFGUp^1Rzwy03oi}sHb2BHe%zpr{6rs0XSOP z<#RZV1(Zy>n1)|=M^;xeHmm;GrMT~FH7+j_B zH&GJi1S@PZSRqE*rtOr>3?Jsna$m2ZrGZCikc%sTd`-5zMt%s&5qE25eWf?Td;%5*#mQpa0e_ck%$_`ii z6wS`+Xc|>#@8en?I|z)4{*pw`2?mbz3UCnirwAG|{u;cZptb4ONrg3Qw>LKBvTsz& zhoPWq-X+0KKryNKb9}bpDKeoM@9;we5ZV5Q)A;+D8Ud-^J4sw_Y*ZPOZg}c;)5t2mjrT{P2hquZH|D!@2p{C!T<} z00Pm6RPC>?Me74vA%y>39ZXl9!F702h`q;?ELg+XGn7nE-)%w zTN-&_IuH6U)eT*L$qQUe6d-3&WR|ytyWs0FLRtE?ND^6@zaI+0`H=J1W;27DI^KZBj@Wb(p82~L(ZaHY1XY|J-WVcRkJb%v%jT~qMeAoM!7BsF}+_h1Br@B^p+kFKJjQ+20J zvraG$ZRf~Gd6Chac*&XhUfjM6P=@)i=$$zh?OHN3tCsH0lt9l5Nr^?E2?`^#pI*%F|8Tb6s_G=^sS@$#YR8jQ56B$U}s`uv=9#p{4 zY5goq1Pa#i;B;xZjI`#7M-`Wcwa297{0ZZ+&XY|cI;%y`sp3u2oL+e4&W`dw!fw*` zV1Ith<$J-YB~}=r;OqFp`^x9A9ohwAtyDB@?qPJClMvfk>qi=tPI(e(8BWtY`^mji1yxTblQOn znr8GPY6P=YzIG%^1%%RL(x_jUY{Vb#$fSun+ElvpQ#Iy^j`QB7A~6dR45?^4ZkQvb zEX(DaJ`hTYHk-w+HZx4JKSV=m(jXR0_@?U%JJoNfhWo z$dN!FPcb8Ow<|vH=B30_I7eqbUW6QykrPP5Ek4FfH>oST8z+(^lNNgL^Er+>;u>`f zkddQ;oF%0%;cs#w1>#;E*r;A0pa+!Ic^B=sobqyuJc2X78}(i|HJossc3U8Oa@1EH z;&J(XS^B`itHMFKJzOG_cFF@YEDa6VioMiv$0HUlES0N_I>;6zQw5%4u6o29Ugy*I zY{0iU52cxL)ks${`mA%o@?ayRC-6uTKn{RLid{uUjZ!{v%4U8j5mx)zB$G$Dsl{@u zHTs_oDPRfXj+L*V=0sEr+$gS=56EG@3pmfu1X9Xer)MrtZo$~Nk7kv88)QXL9KB7~ z_wm7V9Z_{L8-|?xwY+EN;D*ztmdpxm_Rg{Aoe>AxzJG#EAZ4mR$>-JblV(9mjRGVR zS>eHT7~OfX)L-{BBTn=W!N!svn#TJOERQOfM?V4KJ&Q}`b9T-HH6|XxzP8CTgFaUj zH<7CcfM8cT7?Qw(yLsmtCiO~JTcEt)GAk}G0Az!lv~a;A{@U-~kQ_z^5I^tG*Q)vTz%aBqj$E!)PC6o{VId_|VGQ$W znIcb%(OhH5RRbea=1{C;q}>OcxBA6Ffe+YGSD?~4AOJ&zG#Jzb9_-l&3A&pWn^)TD z=utHB(M$^6uFOghaCnxT%pw`D*1-Igj3}=LH0zJnoynr?ULb(67~NSOYT&ut(w%)% zV=J{XD<&?UEMxV11Z#SN;Npv1Z*50kUS|$mOZUupD~K(gG*bWY!eZDd4mFSMIRV_c zJ)oMuNY-UqNB`sm!kvYj1(t2`;tm6aBIAI=YR3(G-v)a2X;kY`r!F$)lUu~2t@ih{ zY+C9)`tSlFWR|)O;(pt!sV`CDReKl6;_yR&S2`P2^Q5O?sRc2NpmHXokN%mmajzTX zYUd5xccRM!E(uKTgo4e{TV)Cw8ZY4ho&qfwLDW5DDm1TgF|AC@nLGrNFAAS6fDjdc zR_uLjv0adg^_9Ehme3(Vwq;XmqpLyFDfg~I~aLJO{_2}oaYSms>v0q0){_P z40wARiVPHy<18MDTg^q!_Q28nd&K-*7l;dSGH96CbEJuIw@ks+z3T zm`#`FG$8uY+`P^^YoC{W$*@oeezuSK`6bB}KAAt!AS76G`q-X7BgGP+Y8&A7WZixh zQBv9F1g_Jqj$G$dJF|l~^;@mdIQV6o^Q4?QvdUcQX7-cYVOtb)Apj|KG+q?|)wl>5 zLPgT!0cex`E2uPX0!lmN_xXyR<1y}=Qm?b^rE0Scj|Xa2L0_21x0vV^at0KvHkger zu-%Va4>^G(uimu_rWBjO#i7~J5Zo{Um!?RFn=;~JX!Vpg}Q7t50is~Ln^nl6s{MO`1TQb z6R?^Z!Lye4iY`FU3qSr@ia#FQPgdVM8roL|0$$hL(iVttQl+DsNzz_-mgYi~y%~^x z1HJoR&yj8d(X0Waxde$m?yI$ci%) zQSqEwKMh#8ot|WU=iCf>Jkp5~adfL3xcdOLw_5$H88P~8N-;Mzv6#eSGA(C;zD0<< z@pIim(Fx;$jdh4=Q&hiEZS+HuQApHF5<~4pOhH+0y6(on%?~u#ycQjSQa|2=GhjWD zKBA(x%hL=UxPbmPZMkIm?>wEJa^7H_O*gOIj)O*B0PoiUWUm%^@VABn59?i=m0*y zq)rA!t}i3>zR)GZ!+rE+@8VtWX?eW~PQG(Df*RqwyI(Zq&Bi;24|lpmZq(W02rV_8 zTbXvI{w64_FK6HKOdI~--~i{_m=$=M{mZT|bIPJ`rC{+r_U299j~h|4HTP>w*@WI{ zq)GBI;rv)pQFSOBq21b-;TjTt`0zdIkl&;RTdl)ldJ*H5p^mN9%80|#oY1Ih-0pw2 z7BpFqjoBrEg=eQpDNxdRB~iFa6E}(aWs*}?Gf?|7fA_?!^v%nXQSqa_XJYs#W@@0(vp_!oFwwbLADrZ2fG4%8(H zhO%s=z=v5LZk5-Q-s?6dFsYqZ$tQ4;>dPz_0#bH}s3mH1`upSJMZy^7RE&5K)}x{K zYPai#z3+v8qJGA;J3yyVPou&orXOjoFY7d5%k_Dkgrnm9d;@i)Wbe z_YUyq)H1VscxDwL>1sXMX*R$4E)*wOJ!B7YW8wVrr5j!c_|&O0)5Ib>V>An=%42-a z%wDaBV32d5OmtQ^!qfxj+lyq4S0Z#`)sK|57ToW7$vU6=iWK|aMj16)jiouJA)QxR zl$;UI2Wzr+Yza%E^*!e=m6SlYB-tKTxp**1Jhy;*Qeow*wcqZEJv3*67-nQD5Uk=U z`k{u67|w%-FT5t+J8GX9?#}jEe3A89t>B~PKB;XH<2&6x!63e!5c~O#wCZaT$HFJy zpo0T6ajh??tNh(&bJ1n{*IMO0Z({e1hXTO@k-Irs<7$2Zb=k>L%Cks7; z8pcv_4jF~)k`?lN2FHP2M)v)1s92$yDy8!bvDCOC-*`jL1M~a=oU5`lq|L(x$cij= z2xzK8=ueiB&x%+Fy=EeQ86D*dCs>70>=o<1-kObIJdez(`PIWU&8ls>#k%Ed1xjF3 z=_7^+*PZn#3o}4?G#cGo?y1Jjc7Z@rvC%B6OoQ+o93oR=i-cNTa@6Q9NyUqH-Zy^G@4WzG!dFBIXu)k7aMo!RD@ z!pp>=TaHZ!ugzW!jpX_+ld@*82@Geu*~_ZvNTIo!V1 z7le1m`X@v{5vz$$dwx$_{jbzo3)sSA>&3n|&0Z`F-`YUT>XIlGeTK#L8H_7X{YZXv zlEXC`Ht9D;ZZWt6we!oyT%w{poPRyP=ehEMoSN#^LBu?bsPbdomJSigBs>({>(oFCd}CVN#v6R3o9?tG6qp^Tf2-w;-7wcU<12P_&t> zsp9YK?EE$+^pJLqi1%>}@oowN1&xd6E;s~S27M3*wMz?C#Rd^&cPEJX=#pf*Kzjaf zW&A#2pA`QWaS0-BhNgZgC!Bue&8{UWUfpk)%_hUY<5T(~jRUu61H)n0c28gIDmlDX z|B*x_!XO_qZy8NOnI4(>&ujR2W$OupfD|ZDSlHsM?jzyWl8R;B;APsC%-r7$`0xC3 z>quU7^ReAW-4rq3zQ@Nv;7twS8qf4t6dWwha56m(@vc$@W_$d2kJJRFQ+!9l*_iVkW1n`Ri+ zW%MHt)S=$bsO%#jcIQ#$K>3hMd|We;0RnmQC*>VJN_mCo3YzLD7IDX(G3#dm9xj+3 zD$ER1sgcoby`*Dp5<=Mko^Jm;9~ zK`QM<@~o-Fo$zz9hfR5F-^p6-ty``#){7KdosKT?C)CTAFLy@2?VlbWtw1|!8{gJ>}I zw#OxITK##|P*5j`u&&}#DR>_O>Nejmkb4HF*~A1Nj+4R5`t$DqGW;zkx%;|?X&eRO z%;WAFIcQ$8om+ouYO08axbw&z;BV;s6LGbzfSQ+e3ms3_cD5yxU6)4%_|D2c;I0l; z31T>qiCr_^&-~s}CiHp-fSj30hAX~1$a#h*NaTB44cd2N zsD{O~9(8)+{BHC_(9{7CPyXftYMf+LMrj^5={PF0uN(bO6L;G;$6Sh+vp^0dyNc!3 zY(HLgO1lv_ZsbZ*VLcwZ9?QNK&Li2k&0DusU0wC9MAg$CnMEN9h`S7U zhk`?Sd>bcatSP3|H?@Md>(u()|kHa=Nz|gQ9PKNOgAJ|EWXaCQnL1cimmV67SgK zR2(y%&jP=bgUkdv$*#h)qSg3bYQ>UB391_g*ipYT25p2rQQ4qRe8I*vP$EYcIl>#q zKEzIaX9%iW4D`*In0csGNW5tzc)(IWBXD>TGf$4lmyLop6AAu(Nt`rzWMk+=&hh@= zL1P)+?r^!Y(I?kH?DL~3S@5StmWYOAVvLqgR;jEfQ#pj3VF?;B=WetPh294w_a^OI z%{5-g(vRHJG*qUsF$lB=^XK{}9RzQORoF6mIVK(tE6e-S%%-|{*S}DsVIMzbKkZEy z>GaifFI6N%WV@=`jnJ>rIbz;UO@(B(dYDqwMSu4OeyiuFx^OxBJ;yKp*8`nQEA0FV zX2a0}>t?FpUgK(am@SqF_YS1p17%J3ISNWH`g*=y`Z-!%lfHm++pCg5aNfPL>GNv% zbC4#9M`)MSY9eCwh5TOk++~`K_o{!-vm-6S=}I-}fy0w3Q8B+}K#|0QHA`NI)x8W@ z%{lA0Alm8$Hayf$7gj0m?~e?bxGY?f%(M%d_}VQ{Oqkhyd$xEJKhlPcFfZw1nLvmN z-G{iJI(pJY_~6XzX2ecq1v&E&E+eM8QbvW_(5s>hG_P@T^=3-A&OCWJ9A$R=dv3Z^Ds2ObbCP9)jFis<9!iF}Lcy(MCpc`=%}nor$TzyUxHz=~h=AmXzO!e0ch9Sgtd(hjybaiZ z@Wn9*KiL56XmDu}w^u6wV$4QJ2sbM)LlXkbM1hIG2eOMQfFto4`g0!zYP+NR{B~UsCk6YyqJe4tOa;tEMl$x^T*zc=F;cdGA3Ag91e)@;{ zzIUd|H+L!1eo)YL1`_Dmnw^q0uKmfxQ!sonW9uv5YZ(l)tW4(S+$2!7$u=Hy0nChOipc3~)x9*!ou&@$qX4+*Z z2po6()^QH?8#xYa13b{ziYSi3p_+T$5$6S}pxU>l*6LYCn?fjaNA$?}mDGDl6q5jF z6`d?t`AEAn_#xBNEFkn)>Hge=syo0eWE&_Yh7X-8HhS9~whQ1$RjO~U9|5|`cOq6K3}ukwe=kIAC{U?&2GIP;z&M&R3#%xNcF+%(TDK$$b!kA5q>!3aVWz zWNrr4K*hhByV56^vdO>KHR_s2l$p>*6Tc>!(|SnkT8P7uQR`? zXg#oU=$#zhsqHtBSGn9Cx#jrEsZAZ>CD~23asWPFI`qMDpFvUSXlP#{V^uDDU6xr1#EOJ12UH+r~-5xgTijppFcL5#`$tu^# zdb~$ymTHMb{Oo3`ByIc2$*q69p&_&O6UYDnBgd3-rvR_y2W~dN1*8U;mE2c{&(Oqr z2al%|JbcHP?6I=r87TbYo@qB(%CE_T}g?!n%%N``;UT;_ja1O>;)-oa1(fiZG5 zh(Warf)9Yvn?fwLhP1^boQs?lRrkvPYXaA5Q(-bhaa0%}F^_Knh$DNl!GpL<_P1@j zP6-M6-^IZD$;4!U+sR&#^pI9#+#vx!g!t;p4~V5oIMmV33|#}D7It)W^Ba3)ifFOM zJKz%6{|wLSA&e3)?ys8li-%PH!4rZrjf2B`5_!I})cAHTTq{owsrSJ&gz#8Oq6}6? zO<-;@0)fg&jVdXyReaF&z+DSQ$6vgC{h=Fhk$8T`w%W4oG#PjU3gb#&3UzWn-%UI| zT*LL?rSZ~F9TMx6KjP$4Xx`(pxI^~eM+dU&2wGu0Kjch8QIh>cnA1$ zP0(}7jDg+kf>55FtZV^5#Tu12o#Qrxs+G3z8DGXNdjjcVCkKmcH>zvHlje;q3^ zZ$sxOvKs^eU29l12%aCrj!VgP{H zbW#2X#O5CZk-&ZL&t-MI7L>&GoAJ{+^|tY*Tjjmm3t2TkUu7%iLMxe%-enJ|-FYG= z%!Wb6%-P6H-#KhgN#Oayk+dW*$<-I5$CQ#4M}f-{IV1i({^KR(rDZh_F{GEXCnwT> z1}&Me`)B+ca15#?C;vIS|G%)i?|6vLt#@AUpD2%w3+k?8A7vi|_CVypeq*ugXCE5>vB0UIgm*^pyfN^aHfkIA(inJ48Cx?G`$LRr;IEywQl5$3j4YK%P_ zY+vGiH#&!~ABTGl|9qTyWPSuAl!1@Kvu>8$y4PFsm9!^L7)~v#8HtM(dt`}aUEco8 zx_n3!S2p?6Gg&3~tr9 zvX6G9*#=MmQcuqb)E&+J(r1dj_EAs&jtXkL30&;SL(cICoHOKC!vn;mOcS_wi!jR( z2E8M*e|?D^s#=?xl@zjDUubh~;ylFEarjDA$#Y1-u=hJ#ZGL{B%c&hh?#4xk6d zaArs3CD36UIzp85C)w?|Z@iI8vRY53H;u=Zr?{j!y(yM)79A}xt_fp^@&Nc=1B2+< z>o-P%+X@~LScbx9W^)P-5by9ZY2K}AE47r$3cF*rZ{`IVv2XX*o@#K`uSFK-AP&~J1A>oS&Xumjz8c_vU&lP_NJpw3LKTO zlir?l$y@*C%5l0Mmx8+d(0Y@TgHDh8%77XdCZe|$5qQ5)eI9;AKXdG(bg{D;C-$pK z+m^3~8xvx4hz6>OeV{tJ#5xVXIZX`um8=!v!>wJZi3WDw+!N?n^9qy=`-FLkT6Mq- z{^-&ma}O``094K5bN3qjxR349xySH}0};B3a@sWQR9aGZxLIE0?e z>fK)!_VuY0yWbvzmEFnxU^a~wUPO>R&p@O-#&?_w!h3n#Y`@At9O-?_9v1$&cgE0T zU4_?k(yqAStspUXF}6*2?i+4^2elooMxY$7*V`LaZ;Nbd;I%`@`8&QjeYn#+e7O*j zv-URe6lkLI)D%GJ_R$PMXYw(BDMX*3+VODFNobmHMew8`0%q1k4uV{Rl;4&e&M8`q zFmiLx>K*!*mlP5XXQ)5lk?9IEi{jyThx=+Itcw0#yNO3sp}!bSiFr`o@SCg&_h)YI zl(R&`WsP%=-~TDYpP!HsA3G^@t|3qEa;EQ6k%(bvVP0s$1q?szDv19@Q^et}n+-*`LB;ND`QCq?Z|$2Pn`KC~D*@ch zKHtF@yoTOsX>+sF0$w{Yza-6U8?PVDVDMi#ug*bW;deaQpLl$6v6B%CTii#f8&+-cvps&7+b| z09{RLQfi+G`@+6&fQ(E;Om(-{N`%wD*5Lo(4ZYdJB3t*Qyu6BA6?h#!o=GG4+NWM$ zS-6P)ncZA_jy_LCh;EwZEK}BqwBJfj%FAly!-m$#Q|zpRIq*-w6qgC{|Cqi|K-A6w zoP_r0(*t8RQC)^~QTjD1Q+m=e*!B}bQA$dm<1&piqyMCf>15CYtcCr;^E7tWJNNL> z90|1T_EPPW9_{$cy&^A^{_NKyEZ~shrKIkv|8Y9q&ty|c5l}Cq&zJg|3a9tk_PWLMajj8C%Z30+iBHGDAl=&+gPI7+jDv+2L? zIZBcxd!xVdJH8+>VHrun)DT$1|CqUzJ?Wr&{P^DPz@bgoN@}TUV2iS9l;T0z$1vNm z^VO7^DFqH$<*0!1``hcToK>5V=`8=uS;1GOq*d9!w%bgVR|xmwe}3@Gbo>m4pJ3LAB6*lzm3Q7jw?kR*Vvx=N)yK1wnGT0HY9%4C{uOl=P zL!^PoJ(Kj_dAmB2^+AZ}H_Uyt?q`H;nn&l=D6-a*cE`~_{dRA7{qyP&;l^Q(mRE&a zy*M}PP{WS#sQXh-hpXfnVPESB2@u=nK3JVotTVx`?R{ymCdcD>f0GZ&;2~}{nH05K z>GSQ8;nL$ox9XaqP%-5xos?7wwp5Gl_94T$g5rE9X^7|0you1k6OVS?mS zpCMj(z4*S#Gg$!jz47}>$b?WH+|ckxr7zh?&MW^s$c96D(9(XE}VGrXC;G_1gy~8)LoB$4kX9} ziRnwfzZD#(1Rg`jE9kAlaF?XuD+wxhI2(Td?RQlM)-QFirDq|zlkWC~>F7I&QN_pO zFHp$!mbj{fQzX`D9c~t^$fg`bIgcB#4Z_X<(0+AFTtgGdb@YvxyPbwU9Vo6F5QGh~ zK?D~=F0}`1Ze}wCd^7W&qN+b65rJ9AUqGjXY+O4EEQU+-$x^dmOm1b9ohEzufFtyZ zvh3dLMm*g0rNhxh$kmeLFo=Kc_1o)A#cCT;cmC` z@8AzMcJ%F4%`o{OvR!RWOc=L;fu~XxMBA8bvY94g5lWtms-v40I(oL?{^UM_IbpH`l@W_cJ?VC0 za!mubRJ-3?k`dIvAPGQuu8q(_Iwor8GaXIqJzpmGTqHjXFk-0MPrx8q`?EZ&bmlvu zWcb#0-i?6vI`>6J_%R4<<`003i4Lr%5j)@wQT=>Qjfg!Yxe{xFh~kXD=N(|?&x3zN zKaevO!D0qplkJ*p^XEsu0BqB(KtaQ>?*ctAf$zG9tt1@~|4b`b6}8|(;P0DZq7NvA z$kw#v!3AjXJ+u?MU0y5Tis`}th3EIsC4YE5m-B$P((Z|f9pqa#Fo-WLF75yhpzMQI zUc}X!C}+{%Z$;kGKOr}dLnx^qs6%>iVopELP^_EfgM=H-r&%XsT99z++3q#AF;F7; z><*ZVQ;+IEaTN^MCve*v?$a$ae!t$?u5<_>{&s-CEEj1G0hw?#{jQtfYnAX@&!$@v zd^duCEBaKO5lEZ|t;Ah14Ifs?EXLorqRkIr?vofltg~<5o&Ixa820d(%&wMpzZ^d! z2l5&b8N^e{*}jzx3Vch>vmf3+=EIB=j+t)Vop<)_JjvoJI=S43>hx#3fjfUAVMpIetjUj{|>>>Vxa;Ay$?YzWx{ zM2|`zxE}hd!4&0l+TZXftMjq|rQ+yc;30do2Dnf!Zi9(ZO0Gq2Ec>cOWGv&vF*KAr=nn;?hKSl;)?p<&ka?^ovgJQi7*Ui6hO z&_Lnc=RvsP{`c0-h?6;mOUO$+*&^m+A&~EZUOaH z&1o%ve(hX{U;botUBr6G4e6dtj-B>xrs7aMMyrN*5*r;sHifZf*So)o%<>YSYQB*5 z)#NWbzo26M&FRry4>C{~%@g<%nv!XEHfY2HKshXyOf`=|HULlSt%xZQ1$&!$dQV3C zF9|bR_6Fk#QOPnS&w(GW^v$f;tV7`HgA0k^VO0t_FXYI^{G-5Y>V5Fv+nZJjj;lZ`J5{|Ze0^EFsgN5ZL=D_x_Z|~m zUQff@61NN-#k7`uo6NEfXpsWP(zQ~QgxUwV-*mdWpuT#CO0sD^D)1Ui)P(O|BOP1~ zbnZ(vJbQF0uo?X)<(CIFw3XKb-!s2J`{(lriNf-ScF*O&Zvx-WGl{r>8C6P#Z-tuo z=U>!>o}sewH&5~>qPtq^tzuXpa>R|bd8S0daYVw%p1)DBnQ7myHz)D3;82A0zNpfxVFC%FrJ*Sl`I zvwV#jq(_qWQ`@K zYx}wd0)?4TGO8#W+^T-M*X_b<%K0raN7u99KbPj@y+*V#0i1$c=#?9sxBUL{EWTzi zEMIZ;(3Z#3f0WUL)Xu1Nt>)f_(j%jj3_n%C>@lCg9eaZh&#!s@EhY1cL1=Tj8@vm8JeO|o?{9Y3fV0n7Lu1312A~@Y z{jPI20)AqaM?;iav)4KD{lgw5DtAWOCcittE80{|h&W2w4Z-7wYx}yLIQ zZ9z5hVeR_wr7o8I?LC&ChHJ482Wz564n^*f6gEE1r_mGV3mKE*f=_G9vz~q{y*u19 zXttB7qu8`0Y-76j7T>@%s9QD_Zan>BI2(1X^N>4bIid5Vh1YW5gwp_fkq?X#H%_+9 zfbgErd*}4?Io$aFV(l&Cn)?4f;2E?7B$YN01PPJG5ds1tju1f_B}OAk4j4aDL_!o$ zl$4H*?tz3L3J#>Z1xAeCU@-18^mqOL*L^*>pWJ)kYwFoK-}8-6yx*Ug>zyAk`j~Pg zT5hqZAw1ffYHQb#1_g@#@y&ov%PXtq59k14wDL-=RPCZP5sW0kQ`xzP< zN&~51c{xWe!zGtKk=y3!>8v2bYj9piX!3<0aljgy62t ziltJb2_@)VO8dlAS(_!QvY`En9Xk92xM|XP+VpcJg{;#4M6YMiNGZ1+bb{M3G3m_} zjl0il$yDT}(sVV=I&w|G=j0g!rN2vfP-guj+Acbx+b>pvQ}%j6*9_s3_9`*pebwWn zR67VpMw{!F!p2G-6G)fsL4#G~@yDkF5rJZO>U8v z_iquq!HI-rQ;|}*VMPx3XP}1T!D>Lhg94eh^l5nxR9Dc`Aqwwst@Wx?f>?^LbYj{? zw&SNnI=cM8l?8e-?>!ZSO-6qHOmpgFcvzlGx>fKkt?te*`_fn5QS)h-P1pFtTS_Uo zLZ)NImqQ)(H@DcRh2-rTe&!xnXdcJ(JRF0wKiKrF`$_KEynmv%>)48ifU*Q6`38c# zQd$h})U~n34<@=NuM!kvc-R>}>h^&fF<8`LRlbdk5h^#xY_7Ud4rGLz4t(=Y_SAY0 zAyH`G9&1<3D6GGxji3LAL4!4$e@fsk>!-~x`drXYrv(*=2-~V#`{=k&#T*B&<r-WroCWywlD}UB2rLg8LIFhpb3`1`4(c+Qn!w=?9I`G}3 zt;#r9Nm4-nYBq0W!FhvLS{x^G&c!F~~> z`=bBe+K8Kg(iBHAcHA2%PJF(2$tu7i{!kR_xHnsumuX9;NBZj5>xA#``W9h+`;)tH zoZU5KsWB3__y^7~i6S?&-VL}EmWn!*l5*qaNXaK}sJwU`Yoj`g;-$Gs>Y-4lV^VmO ze6&!Q!LOQWnwBU1cxq*QzVJRzcE(Sp*Z`pdm+U~)%epTFyN7QwgQC4h(q~U`;W%27 z(55sH-;3TI+}@IFoH+W{`U2feSHVw1g#_l@SeHW@=&RN z8e#v)(ZdG9t-n(3@hh+zs|w0zRHV%#xy6EU7XFE>y(0}~RT zWTH4o5Z}PqCEOVp9F(rSud7YLeT#I|Hz|K*35C1K|Ky#&t`j{vX9xG-IoPJs05)G5TKX%)wXhvfSu09p)ku&FyCWKMMz8viNP z=Vm3>CMenjBzU1eF(`V^P+aR26U98Mq#j7q(?kYvIdsKn(*@sW`X%_t039;SZSoYy z-lDL9Pk{7qYfe2pi{G98q@&>vK=*5oiYD*H45U!M`rSjR6`mr~YSALRs3g!J9F?j$ zAaAbfH%kGM?=SDfMXDn1|9tq^u)Dv(L^5;}!SjotG-Nt!@210FN!JU9IUaQV>X&3V zxV?vYczvh*Il1dj!P5etpvkv$YsI(T{+P^!PDve*9CVWYSbOR2Uq3j@Ze|)v-L{Q3 zgmh6hC>C@T`DR`^e{Xgq?Y+xU!AKR#WT0=VyuilXFv+I(pzc_z@W{e((ce?cLPKbb zku623G(V^=cyHvO^yhDYdpp;6VxOPh^#f{%9-haww}k9rRmZZGZjS0FY0!T0NxE>) zPP4K30@QiQPmKo5p#OE>=^{B72Jr04ufNQmj{WTk4&(wYu@Hx{auypPO==-^3&f^* z@2EzlyNy2z!gZvHD?>L*%fEz%cuFbM$s}WR(uk>MC&78I1kOo%{R88~JrMl)mRjiG zaKOH*v2drq2_Z_9rJtP=BL#fU$1G}h+H4|Y--#y?yzg8iP0X9iX&vAnh)!OH9)3F6 z8|lwkZObyAt+*t@U=>(vkqQ=B3xK_Re4{t+)4`#^ly*Y|2r- z@*Yp2V&#QR<=E6wqr#9oX|jeJ8Y=#XV8f1wo9TcRtJtjY>Y(?LyLL$Mt6+0Ko!if7 z)BBv!qEe9UvO%EFO&0P4Q~PnL(fGUMsVyn(RUy8a9^&DA1YETu?&IkV+QyYz1|q%h z#2-zYr{y1{ZmcIriUteB&F$0{V$4`K&sGK#NRNv`L#z63dOCA=H1$c6f(1@(WzWGZ z-7*#N=u zm_$to47g}{zMYQ@Z|x|;PMZGSZI

9@ma37di&>3sRRIG`@X`0~ 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 | This is the absolute path to the configuration file. E.g. `c:\my-config\config.yaml` or `~/my-config/config.yaml`. For YAML on Windows you will need to escape the `\`, i.e. `c:\\my-config\\config.yaml`. | -| `default_postfix` | `` | This is the default postfix used for resource names. | - -## Further details on the Complete Starter Module and config file - -The `config.yaml` file also comes with helpful templated variables such as `starter_location` and `root_parent_management_group_id` which get prompted for during the ALZ PowerShell Module run. Alternatively, you can opt to not use the templated variables and hard-code the values in the `config.yaml` file. - -{{< hint type=note >}} -We recommend that you use the `caf-enterprise-scale` module for management groups and policies, and the `hubnetworking` module for connectivity resources. However, connectivity resources can be deployed using the `caf-enterprise-scale` module if you desire. -{{< /hint >}} - -The schema for the `config.yaml` is documented here - [Configuration YAML Schema][wiki_yaml_schema_reference]. - -### High Level Design - -{{< img name="starter-module-hubnetworking" size="origin" lazy=true >}} - -### Terraform Modules - -#### `caf-enterprise-scale` - -The `caf-enterprise-scale` module is used to deploy the management group hierarchy, policy assignments and management resources. For more information on the module itself see [here](https://github.com/Azure/terraform-azurerm-caf-enterprise-scale). - -#### `hubnetworking` - -The `hubnetworking` module is used to deploy connectivity resources such as Virtual Networks and Firewalls. -This module can be extended to deploy multiple Virtual Networks at scale, Route Tables, and Resource Locks. For more information on the module itself see [here](https://github.com/Azure/terraform-azurerm-hubnetworking). - -#### `avm-ptn-vnetgateway` - -The `avm-ptn-vnetgateway` module is used to deploy a Virtual Network Gateway inside your Virtual Network. Further configuration can be added (depending on requirements) to deploy Local Network Gateways, configure Virtual Network Gateway Connections, deploy ExpressRoute Gateways, and more. Additional information on the module can be found [here](https://github.com/Azure/terraform-azurerm-avm-ptn-vnetgateway). - -#### `avm-ptn-vwan` - -The `avm-ptn-vwan` module is used to deploy a Virtual WAN. Further configuration can be added (depending on requirements) to deploy VPN Sites, configure VPN Connections, and more. Additional information on the module can be found [here](https://github.com/Azure/terraform-azurerm-avm-ptn-vwan). - -#### Design your Azure Landing Zone through a custom config file - -Create a custom yaml config to tailor to your needs, for example an Azure Landing Zone with a three-region mesh: - -- Example config file for hub and spoke: [config-hub-spoke.yaml][example_starter_module_complete_config_hub_spoke] -- Example config file for Virtual WAN: [config-vwan.yaml][example_starter_module_complete_config_vwan] - - [//]: # (************************) - [//]: # (INSERT LINK LABELS BELOW) - [//]: # (************************) - -[wiki_yaml_schema_reference]: %5BUser-Guide%5D-YAML-Schema-Reference "Wiki - YAML Schema Reference" -[example_starter_module_complete_config_hub_spoke]: examples/starter-module-config/complete/config-hub-spoke.yaml "Example - Starter Module Config - Complete - Hub and Spoke" -[example_starter_module_complete_config_vwan]: examples/starter-module-config/complete/config-vwan.yaml "Example - Starter Module Config - Complete - Virtual WAN" -[example_powershell_inputs_azure_devops_terraform_complete]: examples/powershell-inputs/inputs-azure-devops-terraform-complete.yaml "Example - PowerShell Inputs - Azure DevOps - Terraform - Complete" -[example_powershell_inputs_github_terraform_complete]: examples/powershell-inputs/inputs-github-terraform-complete.yaml "Example - PowerShell Inputs - GitHub - Terraform - Complete" -[example_powershell_inputs_local_terraform_complete]: examples/powershell-inputs/inputs-local-terraform-complete.yaml "Example - PowerShell Inputs - Local - Terraform - Complete" diff --git a/docs/content/accelerator/startermodules/terraformcompletemultiregion.md b/docs/content/accelerator/startermodules/terraformcompletemultiregion.md deleted file mode 100644 index 672bdbe..0000000 --- a/docs/content/accelerator/startermodules/terraformcompletemultiregion.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Terraform complete multi-region ---- - -The `complete_multi_region` starter module provides full customization of the Azure Landing Zone. It is multi-regional by default and can support 1 or more regions. - -The ALZ PowerShell Module can accept multiple input files and we recommend using a separate file for the `complete_multi_region` starter module. This allows you to more easily manage and maintain your configuration files. - -## Inputs - -The following tables describe the inputs required for the `complete_multi_region` starter module. Depending on you choice of networking technology, you will need to supply the relevant inputs. - -### Shared Inputs - -| Input | Placeholder | Description | -| - | -- | --- | -| `management_settings_es` | `{}` | This is the management resource configuration for the ES (Enterprise Scale) versions of the management modules. Full details of the inputs can be seen [here](https://registry.terraform.io/modules/Azure/caf-enterprise-scale/azurerm/latest) | -| `connectivity_type` | `hub_and_spoke_vnet` | This is the choice of networking technology. Allowed values are `hub_and_spoke_vnet`, `virtual_wan` or `none`. | -| `connectivity_resource_groups` | `{}` | The resource groups used by the connectivity resources must be specified here. See the example files for usage. | -| ~~`management_use_avm`~~ | `false` | [NOTE: This variable will be implemented in a future version, setting to `true` will result in an error] This input is to specify to use the AVM (Azure Verified Modules) versions of the management modules. Defaults to `false`. | -| ~~`management_settings_avm`~~ | `{}` | [NOTE: This variable will be implemented in a future version] This is the management resource configuration for the AVM (Azure Verified Modules) versions of the management modules. | - -### Hub and Spoke Virtual Network Inputs - -| Input | Placeholder | Description | -| - | -- | --- | -| `hub_and_spoke_vnet_settings` | `{}` | This is for configuring global resources, such as the DDOS protection plan. See the example files for usage. | -| `hub_and_spoke_vnet_virtual_networks` | `{}` | This is the details configuration of each region for the hub networks. There are three top level components for each region: `hub_virtual_network`, `virtual_network_gateways` and `private_dns_zones`. Detailed information for `hub_virtual_network` inputs can be found [here](https://registry.terraform.io/modules/Azure/avm-ptn-hubnetworking). Detailed information for `virtual_network_gateways` can be found [here](https://registry.terraform.io/modules/Azure/avm-ptn-vnetgateway/azurerm/latest). See the example files for usage. | - -### Virtual WAN Inputs - -| Input | Placeholder | Description | -| - | -- | --- | -| `virtual_wan_settings` | `{}` | This is for configuring global resources, such as the Virtual WAN and DDOS protection plan. See the example files for usage. | -| `virtual_wan_virtual_hubs` | `{}` | This is the details configuration of each region for the virtual hubs. There are three top level components for each region: `hub`, `firewall` and `private_dns_zones`. Detailed information for `hub` and `firewall` inputs can be found [here](https://registry.terraform.io/modules/Azure/avm-ptn-virtualwan/azurerm/latest). See the example files for usage. | - -Example ALZ PowerShell input files can be found here: - -- [inputs-azure-devops-terraform-complete-multi-region.yaml](https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/powershell-inputs/inputs-azure-devops-terraform-complete-multi-region.yaml) -- [inputs-github-terraform-complete-multi-region.yaml](https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/powershell-inputs/inputs-github-terraform-complete-multi-region.yaml) -- [inputs-local-terraform-complete-multi-region.yaml](https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/powershell-inputs/inputs-local-terraform-complete-multi-region.yaml) - -Example network technology specific input files can be found here: - -- Multi region hub and spoke virtual network: [config-hub-and-spoke-vnet-multi-region.yaml](https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-multi-region.yaml) -- Multi region virtual WAN: [config-virtual-wan-multi-region.yaml](https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/starter-module-config/complete-multi-region/config-virtual-wan-multi-region.yaml) -- Single region hub and spoke virtual network: [config-hub-and-spoke-vnet-single-region.yaml](https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-single-region.yaml) -- Single region virtual WAN: [config-virtual-wan-single-region.yaml](https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/starter-module-config/complete-multi-region/config-virtual-wan-single-region.yaml) - -## Further details on the Complete Multi Region Starter Module and config file - -The example config files have helpful templated variables such as `starter_location_##` and `root_parent_management_group_id` which get prompted for during the ALZ PowerShell Module run. Alternatively, you can opt to not use the templated variables and hard-code the values in your config file. - -> **Note:** We currently use the `caf-enterprise-scale` module for management groups and policies, and the Azure Verified Modules for connectivity resources. - -### High Level Design - -![Alt text](Azure-Landing-Zones/docs/content/accelerator/startermodules/terraformcomplete/img/starter-module-hubnetworking.png) - -### Terraform Modules - -The following modules are composed together in the `complete_multi_region` starter module. - -#### `caf-enterprise-scale` - -The `caf-enterprise-scale` module is used to deploy the management group hierarchy, policy assignments and management resources. For more information on the module itself see [here](https://github.com/Azure/terraform-azurerm-caf-enterprise-scale). - -#### `avm-ptn-hubnetworking` - -The `avm-ptn-hubnetworking` module is used to deploy connectivity resources such as Virtual Networks and Firewalls. -This module can be extended to deploy multiple Virtual Networks at scale, Route Tables, and Resource Locks. For more information on the module itself see [here](https://github.com/Azure/terraform-azurerm-avm-ptn-hu). - -#### `avm-ptn-vnetgateway` - -The `avm-ptn-vnetgateway` module is used to deploy a Virtual Network Gateway inside your Virtual Network. Further configuration can be added (depending on requirements) to deploy Local Network Gateways, configure Virtual Network Gateway Connections, deploy ExpressRoute Gateways, and more. Additional information on the module can be found [here](https://github.com/Azure/terraform-azurerm-avm-ptn-vnetgateway). - -#### `avm-ptn-vwan` - -The `avm-ptn-vwan` module is used to deploy a Virtual WAN. Further configuration can be added (depending on requirements) to deploy VPN Sites, configure VPN Connections, and more. Additional information on the module can be found [here](https://github.com/Azure/terraform-azurerm-avm-ptn-vwan). - -#### `avm-ptn-network-private-link-private-dns-zones` - -The `avm-ptn-network-private-link-private-dns-zones` module is used to deploy Private DNS Zones for Private Link Services. Further configuration can be added depending on requirements. Additional information on the module can be found [here](https://github.com/Azure/terraform-azurerm-avm-ptn-network-private-link-private-dns-zones). - - [//]: # (************************) - [//]: # (INSERT LINK LABELS BELOW) - [//]: # (************************) - -[example_starter_module_complete_config_hub_spoke_single_region]: examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-single-region.yaml "Example - Starter Module Config - Complete - Hub and Spoke VNet Single Region" -[example_starter_module_complete_config_vwan_single_region]: examples/starter-module-config/complete-multi-region/config-virtual-wan-single-region.yaml "Example - Starter Module Config - Complete - Virtual WAN Single Region" -[example_starter_module_complete_config_hub_spoke_multi_region]: examples/starter-module-config/complete-multi-region/config-hub-and-spoke-vnet-multi-region.yaml "Example - Starter Module Config - Complete - Hub and Spoke VNet Multi Region" -[example_starter_module_complete_config_vwan_multi_region]: examples/starter-module-config/complete-multi-region/config-virtual-wan-multi-region.yaml "Example - Starter Module Config - Complete - Virtual WAN Multi Region" -[example_powershell_inputs_azure_devops_terraform_complete_multi_region]: examples/powershell-inputs/inputs-azure-devops-terraform-complete-multi-region.yaml "Example - PowerShell Inputs - Azure DevOps - Terraform - Complete Multi Region" -[example_powershell_inputs_github_terraform_complete_multi_region]: examples/powershell-inputs/inputs-github-terraform-complete-multi-region.yaml "Example - PowerShell Inputs - GitHub - Terraform - Complete Multi Region" -[example_powershell_inputs_local_terraform_complete_multi_region]: examples/powershell-inputs/inputs-local-terraform-complete-multi-region.yaml "Example - PowerShell Inputs - Local - Terraform - Complete Multi Region" diff --git a/docs/content/accelerator/startermodules/terraformfsi/index.md b/docs/content/accelerator/startermodules/terraformfsi/index.md index 3d50fdf..c33ddd1 100644 --- a/docs/content/accelerator/startermodules/terraformfsi/index.md +++ b/docs/content/accelerator/startermodules/terraformfsi/index.md @@ -1,5 +1,5 @@ --- -title: Terraform FSI +title: Terraform - Financial Services Industry Landing Zone resources: - name: fsi src: img/fsi.png @@ -12,9 +12,9 @@ The default `inputs.yaml` file will need to be modified based on the documentati Example input files can be found here: -- [inputs-azure-devops-terraform-financial-services-landing-zone.yaml][example_powershell_inputs_azure_devops_terraform_financial_services_industry_landing_zone] -- [inputs-github-terraform-financial-services-landing-zone.yaml][example_powershell_inputs_github_terraform_financial_services_industry_landing_zone] -- [inputs-local-terraform-financial-services-landing-zone.yaml][example_powershell_inputs_local_terraform_financial_services_industry_landing_zone] +- [inputs-azure-devops.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/microsoft_cloud_for_industry/financial_services_landing_zone/examples/bootstrap/inputs-azure-devops.yaml) +- [inputs-github.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/microsoft_cloud_for_industry/financial_services_landing_zone/examples/bootstrap/inputs-github.yaml) +- [inputs-local.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/microsoft_cloud_for_industry/financial_services_landing_zone/examples/bootstrap/inputs-local.yaml) The following table describes the inputs for the `financial_services_landing_zone` starter module. @@ -23,7 +23,7 @@ The following table describes the inputs for the `financial_services_landing_zon | `allowed_locations` | Required | List | | This is a list of Azure regions all workloads running outside of the Confidential Management Group scopes are allowed to be deployed into. | | `allowed_locations_for_confidential_computing` | Required | List | | This is a list of Azure regions all workloads running inside of the Confidential Management Group scopes are allowed to be deployed into. | | `az_firewall_policies_enabled` | | Boolean | `true` | Set to `true` to deploy a default Azure Firewall Policy resource if `enable_firewall` is also `true`. | -| `apply_alz_archetypes_via_architecture_definition_template` | | Boolean | `true` | This controls whether to apply the ALZ archetypes (polcy assignments) to the Financial Services Industry Landing Zone deployment. | +| `apply_alz_archetypes_via_architecture_definition_template` | | Boolean | `true` | This controls whether to apply the ALZ archetypes (policy assignments) to the Financial Services Industry Landing Zone deployment. | | `bastion_outbound_ssh_rdp_ports` | | List | `["22", "3389"]` | List of outbound remote access ports to enable on the Azure Bastion NSG if `deploy_bastion` is also `true`. | | `custom_subnets` | | Map | See `inputs.yaml` for default object. | Map of subnets and their configurations to create within the hub network. | | `customer` | | String | `"Country/Region"` | Customer name to use when branding the compliance dashboard. | diff --git a/docs/content/accelerator/startermodules/terraformhubnetworking.md b/docs/content/accelerator/startermodules/terraformhubnetworking.md deleted file mode 100644 index ccd727a..0000000 --- a/docs/content/accelerator/startermodules/terraformhubnetworking.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Terraform hub networking ---- - -The `hubnetworking` starter module deploys the management group hierarchy, management resources, policies and hub networking. - -Example input files can be found here: - -- [inputs-azure-devops-terraform-hubnetworking.yaml][example_powershell_inputs_azure_devops_terraform_hubnetworking] -- [inputs-github-terraform-hubnetworking.yaml][example_powershell_inputs_github_terraform_hubnetworking] -- [inputs-local-terraform-hubnetworking.yaml][example_powershell_inputs_local_terraform_hubnetworking] - -The following table describes the inputs required for the `hubnetworking` starter module. - -| Input | Placeholder | Description | -| - | -- | --- | -| `root_id` | `` | This is the prefix for the ID of management groups. | -| `root_name` | `` | This is the prefix for the name of management groups. | -| `hub_virtual_network_address_prefix` | `` | This is the ip address prefix for the hub virtual network. This must be a valid CIDR, e.g. `10.0.0.0/16`. | -| `firewall_subnet_address_prefix` | `` | This is the ip address prefix for the firewall subnet. This must be a valid CIDR, e.g. `10.0.0.0/24`. | -| `gateway_subnet_address_prefix` | `` | This is the ip address prefix for the gateway subnet. This must be a valid CIDR, e.g. `10.0.1.0/24`. | -| `virtual_network_gateway_creation_enabled` | `true` | Determines whether or not to deploy the gateway. | - - [//]: # (************************) - [//]: # (INSERT LINK LABELS BELOW) - [//]: # (************************) - -[example_powershell_inputs_azure_devops_terraform_hubnetworking]: https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/powershell-inputs/inputs-azure-devops-terraform-hubnetworking.yaml "Example - PowerShell Inputs - Azure DevOps - Terraform - Hub Networking" -[example_powershell_inputs_github_terraform_hubnetworking]: https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/powershell-inputs/inputs-github-terraform-hubnetworking.yaml "Example - PowerShell Inputs - GitHub - Terraform - Hub Networking" -[example_powershell_inputs_local_terraform_hubnetworking]: https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/powershell-inputs/inputs-local-terraform-hubnetworking.yaml "Example - PowerShell Inputs - Local - Terraform - Hub Networking" diff --git a/docs/content/accelerator/startermodules/terraformsovereign/index.md b/docs/content/accelerator/startermodules/terraformsovereign/index.md index 876b381..18a7a26 100644 --- a/docs/content/accelerator/startermodules/terraformsovereign/index.md +++ b/docs/content/accelerator/startermodules/terraformsovereign/index.md @@ -1,5 +1,5 @@ --- -title: Terraform sovereign +title: Terraform - Sovereign Landing Zone resources: - name: microsoft_cloud_for_sovereignty src: img/microsoft_cloud_for_sovereignty.png @@ -14,9 +14,9 @@ The default `inputs.yaml` file will need to be modified based on the documentati Example input files can be found here: -- [inputs-azure-devops-terraform-sovereign-landing-zone.yaml][example_powershell_inputs_azure_devops_terraform_sovereign_landing_zone] -- [inputs-github-terraform-sovereign-landing-zone.yaml][example_powershell_inputs_github_terraform_sovereign_landing_zone] -- [inputs-local-terraform-sovereign-landing-zone.yaml][example_powershell_inputs_local_terraform_sovereign_landing_zone] +- [inputs-azure-devops.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/microsoft_cloud_for_industry/sovereign_landing_zone/examples/bootstrap/inputs-azure-devops.yaml) +- [inputs-github.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/microsoft_cloud_for_industry/sovereign_landing_zone/examples/bootstrap/inputs-github.yaml) +- [inputs-local.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/microsoft_cloud_for_industry/sovereign_landing_zone/examples/bootstrap/inputs-local.yaml) The following table describes the inputs for the `sovereign_landing_zone` starter module. @@ -25,7 +25,7 @@ The following table describes the inputs for the `sovereign_landing_zone` starte | `allowed_locations` | Required | List | | This is a list of Azure regions all workloads running outside of the Confidential Management Group scopes are allowed to be deployed into. | | `allowed_locations_for_confidential_computing` | Required | List | | This is a list of Azure regions all workloads running inside of the Confidential Management Group scopes are allowed to be deployed into. | | `az_firewall_policies_enabled` | | Boolean | `true` | Set to `true` to deploy a default Azure Firewall Policy resource if `enable_firewall` is also `true`. | -| `apply_alz_archetypes_via_architecture_definition_template` | | Boolean | `true` | This controls whether to apply the ALZ archetypes (polcy assignments) to the SLZ deployment. | +| `apply_alz_archetypes_via_architecture_definition_template` | | Boolean | `true` | This controls whether to apply the ALZ archetypes (policy assignments) to the SLZ deployment. | | `bastion_outbound_ssh_rdp_ports` | | List | `["22", "3389"]` | List of outbound remote access ports to enable on the Azure Bastion NSG if `deploy_bastion` is also `true`. | | `custom_subnets` | | Map | See `inputs.yaml` for default object. | Map of subnets and their configurations to create within the hub network. | | `customer` | | String | `"Country/Region"` | Customer name to use when branding the compliance dashboard. | diff --git a/docs/content/accelerator/startermodules/terrafromcompletevnext.md b/docs/content/accelerator/startermodules/terrafromcompletevnext.md deleted file mode 100644 index f83840d..0000000 --- a/docs/content/accelerator/startermodules/terrafromcompletevnext.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: Terraform complete v.next ---- - -{{< hint type=warning >}} -The Complete vNext starter module is a work in progress. Do not use this for any production workloads. -{{< /hint >}} - -The `complete_vnext` starter module provides full customization of the Azure Landing Zone using the `config.yaml` file. The `config.yaml` file provides the ability to enable and disable modules, configure module inputs and outputs, and configure module resources. -A custom `config.yaml` file can be passed to the `configuration_file_path` argument of the ALZ PowerShell Module. This allows you to firstly design your Azure Landing Zone, and then deploy it. - -If not specified, the default `config.yaml` file will be used, which can be seen [here](https://github.com/Azure/alz-terraform-accelerator/blob/main/templates/complete_vnext/config.yaml). - -Example input files can be found here: - -- [inputs-azure-devops-terraform-complete_vnext.yaml][example_powershell_inputs_azure_devops_terraform_complete_vnext] -- [inputs-github-terraform-complete_vnext.yaml][example_powershell_inputs_github_terraform_complete_vnext] -- [inputs-local-terraform-complete_vnext.yaml][example_powershell_inputs_local_terraform_complete_vnext] - -The following table describes the inputs required for the `complete_vnext` starter module. - -| Input | Placeholder | Description | -| - | -- | --- | -| `configuration_file_path` | `` | This is the absolute path to the configuration file. E.g. `c:\my-config\config.yaml` or `~/my-config/config.yaml`. For YAML on Windows you will need to escape the `\`, i.e. `c:\\my-config\\config.yaml`. | -| `default_postfix` | `` | This is the default postfix used for resource names. | - -## Further details on the Complete Starter Module and config file - -The `config.yaml` file also comes with helpful templated variables such as `default_location` and `root_parent_management_group_id` which get prompted for during the ALZ PowerShell Module run. Alternatively, you can opt to not use the templated variables and hard-code the values in the `config.yaml` file. - -> **Note:** We recommend that you use the `caf-enterprise-scale` module for management groups and policies, and the `hubnetworking` module for connectivity resources. However, connectivity resources can be deployed using the `caf-enterprise-scale` module if you desire. - -The schema for the `config.yaml` is documented here - [Configuration YAML Schema][wiki_yaml_schema_reference]. - -### High Level Design - -![Alt text](./media/starter-module-hubnetworking.png) - -### Terraform Modules - -#### `caf-enterprise-scale` - -The `caf-enterprise-scale` module is used to deploy the management group hierarchy, policy assignments and management resources. For more information on the module itself see [here](https://github.com/Azure/terraform-azurerm-caf-enterprise-scale). - -#### `hubnetworking` - -The `hubnetworking` module is used to deploy connectivity resources such as Virtual Networks and Firewalls. -This module can be extended to deploy multiple Virtual Networks at scale, Route Tables, and Resource Locks. For more information on the module itself see [here](https://github.com/Azure/terraform-azurerm-hubnetworking). - -#### `avm-ptn-vnetgateway` - -The `avm-ptn-vnetgateway` module is used to deploy a Virtual Network Gateway inside your Virtual Network. Further configuration can be added (depending on requirements) to deploy Local Network Gateways, configure Virtual Network Gateway Connections, deploy ExpressRoute Gateways, and more. Additional information on the module can be found [here](https://github.com/Azure/terraform-azurerm-avm-ptn-vnetgateway). - -#### `avm-ptn-vwan` - -The `avm-ptn-vwan` module is used to deploy a Virtual WAN. Further configuration can be added (depending on requirements) to deploy VPN Sites, configure VPN Connections, and more. Additional information on the module can be found [here](https://github.com/Azure/terraform-azurerm-avm-ptn-vwan). - -#### Design your Azure Landing Zone through a custom config file - -Create a custom yaml config to tailor to your needs, for example an Azure Landing Zone with a three-region mesh: - -- Example config file for hub and spoke: [config-hub-spoke.yaml][example_starter_module_complete_vnext_config_hub_spoke] -- Example config file for Virtual WAN: [config-vwan.yaml][example_starter_module_complete_vnext_config_vwan] - - [//]: # (************************) - [//]: # (INSERT LINK LABELS BELOW) - [//]: # (************************) - -[wiki_yaml_schema_reference]: https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/%5BUser-Guide%5D-YAML-Schema-Reference.md "Wiki - YAML Schema Reference" -[example_starter_module_complete_vnext_config_hub_spoke]: https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/starter-module-config/complete/config-hub-spoke.yaml "Example - Starter Module Config - Complete - Hub and Spoke" -[example_starter_module_complete_vnext_config_vwan]: https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/starter-module-config/complete/config-vwan.yaml "Example - Starter Module Config - Complete - Virtual WAN" -[example_powershell_inputs_azure_devops_terraform_complete_vnext]: https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/powershell-inputs/inputs-azure-devops-terraform-complete-vnext.yaml "Example - PowerShell Inputs - Azure DevOps - Terraform - Complete vNext" -[example_powershell_inputs_github_terraform_complete_vnext]: https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/powershell-inputs/inputs-github-terraform-complete-vnext.yaml "Example - PowerShell Inputs - GitHub - Terraform - Complete vNext" -[example_powershell_inputs_local_terraform_complete_vnext]: https://raw.githubusercontent.com/Azure/ALZ-PowerShell-Module/refs/heads/main/docs/wiki/examples/powershell-inputs/inputs-local-terraform-complete-vnext.yaml "Example - PowerShell Inputs - Local - Terraform - Complete vNext" diff --git a/docs/content/accelerator/troubleshooting.md b/docs/content/accelerator/troubleshooting.md index 57ee79a..f9a67f1 100644 --- a/docs/content/accelerator/troubleshooting.md +++ b/docs/content/accelerator/troubleshooting.md @@ -4,7 +4,7 @@ weight: 15 --- Having trouble using the module and unable to find a solution in the Wiki? -If it isn't listed below, let us know about it in our [Issues][Issues] log. We'll do our best to help and you may find your issue documented here. +If it isn't listed below, let us know about it in our [Issues](https://github.com/Azure/ALZ-PowerShell-Module/issues) log. We'll do our best to help and you may find your issue documented here. ## PowerShell ALZ Module Failing for non-obvious reasons @@ -41,6 +41,43 @@ To resolve this, you can manually delete the runners from Runner Group in the Gi This only affects you if you have Enterprise licensing and have chosen to use a Runner Group. More details can be found here: - - -[Issues]: https://github.com/Azure/alz-terraform-accelerator/issues "Our issues log" +## Error: creating Container Group + +If you see the following error, it is due to region (e.g. swedencentral) stating it supports availability zones, but it does not support them for Azure Container Instance. There is no way to detect this with automation, so requires a manual workaround at this time. + +In order to work around this issue, add the following setting to your input config file: + +```yaml +# GitHub +runner_container_zone_support: false + +# Azure DevOps +agent_container_zone_support: false +``` + +```text +╷ +│ Error: creating Container Group (Subscription: "0d754f66-65b4-4f64-97f5-221f0174ad48" +│ Resource Group Name: "rg-alz-r14c67r424-agents-swedencentral-001" +│ Container Group Name: "aci-alz-r14c67r424-swedencentral-002"): polling after ContainerGroupsCreateOrUpdate: polling failed: the Azure API returned the following error: +│ +│ Status: "Failed" +│ Code: "Failed" +│ Message: "The requested resource is not available in the location 'swedencentral' at this moment. Please retry with a different resource request or in another location. Resource requested: '2' CPU '4' GB memory 'Linux' OS" +│ Activity Id: "" +│ +│ --- +│ +│ API Response: +│ +│ ----[start]---- +│ {"id":"/subscriptions/**754f66-****-4f64-****-221f0174ad4**/resourceGroups/rg-alz-r14c67r424-agents-swedencentral-001/providers/Microsoft.ContainerInstance/containerGroups/aci-alz-r14c67r424-swedencentral-002","status":"Failed","startTime":"2024-11-29T11:15:39.9940663Z","properties":{"events":[{"count":1,"firstTimestamp":"2024-11-29T11:15:41.1163736Z","lastTimestamp":"2024-11-29T11:15:41.1163736Z","name":"InsufficientCapacity.","message":"The requested resource is not available in the location 'swedencentral' at this moment. Please retry with a different resource request or in another location. Resource requested: '2' CPU '4' GB memory 'Linux' OS","type":"Warning"}]},"error":{"message":"The requested resource is not available in the location 'swedencentral' at this moment. Please retry with a different resource request or in another location. Resource requested: '2' CPU '4' GB memory 'Linux' OS"}} +│ -----[end]----- +│ +│ +│ with module.azure.azurerm_container_group.alz["agent_02"], +│ on ../../modules/azure/container_instances.tf line 1, in resource "azurerm_container_group" "alz": +│ 1: resource "azurerm_container_group" "alz" { +│ +╵ +``` diff --git a/docs/content/accelerator/upgradeguide.md b/docs/content/accelerator/upgradeguide.md index f689ea3..558c44e 100644 --- a/docs/content/accelerator/upgradeguide.md +++ b/docs/content/accelerator/upgradeguide.md @@ -7,6 +7,10 @@ Although the accelerator is designed to be a one-time run, we have some rudiment This upgrade path is specifically for customers using the accelerator who haven't updated the repositories it deploys. If you have updated the repositories post initial bootstrap, you will need to take an alternative approach to upgrading. +{{< hint type=warning >}} +This upgrade process is not supported and may be removed in a future version +{{< /hint >}} + ## Important Notes - The upgrade process does not support the scenario where you have made any changes to the deployed bootstrap or starter modules via git or the VCS system. If you run the upgrade it will overwrite your changes or fail. diff --git a/docs/content/accelerator/userguide/1_prerequisites/1a_serviceprincipal.md b/docs/content/accelerator/userguide/1_prerequisites/1a_serviceprincipal.md index b748886..ba7608f 100644 --- a/docs/content/accelerator/userguide/1_prerequisites/1a_serviceprincipal.md +++ b/docs/content/accelerator/userguide/1_prerequisites/1a_serviceprincipal.md @@ -1,5 +1,6 @@ --- -title: 1.a - Authenticating via Service Principal +title: Authenticating via Service Principal +weight: 100 --- ## Authenticate via Service Principal (Skip this if using a User account) diff --git a/docs/content/accelerator/userguide/1_prerequisites/_index.md b/docs/content/accelerator/userguide/1_prerequisites/_index.md index d03197f..4426394 100644 --- a/docs/content/accelerator/userguide/1_prerequisites/_index.md +++ b/docs/content/accelerator/userguide/1_prerequisites/_index.md @@ -1,6 +1,7 @@ --- -title: 1. Prerequisites +title: Phase 1 - Prerequisites geekdocCollapseSection: true +weight: 5 --- Phase 1 of the accelerator is to setup your pre-requisites. Follow the steps below to do that. @@ -12,7 +13,9 @@ You'll need to install the following tools before getting started. - PowerShell 7.4 (or newer): [Follow the instructions for your operating system](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell) - Azure CLI 2.55.0 (or newer): [Follow the instructions for your operating system](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) -> NOTE: In all cases, ensure that the tools are available from a PowerShell core (pwsh) terminal. You may need to add them to your environment path if they are not. +{{< hint type=note >}} +In all cases, ensure that the tools are available from a PowerShell core (pwsh) terminal. You may need to add them to your environment path if they are not. +{{< /hint >}} ## Azure Subscriptions diff --git a/docs/content/accelerator/userguide/2_start/2a_github.md b/docs/content/accelerator/userguide/2_start/2a_github.md index 9d04f1a..c54a0dd 100644 --- a/docs/content/accelerator/userguide/2_start/2a_github.md +++ b/docs/content/accelerator/userguide/2_start/2a_github.md @@ -1,5 +1,5 @@ --- -title: 2.a GitHub +title: GitHub --- You can choose to bootstrap with `bicep` or `terraform` skip to the relevant section below to do that. @@ -29,11 +29,11 @@ Although you can just run `Deploy-Accelerator` and fill out the prompted inputs, ┗ 📂output ``` -1. Open your `inputs.yaml` file in Visual Studio Code (or your preferred editor) and copy the content from [inputs-github-bicep-complete.yaml][example_powershell_inputs_github_bicep_complete] into that file. +1. Open your `inputs.yaml` file in Visual Studio Code (or your preferred editor) and copy the content from [inputs-github.yaml](https://raw.githubusercontent.com/Azure/alz-bicep/refs/heads/main/accelerator/examples/bootstrap/inputs-github.yaml) into that file. 1. Check through the file and update each input as required. It is mandatory to update items with placeholders surrounded by angle brackets `<>`: - {{< hint type=note >}} -The following inputs can also be supplied via environment variables. This may be useful for sensitive values you don't wish to persist to a file. The `Env Var Prefix` denotes the prefix the environment variable should have. The environment variable is formatting is `_`, e.g. `env:ALZ_iac_type = "bicep"` or `env:TF_VAR_github_personal_access_token = "*****..."`. + {{< hint type=tip >}} +The following inputs can also be supplied via environment variables. This may be useful for sensitive values you don't wish to persist to a file. The `Env Var Prefix` denotes the prefix the environment variable should have. The environment variable is formatting is `_`, e.g. `$env:ALZ_iac_type = "terraform"` or `$env:TF_VAR_github_personal_access_token = "*****..."`. {{< /hint >}} | Input | Env Var Prefix | Placeholder | Description | @@ -102,23 +102,20 @@ The following inputs can also be supplied via environment variables. This may be ``` 1. Open your `inputs.yaml` file in Visual Studio Code (or your preferred editor) and copy the content from the relevant input file for your chosen starter module: - 1. Complete Multi Region - [inputs-github-terraform-complete-multi-region.yaml][example_powershell_inputs_github_terraform_complete_multi_region] - 1. Financial Services Industry Landing Zone - [inputs-github-terraform-financial-services-landing-zone.yaml][example_powershell_inputs_github_terraform_financial_services_industry_landing_zone] - 1. Sovereign Landing Zone - [inputs-github-terraform-sovereign-landing-zone.yaml][example_powershell_inputs_github_terraform_sovereign_landing_zone] - 1. Basic - [inputs-github-terraform-basic.yaml][example_powershell_inputs_github_terraform_basic] - 1. Hub Networking - [inputs-github-terraform-hubnetworking.yaml][example_powershell_inputs_github_terraform_hubnetworking] - 1. Complete - [inputs-github-terraform-complete.yaml][example_powershell_inputs_github_terraform_complete] + 1. Azure Verified Modules for Platform Landing Zone (ALZ) - [inputs-github.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/bootstrap/inputs-github.yaml) + 1. Financial Services Industry Landing Zone - [inputs-github.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/microsoft_cloud_for_industry/financial_services_landing_zone/examples/bootstrap/github-local.yaml) + 1. Sovereign Landing Zone - [inputs-github.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/microsoft_cloud_for_industry/sovereign_landing_zone/examples/bootstrap/github-local.yaml) 1. Check through the file and update each input as required. It is mandatory to update items with placeholders surrounded by angle brackets `<>`: - {{< hint type=note >}} -The following inputs can also be supplied via environment variables. This may be useful for sensitive values you don't wish to persist to a file. The `Env Var Prefix` denotes the prefix the environment variable should have. The environment variable is formatting is `_`, e.g. `env:ALZ_iac_type = "terraform"` or `env:TF_VAR_github_personal_access_token = "*****..."`. + {{< hint type=tip >}} +The following inputs can also be supplied via environment variables. This may be useful for sensitive values you don't wish to persist to a file. The `Env Var Prefix` denotes the prefix the environment variable should have. The environment variable is formatting is `_`, e.g. `$env:ALZ_iac_type = "terraform"` or `$env:TF_VAR_github_personal_access_token = "*****..."`. {{< /hint >}} | Input | Env Var Prefix | Placeholder | Description | | - | - | -- | --- | | `iac_type` | `ALZ` | `terraform` | This is the choice of `bicep` or `terraform`. Keep this as `terraform` for this example. | | `bootstrap_module_name` | `ALZ` | `alz_github` | This is the choice of Version Control System. Keep this as `alz_github` for this example. | - | `starter_module_name` | `ALZ` | `complete_multi_region` | This is the choice of [Starter Modules]({{< relref "../../startermodules" >}}), which is the baseline configuration you want for your Azure landing zone. Choose `complete_multi_region`, `complete`, `hubnetworking` or `basic` for this example. | + | `starter_module_name` | `ALZ` | `platform_landing_zone` | This is the choice of [Starter Modules]({{< relref "../../startermodules" >}}), which is the baseline configuration you want for your Azure landing zone. Choose `platform_landing_zone` for this example. | | `bootstrap_location` | `TF_VAR` | `` | Replace `` with the Azure region where you would like to deploy the bootstrap resources in Azure. This field expects the `name` of the region, such as `uksouth`. You can find a full list of names by running `az account list-locations -o table`. | | `starter_locations` | `TF_VAR` | `[,]` | Replace `` and `` with the Azure regions where you would like to deploy the starter module resources in Azure. This field expects the `name` of the regions in and array, such as `["uksouth", "ukwest"]`. You can find a full list of names by running `az account list-locations -o table`. | | `root_parent_management_group_id` | `TF_VAR` | `""` | This is the id of the management group that will be the parent of the management group structure created by the accelerator. If you are using the `Tenant Root Group` management group, you leave this as an empty string `""` or supply the tenant id. | @@ -141,17 +138,14 @@ The following inputs can also be supplied via environment variables. This may be | `architecture_definition_name` | `TF_VAR` | N/A | This is the name of the architecture definition to use when applying the ALZ archetypes via the architecture definition template. This is only relevant to some starter modules, such as the `sovereign_landing_zone` starter module. This defaults to `null`. | 1. Now head over to your chosen starter module documentation to get the specific inputs for that module. Come back here when you are done. - - [Terraform Complete Multi Region Starter Module]({{< relref "../../startermodules/terraformcompletemultiregion" >}}): Management groups, policies, Multi Region hub networking with fully custom configuration. + - [Terraform Azure Verified Modules for Platform Landing Zone (ALZ)]({{< relref "../../startermodules/terraform-platform-landing-zone" >}}): Management groups, policies, Multi Region hub networking with fully custom configuration. - [Terraform Financial Services Industry Landing Zone Starter Module]({{< relref "../../startermodules/terraformfsi" >}}): Management groups, policies, hub networking for the Financial Services Industry Landing Zone. - [Terraform Sovereign Landing Zone Starter Module]({{< relref "../../startermodules/terraformsovereign" >}}): Management groups, policies, hub networking for the Sovereign Landing Zone. - - [Terraform Basic Starter Module]({{< relref "../../startermodules/terraformbasic" >}}): Management groups and policies. - - [Terraform Hub Networking Starter Module]({{< relref "../../startermodules/terraformhubnetworking" >}}): Management groups, policies and hub networking. - - [Terraform Complete Starter Module]({{< relref "../../startermodules/terraformcomplete" >}}): Management groups, policies, hub networking with fully custom configuration. 1. In your PowerShell Core (pwsh) terminal run the module: - {{< hint type=note >}} -The following examples include 2 input files. This is the recommended approach for the `complete_multi_region` starter module. However, all inputs can be combined into a single file if desired and other starter modules only require a single input file. + {{< hint type=tip >}} +The following examples include 2 input files. This is the recommended approach for the `platform_landing_zone` starter module. However, all inputs into multiple files if desired. {{< /hint >}} ```pwsh @@ -172,11 +166,3 @@ The following examples include 2 input files. This is the recommended approach f ## Next Steps Now head to [Phase 3]({{< relref "3_deploy" >}}). - -[example_powershell_inputs_github_bicep_complete]: examples/powershell-inputs/inputs-github-bicep-complete.yaml "Example - PowerShell Inputs - GitHub - Bicep - Complete" -[example_powershell_inputs_github_terraform_basic]: examples/powershell-inputs/inputs-github-terraform-basic.yaml "Example - PowerShell Inputs - GitHub - Terraform - Basic" -[example_powershell_inputs_github_terraform_hubnetworking]: examples/powershell-inputs/inputs-github-terraform-hubnetworking.yaml "Example - PowerShell Inputs - GitHub - Terraform - Hub Networking" -[example_powershell_inputs_github_terraform_complete]: examples/powershell-inputs/inputs-github-terraform-complete.yaml "Example - PowerShell Inputs - GitHub - Terraform - Complete" -[example_powershell_inputs_github_terraform_complete_multi_region]: examples/powershell-inputs/inputs-github-terraform-complete-multi-region.yaml "Example - PowerShell Inputs - GitHub - Terraform - Complete Multi Region" -[example_powershell_inputs_github_terraform_financial_services_industry_landing_zone]: examples/powershell-inputs/inputs-github-terraform-financial-services-landing-zone.yaml "Example - PowerShell Inputs - GitHub - Terraform - Financial Services Industry Landing Zone" -[example_powershell_inputs_github_terraform_sovereign_landing_zone]: examples/powershell-inputs/inputs-github-terraform-sovereign-landing-zone.yaml "Example - PowerShell Inputs - GitHub - Terraform - Sovereign Landing Zone" diff --git a/docs/content/accelerator/userguide/2_start/2b_azuredevops.md b/docs/content/accelerator/userguide/2_start/2b_azuredevops.md index 0feea65..f08763d 100644 --- a/docs/content/accelerator/userguide/2_start/2b_azuredevops.md +++ b/docs/content/accelerator/userguide/2_start/2b_azuredevops.md @@ -1,5 +1,5 @@ --- -title: 2.b Azure DevOps +title: Azure DevOps --- You can choose to bootstrap with `bicep` or `terraform` skip to the relevant section below to do that. @@ -31,10 +31,12 @@ Although you can just run `Deploy-Accelerator` and fill out the prompted inputs, ┗ 📂output ``` -1. Open your `inputs.yaml` file in Visual Studio Code (or your preferred editor) and copy the content from [inputs-azure-devops-bicep-complete.yaml][example_powershell_inputs_azure_devops_bicep_complete] into that file. +1. Open your `inputs.yaml` file in Visual Studio Code (or your preferred editor) and copy the content from [inputs-azure-devops.yaml](https://raw.githubusercontent.com/Azure/alz-bicep/refs/heads/main/accelerator/examples/bootstrap/inputs-azure-devops.yaml) into that file. 1. Check through the file and update each input as required. It is mandatory to update items with placeholders surrounded by angle brackets `<>`: - >NOTE: The following inputs can also be supplied via environment variables. This may be useful for sensitive values you don't wish to persist to a file. The `Env Var Prefix` denotes the prefix the environment variable should have. The environment variable is formatting is `_`, e.g. `env:ALZ_iac_type = "bicep"` or `env:TF_VAR_azure_devops_personal_access_token = "*****..."`. + {{< hint type=tip >}} +The following inputs can also be supplied via environment variables. This may be useful for sensitive values you don't wish to persist to a file. The `Env Var Prefix` denotes the prefix the environment variable should have. The environment variable is formatting is `_`, e.g. `$env:ALZ_iac_type = "terraform"` or `$env:TF_VAR_github_personal_access_token = "*****..."`. + {{< /hint >}} | Input | Env Var Prefix | Placeholder | Description | | - | - | -- | --- | @@ -110,22 +112,20 @@ Although you can just run `Deploy-Accelerator` and fill out the prompted inputs, ``` 1. Open your `inputs.yaml` file in Visual Studio Code (or your preferred editor) and copy the content from the relevant input file for your chosen starter module: - 1. Complete Multi Region - [inputs-azure-devops-terraform-complete-multi-region.yaml][example_powershell_inputs_azure_devops_terraform_complete_multi_region] - 1. Financial Services Industry Landing Zone - [inputs-azure-devops-terraform-financial-services-landing-zone.yaml][example_powershell_inputs_azure_devops_terraform_financial_services_industry_landing_zone] - 1. Sovereign Landing Zone - [inputs-azure-devops-terraform-sovereign-landing-zone.yaml][example_powershell_inputs_azure_devops_terraform_sovereign_landing_zone] - 1. Basic - [inputs-azure-devops-terraform-basic.yaml][example_powershell_inputs_azure_devops_terraform_basic] - 1. Hub Networking - [inputs-azure-devops-terraform-hubnetworking.yaml][example_powershell_inputs_azure_devops_terraform_hubnetworking] - 1. Complete - [inputs-azure-devops-terraform-complete.yaml][example_powershell_inputs_azure_devops_terraform_complete] - + 1. Azure Verified Modules for Platform Landing Zone (ALZ) - [inputs-azure-devops.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/bootstrap/inputs-azure-devops.yaml) + 1. Financial Services Industry Landing Zone - [inputs-azure-devops.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/microsoft_cloud_for_industry/financial_services_landing_zone/examples/bootstrap/azure-devops-local.yaml) + 1. Sovereign Landing Zone - [inputs-azure-devops.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/microsoft_cloud_for_industry/sovereign_landing_zone/examples/bootstrap/azure-devops-local.yaml) 1. Check through the file and update each input as required. It is mandatory to update items with placeholders surrounded by angle brackets `<>`: - >NOTE: The following inputs can also be supplied via environment variables. This may be useful for sensitive values you don't wish to persist to a file. The `Env Var Prefix` denotes the prefix the environment variable should have. The environment variable is formatting is `_`, e.g. `env:ALZ_iac_type = "terraform"` or `env:TF_VAR_azure_devops_personal_access_token = "*****..."`. + {{< hint type=tip >}} +The following inputs can also be supplied via environment variables. This may be useful for sensitive values you don't wish to persist to a file. The `Env Var Prefix` denotes the prefix the environment variable should have. The environment variable is formatting is `_`, e.g. `$env:ALZ_iac_type = "terraform"` or `$env:TF_VAR_github_personal_access_token = "*****..."`. + {{< /hint >}} | Input | Env Var Prefix | Placeholder | Description | | - | - | -- | --- | | `iac_type` | `ALZ` | `terraform` | This is the choice of `bicep` or `terraform`. Keep this as `terraform` for this example. | | `bootstrap_module_name` | `ALZ` | `alz_azuredevops` | This is the choice of Version Control System. Keep this as `alz_azuredevops` for this example. | - | `starter_module_name` | `ALZ` | `complete_multi_region` | This is the choice of [Starter Modules]({{< relref "../../startermodules" >}}), which is the baseline configuration you want for your Azure landing zone. Choose `complete_multi_region`, `complete`, `hubnetworking` or `basic` for this example. | + | `starter_module_name` | `ALZ` | `platform_landing_zone` | This is the choice of [Starter Modules]({{< relref "../../startermodules" >}}), which is the baseline configuration you want for your Azure landing zone. Choose `platform_landing_zone` for this example. | | `bootstrap_location` | `TF_VAR` | `` | Replace `` with the Azure region where you would like to deploy the bootstrap resources in Azure. This field expects the `name` of the region, such as `uksouth`. You can find a full list of names by running `az account list-locations -o table`. | | `starter_locations` | `TF_VAR` | `[,]` | Replace `` and `` with the Azure regions where you would like to deploy the starter module resources in Azure. This field expects the `name` of the regions in and array, such as `["uksouth", "ukwest"]`. You can find a full list of names by running `az account list-locations -o table`. | | `root_parent_management_group_id` | `TF_VAR` | `""` | This is the id of the management group that will be the parent of the management group structure created by the accelerator. If you are using the `Tenant Root Group` management group, you leave this as an empty string `""` or supply the tenant id. | @@ -151,16 +151,15 @@ Although you can just run `Deploy-Accelerator` and fill out the prompted inputs, | `architecture_definition_name` | `TF_VAR` | N/A | This is the name of the architecture definition to use when applying the ALZ archetypes via the architecture definition template. This is only relevant to some starter modules, such as the `sovereign_landing_zone` starter module. This defaults to `null`. | 1. Now head over to your chosen starter module documentation to get the specific inputs for that module. Come back here when you are done. - - [Terraform Complete Multi Region Starter Module]({{< relref "../../startermodules/terraformcompletemultiregion" >}}): Management groups, policies, Multi Region hub networking with fully custom configuration. + - [Terraform Azure Verified Modules for Platform Landing Zone (ALZ)]({{< relref "../../startermodules/terraform-platform-landing-zone" >}}): Management groups, policies, Multi Region hub networking with fully custom configuration. - [Terraform Financial Services Industry Landing Zone Starter Module]({{< relref "../../startermodules/terraformfsi" >}}): Management groups, policies, hub networking for the Financial Services Industry Landing Zone. - [Terraform Sovereign Landing Zone Starter Module]({{< relref "../../startermodules/terraformsovereign" >}}): Management groups, policies, hub networking for the Sovereign Landing Zone. - - [Terraform Basic Starter Module]({{< relref "../../startermodules/terraformbasic" >}}): Management groups and policies. - - [Terraform Hub Networking Starter Module]({{< relref "../../startermodules/terraformhubnetworking" >}}): Management groups, policies and hub networking. - - [Terraform Complete Starter Module]({{< relref "../../startermodules/terraformcomplete" >}}): Management groups, policies, hub networking with fully custom configuration. 1. In your PowerShell Core (pwsh) terminal run the module: - >NOTE: The following examples include 2 input files. This is the recommended approach for the `complete_multi_region` starter module. However, all inputs can be combined into a single file if desired and other starter modules only require a single input file. + {{< hint type=tip >}} +The following examples include 2 input files. This is the recommended approach for the `platform_landing_zone` starter module. However, all inputs into multiple files if desired. + {{< /hint >}} ```pwsh # Windows (adjust the paths to match your setup) @@ -180,11 +179,3 @@ Although you can just run `Deploy-Accelerator` and fill out the prompted inputs, ## Next Steps Now head to [Phase 3]({{< relref "3_deploy" >}}). - -[example_powershell_inputs_azure_devops_bicep_complete]: examples/powershell-inputs/inputs-azure-devops-bicep-complete.yaml "Example - PowerShell Inputs - Azure DevOps - Bicep - Complete" -[example_powershell_inputs_azure_devops_terraform_basic]: examples/powershell-inputs/inputs-azure-devops-terraform-basic.yaml "Example - PowerShell Inputs - Azure DevOps - Terraform - Basic" -[example_powershell_inputs_azure_devops_terraform_hubnetworking]: examples/powershell-inputs/inputs-azure-devops-terraform-hubnetworking.yaml "Example - PowerShell Inputs - Azure DevOps - Terraform - Hub Networking" -[example_powershell_inputs_azure_devops_terraform_complete]: examples/powershell-inputs/inputs-azure-devops-terraform-complete.yaml "Example - PowerShell Inputs - Azure DevOps - Terraform - Complete" -[example_powershell_inputs_azure_devops_terraform_complete_multi_region]: examples/powershell-inputs/inputs-azure-devops-terraform-complete-multi-region.yaml "Example - PowerShell Inputs - Azure DevOps - Terraform - Complete Multi Region" -[example_powershell_inputs_azure_devops_terraform_financial_services_industry_landing_zone]: examples/powershell-inputs/inputs-azure-devops-terraform-financial-services-landing-zone.yaml "Example - PowerShell Inputs - Azure DevOps - Terraform - Financial Services Industry Landing Zone" -[example_powershell_inputs_azure_devops_terraform_sovereign_landing_zone]: examples/powershell-inputs/inputs-azure-devops-terraform-sovereign-landing-zone.yaml "Example - PowerShell Inputs - Azure DevOps - Terraform - Sovereign Landing Zone" diff --git a/docs/content/accelerator/userguide/2_start/2c_local.md b/docs/content/accelerator/userguide/2_start/2c_local.md index 4d5eccf..54bd0ce 100644 --- a/docs/content/accelerator/userguide/2_start/2c_local.md +++ b/docs/content/accelerator/userguide/2_start/2c_local.md @@ -1,5 +1,5 @@ --- -title: 2.c Local filesystem +title: Local File System --- You can choose to bootstrap with `bicep` or `terraform` skip to the relevant section below to do that. @@ -29,10 +29,12 @@ Although you can just run `Deploy-Accelerator` and fill out the prompted inputs, ┗ 📂output ``` -1. Open your `inputs.yaml` file in Visual Studio Code (or your preferred editor) and copy the content from [inputs-local-bicep-complete.yaml][example_powershell_inputs_local_bicep_complete] into that file. +1. Open your `inputs.yaml` file in Visual Studio Code (or your preferred editor) and copy the content from [inputs-local.yaml](https://raw.githubusercontent.com/Azure/alz-bicep/refs/heads/main/accelerator/examples/bootstrap/inputs-local.yaml) into that file. 1. Check through the file and update each input as required. It is mandatory to update items with placeholders surrounded by angle brackets `<>`: - >NOTE: The following inputs can also be supplied via environment variables. This may be useful for sensitive values you don't wish to persist to a file. The `Env Var Prefix` denotes the prefix the environment variable should have. The environment variable is formatting is `_`, e.g. `env:ALZ_iac_type = "bicep"` or `env:TF_VAR_target_directory = "./accelerator/target"`. + {{< hint type=tip >}} +The following inputs can also be supplied via environment variables. This may be useful for sensitive values you don't wish to persist to a file. The `Env Var Prefix` denotes the prefix the environment variable should have. The environment variable is formatting is `_`, e.g. `$env:ALZ_iac_type = "terraform"` or `$env:TF_VAR_github_personal_access_token = "*****..."`. + {{< /hint >}} | Input | Env Var Prefix | Placeholder | Description | | - | - | -- | --- | @@ -95,24 +97,20 @@ Although you can just run `Deploy-Accelerator` and fill out the prompted inputs, ``` 1. Open your `inputs.yaml` file in Visual Studio Code (or your preferred editor) and copy the content from the relevant input file for your chosen starter module: - 1. Complete Multi Region - [inputs-local-terraform-complete-multi-region.yaml][example_powershell_inputs_local_terraform_complete_multi_region] - 1. Financial Services Industry Landing Zone - [inputs-local-terraform-financial-services-landing-zone.yaml][example_powershell_inputs_local_terraform_financial_service_industry_landing_zone] - 1. Sovereign Landing Zone - [inputs-local-terraform-sovereign-landing-zone.yaml][example_powershell_inputs_local_terraform_sovereign_landing_zone] - 1. Basic - [inputs-local-terraform-basic.yaml][example_powershell_inputs_local_terraform_basic] - 1. Hub Networking - [inputs-local-terraform-hubnetworking.yaml][example_powershell_inputs_local_terraform_hubnetworking] - 1. Complete - [inputs-local-terraform-complete.yaml][example_powershell_inputs_local_terraform_complete] - + 1. Azure Verified Modules for Platform Landing Zone (ALZ) - [inputs-local.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/platform_landing_zone/examples/bootstrap/inputs-local.yaml) + 1. Financial Services Industry Landing Zone - [inputs-local.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/microsoft_cloud_for_industry/financial_services_landing_zone/examples/bootstrap/inputs-local.yaml) + 1. Sovereign Landing Zone - [inputs-local.yaml](https://raw.githubusercontent.com/Azure/alz-terraform-accelerator/refs/heads/main/templates/microsoft_cloud_for_industry/sovereign_landing_zone/examples/bootstrap/inputs-local.yaml) 1. Check through the file and update each input as required. It is mandatory to update items with placeholders surrounded by angle brackets `<>`: - {{< hint type=note >}} -The following inputs can also be supplied via environment variables. This may be useful for sensitive values you don't wish to persist to a file. The `Env Var Prefix` denotes the prefix the environment variable should have. The environment variable is formatting is `_`, e.g. `env:ALZ_iac_type = "terraform"` or `env:TF_VAR_target_directory = "./accelerator/target"`. + {{< hint type=tip >}} +The following inputs can also be supplied via environment variables. This may be useful for sensitive values you don't wish to persist to a file. The `Env Var Prefix` denotes the prefix the environment variable should have. The environment variable is formatting is `_`, e.g. `$env:ALZ_iac_type = "terraform"` or `$env:TF_VAR_github_personal_access_token = "*****..."`. {{< /hint >}} | Input | Env Var Prefix | Placeholder | Description | | - | - | -- | --- | | `iac_type` | `ALZ` | `terraform` | This is the choice of `bicep` or `terraform`. Keep this as `terraform` for this example. | | `bootstrap_module_name` | `ALZ` | `alz_local` | This is the choice of Version Control System. Keep this as `alz_local` for this example. | - | `starter_module_name` | `ALZ` | `complete_multi_region` | This is the choice of [Starter Modules]({{< relref "../../startermodules" >}}), which is the baseline configuration you want for your Azure landing zone. Choose `complete_multi_region`, `complete`, `hubnetworking` or `basic` for this example. | + | `starter_module_name` | `ALZ` | `platform_landing_zone` | This is the choice of [Starter Modules]({{< relref "../../startermodules" >}}), which is the baseline configuration you want for your Azure landing zone. Choose `platform_landing_zone` for this example. | | `bootstrap_location` | `TF_VAR` | `` | Replace `` with the Azure region where you would like to deploy the bootstrap resources in Azure. This field expects the `name` of the region, such as `uksouth`. You can find a full list of names by running `az account list-locations -o table`. | | `starter_locations` | `TF_VAR` | `[,]` | Replace `` and `` with the Azure regions where you would like to deploy the starter module resources in Azure. This field expects the `name` of the regions in and array, such as `["uksouth", "ukwest"]`. You can find a full list of names by running `az account list-locations -o table`. | | `root_parent_management_group_id` | `TF_VAR` | `""` | This is the id of the management group that will be the parent of the management group structure created by the accelerator. If you are using the `Tenant Root Group` management group, you leave this as an empty string `""` or supply the tenant id. | @@ -129,17 +127,14 @@ The following inputs can also be supplied via environment variables. This may be | `architecture_definition_name` | `TF_VAR` | N/A | This is the name of the architecture definition to use when applying the ALZ archetypes via the architecture definition template. This is only relevant to some starter modules, such as the `sovereign_landing_zone` starter module. This defaults to `null`. | 1. Now head over to your chosen starter module documentation to get the specific inputs for that module. Come back here when you are done. - - [Terraform Complete Multi Region Starter Module]({{< relref "../../startermodules/terraformcompletemultiregion" >}}): Management groups, policies, Multi Region hub networking with fully custom configuration. + - [Terraform Azure Verified Modules for Platform Landing Zone (ALZ)]({{< relref "../../startermodules/terraform-platform-landing-zone" >}}): Management groups, policies, Multi Region hub networking with fully custom configuration. - [Terraform Financial Services Industry Landing Zone Starter Module]({{< relref "../../startermodules/terraformfsi" >}}): Management groups, policies, hub networking for the Financial Services Industry Landing Zone. - [Terraform Sovereign Landing Zone Starter Module]({{< relref "../../startermodules/terraformsovereign" >}}): Management groups, policies, hub networking for the Sovereign Landing Zone. - - [Terraform Basic Starter Module]({{< relref "../../startermodules/terraformbasic" >}}): Management groups and policies. - - [Terraform Hub Networking Starter Module]({{< relref "../../startermodules/terraformhubnetworking" >}}): Management groups, policies and hub networking. - - [Terraform Complete Starter Module]({{< relref "../../startermodules/terraformcomplete" >}}): Management groups, policies, hub networking with fully custom configuration. 1. In your PowerShell Core (pwsh) terminal run the module: - {{< hint type=note >}} -The following examples include 2 input files. This is the recommended approach for the `complete_multi_region` starter module. However, all inputs can be combined into a single file if desired and other starter modules only require a single input file. + {{< hint type=tip >}} +The following examples include 2 input files. This is the recommended approach for the `platform_landing_zone` starter module. However, all inputs into multiple files if desired. {{< /hint >}} ```pwsh @@ -161,11 +156,3 @@ The following examples include 2 input files. This is the recommended approach f ## Next Steps Now head to [Phase 3]({{< relref "3_deploy" >}}) - -[example_powershell_inputs_local_bicep_complete]: examples/powershell-inputs/inputs-local-bicep-complete.yaml "Example - PowerShell Inputs - Local - Bicep - Complete" -[example_powershell_inputs_local_terraform_basic]: examples/powershell-inputs/inputs-local-terraform-basic.yaml "Example - PowerShell Inputs - Local - Terraform - Basic" -[example_powershell_inputs_local_terraform_hubnetworking]: examples/powershell-inputs/inputs-local-terraform-hubnetworking.yaml "Example - PowerShell Inputs - Local - Terraform - Hub Networking" -[example_powershell_inputs_local_terraform_complete]: examples/powershell-inputs/inputs-local-terraform-complete.yaml "Example - PowerShell Inputs - Local - Terraform - Complete" -[example_powershell_inputs_local_terraform_complete_multi_region]: examples/powershell-inputs/inputs-local-terraform-complete-multi-region.yaml "Example - PowerShell Inputs - Local - Terraform - Complete Multi Region" -[example_powershell_inputs_local_terraform_financial_service_industry_landing_zone]: examples/powershell-inputs/inputs-local-terraform-financial-services-landing-zone.yaml "Example - PowerShell Inputs - Local - Terraform - Financial Services Industry Landing Zone" -[example_powershell_inputs_local_terraform_sovereign_landing_zone]: examples/powershell-inputs/inputs-local-terraform-sovereign-landing-zone.yaml "Example - PowerShell Inputs - Local - Terraform - Sovereign Landing Zone" diff --git a/docs/content/accelerator/userguide/2_start/_index.md b/docs/content/accelerator/userguide/2_start/_index.md index 496b0a1..bfd2d1e 100644 --- a/docs/content/accelerator/userguide/2_start/_index.md +++ b/docs/content/accelerator/userguide/2_start/_index.md @@ -1,6 +1,7 @@ --- -title: 2. Run PowerShell +title: Phase 2 - Bootstrap geekdocCollapseSection: true +weight: 5 --- Phase 2 of the accelerator is to run the bootstrap. Follow the steps below to do that. diff --git a/docs/content/accelerator/userguide/3_deploy.md b/docs/content/accelerator/userguide/3_deploy.md index 27d94ea..60bd47f 100644 --- a/docs/content/accelerator/userguide/3_deploy.md +++ b/docs/content/accelerator/userguide/3_deploy.md @@ -1,5 +1,6 @@ --- -title: 3. Deploy +title: Phase 3 - Run +weight: 5 --- Phase 3 of the accelerator is to run pipeline. Follow the steps below to do that. diff --git a/docs/content/accelerator/userguide/_index.md b/docs/content/accelerator/userguide/_index.md index 539cd1f..ff7076d 100644 --- a/docs/content/accelerator/userguide/_index.md +++ b/docs/content/accelerator/userguide/_index.md @@ -1,7 +1,7 @@ --- title: User guide geekdocCollapseSection: true -weight: 10 +weight: 5 resources: - name: alz-accelerator-overview src: img/alz-terraform-accelerator.png @@ -22,14 +22,14 @@ See our [FAQ]({{< relref "faq" >}}) and [Advanced Scenarios]({{< relref "advance ## Introduction -The quick start guide takes you through the steps to prepare your pre-requisites and then run the PowerShell module. +This guide takes you through the steps to prepare your pre-requisites and then run the PowerShell module. The accelerator bootstraps a continuous delivery environment for you. It supports both the Azure DevOps and GitHub version control system (VCS). It uses the [ALZ PowerShell module](https://www.powershellgallery.com/packages/ALZ) to gather required user input and apply a Terraform module to configure the bootstrap environment. The accelerator follows a 3 phase approach: -- [Quick Start Phase 1]({{< relref "1_prerequisites" >}}): Instructions to configure credentials and subscriptions. -- [Quick Start Phase 2]({{< relref "2_start" >}}): Run the PowerShell script to generate the continuous delivery environment. -- [Quick Start Phase 3]({{< relref "3_deploy" >}}): Update the module (if needed) to suit the needs of your organisation and deploy via continuous delivery. +- [Phase 1]({{< relref "1_prerequisites" >}}): Instructions to configure credentials and subscriptions. +- [Phase 2]({{< relref "2_start" >}}): Run the PowerShell module to generate the continuous delivery environment. +- [Phase 3]({{< relref "3_deploy" >}}): Update the module (if needed) to suit the needs of your organization and deploy via continuous delivery. {{< img name="alz-accelerator-overview" size="origin" lazy=true >}} diff --git a/docs/content/accelerator/userguide/advancedscenarios.md b/docs/content/accelerator/userguide/advancedscenarios.md index 0c5b2bb..f01c09d 100644 --- a/docs/content/accelerator/userguide/advancedscenarios.md +++ b/docs/content/accelerator/userguide/advancedscenarios.md @@ -1,5 +1,6 @@ --- -title: 4. Advanced scenarios +title: Advanced scenarios +weight: 10 --- ## Scenario 1 - Secure island for bootstrap resources @@ -31,43 +32,34 @@ This will result in the bootstrap resources being deployed in the new subscripti 1. Create a new subscription for the bootstrap resources. Take note of the subscription id. 2. Grant owner rights to the account you are using to deploy the accelerator on the new subscription. -3. Use the `complete` starter module to deploy the Azure Landing Zone. -4. Update the `config.yaml` file to include subscription placement for the new subscription using the `subscription-id-overrides` setting. For example: +3. Use the `platform_landing_zone` starter module to deploy the Azure Landing Zone. +4. Update the `tfvars` file to include subscription placement for the new subscription using the `management_group_settings.subscription_placement` setting. For example: - ```yaml - archetypes: # `caf-enterprise-scale` module, add inputs as listed on the module registry where necessary. - root_name: es - root_id: Enterprise-Scale - deploy_corp_landing_zones: true - deploy_online_landing_zones: true - default_location: uksouth - disable_telemetry: true - deploy_management_resources: true - configure_management_resources: - location: uksouth - settings: - security_center: - config: - email_security_contact: "security_contact@replace_me" - advanced: - asc_export_resource_group_name: rg-asc-export - custom_settings_by_resource_type: - azurerm_resource_group: - management: - name: rg-management - azurerm_log_analytics_workspace: - management: - name: log-management - azurerm_automation_account: - management: - name: aa-management - subscription-id-overrides: - management: - - "00000000-0000-0000-0000-000000000000" # Your new subscription id + ```terraform + management_group_settings = { + subscription_placement = { + identity = { + subscription_id = "$${subscription_id_identity}" + management_group_name = "identity" + } + connectivity = { + subscription_id = "$${subscription_id_connectivity}" + management_group_name = "connectivity" + } + management = { + subscription_id = "$${subscription_id_management}" + management_group_name = "management" + } + bootstrap = { + subscription_id = "" # Add your bootstrap subscription id here + management_group_name = "management" + } + } + } ``` 5. Run the bootstrap as normal, following the instructions in the [Quick Start]({{< relref "1_prerequisites" >}}) guide. -6. When you get to step for updating the input config file variables, enter the subscription id of the new subscription you created into the `bootstrap_subscription_id` field. +6. When you get to step for updating the bootstrap configuration file variables, enter the subscription id of the new subscription you created into the `bootstrap_subscription_id` field. 7. Continue with the rest of the steps in the [Quick Start]({{< relref "1_prerequisites" >}}) guide. This will result in the bootstrap resources being deployed in the new subscription. diff --git a/docs/content/accelerator/yamlschemareference.md b/docs/content/accelerator/yamlschemareference.md deleted file mode 100644 index 31dd526..0000000 --- a/docs/content/accelerator/yamlschemareference.md +++ /dev/null @@ -1,211 +0,0 @@ ---- -title: YAML Schema Reference -weight: 30 ---- - -## `archetypes` - -Specifies the archetypes to be used through the `caf-enterprise-scale` module. - -```yaml -archetypes: # Arguments from https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/blob/v4.2.0/variables.tf converted to YAML. - disable_telemetry: # boolean - default_location: # string - root_parent_id: # string - archetype_config_overrides: # object - configure_connectivity_resources: # object - configure_identity_resources: # object - configure_management_resources: # object - create_duration_delay: # object - custom_landing_zones: # object - custom_policy_roles: # object - default_tags: # object - deploy_connectivity_resources: # boolean - deploy_corp_landing_zones: # boolean - deploy_core_landing_zones: # boolean - deploy_demo_landing_zones: # boolean - deploy_diagnostics_for_mg: # boolean - deploy_identity_resources: # boolean - deploy_management_resources: # boolean - deploy_online_landing_zones: # boolean - deploy_sap_landing_zones: # boolean - destroy_duration_delay: # object - disable_base_module_tags: # boolean - library_path: # string - policy_non_compliance_message_default: # string - policy_non_compliance_message_default_enabled: # boolean - policy_non_compliance_message_enabled: # boolean - policy_non_compliance_message_enforced_replacement: # string - policy_non_compliance_message_enforcement_placeholder: # string - policy_non_compliance_message_not_enforced_replacement: # string - policy_non_compliance_message_not_supported_definitions: # list - resource_custom_timeouts: # object - root_id: # string - root_name: # string - strict_subscription_association: # boolean - subscription_id_connectivity: # string - subscription_id_identity: # string - subscription_id_management: # string - subscription_id_overrides: # object - template_file_variables: # string - -``` - -### `archetypes` Example - -```yaml -archetypes: # `caf-enterprise-scale` module, add inputs as listed on the module registry where necessary. - root_name: es - root_id: Enterprise-Scale - deploy_corp_landing_zones: true - deploy_online_landing_zones: true - default_location: uksouth - disable_telemetry: true - deploy_management_resources: true - default_tags: - environment: dev - costcenter: 12345 - configure_management_resources: - location: uksouth - settings: - security_center: - config: - email_security_contact: "security_contact@replace_me" - custom_landing_zones: - eucustomers: - display_name: EU Customers - parent_management_group_id: es-landing-zones - -``` - -## `connectivity` - -Specifies the connectivity configuration to be used. - -```yaml -connectivity: [ hubnetworking ] # Type of connectivity to be deployed (e.g. hubnetworking or virtual wan.) -``` - -## `connectivity.hubnetworking` - -Specifies the hub networking configuration to be used from the `terraform-azurerm-hubnetworking` module. - -```yaml -connectivity: - hubnetworking: # # Arguments from https://github.com/Azure/terraform-azurerm-hubnetworking/blob/v1.1.1/variables.tf converted to YAML. - hub_virtual_networks: # object -``` - -### `connectivity.hubnetworking` Example - -```yaml -connectivity: - hubnetworking: - hub_virtual_networks: - hub-one: - name: vnet-hub - resource_group_name: rg-connectivity - location: uksouth - address_space: - - 10.0.0.0/16 - firewall: - name: fw-hub - sku_name: AZFW_VNet - sku_tier: Standard - subnet_address_prefix: 10.0.1.0/24 -``` - -## `connectivity.hubnetworking.hub_virtual_networks..virtual_network_gateway` - -Specifies the virtual network gateway configuration to be used from the `terraform-azurerm-avm-ptn-vnetgateway` module. - -```yaml -connectivity: - hubnetworking: - hub_virtual_networks: - : - name: # string - resource_group_name: # string - location: # string - address_space: # list - virtual_network_gateway: # Arguments from https://github.com/Azure/terraform-azurerm-avm-ptn-vnetgateway/blob/v0.3.0/variables.tf converted to YAML. - name: # string - sku: # string - subnet_address_prefix: # string - subnet_creation_enabled: # boolean - type: # string - default_tags: # object - edge_zone: # string - express_route_circuits: # object - ip_configurations: # object - local_network_gateways: # object - tags: # object - vpn_active_active_enabled: # boolean - vpn_bgp_enabled: # boolean - vpn_bgp_settings: # object - vpn_generation: # string - vpn_point_to_site: # object - vpn_type: # string - vpn_private_ip_address_enabled: # boolean - route_table_bgp_route_propagation_enabled: # boolean - route_table_creation_enabled: # boolean - route_table_name: # string - route_table_tags: # object -``` - -### `connectivity.hubnetworking.hub_virtual_networks..virtual_network_gateway` Example - -```yaml -connectivity: - hubnetworking: - hub_virtual_networks: - hub-one: - name: vnet-hub - resource_group_name: rg-connectivity - location: uksouth - address_space: - - 10.0.0.0/16 - firewall: - name: fw-hub - sku_name: AZFW_VNet - sku_tier: Standard - subnet_address_prefix: 10.0.1.0/24 - virtual_network_gateway: - name: vgw-hub - sku: VpnGw1 - type: Vpn - subnet_address_prefix: 10.0.2.0/24 -``` - -## `connectivity.vwan` - -Specifies the hub networking configuration to be used from the `terraform-azurerm-avm-ptn-virtualwan` module. - -```yaml -connectivity: - vwan: # Arguments from https://github.com/Azure/terraform-azurerm-avm-ptn-virtualwan/blob/v0.4.0/variables.tf converted to YAML. - allow_branch_to_branch_traffic: # boolean - create_resource_group: # boolean - disable_vpn_encryption: # boolean - enable_telemetry: # boolean - er_circuit_connections: # object - expressroute_gateways: # object - firewalls: # object - location: # string - office365_local_breakout_category - p2s_gateway_vpn_server_configurations: # object - p2s_gateways: # object - resource_group_name: # string - resource_group_tags: # object - routing_intents: # object - telemetry_resource_group_name: # string - type: # string - virtual_hubs: # object - virtual_network_connections: # object - virtual_wan_name: # string - virtual_wan_tags: # object - vpn_gateways: # object - vpn_site_connections: # object - vpn_sites: # object - tags: # object -``` diff --git a/docs/static/examples/tf/accelerator/config/connectivity_resource_groups.tfvars b/docs/static/examples/tf/accelerator/config/connectivity_resource_groups.tfvars new file mode 100644 index 0000000..6e267af --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/connectivity_resource_groups.tfvars @@ -0,0 +1,43 @@ +# Example for hub and spoke Virtual Network +connectivity_resource_groups = { + ddos = { + name = "$${ddos_resource_group_name}" + location = "$${starter_location_01}" + } + vnet_primary = { + name = "$${connectivity_hub_primary_resource_group_name}" + location = "$${starter_location_01}" + } + vnet_secondary = { + name = "$${connectivity_hub_secondary_resource_group_name}" + location = "$${starter_location_02}" + } + dns = { + name = "$${dns_resource_group_name}" + location = "$${starter_location_01}" + } +} + +# Example for Virtual WAN +connectivity_resource_groups = { + ddos = { + name = "$${ddos_resource_group_name}" + location = "$${starter_location_01}" + } + vwan = { + name = "$${connectivity_hub_vwan_resource_group_name}" + location = "$${starter_location_01}" + } + vwan_hub_primary = { + name = "$${connectivity_hub_primary_resource_group_name}" + location = "$${starter_location_01}" + } + vwan_hub_secondary = { + name = "$${connectivity_hub_secondary_resource_group_name}" + location = "$${starter_location_02}" + } + dns = { + name = "$${dns_resource_group_name}" + location = "$${starter_location_01}" + } +} diff --git a/docs/static/examples/tf/accelerator/config/connectivity_type.tfvars b/docs/static/examples/tf/accelerator/config/connectivity_type.tfvars new file mode 100644 index 0000000..3601b75 --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/connectivity_type.tfvars @@ -0,0 +1,8 @@ +# Example of how to use a hub and spoke Virtual Network for connectivity +connectivity_type = "hub_and_spoke_vnet" + +# Example of how to use a Virtual WAN for connectivity +connectivity_type = "virtual_wan" + +# Example of how to disable connectivity +connectivity_type = "none" diff --git a/docs/static/examples/tf/accelerator/config/custom_replacements.names.ip_ranges.tfvars b/docs/static/examples/tf/accelerator/config/custom_replacements.names.ip_ranges.tfvars new file mode 100644 index 0000000..f5f82b0 --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/custom_replacements.names.ip_ranges.tfvars @@ -0,0 +1,70 @@ +# Example of 172.16 IP ranges for a hub and spoke Virtual Network +# NOTE: The 172.16 prefix is only suitable for medium sized deployments as it only supports 1,000,000 ip addresses) +custom_replacements = { + names = { + # IP Ranges Primary + # Regional Address Space: 172.16.0.0/16 + primary_hub_address_space = "172.16.0.0/16" + primary_hub_virtual_network_address_space = "172.16.0.0/22" + primary_firewall_subnet_address_prefix = "172.16.0.0/26" + primary_bastion_subnet_address_prefix = "172.16.0.64/26" + primary_gateway_subnet_address_prefix = "172.16.0.128/27" + primary_private_dns_resolver_subnet_address_prefix = "172.16.0.160/28" + + # IP Ranges Secondary + # Regional Address Space: 172.17.0.0/16 + secondary_hub_address_space = "172.17.0.0/16" + secondary_hub_virtual_network_address_space = "172.17.0.0/22" + secondary_firewall_subnet_address_prefix = "172.17.0.0/26" + secondary_bastion_subnet_address_prefix = "172.17.0.64/26" + secondary_gateway_subnet_address_prefix = "172.17.0.128/27" + secondary_private_dns_resolver_subnet_address_prefix = "172.17.0.160/28" + } +} +# Example of 192.168 IP ranges for a hub and spoke Virtual Network +# NOTE that the 192.168 prefix is only suitable for a small, isngle region deployment as it only supports 65,000 ip addresses) +custom_replacements = { + names = { + # IP Ranges Primary + # Regional Address Space: 192.168.0.0/16 + primary_hub_address_space = "192.168.0.0/16" + primary_hub_virtual_network_address_space = "192.168.0.0/22" + primary_firewall_subnet_address_prefix = "192.168.0.0/26" + primary_bastion_subnet_address_prefix = "192.168.0.64/26" + primary_gateway_subnet_address_prefix = "192.168.0.128/27" + primary_private_dns_resolver_subnet_address_prefix = "192.168.0.160/28" + } +} + +# Example of 172.16 IP ranges for a Virtual WAN +# NOTE: The 172.16 prefix is only suitable for medium sized deployments as it only supports 1,000,000 ip addresses) +custom_replacements = { + names = { + # IP Ranges Primary + # Regional Address Space: 172.16.0.0/16 + primary_hub_address_space = "172.16.0.0/22" + primary_side_car_virtual_network_address_space = "172.16.4.0/22" + primary_bastion_subnet_address_prefix = "172.16.4.0/26" + primary_private_dns_resolver_subnet_address_prefix = "172.16.4.64/28" + + # IP Ranges Secondary + # Regional Address Space: 172.17.0.0/16 + secondary_hub_address_space = "172.17.0.0/22" + secondary_side_car_virtual_network_address_space = "172.17.4.0/22" + secondary_bastion_subnet_address_prefix = "172.17.4.0/26" + secondary_private_dns_resolver_subnet_address_prefix = "172.17.4.64/28" + } +} +# Example of 192.168 IP ranges for a Virtual WAN +# NOTE that the 192.168 prefix is only suitable for a small, isngle region deployment as it only supports 65,000 ip addresses) +custom_replacements = { + names = { + # IP Ranges Primary + # Regional Address Space: 192.168.0.0/16 + primary_hub_address_space = "10.0.0.0/22" + primary_side_car_virtual_network_address_space = "10.0.4.0/22" + primary_bastion_subnet_address_prefix = "10.0.4.0/26" + primary_private_dns_resolver_subnet_address_prefix = "10.0.4.64/28" + } +} + diff --git a/docs/static/examples/tf/accelerator/config/custom_replacements.names.tfvars b/docs/static/examples/tf/accelerator/config/custom_replacements.names.tfvars new file mode 100644 index 0000000..8e23f85 --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/custom_replacements.names.tfvars @@ -0,0 +1,29 @@ +custom_replacements = { + names = { + # Resource group names + management_resource_group_name = "rg-management-$${starter_location_01}" + connectivity_hub_primary_resource_group_name = "rg-hub-$${starter_location_01}" + connectivity_hub_secondary_resource_group_name = "rg-hub-$${starter_location_02}" + dns_resource_group_name = "rg-hub-dns-$${starter_location_01}" + ddos_resource_group_name = "rg-hub-ddos-$${starter_location_01}" + asc_export_resource_group_name = "rg-asc-export-$${starter_location_01}" + + # Resource names + log_analytics_workspace_name = "law-management-$${starter_location_01}" + ddos_protection_plan_name = "ddos-$${starter_location_01}" + automation_account_name = "aa-management-$${starter_location_01}" + ama_user_assigned_managed_identity_name = "uami-management-ama-$${starter_location_01}" + dcr_change_tracking_name = "dcr-change-tracking" + dcr_defender_sql_name = "dcr-defender-sql" + dcr_vm_insights_name = "dcr-vm-insights" + + # IP Ranges Primary + # Regional Address Space: 10.0.0.0/16 + primary_hub_address_space = "10.0.0.0/16" + primary_hub_virtual_network_address_space = "10.0.0.0/22" + primary_firewall_subnet_address_prefix = "10.0.0.0/26" + primary_bastion_subnet_address_prefix = "10.0.0.64/26" + primary_gateway_subnet_address_prefix = "10.0.0.128/27" + primary_private_dns_resolver_subnet_address_prefix = "10.0.0.160/28" + } +} diff --git a/docs/static/examples/tf/accelerator/config/custom_replacements.resource_group_identifiers.tfvars b/docs/static/examples/tf/accelerator/config/custom_replacements.resource_group_identifiers.tfvars new file mode 100644 index 0000000..caaa32f --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/custom_replacements.resource_group_identifiers.tfvars @@ -0,0 +1,6 @@ +custom_replacements = { + resource_group_identifiers = { + management_resource_group_id = "/subscriptions/$${subscription_id_management}/resourcegroups/$${management_resource_group_name}" + ddos_protection_plan_resource_group_id = "/subscriptions/$${subscription_id_connectivity}/resourcegroups/$${ddos_resource_group_name}" + } +} diff --git a/docs/static/examples/tf/accelerator/config/custom_replacements.resource_identifiers.tfvars b/docs/static/examples/tf/accelerator/config/custom_replacements.resource_identifiers.tfvars new file mode 100644 index 0000000..0dc616d --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/custom_replacements.resource_identifiers.tfvars @@ -0,0 +1,10 @@ +custom_replacements = { + resource_identifiers = { + ama_change_tracking_data_collection_rule_id = "$${management_resource_group_id}/providers/Microsoft.Insights/dataCollectionRules/$${dcr_change_tracking_name}" + ama_mdfc_sql_data_collection_rule_id = "$${management_resource_group_id}/providers/Microsoft.Insights/dataCollectionRules/$${dcr_defender_sql_name}" + ama_vm_insights_data_collection_rule_id = "$${management_resource_group_id}/providers/Microsoft.Insights/dataCollectionRules/$${dcr_vm_insights_name}" + ama_user_assigned_managed_identity_id = "$${management_resource_group_id}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$${ama_user_assigned_managed_identity_name}" + log_analytics_workspace_id = "$${management_resource_group_id}/providers/Microsoft.OperationalInsights/workspaces/$${log_analytics_workspace_name}" + ddos_protection_plan_id = "$${ddos_protection_plan_resource_group_id}/providers/Microsoft.Network/ddosProtectionPlans/$${ddos_protection_plan_name}" + } +} diff --git a/docs/static/examples/tf/accelerator/config/enable_telemetry.tfvars b/docs/static/examples/tf/accelerator/config/enable_telemetry.tfvars new file mode 100644 index 0000000..3ab2779 --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/enable_telemetry.tfvars @@ -0,0 +1 @@ +enable_telemetry = true diff --git a/docs/static/examples/tf/accelerator/config/hub_and_spoke_vnet_settings.tfvars b/docs/static/examples/tf/accelerator/config/hub_and_spoke_vnet_settings.tfvars new file mode 100644 index 0000000..2fec0d1 --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/hub_and_spoke_vnet_settings.tfvars @@ -0,0 +1,7 @@ +hub_and_spoke_vnet_settings = { + ddos_protection_plan = { + name = "$${ddos_protection_plan_name}" + resource_group_name = "$${ddos_resource_group_name}" + location = "$${starter_location_01}" + } +} diff --git a/docs/static/examples/tf/accelerator/config/hub_and_spoke_vnet_virtual_networks.tfvars b/docs/static/examples/tf/accelerator/config/hub_and_spoke_vnet_virtual_networks.tfvars new file mode 100644 index 0000000..2c4518f --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/hub_and_spoke_vnet_virtual_networks.tfvars @@ -0,0 +1,92 @@ +hub_and_spoke_vnet_virtual_networks = { + primary = { + # Example hub network settings for this region + hub_virtual_network = { + name = "vnet-hub-$${starter_location_01}" + resource_group_name = "$${connectivity_hub_primary_resource_group_name}" + resource_group_creation_enabled = false + location = "$${starter_location_01}" + address_space = ["$${primary_hub_virtual_network_address_space}"] + routing_address_space = ["$${primary_hub_address_space}"] + route_table_name_firewall = "rt-hub-fw-$${starter_location_01}" + route_table_name_user_subnets = "rt-hub-std-$${starter_location_01}" + mesh_peering = true + ddos_protection_plan_id = "$${management_resource_group_id}/providers/Microsoft.Network/ddosProtectionPlans/$${ddos_protection_plan_name}" + subnets = {} + # Example Azure Firewall settings for this region (omit this section if not using Azure Firewall) + firewall = { + subnet_address_prefix = "$${primary_firewall_subnet_address_prefix}" + 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}" + } + } + # Example firewall policy settings for this region + firewall_policy = { + name = "fwp-hub-$${starter_location_01}" + } + } + } + # Example Virtual Network Gateway settings for this region (omit this section if not using Virtual Network Gateway) + virtual_network_gateways = { + subnet_address_prefix = "$${primary_gateway_subnet_address_prefix}" + # Example ExpressRoute settings for this region (omit this section if not using ExpressRoute) + express_route = { + location = "$${starter_location_01}" + name = "vgw-hub-expressroute-$${starter_location_01}" + sku = "$${starter_location_01_virtual_network_gateway_sku_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}" + } + } + } + } + # Example VPN Gateway settings for this region (omit this section if not using VPN Gateway) + vpn = { + location = "$${starter_location_01}" + name = "vgw-hub-vpn-$${starter_location_01}" + sku = "$${starter_location_01_virtual_network_gateway_sku_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}" + } + } + } + } + } + # Example Private DNS Zone settings for this region (omit this section if not using Private DNS Zones) + private_dns_zones = { + resource_group_name = "$${dns_resource_group_name}" + is_primary = true + auto_registration_zone_enabled = true + auto_registration_zone_name = "$${starter_location_01}.azure.local" + subnet_address_prefix = "$${primary_private_dns_resolver_subnet_address_prefix}" + private_dns_resolver = { + name = "pdr-hub-dns-$${starter_location_01}" + } + } + # Example Bastion Host settings for this region (omit this section if not using Bastion Host) + bastion = { + subnet_address_prefix = "$${primary_bastion_subnet_address_prefix}" + bastion_host = { + name = "bastion-hub-$${starter_location_01}" + } + bastion_public_ip = { + name = "pip-bastion-hub-$${starter_location_01}" + zones = "$${starter_location_01_availability_zones}" + } + } + } +} diff --git a/docs/static/examples/tf/accelerator/config/lib/architecture_definitions/alz.alz_architecture_definition.json b/docs/static/examples/tf/accelerator/config/lib/architecture_definitions/alz.alz_architecture_definition.json new file mode 100644 index 0000000..25806ec --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/lib/architecture_definitions/alz.alz_architecture_definition.json @@ -0,0 +1,96 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/Azure-Landing-Zones-Library/main/schemas/architecture_definition.json", + "name": "alz", + "management_groups": [ + { + "archetypes": [ + "root" + ], + "display_name": "Contoso", + "exists": false, + "id": "contoso-root", + "parent_id": null + }, + { + "archetypes": [ + "platform" + ], + "display_name": "Contoso Platform", + "exists": false, + "id": "contoso-platform", + "parent_id": "contoso-root" + }, + { + "archetypes": [ + "landing_zones" + ], + "display_name": "Contoso Landing zones", + "exists": false, + "id": "contoso-landingzones", + "parent_id": "contoso-root" + }, + { + "archetypes": [ + "corp" + ], + "display_name": "Contoso Corp", + "exists": false, + "id": "contoso-corp", + "parent_id": "contoso-landingzones" + }, + { + "archetypes": [ + "online" + ], + "display_name": "Contoso Online", + "exists": false, + "id": "contoso-online", + "parent_id": "contoso-landingzones" + }, + { + "archetypes": [ + "sandboxes" + ], + "display_name": "Contoso Sandboxes", + "exists": false, + "id": "contoso-sandboxes", + "parent_id": "contoso-root" + }, + { + "archetypes": [ + "management" + ], + "display_name": "Contoso Management", + "exists": false, + "id": "contoso-management", + "parent_id": "contoso-platform" + }, + { + "archetypes": [ + "connectivity" + ], + "display_name": "Contoso Connectivity", + "exists": false, + "id": "contoso-connectivity", + "parent_id": "contoso-platform" + }, + { + "archetypes": [ + "identity" + ], + "display_name": "Contoso Identity", + "exists": false, + "id": "contoso-identity", + "parent_id": "contoso-platform" + }, + { + "archetypes": [ + "decommissioned" + ], + "display_name": "Contoso Decommissioned", + "exists": false, + "id": "contoso-decommissioned", + "parent_id": "contoso-root" + } + ] +} diff --git a/docs/static/examples/tf/accelerator/config/management_group_settings.tfvars b/docs/static/examples/tf/accelerator/config/management_group_settings.tfvars new file mode 100644 index 0000000..a9ca61e --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/management_group_settings.tfvars @@ -0,0 +1,68 @@ +management_group_settings = { + location = "$${starter_location_01}" + architecture_name = "alz" + parent_resource_id = "$${root_parent_management_group_id}" + # Example of how to set default values for policy parameters + policy_default_values = { + ama_change_tracking_data_collection_rule_id = "$${ama_change_tracking_data_collection_rule_id}" + ama_mdfc_sql_data_collection_rule_id = "$${ama_mdfc_sql_data_collection_rule_id}" + ama_vm_insights_data_collection_rule_id = "$${ama_vm_insights_data_collection_rule_id}" + ama_user_assigned_managed_identity_id = "$${ama_user_assigned_managed_identity_id}" + ama_user_assigned_managed_identity_name = "$${ama_user_assigned_managed_identity_name}" + log_analytics_workspace_id = "$${log_analytics_workspace_id}" + ddos_protection_plan_id = "$${ddos_protection_plan_id}" + private_dns_zone_subscription_id = "$${subscription_id_connectivity}" + private_dns_zone_region = "$${starter_location_01}" + private_dns_zone_resource_group_name = "$${dns_resource_group_name}" + } + # Example of how to place the 3 platform subscriptions under their management groups + subscription_placement = { + identity = { + subscription_id = "$${subscription_id_identity}" + management_group_name = "identity" + } + connectivity = { + subscription_id = "$${subscription_id_connectivity}" + management_group_name = "connectivity" + } + management = { + subscription_id = "$${subscription_id_management}" + management_group_name = "management" + } + } + policy_assignments_to_modify = { + # Example of how to update a policy assignment parameters for Defender for Cloud + alzroot = { + policy_assignments = { + Deploy-MDFC-Config-H224 = { + parameters = { + ascExportResourceGroupName = "$${asc_export_resource_group_name}" + ascExportResourceGroupLocation = "$${starter_location_01}" + emailSecurityContact = "security_contact@replace_me" + enableAscForServers = "DeployIfNotExists" + enableAscForServers = "DeployIfNotExists" + enableAscForServersVulnerabilityAssessments = "DeployIfNotExists" + enableAscForSql = "DeployIfNotExists" + enableAscForAppServices = "DeployIfNotExists" + enableAscForStorage = "DeployIfNotExists" + enableAscForContainers = "DeployIfNotExists" + enableAscForKeyVault = "DeployIfNotExists" + enableAscForSqlOnVm = "DeployIfNotExists" + enableAscForArm = "DeployIfNotExists" + enableAscForOssDb = "DeployIfNotExists" + enableAscForCosmosDbs = "DeployIfNotExists" + enableAscForCspm = "DeployIfNotExists" + } + } + } + } + # Example of how to update a policy assignment enforcement mode for DDOS Protection Plan + connectivity = { + policy_assignments = { + Enable-DDoS-VNET = { + enforcement_mode = "DoNotEnforce" + } + } + } + } +} diff --git a/docs/static/examples/tf/accelerator/config/management_resource_settings.tfvars b/docs/static/examples/tf/accelerator/config/management_resource_settings.tfvars new file mode 100644 index 0000000..84bb0b6 --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/management_resource_settings.tfvars @@ -0,0 +1,22 @@ +management_resource_settings = { + automation_account_name = "$${automation_account_name}" + location = "$${starter_location_01}" + log_analytics_workspace_name = "$${log_analytics_workspace_name}" + resource_group_name = "$${management_resource_group_name}" + user_assigned_managed_identities = { + ama = { + name = "$${ama_user_assigned_managed_identity_name}" + } + } + data_collection_rules = { + change_tracking = { + name = "$${dcr_change_tracking_name}" + } + defender_sql = { + name = "$${dcr_defender_sql_name}" + } + vm_insights = { + name = "$${dcr_vm_insights_name}" + } + } +} diff --git a/docs/static/examples/tf/accelerator/config/tags.tfvars b/docs/static/examples/tf/accelerator/config/tags.tfvars new file mode 100644 index 0000000..aff4d8a --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/tags.tfvars @@ -0,0 +1,4 @@ +tags = { + deployed_by = "terraform" + source = "Azure Landing Zones Accelerator" +} diff --git a/docs/static/examples/tf/accelerator/config/virtual_wan_settings.tfvars b/docs/static/examples/tf/accelerator/config/virtual_wan_settings.tfvars new file mode 100644 index 0000000..8c31101 --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/virtual_wan_settings.tfvars @@ -0,0 +1,10 @@ +virtual_wan_settings = { + name = "vwan-$${starter_location_01}" + resource_group_name = "$${connectivity_hub_vwan_resource_group_name}" + location = "$${starter_location_01}" + ddos_protection_plan = { + name = "$${ddos_protection_plan_name}" + resource_group_name = "$${ddos_resource_group_name}" + location = "$${starter_location_01}" + } +} diff --git a/docs/static/examples/tf/accelerator/config/virtual_wan_virtual_hubs.tfvars b/docs/static/examples/tf/accelerator/config/virtual_wan_virtual_hubs.tfvars new file mode 100644 index 0000000..469d6f4 --- /dev/null +++ b/docs/static/examples/tf/accelerator/config/virtual_wan_virtual_hubs.tfvars @@ -0,0 +1,60 @@ +virtual_wan_virtual_hubs = { + primary = { + # Example hub network settings for this region + hub = { + name = "vwan-hub-$${starter_location_01}" + resource_group = "$${connectivity_hub_primary_resource_group_name}" + location = "$${starter_location_01}" + address_prefix = "$${primary_hub_address_space}" + } + # Example Azure Firewall settings for this region (omit this section if not using Azure Firewall) + firewall = { + name = "fw-hub-$${starter_location_01}" + sku_name = "AZFW_Hub" + sku_tier = "Standard" + zones = "$${starter_location_01_availability_zones}" + } + # Example firewall policy settings for this region (omit this section if not using Azure Firewall) + firewall_policy = { + name = "fwp-hub-$${starter_location_01}" + } + # Example Virtual Network Gateway settings for this region (omit this section if not using Virtual Network Gateway) + virtual_network_gateways = { + # Example ExpressRoute settings for this region (omit this section if not using ExpressRoute) + express_route = { + name = "vgw-hub-expressroute-$${starter_location_01}" + } + # Example VPN Gateway settings for this region (omit this section if not using VPN Gateway) + vpn = { + name = "vgw-hub-vpn-$${starter_location_01}" + } + } + # Example Private DNS Zone settings for this region (omit this section if not using Private DNS Zones) + private_dns_zones = { + resource_group_name = "$${dns_resource_group_name}" + is_primary = true + auto_registration_zone_enabled = true + auto_registration_zone_name = "$${starter_location_01}.azure.local" + subnet_address_prefix = "$${primary_private_dns_resolver_subnet_address_prefix}" + private_dns_resolver = { + name = "pdr-hub-dns-$${starter_location_01}" + } + } + # Example Bastion Host settings for this region (omit this section if not using Bastion Host) + bastion = { + subnet_address_prefix = "$${primary_bastion_subnet_address_prefix}" + bastion_host = { + name = "bastion-hub-$${starter_location_01}" + } + bastion_public_ip = { + name = "pip-bastion-hub-$${starter_location_01}" + zones = "$${starter_location_01_availability_zones}" + } + } + # Example Side Car Virtual Network settings for this region + side_car_virtual_network = { + name = "vnet-side-car-$${starter_location_01}" + address_space = ["$${primary_side_car_virtual_network_address_space}"] + } + } +} diff --git a/docs/themes/hugo-geekdoc/static/custom.css b/docs/themes/hugo-geekdoc/static/custom.css index e488c91..cbec8ec 100644 --- a/docs/themes/hugo-geekdoc/static/custom.css +++ b/docs/themes/hugo-geekdoc/static/custom.css @@ -1 +1,7 @@ /* You can add custom styles here. */ +.container { + max-width: 80%; +} +.lntable tr td { + padding: 0 !important; +}