Skip to content

Commit f1b51ec

Browse files
Add validation and single region NVA scenario (#225)
<!-- Thank you for submitting a Pull Request. Please fill out the template below.--> ## Overview/Summary This PR adds validation for starter locations to match the number of connectivity regions. It also adds example config for single region NVA sceanrios ## This PR fixes/adds/changes/removes 1. Azure/ALZ-PowerShell-Module#326 ### Breaking Changes None ## 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. --------- Co-authored-by: Copilot <[email protected]>
1 parent 2f884e1 commit f1b51ec

File tree

4 files changed

+680
-5
lines changed

4 files changed

+680
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Platform landing zone - Full single-region for NVA (Network Virtual Appliance) example
2+
3+
This example configuration deploys a full single-region landing zone ready for NVA support:
4+
5+
- Management Groups
6+
- Policy
7+
- Management Resources
8+
- Hub Networking (with Hub and Spoke VNet or vWAN)
9+
- Private DNS Zones for Private Link
10+
- DDOS Protection Plan
11+
12+
## Options
13+
14+
There are two options for deploying the hub networking:
15+
16+
- Hub and Spoke VNet: [hub-and-spoke-vnet.tfvars](./hub-and-spoke-vnet.tfvars)
17+
- Virtual WAN: [virtual-wan.tfvars](./virtual-wan.tfvars)
18+
19+
## Limitations
20+
21+
The vWAN module does not currently support routes, we'll need to add that per this issue: <https://github.com/Azure/terraform-azurerm-avm-ptn-virtualwan/issues/119>
22+
23+
## Documentation
24+
25+
The full documentation for this example can be found over at our [Azure Landing Zones documentation site](https://tbc.com).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
/*
2+
--- Built-in Replacements ---
3+
This file contains built-in replacements to avoid repeating the same hard-coded values.
4+
Replacements are denoted by the dollar-dollar curly braces token (e.g. $${starter_location_01}). The following details each built-in replacemnets that you can use:
5+
`starter_location_01`: This the primary an Azure location sourced from the `starter_locations` variable. This can be used to set the location of resources.
6+
`starter_location_02` to `starter_location_10`: These are the secondary Azure locations sourced from the `starter_locations` variable. This can be used to set the location of resources.
7+
`starter_location_01_availability_zones` to `starter_location_10_availability_zones`: These are the availability zones for the Azure locations sourced from the `starter_locations` variable. This can be used to set the availability zones of resources.
8+
`starter_location_01_virtual_network_gateway_sku_express_route` to `starter_location_10_virtual_network_gateway_sku_express_route`: These are the default SKUs for the Express Route virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways.
9+
`starter_location_01_virtual_network_gateway_sku_vpn` to `starter_location_10_virtual_network_gateway_sku_vpn`: These are the default SKUs for the VPN virtual network gateways based on the Azure locations sourced from the `starter_locations` variable. This can be used to set the SKU of the virtual network gateways.
10+
`root_parent_management_group_id`: This is the id of the management group that the ALZ hierarchy will be nested under.
11+
`subscription_id_identity`: The subscription ID of the subscription to deploy the identity resources to, sourced from the variable `subscription_id_identity`.
12+
`subscription_id_connectivity`: The subscription ID of the subscription to deploy the connectivity resources to, sourced from the variable `subscription_id_connectivity`.
13+
`subscription_id_management`: The subscription ID of the subscription to deploy the management resources to, sourced from the variable `subscription_id_management`.
14+
*/
15+
16+
/*
17+
--- Custom Replacements ---
18+
You can define custom replacements to use throughout the configuration.
19+
*/
20+
custom_replacements = {
21+
/*
22+
--- Custom Name Replacements ---
23+
You can define custom names and other strings to use throughout the configuration.
24+
You can only use the built in replacements in this section.
25+
NOTE: You cannot refer to another custom name in this variable.
26+
*/
27+
names = {
28+
# Defender email security contact
29+
defender_email_security_contact = "replace_me@replace_me.com"
30+
31+
# Resource group names
32+
management_resource_group_name = "rg-management-$${starter_location_01}"
33+
connectivity_hub_primary_resource_group_name = "rg-hub-$${starter_location_01}"
34+
dns_resource_group_name = "rg-hub-dns-$${starter_location_01}"
35+
ddos_resource_group_name = "rg-hub-ddos-$${starter_location_01}"
36+
asc_export_resource_group_name = "rg-asc-export-$${starter_location_01}"
37+
38+
# Resource names
39+
log_analytics_workspace_name = "law-management-$${starter_location_01}"
40+
ddos_protection_plan_name = "ddos-$${starter_location_01}"
41+
automation_account_name = "aa-management-$${starter_location_01}"
42+
ama_user_assigned_managed_identity_name = "uami-management-ama-$${starter_location_01}"
43+
dcr_change_tracking_name = "dcr-change-tracking"
44+
dcr_defender_sql_name = "dcr-defender-sql"
45+
dcr_vm_insights_name = "dcr-vm-insights"
46+
47+
# Resource names primary connectivity
48+
primary_virtual_network_name = "vnet-hub-$${starter_location_01}"
49+
primary_subnet_nva_name = "subnet-nva-$${starter_location_01}"
50+
primary_route_table_firewall_name = "rt-hub-fw-$${starter_location_01}"
51+
primary_route_table_user_subnets_name = "rt-hub-std-$${starter_location_01}"
52+
primary_virtual_network_gateway_express_route_name = "vgw-hub-er-$${starter_location_01}"
53+
primary_virtual_network_gateway_express_route_public_ip_name = "pip-vgw-hub-er-$${starter_location_01}"
54+
primary_virtual_network_gateway_vpn_name = "vgw-hub-vpn-$${starter_location_01}"
55+
primary_virtual_network_gateway_vpn_public_ip_name_1 = "pip-vgw-hub-vpn-$${starter_location_01}-001"
56+
primary_virtual_network_gateway_vpn_public_ip_name_2 = "pip-vgw-hub-vpn-$${starter_location_01}-002"
57+
primary_private_dns_resolver_name = "pdr-hub-dns-$${starter_location_01}"
58+
primary_bastion_host_name = "bas-hub-$${starter_location_01}"
59+
primary_bastion_host_public_ip_name = "pip-bastion-hub-$${starter_location_01}"
60+
61+
# Private DNS Zones primary
62+
primary_auto_registration_zone_name = "$${starter_location_01}.azure.local"
63+
64+
# IP Ranges Primary
65+
# Regional Address Space: 10.0.0.0/16
66+
primary_hub_address_space = "10.0.0.0/16"
67+
primary_hub_virtual_network_address_space = "10.0.0.0/22"
68+
primary_nva_subnet_address_prefix = "10.0.0.0/26"
69+
primary_nva_ip_address = "10.0.0.4"
70+
primary_bastion_subnet_address_prefix = "10.0.0.64/26"
71+
primary_gateway_subnet_address_prefix = "10.0.0.128/27"
72+
primary_private_dns_resolver_subnet_address_prefix = "10.0.0.160/28"
73+
}
74+
75+
/*
76+
--- Custom Resource Group Identifier Replacements ---
77+
You can define custom resource group identifiers to use throughout the configuration.
78+
You can only use the templated variables and custom names in this section.
79+
NOTE: You cannot refer to another custom resource group identifier in this variable.
80+
*/
81+
resource_group_identifiers = {
82+
management_resource_group_id = "/subscriptions/$${subscription_id_management}/resourcegroups/$${management_resource_group_name}"
83+
ddos_protection_plan_resource_group_id = "/subscriptions/$${subscription_id_connectivity}/resourcegroups/$${ddos_resource_group_name}"
84+
}
85+
86+
/*
87+
--- Custom Resource Identifier Replacements ---
88+
You can define custom resource identifiers to use throughout the configuration.
89+
You can only use the templated variables, custom names and customer resource group identifiers in this variable.
90+
NOTE: You cannot refer to another custom resource identifier in this variable.
91+
*/
92+
resource_identifiers = {
93+
ama_change_tracking_data_collection_rule_id = "$${management_resource_group_id}/providers/Microsoft.Insights/dataCollectionRules/$${dcr_change_tracking_name}"
94+
ama_mdfc_sql_data_collection_rule_id = "$${management_resource_group_id}/providers/Microsoft.Insights/dataCollectionRules/$${dcr_defender_sql_name}"
95+
ama_vm_insights_data_collection_rule_id = "$${management_resource_group_id}/providers/Microsoft.Insights/dataCollectionRules/$${dcr_vm_insights_name}"
96+
ama_user_assigned_managed_identity_id = "$${management_resource_group_id}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$${ama_user_assigned_managed_identity_name}"
97+
log_analytics_workspace_id = "$${management_resource_group_id}/providers/Microsoft.OperationalInsights/workspaces/$${log_analytics_workspace_name}"
98+
ddos_protection_plan_id = "$${ddos_protection_plan_resource_group_id}/providers/Microsoft.Network/ddosProtectionPlans/$${ddos_protection_plan_name}"
99+
}
100+
}
101+
102+
enable_telemetry = true
103+
104+
/*
105+
--- Tags ---
106+
This variable can be used to apply tags to all resources that support it. Some resources allow overriding these tags.
107+
*/
108+
tags = {
109+
deployed_by = "terraform"
110+
source = "Azure Landing Zones Accelerator"
111+
}
112+
113+
/*
114+
--- Management Resources ---
115+
You can use this section to customize the management resources that will be deployed.
116+
*/
117+
management_resource_settings = {
118+
automation_account_name = "$${automation_account_name}"
119+
location = "$${starter_location_01}"
120+
log_analytics_workspace_name = "$${log_analytics_workspace_name}"
121+
resource_group_name = "$${management_resource_group_name}"
122+
user_assigned_managed_identities = {
123+
ama = {
124+
name = "$${ama_user_assigned_managed_identity_name}"
125+
}
126+
}
127+
data_collection_rules = {
128+
change_tracking = {
129+
name = "$${dcr_change_tracking_name}"
130+
}
131+
defender_sql = {
132+
name = "$${dcr_defender_sql_name}"
133+
}
134+
vm_insights = {
135+
name = "$${dcr_vm_insights_name}"
136+
}
137+
}
138+
}
139+
140+
/*
141+
--- Management Groups and Policy ---
142+
You can use this section to customize the management groups and policies that will be deployed.
143+
You can further configure management groups and policy by supplying a `lib` folder. This is detailed in the Accelerator documentation.
144+
*/
145+
management_group_settings = {
146+
location = "$${starter_location_01}"
147+
parent_resource_id = "$${root_parent_management_group_id}"
148+
policy_default_values = {
149+
ama_change_tracking_data_collection_rule_id = "$${ama_change_tracking_data_collection_rule_id}"
150+
ama_mdfc_sql_data_collection_rule_id = "$${ama_mdfc_sql_data_collection_rule_id}"
151+
ama_vm_insights_data_collection_rule_id = "$${ama_vm_insights_data_collection_rule_id}"
152+
ama_user_assigned_managed_identity_id = "$${ama_user_assigned_managed_identity_id}"
153+
ama_user_assigned_managed_identity_name = "$${ama_user_assigned_managed_identity_name}"
154+
log_analytics_workspace_id = "$${log_analytics_workspace_id}"
155+
ddos_protection_plan_id = "$${ddos_protection_plan_id}"
156+
private_dns_zone_subscription_id = "$${subscription_id_connectivity}"
157+
private_dns_zone_region = "$${starter_location_01}"
158+
private_dns_zone_resource_group_name = "$${dns_resource_group_name}"
159+
}
160+
subscription_placement = {
161+
identity = {
162+
subscription_id = "$${subscription_id_identity}"
163+
management_group_name = "identity"
164+
}
165+
connectivity = {
166+
subscription_id = "$${subscription_id_connectivity}"
167+
management_group_name = "connectivity"
168+
}
169+
management = {
170+
subscription_id = "$${subscription_id_management}"
171+
management_group_name = "management"
172+
}
173+
}
174+
policy_assignments_to_modify = {
175+
alz = {
176+
policy_assignments = {
177+
Deploy-MDFC-Config-H224 = {
178+
parameters = {
179+
ascExportResourceGroupName = "$${asc_export_resource_group_name}"
180+
ascExportResourceGroupLocation = "$${starter_location_01}"
181+
emailSecurityContact = "$${defender_email_security_contact}"
182+
enableAscForServers = "DeployIfNotExists"
183+
enableAscForServersVulnerabilityAssessments = "DeployIfNotExists"
184+
enableAscForSql = "DeployIfNotExists"
185+
enableAscForAppServices = "DeployIfNotExists"
186+
enableAscForStorage = "DeployIfNotExists"
187+
enableAscForContainers = "DeployIfNotExists"
188+
enableAscForKeyVault = "DeployIfNotExists"
189+
enableAscForSqlOnVm = "DeployIfNotExists"
190+
enableAscForArm = "DeployIfNotExists"
191+
enableAscForOssDb = "DeployIfNotExists"
192+
enableAscForCosmosDbs = "DeployIfNotExists"
193+
enableAscForCspm = "DeployIfNotExists"
194+
}
195+
}
196+
}
197+
}
198+
/*
199+
# Example of how to update a policy assignment enforcement mode for DDOS Protection Plan
200+
connectivity = {
201+
policy_assignments = {
202+
Enable-DDoS-VNET = {
203+
enforcement_mode = "DoNotEnforce"
204+
}
205+
}
206+
}
207+
*/
208+
/*
209+
# Example of how to update a policy assignment enforcement mode for Private Link DNS Zones
210+
corp = {
211+
policy_assignments = {
212+
Deploy-Private-DNS-Zones = {
213+
enforcement_mode = "DoNotEnforce"
214+
}
215+
}
216+
}
217+
*/
218+
}
219+
}
220+
221+
/*
222+
--- Connectivity - Hub and Spoke Virtual Network ---
223+
You can use this section to customize the hub virtual networking that will be deployed.
224+
*/
225+
connectivity_type = "hub_and_spoke_vnet"
226+
227+
connectivity_resource_groups = {
228+
ddos = {
229+
name = "$${ddos_resource_group_name}"
230+
location = "$${starter_location_01}"
231+
}
232+
vnet_primary = {
233+
name = "$${connectivity_hub_primary_resource_group_name}"
234+
location = "$${starter_location_01}"
235+
}
236+
dns = {
237+
name = "$${dns_resource_group_name}"
238+
location = "$${starter_location_01}"
239+
}
240+
}
241+
242+
hub_and_spoke_vnet_settings = {
243+
ddos_protection_plan = {
244+
name = "$${ddos_protection_plan_name}"
245+
resource_group_name = "$${ddos_resource_group_name}"
246+
location = "$${starter_location_01}"
247+
}
248+
}
249+
250+
hub_and_spoke_vnet_virtual_networks = {
251+
primary = {
252+
hub_virtual_network = {
253+
name = "$${primary_virtual_network_name}"
254+
resource_group_name = "$${connectivity_hub_primary_resource_group_name}"
255+
location = "$${starter_location_01}"
256+
address_space = ["$${primary_hub_virtual_network_address_space}"]
257+
routing_address_space = ["$${primary_hub_address_space}"]
258+
route_table_name_firewall = "$${primary_route_table_firewall_name}"
259+
route_table_name_user_subnets = "$${primary_route_table_user_subnets_name}"
260+
ddos_protection_plan_id = "$${ddos_protection_plan_id}"
261+
hub_router_ip_address = "$${primary_nva_ip_address}"
262+
subnets = {
263+
nva = {
264+
name = "$${primary_subnet_nva_name}"
265+
address_prefixes = ["$${primary_nva_subnet_address_prefix}"]
266+
}
267+
}
268+
}
269+
virtual_network_gateways = {
270+
subnet_address_prefix = "$${primary_gateway_subnet_address_prefix}"
271+
express_route = {
272+
location = "$${starter_location_01}"
273+
name = "$${primary_virtual_network_gateway_express_route_name}"
274+
sku = "$${starter_location_01_virtual_network_gateway_sku_express_route}"
275+
ip_configurations = {
276+
default = {
277+
public_ip = {
278+
name = "$${primary_virtual_network_gateway_express_route_public_ip_name}"
279+
zones = "$${starter_location_01_availability_zones}"
280+
}
281+
}
282+
}
283+
}
284+
vpn = {
285+
location = "$${starter_location_01}"
286+
name = "$${primary_virtual_network_gateway_vpn_name}"
287+
sku = "$${starter_location_01_virtual_network_gateway_sku_vpn}"
288+
ip_configurations = {
289+
active_active_1 = {
290+
public_ip = {
291+
name = "$${primary_virtual_network_gateway_vpn_public_ip_name_1}"
292+
zones = "$${starter_location_01_availability_zones}"
293+
}
294+
}
295+
active_active_2 = {
296+
public_ip = {
297+
name = "$${primary_virtual_network_gateway_vpn_public_ip_name_2}"
298+
zones = "$${starter_location_01_availability_zones}"
299+
}
300+
}
301+
}
302+
}
303+
}
304+
private_dns_zones = {
305+
resource_group_name = "$${dns_resource_group_name}"
306+
is_primary = true
307+
auto_registration_zone_enabled = true
308+
auto_registration_zone_name = "$${primary_auto_registration_zone_name}.azure.local"
309+
subnet_address_prefix = "$${primary_private_dns_resolver_subnet_address_prefix}"
310+
private_dns_resolver = {
311+
name = "$${primary_private_dns_resolver_name}"
312+
}
313+
}
314+
bastion = {
315+
subnet_address_prefix = "$${primary_bastion_subnet_address_prefix}"
316+
bastion_host = {
317+
name = "$${primary_bastion_host_name}"
318+
}
319+
bastion_public_ip = {
320+
name = "$${primary_bastion_host_public_ip_name}"
321+
zones = "$${starter_location_01_availability_zones}"
322+
}
323+
}
324+
}
325+
}

0 commit comments

Comments
 (0)