Skip to content

Commit

Permalink
feat: support azurerm v4 and additional policy role assignments (#204)
Browse files Browse the repository at this point in the history
<!-- Thank you for submitting a Pull Request. Please fill out the
template below.-->
## Overview/Summary

Migrate to azurerm v4 and support policy additional role assignments

## This PR fixes/adds/changes/removes

N/A

### Breaking Changes

Migrate to azurerm v4 and update many module references

## Testing Evidence

Please provide any testing evidence to show that your Pull Request
works/fixes as described and planned (include screenshots, if
appropriate).

## As part of this Pull Request I have

- [x] Checked for duplicate [Pull
Requests](https://github.com/Azure/alz-terraform-accelerator/pulls)
- [x] Associated it with relevant
[issues](https://github.com/Azure/alz-terraform-accelerator/issues), for
tracking and closure.
- [x] Ensured my code/branch is up-to-date with the latest changes in
the `main`
[branch](https://github.com/Azure/alz-terraform-accelerator/tree/main)
- [x] Performed testing and provided evidence.
- [x] Updated relevant and associated documentation.
  • Loading branch information
jaredfholgate authored Jan 20, 2025
1 parent af0fe6a commit e50a779
Show file tree
Hide file tree
Showing 19 changed files with 180 additions and 128 deletions.
28 changes: 28 additions & 0 deletions .github/tests/scripts/examine-plan-file.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Not used in the test, but saving for reference to be able to examine the plan file

$json = Get-Content .\tfplan.json -Raw | ConvertFrom-Json

$resources = $json.resource_changes | Where-Object { $_.address -like 'module.management_groups.module.management_groups.azapi_resource.policy_role_assignments*' }

$result = @()

foreach($resource in $resources) {
$body = $resource.change.after.body
$roleDefinitionId = $body.properties.roleDefinitionId
$parentId = $resource.change.after.parent_id

if($parentId -like "/providers/Microsoft.Management/managementGroups/*") {
continue
}

Write-Output "Role Definition ID: $roleDefinitionId"
Write-Output "Parent ID: $parentId"
Write-Output "----------------------"

$result += [PSCustomObject]@{
RoleDefinitionId = $roleDefinitionId
ParentId = $parentId
}
}

$result | ConvertTo-Json | Out-File .\output.json
5 changes: 5 additions & 0 deletions .github/workflows/end-to-end-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,8 @@ jobs:
Write-Host "Plan Summary"
Write-Host (ConvertTo-Json $items -Depth 10)
shell: pwsh

- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.name }}-tfplan.json
path: tfplan.json
26 changes: 13 additions & 13 deletions templates/.config/ALZ-Powershell.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@
"starter_modules": {
"platform_landing_zone": {
"location": "platform_landing_zone",
"short_name": "Preview - Azure Verified Modules for ALZ Platform Landing Zone",
"description": "Preview - Complete Azure Platform Landing Zones Configurable Deployment with Multi-Region Support using Azure Verified Modules"
},
"complete_multi_region": {
"location": "complete_multi_region",
"short_name": "Complete Multi-Region",
"description": "Complete Azure Landing Zones Configurable Deployment with Multi-Region Support"
"short_name": "Azure Verified Modules for Platform Landing Zone (ALZ)",
"description": "Complete Azure Platform Landing Zones Configurable Deployment with Multi-Region Support using Azure Verified Modules"
},
"sovereign_landing_zone": {
"location": "microsoft_cloud_for_industry",
Expand All @@ -28,20 +23,25 @@
"modules"
]
},
"complete_multi_region": {
"location": "complete_multi_region",
"short_name": "DEPRECATED Complete Multi-Region",
"description": "DEPRECATED Complete Azure Landing Zones Configurable Deployment with Multi-Region Support"
},
"complete": {
"location": "complete",
"short_name": "Complete",
"description": "Complete Azure Landing Zones Configurable Deployment"
"short_name": "DEPRECATED Complete",
"description": "DEPRECATED Complete Azure Landing Zones Configurable Deployment"
},
"basic": {
"location": "basic",
"short_name": "Basic",
"description": "Basic Azure Landing Zones Deployment with Management Groups and Policy"
"short_name": "DEPRECATED Basic",
"description": "DEPRECATED Basic Azure Landing Zones Deployment with Management Groups and Policy"
},
"hubnetworking": {
"location": "hubnetworking",
"short_name": "Hub Networking",
"description": "Hub Networking Azure Landing Zones Deployment with Management Groups, Policy and Hub Networking"
"short_name": "DEPRECATED Hub Networking",
"description": "DEPRECATED Hub Networking Azure Landing Zones Deployment with Management Groups, Policy and Hub Networking"
},
"test": {
"location": "test",
Expand Down
98 changes: 50 additions & 48 deletions templates/complete_multi_region/README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,50 @@
# Azure Landing Zones Accelerator Starter Module for Terraform - Complete Multi-Region

This module is part of the Azure Landing Zones Accelerator solution. It is a complete multi-region implementation of the Azure Landing Zones Platform Landing Zone for Terraform.

It deploys a hub and spoke virtual network or Virtual WAN architecture across multiple regions.

The module deploys the following resources:

- Management group hierarchy
- Azure Policy definitions and assignments
- Role definitions
- Management resources, including Log Analytics workspace and Automation account
- Hub and spoke virtual network or Virtual WAN architecture across multiple regions
- DDOS protection plan
- Private DNS zones

## Usage

The module is intended to be used with the [Azure Landing Zones Accelerator](https://aka.ms/alz/accelerator/docs). Head over there to get started.

>NOTE: The module can be used independently if needed. Example tfvars files can be found in the `examples` directory for that use case.
### Running Directly

#### Run the local examples

Create a `terraform.tfvars` file in the root of the module directory with the following content, replacing the placeholders with the actual values:

```hcl
starter_locations = ["uksouth", "ukwest"]
subscription_id_connectivity = "00000000-0000-0000-0000-000000000000"
subscription_id_identity = "00000000-0000-0000-0000-000000000000"
subscription_id_management = "00000000-0000-0000-0000-000000000000"
```

##### Hub and Spoke Virtual Networks Multi Region

```powershell
terraform init
terraform apply -var-file ./examples/config-hub-and-spoke-virtual-networks-multi-region.tfvars
```

##### Virtual WAN Multi Region

```powershell
terraform init
terraform apply -var-file ./examples/config-virtual-wan-multi-region.tfvars
```
# Azure Landing Zones Accelerator Starter Module for Terraform - Complete Multi-Region

DEPRECATED: This module is deprecated and will be removed in a future release. Please use the [Azure Verified Modules for Platform Landing Zone (ALZ)](https://aka.ms/alz/acc/starter/avm-plz) module as a replacement.

This module is part of the Azure Landing Zones Accelerator solution. It is a complete multi-region implementation of the Azure Landing Zones Platform Landing Zone for Terraform.

It deploys a hub and spoke virtual network or Virtual WAN architecture across multiple regions.

The module deploys the following resources:

- Management group hierarchy
- Azure Policy definitions and assignments
- Role definitions
- Management resources, including Log Analytics workspace and Automation account
- Hub and spoke virtual network or Virtual WAN architecture across multiple regions
- DDOS protection plan
- Private DNS zones

## Usage

The module is intended to be used with the [Azure Landing Zones Accelerator](https://aka.ms/alz/accelerator/docs). Head over there to get started.

>NOTE: The module can be used independently if needed. Example tfvars files can be found in the `examples` directory for that use case.
### Running Directly

#### Run the local examples

Create a `terraform.tfvars` file in the root of the module directory with the following content, replacing the placeholders with the actual values:

```hcl
starter_locations = ["uksouth", "ukwest"]
subscription_id_connectivity = "00000000-0000-0000-0000-000000000000"
subscription_id_identity = "00000000-0000-0000-0000-000000000000"
subscription_id_management = "00000000-0000-0000-0000-000000000000"
```

##### Hub and Spoke Virtual Networks Multi Region

```powershell
terraform init
terraform apply -var-file ./examples/config-hub-and-spoke-virtual-networks-multi-region.tfvars
```

##### Virtual WAN Multi Region

```powershell
terraform init
terraform apply -var-file ./examples/config-virtual-wan-multi-region.tfvars
```
4 changes: 2 additions & 2 deletions templates/platform_landing_zone/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ The module deploys the following resources:

## Usage

The module is intended to be used with the [Azure Landing Zones Accelerator](https://aka.ms/alz/accelerator/docs). Head over there to get started.
The module is intended to be used with the [Azure Landing Zones Accelerator](https://aka.ms/alz/acc). Head over there to get started.

>NOTE: The module can be used independently if needed. Example tfvars files can be found in the `examples` directory for that use case.
>NOTE: The module can be used independently if needed. Example `tfvars` files can be found in the `examples` directory for that use case.
### Running Directly

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ custom_replacements = {
primary_virtual_network_gateway_express_route_name = "vgw-hub-er-$${starter_location_01}"
primary_virtual_network_gateway_express_route_public_ip_name = "pip-vgw-hub-er-$${starter_location_01}"
primary_virtual_network_gateway_vpn_name = "vgw-hub-vpn-$${starter_location_01}"
primary_virtual_network_gateway_vpn_public_ip_name = "pip-vgw-hub-vpn-$${starter_location_01}"
primary_virtual_network_gateway_vpn_public_ip_name_1 = "pip-vgw-hub-vpn-$${starter_location_01}-001"
primary_virtual_network_gateway_vpn_public_ip_name_2 = "pip-vgw-hub-vpn-$${starter_location_01}-002"
primary_private_dns_resolver_name = "pdr-hub-dns-$${starter_location_01}"
primary_bastion_host_name = "bas-hub-$${starter_location_01}"
primary_bastion_host_public_ip_name = "pip-bastion-hub-$${starter_location_01}"
Expand All @@ -66,7 +67,8 @@ custom_replacements = {
secondary_virtual_network_gateway_express_route_name = "vgw-hub-er-$${starter_location_02}"
secondary_virtual_network_gateway_express_route_public_ip_name = "pip-vgw-hub-er-$${starter_location_02}"
secondary_virtual_network_gateway_vpn_name = "vgw-hub-vpn-$${starter_location_02}"
secondary_virtual_network_gateway_vpn_public_ip_name = "pip-vgw-hub-vpn-$${starter_location_02}"
secondary_virtual_network_gateway_vpn_public_ip_name_1 = "pip-vgw-hub-vpn-$${starter_location_02}-001"
secondary_virtual_network_gateway_vpn_public_ip_name_2 = "pip-vgw-hub-vpn-$${starter_location_02}-002"
secondary_private_dns_resolver_name = "pdr-hub-dns-$${starter_location_02}"
secondary_bastion_host_name = "bas-hub-$${starter_location_02}"
secondary_bastion_host_public_ip_name = "pip-bastion-hub-$${starter_location_02}"
Expand Down Expand Up @@ -319,9 +321,15 @@ hub_and_spoke_vnet_virtual_networks = {
name = "$${primary_virtual_network_gateway_vpn_name}"
sku = "$${starter_location_01_virtual_network_gateway_sku_vpn}"
ip_configurations = {
default = {
active_active_1 = {
public_ip = {
name = "$${primary_virtual_network_gateway_vpn_public_ip_name_1}"
zones = "$${starter_location_01_availability_zones}"
}
}
active_active_2 = {
public_ip = {
name = "$${primary_virtual_network_gateway_vpn_public_ip_name}"
name = "$${primary_virtual_network_gateway_vpn_public_ip_name_2}"
zones = "$${starter_location_01_availability_zones}"
}
}
Expand Down Expand Up @@ -389,9 +397,15 @@ hub_and_spoke_vnet_virtual_networks = {
name = "$${secondary_virtual_network_gateway_vpn_name}"
sku = "$${starter_location_02_virtual_network_gateway_sku_vpn}"
ip_configurations = {
default = {
active_active_1 = {
public_ip = {
name = "$${secondary_virtual_network_gateway_vpn_public_ip_name_1}"
zones = "$${starter_location_02_availability_zones}"
}
}
active_active_2 = {
public_ip = {
name = "$${secondary_virtual_network_gateway_vpn_public_ip_name}"
name = "$${secondary_virtual_network_gateway_vpn_public_ip_name_2}"
zones = "$${starter_location_02_availability_zones}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ custom_replacements = {
primary_virtual_network_gateway_express_route_name = "vgw-hub-er-$${starter_location_01}"
primary_virtual_network_gateway_express_route_public_ip_name = "pip-vgw-hub-er-$${starter_location_01}"
primary_virtual_network_gateway_vpn_name = "vgw-hub-vpn-$${starter_location_01}"
primary_virtual_network_gateway_vpn_public_ip_name = "pip-vgw-hub-vpn-$${starter_location_01}"
primary_virtual_network_gateway_vpn_public_ip_name_1 = "pip-vgw-hub-vpn-$${starter_location_01}-001"
primary_virtual_network_gateway_vpn_public_ip_name_2 = "pip-vgw-hub-vpn-$${starter_location_01}-002"
primary_private_dns_resolver_name = "pdr-hub-dns-$${starter_location_01}"
primary_bastion_host_name = "bas-hub-$${starter_location_01}"
primary_bastion_host_public_ip_name = "pip-bastion-hub-$${starter_location_01}"
Expand All @@ -70,7 +71,8 @@ custom_replacements = {
secondary_virtual_network_gateway_express_route_name = "vgw-hub-er-$${starter_location_02}"
secondary_virtual_network_gateway_express_route_public_ip_name = "pip-vgw-hub-er-$${starter_location_02}"
secondary_virtual_network_gateway_vpn_name = "vgw-hub-vpn-$${starter_location_02}"
secondary_virtual_network_gateway_vpn_public_ip_name = "pip-vgw-hub-vpn-$${starter_location_02}"
secondary_virtual_network_gateway_vpn_public_ip_name_1 = "pip-vgw-hub-vpn-$${starter_location_02}-001"
secondary_virtual_network_gateway_vpn_public_ip_name_2 = "pip-vgw-hub-vpn-$${starter_location_02}-002"
secondary_private_dns_resolver_name = "pdr-hub-dns-$${starter_location_02}"
secondary_bastion_host_name = "bas-hub-$${starter_location_02}"
secondary_bastion_host_public_ip_name = "pip-bastion-hub-$${starter_location_02}"
Expand Down Expand Up @@ -331,9 +333,15 @@ hub_and_spoke_vnet_virtual_networks = {
name = "$${primary_virtual_network_gateway_vpn_name}"
sku = "$${starter_location_01_virtual_network_gateway_sku_vpn}"
ip_configurations = {
default = {
active_active_1 = {
public_ip = {
name = "$${primary_virtual_network_gateway_vpn_public_ip_name_1}"
zones = "$${starter_location_01_availability_zones}"
}
}
active_active_2 = {
public_ip = {
name = "$${primary_virtual_network_gateway_vpn_public_ip_name}"
name = "$${primary_virtual_network_gateway_vpn_public_ip_name_2}"
zones = "$${starter_location_01_availability_zones}"
}
}
Expand Down Expand Up @@ -411,9 +419,15 @@ hub_and_spoke_vnet_virtual_networks = {
name = "$${secondary_virtual_network_gateway_vpn_name}"
sku = "$${starter_location_02_virtual_network_gateway_sku_vpn}"
ip_configurations = {
default = {
active_active_1 = {
public_ip = {
name = "$${secondary_virtual_network_gateway_vpn_public_ip_name_1}"
zones = "$${starter_location_02_availability_zones}"
}
}
active_active_2 = {
public_ip = {
name = "$${secondary_virtual_network_gateway_vpn_public_ip_name}"
name = "$${secondary_virtual_network_gateway_vpn_public_ip_name_2}"
zones = "$${starter_location_02_availability_zones}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ custom_replacements = {
primary_virtual_network_gateway_express_route_name = "vgw-hub-er-$${starter_location_01}"
primary_virtual_network_gateway_express_route_public_ip_name = "pip-vgw-hub-er-$${starter_location_01}"
primary_virtual_network_gateway_vpn_name = "vgw-hub-vpn-$${starter_location_01}"
primary_virtual_network_gateway_vpn_public_ip_name = "pip-vgw-hub-vpn-$${starter_location_01}"
primary_virtual_network_gateway_vpn_public_ip_name_1 = "pip-vgw-hub-vpn-$${starter_location_01}-001"
primary_virtual_network_gateway_vpn_public_ip_name_2 = "pip-vgw-hub-vpn-$${starter_location_01}-002"
primary_private_dns_resolver_name = "pdr-hub-dns-$${starter_location_01}"
primary_bastion_host_name = "bas-hub-$${starter_location_01}"
primary_bastion_host_public_ip_name = "pip-bastion-hub-$${starter_location_01}"
Expand Down Expand Up @@ -299,9 +300,15 @@ hub_and_spoke_vnet_virtual_networks = {
name = "$${primary_virtual_network_gateway_vpn_name}"
sku = "$${starter_location_01_virtual_network_gateway_sku_vpn}"
ip_configurations = {
default = {
active_active_1 = {
public_ip = {
name = "$${primary_virtual_network_gateway_vpn_public_ip_name_1}"
zones = "$${starter_location_01_availability_zones}"
}
}
active_active_2 = {
public_ip = {
name = "$${primary_virtual_network_gateway_vpn_public_ip_name}"
name = "$${primary_virtual_network_gateway_vpn_public_ip_name_2}"
zones = "$${starter_location_01_availability_zones}"
}
}
Expand Down
2 changes: 1 addition & 1 deletion templates/platform_landing_zone/main.resource.groups.tf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module "resource_groups" {
source = "Azure/avm-res-resources-resourcegroup/azurerm"
version = "0.1.0"
version = "0.2.0"

for_each = local.connectivity_resource_groups

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ locals {
} } if try(value.virtual_network_gateways, null) != null && (can(value.virtual_network_gateways.express_route) || can(value.virtual_network_gateways.vpn))
}

subnets = { for key, value in var.hub_virtual_networks : key => merge(local.private_dns_resolver_subnets[key], local.bastion_subnets[key], local.gateway_subnets[key]) }
subnets = { for key, value in var.hub_virtual_networks : key => merge(lookup(local.private_dns_resolver_subnets, key, {}), lookup(local.bastion_subnets, key, {}), lookup(local.gateway_subnets, key, {})) }
}
Loading

0 comments on commit e50a779

Please sign in to comment.