Add VWAN deployment capability (#287)
* Add VWAN capabilities to upstream branch (#250) * Initial MVP for virtual wan and hub resources * Update resource dependencies * Refactor to create dedicated resources for vwan * Refactor to simplify for management resources * Replace `try()` with `lookup()` * Update custom settings for Virtual WAN * Add DNS links for spokes connected to Virtual Hubs * Add virtual hub connections * Fix incorrect VPN gateway name (#251) * Fix incorrect VPN gateway name * Refactor test framework for VWAN additions (#265) * Refactor test deployments * Update minimum supported provider version * Fix linting error * Update root_name * Update unit test pipeline * Fix certificate path error * Rename job display names * Update e2e test pipeline * Update location variable * Remove unused TF_PLAN_OUT variable * Update parallelism environment variable * Update path for terraform destroy * Increase job timeouts for e2e * Update OPA value generator for pwsh * Add `planned_values.json` for each test case * Remove trailing whitespace * Update OPA tests script for new framework * Add OPA tasks to Unit Tests job * Remove `.sh` script (to be unified with `.ps1` version) * Refactor OPA installation scripts * Update execution bit * Update task names * Add readme to test framework * Add VWAN config to connectivity settings * Remove unsupported tags object from config * Update minimum supported version to fix #271 * Fix #271 error deleting firewall * Updates to fix #272 * Fix formatting error on fix for #273 * Fix to prevent lock file versions error * Update rego files to reflect changes for #272 * Updated for latest test framework plans * Update conftest baseline * Add opt-out for `terraform destroy` * Update for remote backend configuration * Update dependsOn for test jobs * Update execution bit on script file * Output variables to pipeline * Update auth config for backend * Update backend config for SPN auth * Update comment * Move random `root_id` generation to strategy job * Add SPN credentials to backend configuration * Do not try to overwrite readonly variable * Rename function for linting error * Remove `use_microsoft_graph` due to error * Add `az logout` step * Troubleshoot `terraform init` error * Map dependent variables * Add `az cli` login to init step * Troubleshoot auth issue for `terraform init` * Add `ARM_CLIENT_SECRET` to `terraform init` steps * Add dependent variables to e2e test jobs * Split e2e tests into multiple jobs * Update condition in test loop * Rename jobs * Update timeout on clean-up * Update condition format * Update dependencies * Update conditions * Update conditions * Update timeout and conditions for e2e tests * Rename tasks * Update logic for `terraform destroy` * Update logic for `terraform destroy` * Update condition * Rename e2e clean-up job
This commit is contained in:
Родитель
72ad2a3dbe
Коммит
739a3f9053
6
Makefile
6
Makefile
|
@ -8,6 +8,10 @@ azp-strategy:
|
|||
@echo "==> Running script..."
|
||||
./tests/scripts/azp-strategy.ps1
|
||||
|
||||
azp-backend:
|
||||
@echo "==> Running script..."
|
||||
./tests/scripts/azp-backend.sh
|
||||
|
||||
azp-spn-generator:
|
||||
@echo "==> Running script..."
|
||||
./tests/scripts/azp-spn-generator.sh
|
||||
|
@ -46,7 +50,7 @@ tf-destroy:
|
|||
|
||||
opa-install:
|
||||
@echo "==> Running script..."
|
||||
./tests/scripts/opa-install.sh
|
||||
./tests/scripts/opa-install-linux.sh
|
||||
|
||||
opa-run-tests:
|
||||
@echo "==> Running script..."
|
||||
|
|
|
@ -109,7 +109,7 @@ Please refer to the [Deploy Identity Resources][wiki_deploy_identity_resources]
|
|||
|
||||
## Terraform versions
|
||||
|
||||
This module has been tested using Terraform `0.15.0` and AzureRM Provider `2.77.0` as a baseline, and various versions to up the most recent at the time of release.
|
||||
This module has been tested using Terraform `0.15.0` and AzureRM Provider `2.96.0` as a baseline, and various versions to up the most recent at the time of release.
|
||||
In some cases, individual versions of the AzureRM provider may cause errors.
|
||||
If this happens, we advise upgrading to the latest version and checking our [troubleshooting][wiki_troubleshooting] guide before [raising an issue](https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/issues).
|
||||
|
||||
|
@ -132,7 +132,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Before getting started with this module, please take note of the following considerations:
|
||||
|
||||
1. This module requires a minimum `azurerm` provider version of `2.77.0`.
|
||||
1. This module requires a minimum `azurerm` provider version of `2.96.0`.
|
||||
|
||||
1. This module requires a minimum Terraform version `0.15.0`.
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
configuration_aliases = [
|
||||
azurerm.connectivity,
|
||||
azurerm.management,
|
||||
|
|
|
@ -1,174 +1,110 @@
|
|||
# The following locals are used to extract the Resource Group
|
||||
# configuration from the solution module outputs.
|
||||
locals {
|
||||
es_connectivity_resource_groups = module.connectivity_resources.configuration.azurerm_resource_group
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Resource
|
||||
# Groups to deploy.
|
||||
locals {
|
||||
azurerm_resource_group_connectivity = {
|
||||
for resource in local.es_connectivity_resource_groups :
|
||||
for resource in module.connectivity_resources.configuration.azurerm_resource_group :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
if resource.managed_by_module &&
|
||||
contains(["connectivity", "ddos", "dns"], resource.scope)
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Virtual Network
|
||||
# configuration from the solution module outputs.
|
||||
locals {
|
||||
es_connectivity_virtual_network = module.connectivity_resources.configuration.azurerm_virtual_network
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Virtual
|
||||
# Networks to deploy.
|
||||
locals {
|
||||
azurerm_virtual_network_connectivity = {
|
||||
for resource in local.es_connectivity_virtual_network :
|
||||
for resource in module.connectivity_resources.configuration.azurerm_virtual_network :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Subnets
|
||||
# configuration from the solution module outputs.
|
||||
locals {
|
||||
es_connectivity_subnet = module.connectivity_resources.configuration.azurerm_subnet
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Subnets
|
||||
# to deploy.
|
||||
locals {
|
||||
azurerm_subnet_connectivity = {
|
||||
for resource in local.es_connectivity_subnet :
|
||||
for resource in module.connectivity_resources.configuration.azurerm_subnet :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Virtual Network
|
||||
# Gateway configuration from the solution module outputs.
|
||||
locals {
|
||||
es_connectivity_virtual_network_gateway = module.connectivity_resources.configuration.azurerm_virtual_network_gateway
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Virtual
|
||||
# Network Gateways to deploy.
|
||||
locals {
|
||||
azurerm_virtual_network_gateway_connectivity = {
|
||||
for resource in local.es_connectivity_virtual_network_gateway :
|
||||
for resource in module.connectivity_resources.configuration.azurerm_virtual_network_gateway :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Public IP
|
||||
# configuration from the solution module outputs.
|
||||
locals {
|
||||
es_connectivity_public_ip = module.connectivity_resources.configuration.azurerm_public_ip
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Public
|
||||
# IPs to deploy.
|
||||
locals {
|
||||
azurerm_public_ip_connectivity = {
|
||||
for resource in local.es_connectivity_public_ip :
|
||||
for resource in module.connectivity_resources.configuration.azurerm_public_ip :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Azure Firewall
|
||||
# configuration from the solution module outputs.
|
||||
locals {
|
||||
es_connectivity_firewall = module.connectivity_resources.configuration.azurerm_firewall
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Azure
|
||||
# Firewalls to deploy.
|
||||
locals {
|
||||
azurerm_firewall_connectivity = {
|
||||
for resource in local.es_connectivity_firewall :
|
||||
for resource in module.connectivity_resources.configuration.azurerm_firewall :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
if resource.managed_by_module &&
|
||||
resource.scope == "connectivity"
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the DDoS Protection
|
||||
# Plan configuration from the solution module outputs.
|
||||
locals {
|
||||
es_connectivity_network_ddos_protection_plan = module.connectivity_resources.configuration.azurerm_network_ddos_protection_plan
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of DDoS
|
||||
# Protection Plans to deploy.
|
||||
locals {
|
||||
azurerm_network_ddos_protection_plan_connectivity = {
|
||||
for resource in local.es_connectivity_network_ddos_protection_plan :
|
||||
for resource in module.connectivity_resources.configuration.azurerm_network_ddos_protection_plan :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Private DNS Zone
|
||||
# configuration from the solution module outputs.
|
||||
locals {
|
||||
es_connectivity_private_dns_zone = module.connectivity_resources.configuration.azurerm_private_dns_zone
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Private DNS
|
||||
# Zones to deploy.
|
||||
locals {
|
||||
azurerm_private_dns_zone_connectivity = {
|
||||
for resource in local.es_connectivity_private_dns_zone :
|
||||
for resource in module.connectivity_resources.configuration.azurerm_private_dns_zone :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Public DNS Zone
|
||||
# configuration from the solution module outputs.
|
||||
locals {
|
||||
es_connectivity_dns_zone = module.connectivity_resources.configuration.azurerm_dns_zone
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Public DNS
|
||||
# Zones to deploy.
|
||||
locals {
|
||||
azurerm_dns_zone_connectivity = {
|
||||
for resource in local.es_connectivity_dns_zone :
|
||||
for resource in module.connectivity_resources.configuration.azurerm_dns_zone :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Private DNS Zone
|
||||
# Virtual Network Links configuration from the solution module outputs.
|
||||
locals {
|
||||
es_connectivity_private_dns_zone_virtual_network_link = module.connectivity_resources.configuration.azurerm_private_dns_zone_virtual_network_link
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Private DNS Zone
|
||||
# Virtual Network Links to deploy.
|
||||
locals {
|
||||
azurerm_private_dns_zone_virtual_network_link_connectivity = {
|
||||
for resource in local.es_connectivity_private_dns_zone_virtual_network_link :
|
||||
for resource in module.connectivity_resources.configuration.azurerm_private_dns_zone_virtual_network_link :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Virtual Network
|
||||
# Peering configuration from the solution module outputs.
|
||||
locals {
|
||||
es_connectivity_virtual_network_peering = module.connectivity_resources.configuration.azurerm_virtual_network_peering
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Virtual
|
||||
# Network Peerings to deploy.
|
||||
locals {
|
||||
azurerm_virtual_network_peering_connectivity = {
|
||||
for resource in local.es_connectivity_virtual_network_peering :
|
||||
for resource in module.connectivity_resources.configuration.azurerm_virtual_network_peering :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
|
|
|
@ -1,78 +1,48 @@
|
|||
# The following locals are used to extract the Resource Group
|
||||
# configuration from the solution module outputs.
|
||||
locals {
|
||||
es_management_resource_groups = module.management_resources.configuration.azurerm_resource_group
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Resource
|
||||
# Groups to deploy.
|
||||
locals {
|
||||
azurerm_resource_group_management = {
|
||||
for resource in local.es_management_resource_groups :
|
||||
for resource in module.management_resources.configuration.azurerm_resource_group :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Log Analytics
|
||||
# configuration from the solution module outputs.
|
||||
locals {
|
||||
es_management_log_analytics_workspaces = module.management_resources.configuration.azurerm_log_analytics_workspace
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Log
|
||||
# Analytics workspaces to deploy.
|
||||
locals {
|
||||
azurerm_log_analytics_workspace_management = {
|
||||
for resource in local.es_management_log_analytics_workspaces :
|
||||
for resource in module.management_resources.configuration.azurerm_log_analytics_workspace :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Log Analytics
|
||||
# Solutions configuration from the solution module outputs.
|
||||
locals {
|
||||
es_management_log_analytics_solution = module.management_resources.configuration.azurerm_log_analytics_solution
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Log
|
||||
# Analytics workspaces to deploy.
|
||||
locals {
|
||||
azurerm_log_analytics_solution_management = {
|
||||
for resource in local.es_management_log_analytics_solution :
|
||||
for resource in module.management_resources.configuration.azurerm_log_analytics_solution :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Automation
|
||||
# Account configuration from the solution module outputs.
|
||||
locals {
|
||||
es_management_automation_account = module.management_resources.configuration.azurerm_automation_account
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Log
|
||||
# Analytics workspaces to deploy.
|
||||
locals {
|
||||
azurerm_automation_account_management = {
|
||||
for resource in local.es_management_automation_account :
|
||||
for resource in module.management_resources.configuration.azurerm_automation_account :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to extract the Log Analytics
|
||||
# Linked Service configuration from the solution module outputs.
|
||||
locals {
|
||||
es_management_log_analytics_linked_service = module.management_resources.configuration.azurerm_log_analytics_linked_service
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Log
|
||||
# Analytics workspaces to deploy.
|
||||
locals {
|
||||
azurerm_log_analytics_linked_service_management = {
|
||||
for resource in local.es_management_log_analytics_linked_service :
|
||||
for resource in module.management_resources.configuration.azurerm_log_analytics_linked_service :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
|
|
|
@ -85,8 +85,8 @@ locals {
|
|||
azurerm_policy_set_definition_external_lookup = {
|
||||
for policy_set_definition_id in keys(transpose(local.policy_assignments_with_managed_identity_using_external_policy_set_definition)) :
|
||||
policy_set_definition_id => {
|
||||
name = basename(policy_set_definition_id)
|
||||
management_group_name = regex(local.regex_split_resource_id, policy_set_definition_id)[0] == "/providers/Microsoft.Management/managementGroups/" ? regex(local.regex_split_resource_id, policy_set_definition_id)[1] : null
|
||||
name = basename(policy_set_definition_id)
|
||||
management_group_id = regex(local.regex_split_resource_id, policy_set_definition_id)[0] == "/providers/Microsoft.Management/managementGroups/" ? regex(local.regex_split_resource_id, policy_set_definition_id)[1] : null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ data "azurerm_policy_set_definition" "external_lookup" {
|
|||
for_each = local.azurerm_policy_set_definition_external_lookup
|
||||
|
||||
name = each.value.name
|
||||
management_group_name = each.value.management_group_name
|
||||
management_group_name = each.value.management_group_id
|
||||
}
|
||||
|
||||
# Create a list of Policy Definitions IDs used by all assigned Policy Set Definitions
|
||||
|
@ -134,16 +134,16 @@ locals {
|
|||
external_policy_definitions_from_azurerm_policy_set_definition_external_lookup = {
|
||||
for policy_definition_id in local.external_policy_definition_ids_from_policy_set_definitions :
|
||||
policy_definition_id => {
|
||||
name = basename(policy_definition_id)
|
||||
management_group_name = regex(local.regex_split_resource_id, policy_definition_id)[0] == "/providers/Microsoft.Management/managementGroups/" ? regex(local.regex_split_resource_id, policy_definition_id)[1] : null
|
||||
name = basename(policy_definition_id)
|
||||
management_group_id = regex(local.regex_split_resource_id, policy_definition_id)[0] == "/providers/Microsoft.Management/managementGroups/" ? regex(local.regex_split_resource_id, policy_definition_id)[1] : null
|
||||
}
|
||||
}
|
||||
# From Policy Assignments using Policy Definitions
|
||||
external_policy_definitions_from_internal_policy_assignments = {
|
||||
for policy_definition_id in keys(transpose(local.policy_assignments_with_managed_identity_using_external_policy_definition)) :
|
||||
policy_definition_id => {
|
||||
name = basename(policy_definition_id)
|
||||
management_group_name = regex(local.regex_split_resource_id, policy_definition_id)[0] == "/providers/Microsoft.Management/managementGroups/" ? regex(local.regex_split_resource_id, policy_definition_id)[1] : null
|
||||
name = basename(policy_definition_id)
|
||||
management_group_id = regex(local.regex_split_resource_id, policy_definition_id)[0] == "/providers/Microsoft.Management/managementGroups/" ? regex(local.regex_split_resource_id, policy_definition_id)[1] : null
|
||||
}
|
||||
}
|
||||
# Then create a single list containing all Policy Definitions to lookup from Azure
|
||||
|
@ -158,7 +158,7 @@ data "azurerm_policy_definition" "external_lookup" {
|
|||
for_each = local.azurerm_policy_definition_external_lookup
|
||||
|
||||
name = each.value.name
|
||||
management_group_name = each.value.management_group_name
|
||||
management_group_name = each.value.management_group_id
|
||||
}
|
||||
|
||||
# Extract the Role Definition IDs from the internal and external
|
||||
|
|
35
locals.tf
35
locals.tf
|
@ -42,6 +42,17 @@ locals {
|
|||
disable_base_module_tags = var.disable_base_module_tags
|
||||
}
|
||||
|
||||
# The following locals are used to ensure non-null values
|
||||
# are assigned to each of the corresponding inputs for
|
||||
# correct processing in `lookup()` functions
|
||||
locals {
|
||||
enforcement_mode_default = {
|
||||
enforcement_mode = null
|
||||
}
|
||||
connectivity_resources_advanced = coalesce(local.configure_connectivity_resources.advanced, local.empty_map)
|
||||
management_resources_advanced = coalesce(local.configure_management_resources.advanced, local.empty_map)
|
||||
}
|
||||
|
||||
# The following locals are used to define a set of module
|
||||
# tags applied to all resources unless disabled by the
|
||||
# input variable "disable_module_tags" and prepare the
|
||||
|
@ -109,19 +120,19 @@ locals {
|
|||
default_create_duration_delay = "30s"
|
||||
default_destroy_duration_delay = "0s"
|
||||
create_duration_delay = {
|
||||
after_azurerm_management_group = try(var.create_duration_delay["azurerm_management_group"], local.default_create_duration_delay)
|
||||
after_azurerm_policy_assignment = try(var.create_duration_delay["azurerm_policy_assignment"], local.default_create_duration_delay)
|
||||
after_azurerm_policy_definition = try(var.create_duration_delay["azurerm_policy_definition"], local.default_create_duration_delay)
|
||||
after_azurerm_policy_set_definition = try(var.create_duration_delay["azurerm_policy_set_definition"], local.default_create_duration_delay)
|
||||
after_azurerm_role_assignment = try(var.create_duration_delay["azurerm_role_assignment"], local.default_create_duration_delay)
|
||||
after_azurerm_role_definition = try(var.create_duration_delay["azurerm_role_definition"], local.default_create_duration_delay)
|
||||
after_azurerm_management_group = lookup(var.create_duration_delay, "azurerm_management_group", local.default_create_duration_delay)
|
||||
after_azurerm_policy_assignment = lookup(var.create_duration_delay, "azurerm_policy_assignment", local.default_create_duration_delay)
|
||||
after_azurerm_policy_definition = lookup(var.create_duration_delay, "azurerm_policy_definition", local.default_create_duration_delay)
|
||||
after_azurerm_policy_set_definition = lookup(var.create_duration_delay, "azurerm_policy_set_definition", local.default_create_duration_delay)
|
||||
after_azurerm_role_assignment = lookup(var.create_duration_delay, "azurerm_role_assignment", local.default_create_duration_delay)
|
||||
after_azurerm_role_definition = lookup(var.create_duration_delay, "azurerm_role_definition", local.default_create_duration_delay)
|
||||
}
|
||||
destroy_duration_delay = {
|
||||
after_azurerm_management_group = try(var.destroy_duration_delay["azurerm_management_group"], local.default_destroy_duration_delay)
|
||||
after_azurerm_policy_assignment = try(var.destroy_duration_delay["azurerm_policy_assignment"], local.default_destroy_duration_delay)
|
||||
after_azurerm_policy_definition = try(var.destroy_duration_delay["azurerm_policy_definition"], local.default_destroy_duration_delay)
|
||||
after_azurerm_policy_set_definition = try(var.destroy_duration_delay["azurerm_policy_set_definition"], local.default_destroy_duration_delay)
|
||||
after_azurerm_role_assignment = try(var.destroy_duration_delay["azurerm_role_assignment"], local.default_destroy_duration_delay)
|
||||
after_azurerm_role_definition = try(var.destroy_duration_delay["azurerm_role_definition"], local.default_destroy_duration_delay)
|
||||
after_azurerm_management_group = lookup(var.destroy_duration_delay, "azurerm_management_group", local.default_destroy_duration_delay)
|
||||
after_azurerm_policy_assignment = lookup(var.destroy_duration_delay, "azurerm_policy_assignment", local.default_destroy_duration_delay)
|
||||
after_azurerm_policy_definition = lookup(var.destroy_duration_delay, "azurerm_policy_definition", local.default_destroy_duration_delay)
|
||||
after_azurerm_policy_set_definition = lookup(var.destroy_duration_delay, "azurerm_policy_set_definition", local.default_destroy_duration_delay)
|
||||
after_azurerm_role_assignment = lookup(var.destroy_duration_delay, "azurerm_role_assignment", local.default_destroy_duration_delay)
|
||||
after_azurerm_role_definition = lookup(var.destroy_duration_delay, "azurerm_role_definition", local.default_destroy_duration_delay)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
# The following locals are used to build the map of Resource
|
||||
# Groups to deploy.
|
||||
locals {
|
||||
azurerm_resource_group_virtual_wan = {
|
||||
for resource in module.connectivity_resources.configuration.azurerm_resource_group :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module &&
|
||||
resource.scope == "virtual_wan"
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Azure
|
||||
# Virtual WANs to deploy.
|
||||
locals {
|
||||
azurerm_virtual_wan_virtual_wan = {
|
||||
for resource in module.connectivity_resources.configuration.azurerm_virtual_wan :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Azure
|
||||
# Virtual Hubs to deploy.
|
||||
locals {
|
||||
azurerm_virtual_hub_virtual_wan = {
|
||||
for resource in module.connectivity_resources.configuration.azurerm_virtual_hub :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Azure
|
||||
# Expressroute Gateways to deploy.
|
||||
locals {
|
||||
azurerm_express_route_gateway_virtual_wan = {
|
||||
for resource in module.connectivity_resources.configuration.azurerm_express_route_gateway :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Azure
|
||||
# VPN Gateways to deploy.
|
||||
locals {
|
||||
azurerm_vpn_gateway_virtual_wan = {
|
||||
for resource in module.connectivity_resources.configuration.azurerm_vpn_gateway :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Azure
|
||||
# Firewalls to deploy.
|
||||
locals {
|
||||
azurerm_firewall_virtual_wan = {
|
||||
for resource in module.connectivity_resources.configuration.azurerm_firewall :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module &&
|
||||
resource.scope == "virtual_wan"
|
||||
}
|
||||
}
|
||||
|
||||
# The following locals are used to build the map of Virtual
|
||||
# Network Peerings to deploy.
|
||||
locals {
|
||||
azurerm_virtual_hub_connection = {
|
||||
for resource in module.connectivity_resources.configuration.azurerm_virtual_hub_connection :
|
||||
resource.resource_id => resource
|
||||
if resource.managed_by_module
|
||||
}
|
||||
}
|
30
main.tf
30
main.tf
|
@ -17,9 +17,9 @@ module "management_group_archetypes" {
|
|||
template_file_variables = local.template_file_variables
|
||||
default_location = local.default_location
|
||||
enforcement_mode = merge(
|
||||
try(module.connectivity_resources.configuration.archetype_config_overrides[basename(each.key)].enforcement_mode, null),
|
||||
try(module.identity_resources.configuration.archetype_config_overrides[basename(each.key)].enforcement_mode, null),
|
||||
try(module.management_resources.configuration.archetype_config_overrides[basename(each.key)].enforcement_mode, null),
|
||||
lookup(module.connectivity_resources.configuration.archetype_config_overrides, basename(each.key), local.enforcement_mode_default).enforcement_mode,
|
||||
lookup(module.identity_resources.configuration.archetype_config_overrides, basename(each.key), local.enforcement_mode_default).enforcement_mode,
|
||||
lookup(module.management_resources.configuration.archetype_config_overrides, basename(each.key), local.enforcement_mode_default).enforcement_mode,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -40,13 +40,13 @@ module "management_resources" {
|
|||
tags = local.management_resources_tags
|
||||
|
||||
# Optional input variables (advanced configuration)
|
||||
resource_prefix = try(local.configure_management_resources.advanced.resource_prefix, local.empty_string)
|
||||
resource_suffix = try(local.configure_management_resources.advanced.resource_suffix, local.empty_string)
|
||||
existing_resource_group_name = try(local.configure_management_resources.advanced.existing_resource_group_name, local.empty_string)
|
||||
existing_log_analytics_workspace_resource_id = try(local.configure_management_resources.advanced.existing_log_analytics_workspace_resource_id, local.empty_string)
|
||||
existing_automation_account_resource_id = try(local.configure_management_resources.advanced.existing_automation_account_resource_id, local.empty_string)
|
||||
link_log_analytics_to_automation_account = try(local.configure_management_resources.advanced.link_log_analytics_to_automation_account, true)
|
||||
custom_settings_by_resource_type = try(local.configure_management_resources.advanced.custom_settings_by_resource_type, local.empty_map)
|
||||
resource_prefix = lookup(local.management_resources_advanced, "resource_prefix", local.empty_string)
|
||||
resource_suffix = lookup(local.management_resources_advanced, "resource_suffix", local.empty_string)
|
||||
existing_resource_group_name = lookup(local.management_resources_advanced, "existing_resource_group_name", local.empty_string)
|
||||
existing_log_analytics_workspace_resource_id = lookup(local.management_resources_advanced, "existing_log_analytics_workspace_resource_id", local.empty_string)
|
||||
existing_automation_account_resource_id = lookup(local.management_resources_advanced, "existing_automation_account_resource_id", local.empty_string)
|
||||
link_log_analytics_to_automation_account = lookup(local.management_resources_advanced, "link_log_analytics_to_automation_account", true)
|
||||
custom_settings_by_resource_type = lookup(local.management_resources_advanced, "custom_settings_by_resource_type", local.empty_map)
|
||||
}
|
||||
|
||||
# The following module is used to generate the configuration
|
||||
|
@ -78,8 +78,10 @@ module "connectivity_resources" {
|
|||
tags = local.connectivity_resources_tags
|
||||
|
||||
# Optional input variables (advanced configuration)
|
||||
resource_prefix = try(local.configure_connectivity_resources.advanced.resource_prefix, local.empty_string)
|
||||
resource_suffix = try(local.configure_connectivity_resources.advanced.resource_suffix, local.empty_string)
|
||||
existing_ddos_protection_plan_resource_id = try(local.configure_connectivity_resources.advanced.existing_resource_group_name, local.empty_string)
|
||||
custom_settings_by_resource_type = try(local.configure_connectivity_resources.advanced.custom_settings_by_resource_type, local.empty_map)
|
||||
resource_prefix = lookup(local.connectivity_resources_advanced, "resource_prefix", null)
|
||||
resource_suffix = lookup(local.connectivity_resources_advanced, "resource_suffix", null)
|
||||
existing_ddos_protection_plan_resource_id = lookup(local.connectivity_resources_advanced, "existing_ddos_protection_plan_resource_id", null)
|
||||
existing_virtual_wan_resource_id = lookup(local.connectivity_resources_advanced, "existing_virtual_wan_resource_id", null)
|
||||
resource_group_per_virtual_hub_location = lookup(local.connectivity_resources_advanced, "resource_group_per_virtual_hub_location", false)
|
||||
custom_settings_by_resource_type = lookup(local.connectivity_resources_advanced, "custom_settings_by_resource_type", null)
|
||||
}
|
||||
|
|
|
@ -19,8 +19,10 @@ locals {
|
|||
location = var.location
|
||||
tags = var.tags
|
||||
resource_prefix = coalesce(var.resource_prefix, local.root_id)
|
||||
resource_suffix = length(var.resource_suffix) > 0 ? "-${var.resource_suffix}" : local.empty_string
|
||||
resource_suffix = var.resource_suffix != null ? "-${var.resource_suffix}" : local.empty_string
|
||||
existing_ddos_protection_plan_resource_id = var.existing_ddos_protection_plan_resource_id
|
||||
existing_virtual_wan_resource_id = var.existing_virtual_wan_resource_id != null ? var.existing_virtual_wan_resource_id : local.empty_string
|
||||
resource_group_per_virtual_hub_location = var.resource_group_per_virtual_hub_location
|
||||
custom_settings = var.custom_settings_by_resource_type
|
||||
}
|
||||
|
||||
|
@ -36,22 +38,91 @@ locals {
|
|||
coalesce(hub_network.config.location, local.location) => hub_network
|
||||
}
|
||||
hub_network_locations = keys(local.hub_networks_by_location)
|
||||
ddos_location = coalesce(local.settings.ddos_protection_plan.config.location, local.location)
|
||||
dns_location = coalesce(local.settings.dns.config.location, local.location)
|
||||
virtual_hubs = local.settings.vwan_hub_networks
|
||||
# We generate the virtual_hubs_by_location as a map
|
||||
# to ensure the user has provided unique values for
|
||||
# each hub location. If duplicates are found,
|
||||
# terraform will throw an error at this point.
|
||||
# By default we recommend creating all Virtual WAN
|
||||
# resources in a single Resource Group as per:
|
||||
# https://docs.microsoft.com/en-us/azure/virtual-wan/virtual-wan-faq#can-hubs-be-created-in-different-resource-group-in-virtual-wan
|
||||
# As this is only an issue for customers using the
|
||||
# Portal to manage Virtual WAN resources, the following
|
||||
# logic is used to allow a customer to use dedicated Resource
|
||||
# Groups per location if preferred.
|
||||
virtual_hubs_by_location = {
|
||||
for virtual_hub in local.virtual_hubs :
|
||||
coalesce(virtual_hub.config.location, local.location) => virtual_hub
|
||||
}
|
||||
virtual_hubs_by_location_for_resource_group_per_location = {
|
||||
for virtual_hub in local.virtual_hubs :
|
||||
coalesce(virtual_hub.config.location, local.location) => virtual_hub
|
||||
if local.resource_group_per_virtual_hub_location
|
||||
}
|
||||
virtual_hubs_by_location_for_shared_resource_group = {
|
||||
for virtual_hub in local.virtual_hubs :
|
||||
coalesce(virtual_hub.config.location, local.location) => virtual_hub
|
||||
if !local.resource_group_per_virtual_hub_location
|
||||
}
|
||||
# The following objects are used to identify azurerm_virtual_hub
|
||||
# resources which need to be associated with a new or existing
|
||||
# azurerm_virtual_wan resource
|
||||
virtual_hubs_by_location_for_managed_virtual_wan = {
|
||||
for virtual_hub in local.virtual_hubs :
|
||||
coalesce(virtual_hub.config.location, local.location) => virtual_hub
|
||||
if local.existing_virtual_wan_resource_id == ""
|
||||
}
|
||||
virtual_hubs_by_location_for_existing_virtual_wan = {
|
||||
for virtual_hub in local.virtual_hubs :
|
||||
coalesce(virtual_hub.config.location, local.location) => virtual_hub
|
||||
if local.existing_virtual_wan_resource_id != ""
|
||||
}
|
||||
# Need to know the full list of virtual_hub_locations
|
||||
# for azurerm_virtual_hub resource deployments.
|
||||
virtual_hub_locations = keys(local.virtual_hubs_by_location)
|
||||
# The azurerm_virtual_wan resource will be created in the
|
||||
# default location of the connectivity module if a new.
|
||||
virtual_wan_locations = anytrue(
|
||||
[
|
||||
length(local.virtual_hubs_by_location_for_managed_virtual_wan) > 0,
|
||||
length(local.virtual_hubs_by_location_for_shared_resource_group) > 0,
|
||||
]
|
||||
) ? [local.location, ] : local.empty_list
|
||||
ddos_location = coalesce(local.settings.ddos_protection_plan.config.location, local.location)
|
||||
dns_location = coalesce(local.settings.dns.config.location, local.location)
|
||||
connectivity_locations = distinct(concat(
|
||||
local.hub_network_locations,
|
||||
keys(local.virtual_hubs_by_location_for_resource_group_per_location),
|
||||
))
|
||||
result_when_location_missing = {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Logic to determine whether specific resources
|
||||
# should be created by this module
|
||||
# - Resource Groups
|
||||
locals {
|
||||
deploy_ddos_protection_plan = local.enabled && local.settings.ddos_protection_plan.enabled
|
||||
deploy_dns = local.enabled && local.settings.dns.enabled
|
||||
deploy_resource_groups = {
|
||||
connectivity = {
|
||||
for location, hub_network in local.hub_networks_by_location :
|
||||
for location in local.connectivity_locations :
|
||||
location =>
|
||||
local.enabled &&
|
||||
hub_network.enabled
|
||||
anytrue(
|
||||
[
|
||||
lookup(local.hub_networks_by_location, location, local.result_when_location_missing).enabled,
|
||||
lookup(local.virtual_hubs_by_location_for_resource_group_per_location, location, local.result_when_location_missing).enabled,
|
||||
]
|
||||
)
|
||||
}
|
||||
virtual_wan = {
|
||||
for location in local.virtual_wan_locations :
|
||||
location =>
|
||||
local.enabled &&
|
||||
anytrue(concat(
|
||||
values(local.virtual_hubs_by_location_for_managed_virtual_wan).*.enabled,
|
||||
values(local.virtual_hubs_by_location_for_shared_resource_group).*.enabled,
|
||||
))
|
||||
}
|
||||
ddos = {
|
||||
(local.ddos_location) = local.deploy_ddos_protection_plan
|
||||
|
@ -60,6 +131,28 @@ locals {
|
|||
(local.dns_location) = local.deploy_dns
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Logic to determine whether specific resources
|
||||
# should be created by this module
|
||||
# - DDoS Protection Plan
|
||||
locals {
|
||||
deploy_ddos_protection_plan = local.enabled && local.settings.ddos_protection_plan.enabled
|
||||
}
|
||||
|
||||
# Logic to determine whether specific resources
|
||||
# should be created by this module
|
||||
# - DNS
|
||||
locals {
|
||||
deploy_dns = local.enabled && local.settings.dns.enabled
|
||||
deploy_private_dns_zone_virtual_network_link_on_hubs = local.deploy_dns && local.settings.dns.config.enable_private_dns_zone_virtual_network_link_on_hubs
|
||||
deploy_private_dns_zone_virtual_network_link_on_spokes = local.deploy_dns && local.settings.dns.config.enable_private_dns_zone_virtual_network_link_on_spokes
|
||||
}
|
||||
|
||||
# Logic to determine whether specific resources
|
||||
# should be created by this module
|
||||
# - Hub networks
|
||||
locals {
|
||||
deploy_hub_network = {
|
||||
for location, hub_network in local.hub_networks_by_location :
|
||||
location =>
|
||||
|
@ -73,7 +166,7 @@ locals {
|
|||
hub_network.config.virtual_network_gateway.enabled &&
|
||||
hub_network.config.virtual_network_gateway.config.address_prefix != local.empty_string
|
||||
}
|
||||
deploy_virtual_network_gateway_expressroute = {
|
||||
deploy_virtual_network_gateway_express_route = {
|
||||
for location, hub_network in local.hub_networks_by_location :
|
||||
location =>
|
||||
local.deploy_virtual_network_gateway[location] &&
|
||||
|
@ -95,10 +188,52 @@ locals {
|
|||
for location, hub_network in local.hub_networks_by_location :
|
||||
location =>
|
||||
local.deploy_dns &&
|
||||
local.deploy_hub_network[location] &&
|
||||
hub_network.config.enable_outbound_virtual_network_peering
|
||||
}
|
||||
deploy_private_dns_zone_virtual_network_link_on_hubs = local.deploy_dns && local.settings.dns.config.enable_private_dns_zone_virtual_network_link_on_hubs
|
||||
deploy_private_dns_zone_virtual_network_link_on_spokes = local.deploy_dns && local.settings.dns.config.enable_private_dns_zone_virtual_network_link_on_spokes
|
||||
}
|
||||
|
||||
# Logic to determine whether specific resources
|
||||
# should be created by this module
|
||||
# - VWAN hub networks
|
||||
locals {
|
||||
deploy_virtual_wan = {
|
||||
(local.location) = (
|
||||
local.enabled &&
|
||||
local.existing_virtual_wan_resource_id == "" &&
|
||||
anytrue(values(local.deploy_virtual_hub))
|
||||
)
|
||||
}
|
||||
deploy_virtual_hub = {
|
||||
for location, virtual_hub in local.virtual_hubs_by_location :
|
||||
location =>
|
||||
local.enabled &&
|
||||
virtual_hub.enabled
|
||||
}
|
||||
deploy_virtual_hub_express_route_gateway = {
|
||||
for location, virtual_hub in local.virtual_hubs_by_location :
|
||||
location =>
|
||||
local.deploy_virtual_hub[location] &&
|
||||
virtual_hub.config.expressroute_gateway.enabled
|
||||
}
|
||||
deploy_virtual_hub_vpn_gateway = {
|
||||
for location, virtual_hub in local.virtual_hubs_by_location :
|
||||
location =>
|
||||
local.deploy_virtual_hub[location] &&
|
||||
virtual_hub.config.vpn_gateway.enabled
|
||||
}
|
||||
deploy_virtual_hub_azure_firewall = {
|
||||
for location, virtual_hub in local.virtual_hubs_by_location :
|
||||
location =>
|
||||
local.deploy_virtual_hub[location] &&
|
||||
virtual_hub.config.azure_firewall.enabled
|
||||
}
|
||||
deploy_virtual_hub_connection = {
|
||||
for location, virtual_hub in local.virtual_hubs_by_location :
|
||||
location =>
|
||||
local.deploy_virtual_hub[location] &&
|
||||
virtual_hub.config.enable_virtual_hub_connections
|
||||
}
|
||||
}
|
||||
|
||||
# Configuration settings for resource type:
|
||||
|
@ -107,11 +242,17 @@ locals {
|
|||
# Determine the name of each Resource Group per scope and location
|
||||
resource_group_names_by_scope_and_location = {
|
||||
connectivity = {
|
||||
for location in local.hub_network_locations :
|
||||
for location in local.connectivity_locations :
|
||||
location =>
|
||||
try(local.custom_settings.azurerm_resource_group["connectivity"][location].name,
|
||||
"${local.resource_prefix}-connectivity-${location}${local.resource_suffix}")
|
||||
}
|
||||
virtual_wan = {
|
||||
for location in local.virtual_wan_locations :
|
||||
location =>
|
||||
try(local.custom_settings.azurerm_resource_group["virtual_wan"][location].name,
|
||||
"${local.resource_prefix}-connectivity${local.resource_suffix}")
|
||||
}
|
||||
ddos = {
|
||||
(local.ddos_location) = try(local.custom_settings.azurerm_resource_group["ddos"][local.ddos_location].name,
|
||||
"${local.resource_prefix}-ddos${local.resource_suffix}")
|
||||
|
@ -315,7 +456,7 @@ locals {
|
|||
{
|
||||
# Resource logic attributes
|
||||
resource_id = local.er_gateway_resource_id[location]
|
||||
managed_by_module = local.deploy_virtual_network_gateway_expressroute[location]
|
||||
managed_by_module = local.deploy_virtual_network_gateway_express_route[location]
|
||||
# Resource definition attributes
|
||||
name = local.er_gateway_name[location]
|
||||
resource_group_name = local.resource_group_names_by_scope_and_location["connectivity"][location]
|
||||
|
@ -348,7 +489,7 @@ locals {
|
|||
azurerm_public_ip = {
|
||||
# Resource logic attributes
|
||||
resource_id = "${local.virtual_network_resource_group_id[location]}/providers/Microsoft.Network/publicIPAddresses/${local.er_gateway_name[location]}-pip"
|
||||
managed_by_module = local.deploy_virtual_network_gateway_expressroute[location]
|
||||
managed_by_module = local.deploy_virtual_network_gateway_express_route[location]
|
||||
# Resource definition attributes
|
||||
name = "${local.er_gateway_name[location]}-pip"
|
||||
resource_group_name = local.resource_group_names_by_scope_and_location["connectivity"][location]
|
||||
|
@ -471,21 +612,36 @@ locals {
|
|||
|
||||
# Configuration settings for resource type:
|
||||
# - azurerm_firewall
|
||||
# For VWAN, VPN gateway is required for Security Partner Provider integration
|
||||
locals {
|
||||
azfw_name = {
|
||||
for location in local.hub_network_locations :
|
||||
location => "${local.resource_prefix}-fw-${location}${local.resource_suffix}"
|
||||
}
|
||||
virtual_hub_azfw_name = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location => "${local.resource_prefix}-fw-hub-${location}${local.resource_suffix}"
|
||||
}
|
||||
azfw_resource_id_prefix = {
|
||||
for location in local.hub_network_locations :
|
||||
location =>
|
||||
"${local.virtual_network_resource_group_id[location]}/providers/Microsoft.Network/azureFirewalls"
|
||||
}
|
||||
virtual_hub_azfw_resource_id_prefix = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location =>
|
||||
"${local.virtual_hub_resource_group_id[location]}/providers/Microsoft.Network/azureFirewalls"
|
||||
}
|
||||
azfw_resource_id = {
|
||||
for location in local.hub_network_locations :
|
||||
location =>
|
||||
"${local.azfw_resource_id_prefix[location]}/${local.azfw_name[location]}"
|
||||
}
|
||||
virtual_hub_azfw_resource_id = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location =>
|
||||
"${local.virtual_hub_azfw_resource_id_prefix[location]}/${local.virtual_hub_azfw_name[location]}"
|
||||
}
|
||||
azfw_zones = {
|
||||
for location, hub_network in local.hub_networks_by_location :
|
||||
location =>
|
||||
|
@ -502,59 +658,302 @@ locals {
|
|||
location =>
|
||||
length(local.azfw_zones[location]) > 0
|
||||
}
|
||||
azurerm_firewall = [
|
||||
for location, hub_network in local.hub_networks_by_location :
|
||||
{
|
||||
# Resource logic attributes
|
||||
resource_id = local.azfw_resource_id[location]
|
||||
managed_by_module = local.deploy_azure_firewall[location]
|
||||
# Resource definition attributes
|
||||
name = local.azfw_name[location]
|
||||
resource_group_name = local.resource_group_names_by_scope_and_location["connectivity"][location]
|
||||
location = location
|
||||
ip_configuration = try(
|
||||
local.custom_settings.azurerm_firewall["connectivity"][location].ip_configuration,
|
||||
[
|
||||
azurerm_firewall = concat(
|
||||
[
|
||||
for location, hub_network in local.hub_networks_by_location :
|
||||
{
|
||||
# Resource logic attributes
|
||||
resource_id = local.azfw_resource_id[location]
|
||||
managed_by_module = local.deploy_azure_firewall[location]
|
||||
scope = "connectivity"
|
||||
# Resource definition attributes
|
||||
name = local.azfw_name[location]
|
||||
resource_group_name = local.resource_group_names_by_scope_and_location["connectivity"][location]
|
||||
location = location
|
||||
ip_configuration = try(
|
||||
local.custom_settings.azurerm_firewall["connectivity"][location].ip_configuration,
|
||||
[
|
||||
{
|
||||
name = "${local.azfw_name[location]}-pip"
|
||||
public_ip_address_id = "${local.virtual_network_resource_group_id[location]}/providers/Microsoft.Network/publicIPAddresses/${local.azfw_name[location]}-pip"
|
||||
subnet_id = "${local.virtual_network_resource_id[location]}/subnets/AzureFirewallSubnet"
|
||||
}
|
||||
]
|
||||
)
|
||||
sku_name = "AZFW_VNet"
|
||||
sku_tier = try(local.custom_settings.azurerm_firewall["connectivity"][location].sku_tier, "Standard")
|
||||
firewall_policy_id = try(local.custom_settings.azurerm_firewall["connectivity"][location].firewall_policy_id, null)
|
||||
dns_servers = try(local.custom_settings.azurerm_firewall["connectivity"][location].dns_servers, null)
|
||||
private_ip_ranges = try(local.custom_settings.azurerm_firewall["connectivity"][location].private_ip_ranges, null)
|
||||
management_ip_configuration = try(local.custom_settings.azurerm_firewall["connectivity"][location].management_ip_configuration, local.empty_list)
|
||||
threat_intel_mode = try(local.custom_settings.azurerm_firewall["connectivity"][location].threat_intel_mode, null)
|
||||
virtual_hub = local.empty_list
|
||||
zones = try(local.custom_settings.azurerm_firewall["connectivity"][location].zones, local.azfw_zones[location])
|
||||
tags = try(local.custom_settings.azurerm_firewall["connectivity"][location].tags, local.tags)
|
||||
# Child resource definition attributes
|
||||
azurerm_public_ip = {
|
||||
# Resource logic attributes
|
||||
resource_id = "${local.virtual_network_resource_group_id[location]}/providers/Microsoft.Network/publicIPAddresses/${local.azfw_name[location]}-pip"
|
||||
managed_by_module = local.deploy_azure_firewall[location]
|
||||
# Resource definition attributes
|
||||
name = "${local.azfw_name[location]}-pip"
|
||||
resource_group_name = local.resource_group_names_by_scope_and_location["connectivity"][location]
|
||||
location = location
|
||||
sku = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].sku, "Standard")
|
||||
allocation_method = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].allocation_method, "Static")
|
||||
ip_version = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].ip_version, null)
|
||||
idle_timeout_in_minutes = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].idle_timeout_in_minutes, null)
|
||||
domain_name_label = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].domain_name_label, null)
|
||||
reverse_fqdn = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].reverse_fqdn, null)
|
||||
public_ip_prefix_id = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].public_ip_prefix_id, null)
|
||||
ip_tags = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].ip_tags, null)
|
||||
tags = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].tags, local.tags)
|
||||
availability_zone = try(
|
||||
local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].availability_zone,
|
||||
local.azfw_zones_enabled[location] ? "Zone-Redundant" : "No-Zone"
|
||||
)
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
for location, virtual_hub in local.virtual_hubs_by_location :
|
||||
{
|
||||
# Resource logic attributes
|
||||
resource_id = local.virtual_hub_azfw_resource_id[location]
|
||||
managed_by_module = local.deploy_virtual_hub_azure_firewall[location]
|
||||
scope = "virtual_wan"
|
||||
# Resource definition attributes
|
||||
name = local.virtual_hub_azfw_name[location]
|
||||
resource_group_name = local.virtual_hub_resource_group_name[location]
|
||||
location = location
|
||||
ip_configuration = try(
|
||||
local.custom_settings.azurerm_firewall["virtual_wan"][location].ip_configuration,
|
||||
local.empty_list
|
||||
)
|
||||
sku_name = "AZFW_Hub"
|
||||
sku_tier = try(local.custom_settings.azurerm_firewall["virtual_wan"][location].sku_tier, "Standard")
|
||||
firewall_policy_id = try(local.custom_settings.azurerm_firewall["virtual_wan"][location].firewall_policy_id, null)
|
||||
dns_servers = try(local.custom_settings.azurerm_firewall["virtual_wan"][location].dns_servers, null)
|
||||
private_ip_ranges = try(local.custom_settings.azurerm_firewall["virtual_wan"][location].private_ip_ranges, null)
|
||||
management_ip_configuration = try(local.custom_settings.azurerm_firewall["virtual_wan"][location].management_ip_configuration, local.empty_list)
|
||||
threat_intel_mode = "" # If virtual_hub_settting is specified, the threat_intel_mode has to be explicitly set as "".
|
||||
virtual_hub = [
|
||||
{
|
||||
name = "${local.azfw_name[location]}-pip"
|
||||
public_ip_address_id = "${local.virtual_network_resource_group_id[location]}/providers/Microsoft.Network/publicIPAddresses/${local.azfw_name[location]}-pip"
|
||||
subnet_id = "${local.virtual_network_resource_id[location]}/subnets/AzureFirewallSubnet"
|
||||
virtual_hub_id = local.virtual_hub_resource_id[location]
|
||||
public_ip_count = try(local.custom_settings.azurerm_firewall["virtual_wan"][location].virtual_hub[0].public_ip_count, 1)
|
||||
}
|
||||
]
|
||||
)
|
||||
sku_name = try(local.custom_settings.azurerm_firewall["connectivity"][location].sku_name, "AZFW_VNet")
|
||||
sku_tier = try(local.custom_settings.azurerm_firewall["connectivity"][location].sku_tier, "Standard")
|
||||
firewall_policy_id = try(local.custom_settings.azurerm_firewall["connectivity"][location].firewall_policy_id, null)
|
||||
dns_servers = try(local.custom_settings.azurerm_firewall["connectivity"][location].dns_servers, null)
|
||||
private_ip_ranges = try(local.custom_settings.azurerm_firewall["connectivity"][location].private_ip_ranges, null)
|
||||
management_ip_configuration = try(local.custom_settings.azurerm_firewall["connectivity"][location].management_ip_configuration, local.empty_list)
|
||||
threat_intel_mode = try(local.custom_settings.azurerm_firewall["connectivity"][location].threat_intel_mode, null)
|
||||
virtual_hub = try(local.custom_settings.azurerm_firewall["connectivity"][location].virtual_hub, local.empty_list)
|
||||
zones = try(local.custom_settings.azurerm_firewall["connectivity"][location].zones, local.azfw_zones[location])
|
||||
tags = try(local.custom_settings.azurerm_firewall["connectivity"][location].tags, local.tags)
|
||||
# Child resource definition attributes
|
||||
azurerm_public_ip = {
|
||||
# Resource logic attributes
|
||||
resource_id = "${local.virtual_network_resource_group_id[location]}/providers/Microsoft.Network/publicIPAddresses/${local.azfw_name[location]}-pip"
|
||||
managed_by_module = local.deploy_azure_firewall[location]
|
||||
# Resource definition attributes
|
||||
name = "${local.azfw_name[location]}-pip"
|
||||
resource_group_name = local.resource_group_names_by_scope_and_location["connectivity"][location]
|
||||
location = location
|
||||
sku = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].sku, "Standard")
|
||||
allocation_method = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].allocation_method, "Static")
|
||||
ip_version = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].ip_version, null)
|
||||
idle_timeout_in_minutes = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].idle_timeout_in_minutes, null)
|
||||
domain_name_label = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].domain_name_label, null)
|
||||
reverse_fqdn = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].reverse_fqdn, null)
|
||||
public_ip_prefix_id = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].public_ip_prefix_id, null)
|
||||
ip_tags = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].ip_tags, null)
|
||||
tags = try(local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].tags, local.tags)
|
||||
availability_zone = try(
|
||||
local.custom_settings.azurerm_public_ip["connectivity"]["azfw"][location].availability_zone,
|
||||
local.azfw_zones_enabled[location] ? "Zone-Redundant" : "No-Zone"
|
||||
)
|
||||
zones = try(local.custom_settings.azurerm_firewall["virtual_wan"][location].zones, null)
|
||||
tags = try(local.custom_settings.azurerm_firewall["virtual_wan"][location].tags, local.tags)
|
||||
# Child resource definition attributes
|
||||
azurerm_public_ip = {}
|
||||
}
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
# Configuration settings for resource type:
|
||||
# - azurerm_virtual_wan
|
||||
# We only support creation of a single azurerm_virtual_wan resource
|
||||
# per module deployment. This uses the default location set at the
|
||||
# scope of the connectivity child module.
|
||||
locals {
|
||||
virtual_wan_name = {
|
||||
for location in local.virtual_wan_locations :
|
||||
location =>
|
||||
try(local.custom_settings.azurerm_virtual_wan["virtual_wan"][location].name,
|
||||
"${local.resource_prefix}-vwan-${location}${local.resource_suffix}")
|
||||
}
|
||||
virtual_wan_resource_group_id = {
|
||||
for location in local.virtual_wan_locations :
|
||||
location =>
|
||||
local.resource_group_config_by_scope_and_location["virtual_wan"][location].resource_id
|
||||
}
|
||||
virtual_wan_resource_id_prefix = {
|
||||
for location in local.virtual_wan_locations :
|
||||
location =>
|
||||
"${local.virtual_wan_resource_group_id[location]}/providers/Microsoft.Network/virtualWans"
|
||||
}
|
||||
virtual_wan_resource_id = {
|
||||
for location in local.virtual_wan_locations :
|
||||
location =>
|
||||
"${local.virtual_wan_resource_id_prefix[location]}/${local.virtual_wan_name[location]}"
|
||||
}
|
||||
azurerm_virtual_wan = [
|
||||
for location in local.virtual_wan_locations :
|
||||
{
|
||||
# Resource logic attributes
|
||||
resource_id = local.virtual_wan_resource_id[location]
|
||||
managed_by_module = local.deploy_virtual_wan[location]
|
||||
# Resource definition attributes
|
||||
name = local.virtual_wan_name[location]
|
||||
resource_group_name = local.resource_group_names_by_scope_and_location["virtual_wan"][location]
|
||||
location = location
|
||||
# Optional definition attributes
|
||||
disable_vpn_encryption = try(local.custom_settings.azurerm_virtual_wan["virtual_wan"][location].disable_vpn_encryption, false)
|
||||
allow_branch_to_branch_traffic = try(local.custom_settings.azurerm_virtual_wan["virtual_wan"][location].allow_branch_to_branch_traffic, true)
|
||||
office365_local_breakout_category = try(local.custom_settings.azurerm_virtual_wan["virtual_wan"][location].office365_local_breakout_category, "None")
|
||||
type = try(local.custom_settings.azurerm_virtual_wan["virtual_wan"][location].type, "Standard")
|
||||
tags = try(local.custom_settings.azurerm_virtual_wan["virtual_wan"][location].tags, local.tags)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Configuration settings for resource type:
|
||||
# - azurerm_virtual_hub
|
||||
locals {
|
||||
virtual_hub_name = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location =>
|
||||
try(local.custom_settings.azurerm_virtual_hub["virtual_wan"][location].name,
|
||||
"${local.resource_prefix}-hub-${location}${local.resource_suffix}")
|
||||
}
|
||||
virtual_hub_resource_group_name = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location => (
|
||||
contains(keys(local.virtual_hubs_by_location_for_resource_group_per_location), location) ?
|
||||
local.resource_group_names_by_scope_and_location["connectivity"][location] :
|
||||
local.resource_group_names_by_scope_and_location["virtual_wan"][local.virtual_wan_locations[0]]
|
||||
)
|
||||
}
|
||||
virtual_hub_resource_group_id = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location => (
|
||||
contains(keys(local.virtual_hubs_by_location_for_resource_group_per_location), location) ?
|
||||
local.resource_group_config_by_scope_and_location["connectivity"][location].resource_id :
|
||||
local.resource_group_config_by_scope_and_location["virtual_wan"][local.virtual_wan_locations[0]].resource_id
|
||||
)
|
||||
}
|
||||
virtual_hub_resource_id_prefix = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location =>
|
||||
"${local.virtual_hub_resource_group_id[location]}/providers/Microsoft.Network/virtualHubs"
|
||||
}
|
||||
virtual_hub_resource_id = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location =>
|
||||
"${local.virtual_hub_resource_id_prefix[location]}/${local.virtual_hub_name[location]}"
|
||||
}
|
||||
azurerm_virtual_hub = [
|
||||
for location, virtual_hub in local.virtual_hubs_by_location :
|
||||
{
|
||||
# Resource logic attributes
|
||||
resource_id = local.virtual_hub_resource_id[location]
|
||||
managed_by_module = local.deploy_virtual_hub[location]
|
||||
# Resource definition attributes
|
||||
name = local.virtual_hub_name[location]
|
||||
resource_group_name = local.virtual_hub_resource_group_name[location]
|
||||
location = location
|
||||
# Optional definition attributes
|
||||
sku = coalesce(virtual_hub.config.sku, "Standard")
|
||||
address_prefix = virtual_hub.config.address_prefix
|
||||
virtual_wan_id = length(local.existing_virtual_wan_resource_id) > 0 ? local.existing_virtual_wan_resource_id : (
|
||||
length(local.virtual_wan_locations) > 0 ?
|
||||
lookup(local.virtual_wan_resource_id, local.virtual_wan_locations[0], null) :
|
||||
null
|
||||
)
|
||||
tags = try(local.custom_settings.azurerm_virtual_hub["virtual_wan"][location].tags, local.tags)
|
||||
route = [
|
||||
for route in virtual_hub.config.routes :
|
||||
{
|
||||
address_prefixes = route.address_prefixes
|
||||
next_hop_ip_address = route.next_hop_ip_address
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Configuration settings for resource type:
|
||||
# - azurerm_express_route_gateway
|
||||
locals {
|
||||
virtual_hub_express_route_gateway_name = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location =>
|
||||
try(local.custom_settings.azurerm_express_route_gateway["virtual_wan"][location].name,
|
||||
"${local.resource_prefix}-ergw-${location}${local.resource_suffix}")
|
||||
}
|
||||
virtual_hub_express_route_gateway_resource_id_prefix = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location =>
|
||||
"${local.virtual_hub_resource_group_id[location]}/providers/Microsoft.Network/expressRouteGateways"
|
||||
}
|
||||
virtual_hub_express_route_gateway_resource_id = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location =>
|
||||
"${local.virtual_hub_express_route_gateway_resource_id_prefix[location]}/${local.virtual_hub_express_route_gateway_name[location]}"
|
||||
}
|
||||
azurerm_express_route_gateway = [
|
||||
for location, virtual_hub in local.virtual_hubs_by_location :
|
||||
{
|
||||
# Resource logic attributes
|
||||
resource_id = local.virtual_hub_express_route_gateway_resource_id[location]
|
||||
managed_by_module = local.deploy_virtual_hub_express_route_gateway[location]
|
||||
# Resource definition attributes
|
||||
name = local.virtual_hub_express_route_gateway_name[location]
|
||||
resource_group_name = local.virtual_hub_resource_group_name[location]
|
||||
location = location
|
||||
virtual_hub_id = local.virtual_hub_resource_id[location]
|
||||
scale_units = virtual_hub.config.expressroute_gateway.config.scale_unit
|
||||
# Optional definition attributes
|
||||
tags = try(local.custom_settings.azurerm_express_route_gateway["virtual_wan"][location].tags, local.tags)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Configuration settings for resource type:
|
||||
# - azurerm_vpn_gateway
|
||||
locals {
|
||||
virtual_hub_vpn_gateway_name = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location =>
|
||||
try(local.custom_settings.azurerm_vpn_gateway["virtual_wan"][location].name,
|
||||
"${local.resource_prefix}-vpngw-${location}${local.resource_suffix}")
|
||||
}
|
||||
virtual_hub_vpn_gateway_resource_id_prefix = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location =>
|
||||
"${local.virtual_hub_resource_group_id[location]}/providers/Microsoft.Network/expressRouteGateways"
|
||||
}
|
||||
virtual_hub_vpn_gateway_resource_id = {
|
||||
for location in local.virtual_hub_locations :
|
||||
location =>
|
||||
"${local.virtual_hub_vpn_gateway_resource_id_prefix[location]}/${local.virtual_hub_vpn_gateway_name[location]}"
|
||||
}
|
||||
azurerm_vpn_gateway = [
|
||||
for location, virtual_hub in local.virtual_hubs_by_location :
|
||||
{
|
||||
# Resource logic attributes
|
||||
resource_id = local.virtual_hub_vpn_gateway_resource_id[location]
|
||||
managed_by_module = local.deploy_virtual_hub_vpn_gateway[location]
|
||||
# Resource definition attributes
|
||||
name = local.virtual_hub_vpn_gateway_name[location]
|
||||
resource_group_name = local.virtual_hub_resource_group_name[location]
|
||||
location = location
|
||||
virtual_hub_id = local.virtual_hub_resource_id[location]
|
||||
# Optional definition attributes
|
||||
routing_preference = coalesce(virtual_hub.config.vpn_gateway.config.routing_preference, "Microsoft Network")
|
||||
scale_unit = virtual_hub.config.vpn_gateway.config.scale_unit
|
||||
tags = try(local.custom_settings.azurerm_vpn_gateway["virtual_wan"][location].tags, local.tags)
|
||||
bgp_settings = [
|
||||
for bgp_setting in virtual_hub.config.vpn_gateway.config.bgp_settings :
|
||||
{
|
||||
asn = bgp_setting.asn
|
||||
peer_weight = bgp_setting.peer_weight
|
||||
instance_0_bgp_peering_address = [
|
||||
for instance_bgp_peering_address in bgp_setting.instance_0_bgp_peering_address :
|
||||
{
|
||||
custom_ips = instance_bgp_peering_address.custom_ips
|
||||
}
|
||||
]
|
||||
instance_1_bgp_peering_address = [
|
||||
for instance_bgp_peering_address in bgp_setting.instance_1_bgp_peering_address :
|
||||
{
|
||||
custom_ips = instance_bgp_peering_address.custom_ips
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -562,10 +961,14 @@ locals {
|
|||
# Configuration settings for resource type:
|
||||
# - azurerm_public_ip
|
||||
locals {
|
||||
azurerm_public_ip = concat(
|
||||
local.azurerm_virtual_network_gateway.*.azurerm_public_ip,
|
||||
local.azurerm_firewall.*.azurerm_public_ip,
|
||||
)
|
||||
azurerm_public_ip = [
|
||||
for azurerm_public_ip in concat(
|
||||
local.azurerm_virtual_network_gateway.*.azurerm_public_ip,
|
||||
local.azurerm_firewall.*.azurerm_public_ip,
|
||||
) :
|
||||
azurerm_public_ip
|
||||
if length(azurerm_public_ip) > 0
|
||||
]
|
||||
}
|
||||
|
||||
# Configuration settings for resource type:
|
||||
|
@ -749,7 +1152,7 @@ locals {
|
|||
managed_by_module = local.deploy_private_dns_zone_virtual_network_link_on_hubs
|
||||
}
|
||||
]
|
||||
spoke_virtual_networks_for_dns = flatten(
|
||||
spoke_virtual_networks_for_dns = flatten([
|
||||
[
|
||||
for location, hub_config in local.hub_networks_by_location :
|
||||
[
|
||||
|
@ -760,12 +1163,26 @@ locals {
|
|||
managed_by_module = local.deploy_private_dns_zone_virtual_network_link_on_spokes
|
||||
}
|
||||
]
|
||||
],
|
||||
[
|
||||
for location, virtual_hub_config in local.virtual_hubs_by_location :
|
||||
[
|
||||
for spoke_resource_id in virtual_hub_config.config.spoke_virtual_network_resource_ids :
|
||||
{
|
||||
resource_id = spoke_resource_id
|
||||
name = "${split("/", spoke_resource_id)[2]}-${uuidv5("url", spoke_resource_id)}"
|
||||
managed_by_module = local.deploy_private_dns_zone_virtual_network_link_on_spokes
|
||||
}
|
||||
]
|
||||
]
|
||||
)
|
||||
virtual_networks_for_dns = concat(
|
||||
])
|
||||
# Distinct is used to allow for situations where
|
||||
# the same spoke is associated with multiple hub
|
||||
# networks for peering.
|
||||
virtual_networks_for_dns = distinct(concat(
|
||||
local.hub_virtual_networks_for_dns,
|
||||
local.spoke_virtual_networks_for_dns,
|
||||
)
|
||||
))
|
||||
azurerm_private_dns_zone_virtual_network_link = flatten(
|
||||
[
|
||||
for zone in local.azurerm_private_dns_zone :
|
||||
|
@ -817,6 +1234,31 @@ locals {
|
|||
)
|
||||
}
|
||||
|
||||
# Configuration settings for resource type:
|
||||
# - azurerm_virtual_hub_connection
|
||||
locals {
|
||||
azurerm_virtual_hub_connection = flatten(
|
||||
[
|
||||
for location, virtual_hub_config in local.virtual_hubs_by_location :
|
||||
[
|
||||
for spoke_resource_id in virtual_hub_config.config.spoke_virtual_network_resource_ids :
|
||||
{
|
||||
# Resource logic attributes
|
||||
resource_id = "${local.virtual_hub_resource_id[location]}/hubVirtualNetworkConnections/peering-${uuidv5("url", spoke_resource_id)}"
|
||||
managed_by_module = local.deploy_virtual_hub_connection[location]
|
||||
# Resource definition attributes
|
||||
name = "peering-${uuidv5("url", spoke_resource_id)}"
|
||||
virtual_hub_id = local.virtual_hub_resource_id[location]
|
||||
remote_virtual_network_id = spoke_resource_id
|
||||
# Optional definition attributes
|
||||
internet_security_enabled = false
|
||||
routing = local.empty_list
|
||||
}
|
||||
]
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
# Archetype configuration overrides
|
||||
locals {
|
||||
archetype_config_overrides = {
|
||||
|
@ -900,6 +1342,7 @@ locals {
|
|||
key != "managed_by_module" &&
|
||||
key != "scope"
|
||||
}
|
||||
scope = resource.scope
|
||||
managed_by_module = local.deploy_resource_groups[resource.scope][resource.location]
|
||||
}
|
||||
]
|
||||
|
@ -978,7 +1421,69 @@ locals {
|
|||
if resource.managed_by_module &&
|
||||
key != "resource_id" &&
|
||||
key != "managed_by_module" &&
|
||||
key != "azurerm_public_ip"
|
||||
key != "azurerm_public_ip" &&
|
||||
key != "scope"
|
||||
}
|
||||
scope = resource.scope
|
||||
managed_by_module = resource.managed_by_module
|
||||
}
|
||||
]
|
||||
azurerm_virtual_wan = [
|
||||
for resource in local.azurerm_virtual_wan :
|
||||
{
|
||||
resource_id = resource.resource_id
|
||||
resource_name = resource.name
|
||||
template = {
|
||||
for key, value in resource :
|
||||
key => value
|
||||
if resource.managed_by_module &&
|
||||
key != "resource_id" &&
|
||||
key != "managed_by_module"
|
||||
}
|
||||
managed_by_module = resource.managed_by_module
|
||||
}
|
||||
]
|
||||
azurerm_virtual_hub = [
|
||||
for resource in local.azurerm_virtual_hub :
|
||||
{
|
||||
resource_id = resource.resource_id
|
||||
resource_name = resource.name
|
||||
template = {
|
||||
for key, value in resource :
|
||||
key => value
|
||||
if resource.managed_by_module &&
|
||||
key != "resource_id" &&
|
||||
key != "managed_by_module"
|
||||
}
|
||||
managed_by_module = resource.managed_by_module
|
||||
}
|
||||
]
|
||||
azurerm_express_route_gateway = [
|
||||
for resource in local.azurerm_express_route_gateway :
|
||||
{
|
||||
resource_id = resource.resource_id
|
||||
resource_name = resource.name
|
||||
template = {
|
||||
for key, value in resource :
|
||||
key => value
|
||||
if resource.managed_by_module &&
|
||||
key != "resource_id" &&
|
||||
key != "managed_by_module"
|
||||
}
|
||||
managed_by_module = resource.managed_by_module
|
||||
}
|
||||
]
|
||||
azurerm_vpn_gateway = [
|
||||
for resource in local.azurerm_vpn_gateway :
|
||||
{
|
||||
resource_id = resource.resource_id
|
||||
resource_name = resource.name
|
||||
template = {
|
||||
for key, value in resource :
|
||||
key => value
|
||||
if resource.managed_by_module &&
|
||||
key != "resource_id" &&
|
||||
key != "managed_by_module"
|
||||
}
|
||||
managed_by_module = resource.managed_by_module
|
||||
}
|
||||
|
@ -1052,7 +1557,23 @@ locals {
|
|||
for key, value in resource :
|
||||
key => value
|
||||
if resource.managed_by_module &&
|
||||
key != "resource_id"
|
||||
key != "resource_id" &&
|
||||
key != "managed_by_module"
|
||||
}
|
||||
managed_by_module = resource.managed_by_module
|
||||
}
|
||||
]
|
||||
azurerm_virtual_hub_connection = [
|
||||
for resource in local.azurerm_virtual_hub_connection :
|
||||
{
|
||||
resource_id = resource.resource_id
|
||||
resource_name = resource.name
|
||||
template = {
|
||||
for key, value in resource :
|
||||
key => value
|
||||
if resource.managed_by_module &&
|
||||
key != "resource_id" &&
|
||||
key != "managed_by_module"
|
||||
}
|
||||
managed_by_module = resource.managed_by_module
|
||||
}
|
||||
|
@ -1064,53 +1585,76 @@ locals {
|
|||
|
||||
locals {
|
||||
debug_output = {
|
||||
deploy_resource_groups = local.deploy_resource_groups
|
||||
deploy_hub_network = local.deploy_hub_network
|
||||
deploy_virtual_network_gateway = local.deploy_virtual_network_gateway
|
||||
deploy_virtual_network_gateway_expressroute = local.deploy_virtual_network_gateway_expressroute
|
||||
deploy_virtual_network_gateway_vpn = local.deploy_virtual_network_gateway_vpn
|
||||
deploy_azure_firewall = local.deploy_azure_firewall
|
||||
resource_group_names_by_scope_and_location = local.resource_group_names_by_scope_and_location
|
||||
resource_group_config_by_scope_and_location = local.resource_group_config_by_scope_and_location
|
||||
azurerm_resource_group = local.azurerm_resource_group
|
||||
ddos_resource_group_id = local.ddos_resource_group_id
|
||||
ddos_protection_plan_name = local.ddos_protection_plan_name
|
||||
ddos_protection_plan_resource_id = local.ddos_protection_plan_resource_id
|
||||
azurerm_network_ddos_protection_plan = local.azurerm_network_ddos_protection_plan
|
||||
hub_network_locations = local.hub_network_locations
|
||||
ddos_location = local.ddos_location
|
||||
dns_location = local.dns_location
|
||||
virtual_network_resource_group_id = local.virtual_network_resource_group_id
|
||||
virtual_network_resource_id_prefix = local.virtual_network_resource_id_prefix
|
||||
virtual_network_resource_id = local.virtual_network_resource_id
|
||||
azurerm_virtual_network = local.azurerm_virtual_network
|
||||
subnets_by_virtual_network = local.subnets_by_virtual_network
|
||||
azurerm_subnet = local.azurerm_subnet
|
||||
er_gateway_name = local.er_gateway_name
|
||||
er_gateway_resource_id_prefix = local.er_gateway_resource_id_prefix
|
||||
er_gateway_resource_id = local.er_gateway_resource_id
|
||||
er_gateway_config = local.er_gateway_config
|
||||
vpn_gateway_name = local.vpn_gateway_name
|
||||
vpn_gateway_resource_id_prefix = local.vpn_gateway_resource_id_prefix
|
||||
vpn_gateway_resource_id = local.vpn_gateway_resource_id
|
||||
vpn_gateway_config = local.vpn_gateway_config
|
||||
azurerm_virtual_network_gateway = local.azurerm_virtual_network_gateway
|
||||
azfw_name = local.azfw_name
|
||||
azfw_resource_id_prefix = local.azfw_resource_id_prefix
|
||||
azfw_resource_id = local.azfw_resource_id
|
||||
azurerm_firewall = local.azurerm_firewall
|
||||
azurerm_public_ip = local.azurerm_public_ip
|
||||
enable_private_link_by_service = local.enable_private_link_by_service
|
||||
private_link_locations = local.private_link_locations
|
||||
lookup_private_link_dns_zone_by_service = local.lookup_private_link_dns_zone_by_service
|
||||
lookup_private_link_group_id_by_service = local.lookup_private_link_group_id_by_service
|
||||
services_by_private_link_dns_zone = local.services_by_private_link_dns_zone
|
||||
private_dns_zone_enabled = local.private_dns_zone_enabled
|
||||
azurerm_private_dns_zone = local.azurerm_private_dns_zone
|
||||
azurerm_dns_zone = local.azurerm_dns_zone
|
||||
hub_virtual_networks_for_dns = local.hub_virtual_networks_for_dns
|
||||
spoke_virtual_networks_for_dns = local.spoke_virtual_networks_for_dns
|
||||
virtual_networks_for_dns = local.virtual_networks_for_dns
|
||||
azurerm_private_dns_zone_virtual_network_link = local.azurerm_private_dns_zone_virtual_network_link
|
||||
hub_networks = local.hub_networks
|
||||
hub_networks_by_location = local.hub_networks_by_location
|
||||
hub_network_locations = local.hub_network_locations
|
||||
virtual_hubs = local.virtual_hubs
|
||||
virtual_hubs_by_location = local.virtual_hubs_by_location
|
||||
virtual_hub_locations = local.virtual_hub_locations
|
||||
virtual_hubs_by_location_for_resource_group_per_location = local.virtual_hubs_by_location_for_resource_group_per_location
|
||||
virtual_hubs_by_location_for_shared_resource_group = local.virtual_hubs_by_location_for_shared_resource_group
|
||||
virtual_hubs_by_location_for_managed_virtual_wan = local.virtual_hubs_by_location_for_managed_virtual_wan
|
||||
virtual_hubs_by_location_for_existing_virtual_wan = local.virtual_hubs_by_location_for_existing_virtual_wan
|
||||
virtual_wan_locations = local.virtual_wan_locations
|
||||
ddos_location = local.ddos_location
|
||||
dns_location = local.dns_location
|
||||
connectivity_locations = local.connectivity_locations
|
||||
result_when_location_missing = local.result_when_location_missing
|
||||
deploy_resource_groups = local.deploy_resource_groups
|
||||
deploy_ddos_protection_plan = local.deploy_ddos_protection_plan
|
||||
deploy_dns = local.deploy_dns
|
||||
deploy_private_dns_zone_virtual_network_link_on_hubs = local.deploy_private_dns_zone_virtual_network_link_on_hubs
|
||||
deploy_private_dns_zone_virtual_network_link_on_spokes = local.deploy_private_dns_zone_virtual_network_link_on_spokes
|
||||
deploy_hub_network = local.deploy_hub_network
|
||||
deploy_virtual_network_gateway = local.deploy_virtual_network_gateway
|
||||
deploy_virtual_network_gateway_express_route = local.deploy_virtual_network_gateway_express_route
|
||||
deploy_virtual_network_gateway_vpn = local.deploy_virtual_network_gateway_vpn
|
||||
deploy_azure_firewall = local.deploy_azure_firewall
|
||||
deploy_outbound_virtual_network_peering = local.deploy_outbound_virtual_network_peering
|
||||
deploy_virtual_wan = local.deploy_virtual_wan
|
||||
deploy_virtual_hub = local.deploy_virtual_hub
|
||||
deploy_virtual_hub_express_route_gateway = local.deploy_virtual_hub_express_route_gateway
|
||||
deploy_virtual_hub_vpn_gateway = local.deploy_virtual_hub_vpn_gateway
|
||||
deploy_virtual_hub_azure_firewall = local.deploy_virtual_hub_azure_firewall
|
||||
deploy_virtual_hub_connection = local.deploy_virtual_hub_connection
|
||||
resource_group_names_by_scope_and_location = local.resource_group_names_by_scope_and_location
|
||||
resource_group_config_by_scope_and_location = local.resource_group_config_by_scope_and_location
|
||||
azurerm_resource_group = local.azurerm_resource_group
|
||||
ddos_resource_group_id = local.ddos_resource_group_id
|
||||
ddos_protection_plan_name = local.ddos_protection_plan_name
|
||||
ddos_protection_plan_resource_id = local.ddos_protection_plan_resource_id
|
||||
azurerm_network_ddos_protection_plan = local.azurerm_network_ddos_protection_plan
|
||||
virtual_network_resource_group_id = local.virtual_network_resource_group_id
|
||||
virtual_network_resource_id_prefix = local.virtual_network_resource_id_prefix
|
||||
virtual_network_resource_id = local.virtual_network_resource_id
|
||||
azurerm_virtual_network = local.azurerm_virtual_network
|
||||
subnets_by_virtual_network = local.subnets_by_virtual_network
|
||||
azurerm_subnet = local.azurerm_subnet
|
||||
er_gateway_name = local.er_gateway_name
|
||||
er_gateway_resource_id_prefix = local.er_gateway_resource_id_prefix
|
||||
er_gateway_resource_id = local.er_gateway_resource_id
|
||||
er_gateway_config = local.er_gateway_config
|
||||
vpn_gateway_name = local.vpn_gateway_name
|
||||
vpn_gateway_resource_id_prefix = local.vpn_gateway_resource_id_prefix
|
||||
vpn_gateway_resource_id = local.vpn_gateway_resource_id
|
||||
vpn_gateway_config = local.vpn_gateway_config
|
||||
azurerm_virtual_network_gateway = local.azurerm_virtual_network_gateway
|
||||
azfw_name = local.azfw_name
|
||||
azfw_resource_id_prefix = local.azfw_resource_id_prefix
|
||||
azfw_resource_id = local.azfw_resource_id
|
||||
azurerm_firewall = local.azurerm_firewall
|
||||
azurerm_public_ip = local.azurerm_public_ip
|
||||
enable_private_link_by_service = local.enable_private_link_by_service
|
||||
private_link_locations = local.private_link_locations
|
||||
lookup_private_link_dns_zone_by_service = local.lookup_private_link_dns_zone_by_service
|
||||
lookup_private_link_group_id_by_service = local.lookup_private_link_group_id_by_service
|
||||
services_by_private_link_dns_zone = local.services_by_private_link_dns_zone
|
||||
private_dns_zone_enabled = local.private_dns_zone_enabled
|
||||
azurerm_private_dns_zone = local.azurerm_private_dns_zone
|
||||
azurerm_dns_zone = local.azurerm_dns_zone
|
||||
hub_virtual_networks_for_dns = local.hub_virtual_networks_for_dns
|
||||
spoke_virtual_networks_for_dns = local.spoke_virtual_networks_for_dns
|
||||
virtual_networks_for_dns = local.virtual_networks_for_dns
|
||||
azurerm_private_dns_zone_virtual_network_link = local.azurerm_private_dns_zone_virtual_network_link
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,60 @@ variable "settings" {
|
|||
})
|
||||
})
|
||||
)
|
||||
vwan_hub_networks = list(object({}))
|
||||
vwan_hub_networks = list(
|
||||
object({
|
||||
enabled = bool
|
||||
config = object({
|
||||
address_prefix = string
|
||||
location = string
|
||||
sku = string
|
||||
routes = list(
|
||||
object({
|
||||
address_prefixes = list(string)
|
||||
next_hop_ip_address = string
|
||||
})
|
||||
)
|
||||
expressroute_gateway = object({
|
||||
enabled = bool
|
||||
config = object({
|
||||
scale_unit = number
|
||||
})
|
||||
})
|
||||
vpn_gateway = object({
|
||||
enabled = bool
|
||||
config = object({
|
||||
bgp_settings = list(
|
||||
object({
|
||||
asn = number
|
||||
peer_weight = number
|
||||
instance_0_bgp_peering_address = list(
|
||||
object({
|
||||
custom_ips = list(string)
|
||||
})
|
||||
)
|
||||
instance_1_bgp_peering_address = list(
|
||||
object({
|
||||
custom_ips = list(string)
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
routing_preference = string
|
||||
scale_unit = number
|
||||
})
|
||||
})
|
||||
azure_firewall = object({
|
||||
enabled = bool
|
||||
config = object({
|
||||
enable_dns_proxy = bool
|
||||
sku_tier = string
|
||||
})
|
||||
})
|
||||
spoke_virtual_network_resource_ids = list(string)
|
||||
enable_virtual_hub_connections = bool
|
||||
})
|
||||
})
|
||||
)
|
||||
ddos_protection_plan = object({
|
||||
enabled = bool
|
||||
config = object({
|
||||
|
@ -155,7 +208,7 @@ variable "resource_prefix" {
|
|||
default = ""
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-zA-Z0-9-]{2,10}$", var.resource_prefix)) || var.resource_prefix == ""
|
||||
condition = can(regex("^[a-zA-Z0-9-]{2,10}$", var.resource_prefix)) || var.resource_prefix == null
|
||||
error_message = "Value must be between 2 to 10 characters long, consisting of alphanumeric characters and hyphens."
|
||||
}
|
||||
}
|
||||
|
@ -166,7 +219,7 @@ variable "resource_suffix" {
|
|||
default = ""
|
||||
|
||||
validation {
|
||||
condition = can(regex("^[a-zA-Z0-9-]{2,36}$", var.resource_suffix)) || var.resource_suffix == ""
|
||||
condition = can(regex("^[a-zA-Z0-9-]{2,36}$", var.resource_suffix)) || var.resource_suffix == null
|
||||
error_message = "Value must be between 2 to 36 characters long, consisting of alphanumeric characters and hyphens."
|
||||
}
|
||||
|
||||
|
@ -178,13 +231,28 @@ variable "existing_ddos_protection_plan_resource_id" {
|
|||
default = ""
|
||||
}
|
||||
|
||||
variable "existing_virtual_wan_resource_id" {
|
||||
type = string
|
||||
description = "If specified, module will skip creation of the Virtual WAN and use existing. All Virtual Hubs created by the module will be associated with the specified Virtual WAN."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "resource_group_per_virtual_hub_location" {
|
||||
type = bool
|
||||
description = "If set to true, module will place each Virtual Hub (and associated resources) in a location-specific Resource Group. Default behaviour is to colocate Virtual Hub resources in the same Resource Group as the Virtual WAN resource."
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "custom_settings_by_resource_type" {
|
||||
type = any
|
||||
description = "If specified, allows full customization of common settings for all resources (by type) deployed by this module."
|
||||
default = {}
|
||||
|
||||
validation {
|
||||
condition = can([for k in keys(var.custom_settings_by_resource_type) : contains(["azurerm_resource_group", "azurerm_virtual_network", "azurerm_subnet", "azurerm_virtual_network_gateway", "azurerm_public_ip", "azurerm_firewall", "azurerm_network_ddos_protection_plan", "azurerm_dns_zone", "azurerm_virtual_network_peering"], k)]) || var.custom_settings_by_resource_type == {}
|
||||
condition = (
|
||||
can([for k in keys(var.custom_settings_by_resource_type) : contains(["azurerm_resource_group", "azurerm_virtual_network", "azurerm_subnet", "azurerm_virtual_network_gateway", "azurerm_public_ip", "azurerm_firewall", "azurerm_network_ddos_protection_plan", "azurerm_dns_zone", "azurerm_virtual_network_peering"], k)]) ||
|
||||
var.custom_settings_by_resource_type == null
|
||||
)
|
||||
error_message = "Invalid key specified. Please check the list of allowed resource types supported by the connectivity module for caf-enterprise-scale."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,7 +168,6 @@ locals {
|
|||
workspace_id = try(local.custom_settings_la_linked_service.workspace_id, local.log_analytics_workspace_resource_id)
|
||||
read_access_id = try(local.custom_settings_la_linked_service.read_access_id, local.automation_account_resource_id) # This should be used for linking to an Automation Account resource.
|
||||
write_access_id = null # DO NOT USE. This should be used for linking to a Log Analytics Cluster resource
|
||||
tags = try(local.custom_settings_la_linked_service.tags, local.tags)
|
||||
resource_group_name = coalesce(
|
||||
try(local.custom_settings_la_linked_service.resource_group_name, null),
|
||||
local.resource_group_name,
|
||||
|
|
|
@ -52,7 +52,8 @@ output "azurerm_role_definition" {
|
|||
# Assignment data is returned to the root module.
|
||||
output "azurerm_role_assignment" {
|
||||
value = {
|
||||
enterprise_scale = azurerm_role_assignment.enterprise_scale
|
||||
enterprise_scale = azurerm_role_assignment.enterprise_scale
|
||||
policy_assignment = azurerm_role_assignment.policy_assignment
|
||||
}
|
||||
description = "Returns the configuration data for all Role Assignments created by this module."
|
||||
}
|
||||
|
|
|
@ -8,11 +8,11 @@ resource "azurerm_policy_definition" "enterprise_scale" {
|
|||
display_name = each.value.template.properties.displayName
|
||||
|
||||
# Optional resource attributes
|
||||
description = try(each.value.template.properties.description, "${each.value.template.name} Policy Definition at scope ${each.value.scope_id}")
|
||||
management_group_name = try(basename(each.value.scope_id), null)
|
||||
policy_rule = try(length(each.value.template.properties.policyRule) > 0, false) ? jsonencode(each.value.template.properties.policyRule) : null
|
||||
metadata = try(length(each.value.template.properties.metadata) > 0, false) ? jsonencode(each.value.template.properties.metadata) : null
|
||||
parameters = try(length(each.value.template.properties.parameters) > 0, false) ? jsonencode(each.value.template.properties.parameters) : null
|
||||
description = try(each.value.template.properties.description, "${each.value.template.name} Policy Definition at scope ${each.value.scope_id}")
|
||||
management_group_id = try(basename(each.value.scope_id), null)
|
||||
policy_rule = try(length(each.value.template.properties.policyRule) > 0, false) ? jsonencode(each.value.template.properties.policyRule) : null
|
||||
metadata = try(length(each.value.template.properties.metadata) > 0, false) ? jsonencode(each.value.template.properties.metadata) : null
|
||||
parameters = try(length(each.value.template.properties.parameters) > 0, false) ? jsonencode(each.value.template.properties.parameters) : null
|
||||
|
||||
# Set explicit dependency on Management Group deployments
|
||||
depends_on = [
|
||||
|
|
|
@ -24,10 +24,10 @@ resource "azurerm_policy_set_definition" "enterprise_scale" {
|
|||
}
|
||||
|
||||
# Optional resource attributes
|
||||
description = try(each.value.template.properties.description, "${each.value.template.properties.displayName} Policy Set Definition at scope ${each.value.scope_id}")
|
||||
management_group_name = try(basename(each.value.scope_id), null)
|
||||
metadata = try(length(each.value.template.properties.metadata) > 0, false) ? jsonencode(each.value.template.properties.metadata) : null
|
||||
parameters = try(length(each.value.template.properties.parameters) > 0, false) ? jsonencode(each.value.template.properties.parameters) : null
|
||||
description = try(each.value.template.properties.description, "${each.value.template.properties.displayName} Policy Set Definition at scope ${each.value.scope_id}")
|
||||
management_group_id = try(basename(each.value.scope_id), null)
|
||||
metadata = try(length(each.value.template.properties.metadata) > 0, false) ? jsonencode(each.value.template.properties.metadata) : null
|
||||
parameters = try(length(each.value.template.properties.parameters) > 0, false) ? jsonencode(each.value.template.properties.parameters) : null
|
||||
|
||||
# Set explicit dependency on Management Group and Policy Definition deployments
|
||||
depends_on = [
|
||||
|
|
|
@ -0,0 +1,256 @@
|
|||
resource "azurerm_resource_group" "virtual_wan" {
|
||||
for_each = local.azurerm_resource_group_virtual_wan
|
||||
|
||||
provider = azurerm.connectivity
|
||||
|
||||
# Mandatory resource attributes
|
||||
name = each.value.template.name
|
||||
location = each.value.template.location
|
||||
tags = each.value.template.tags
|
||||
}
|
||||
|
||||
resource "azurerm_virtual_wan" "virtual_wan" {
|
||||
for_each = local.azurerm_virtual_wan_virtual_wan
|
||||
|
||||
provider = azurerm.connectivity
|
||||
|
||||
# Mandatory resource attributes
|
||||
name = each.value.template.name
|
||||
resource_group_name = each.value.template.resource_group_name
|
||||
location = each.value.template.location
|
||||
|
||||
# Optional resource attributes
|
||||
disable_vpn_encryption = each.value.template.disable_vpn_encryption
|
||||
allow_branch_to_branch_traffic = each.value.template.allow_branch_to_branch_traffic
|
||||
office365_local_breakout_category = each.value.template.office365_local_breakout_category
|
||||
type = each.value.template.type
|
||||
tags = each.value.template.tags
|
||||
|
||||
# Set explicit dependencies
|
||||
depends_on = [
|
||||
azurerm_resource_group.connectivity,
|
||||
azurerm_resource_group.virtual_wan,
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
resource "azurerm_virtual_hub" "virtual_wan" {
|
||||
for_each = local.azurerm_virtual_hub_virtual_wan
|
||||
|
||||
provider = azurerm.connectivity
|
||||
|
||||
# Mandatory resource attributes
|
||||
name = each.value.template.name
|
||||
resource_group_name = each.value.template.resource_group_name
|
||||
location = each.value.template.location
|
||||
|
||||
# Optional resource attributes
|
||||
sku = each.value.template.sku
|
||||
address_prefix = each.value.template.address_prefix
|
||||
virtual_wan_id = each.value.template.virtual_wan_id
|
||||
tags = each.value.template.tags
|
||||
|
||||
# Dynamic configuration blocks
|
||||
dynamic "route" {
|
||||
for_each = each.value.template.route
|
||||
content {
|
||||
# Mandatory attributes
|
||||
address_prefixes = route.value["address_prefixes"]
|
||||
next_hop_ip_address = route.value["next_hop_ip_address"]
|
||||
}
|
||||
}
|
||||
|
||||
# Set explicit dependencies
|
||||
depends_on = [
|
||||
azurerm_resource_group.connectivity,
|
||||
azurerm_resource_group.virtual_wan,
|
||||
azurerm_virtual_wan.virtual_wan,
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
resource "azurerm_express_route_gateway" "virtual_wan" {
|
||||
for_each = local.azurerm_express_route_gateway_virtual_wan
|
||||
|
||||
provider = azurerm.connectivity
|
||||
|
||||
# Mandatory resource attributes
|
||||
name = each.value.template.name
|
||||
resource_group_name = each.value.template.resource_group_name
|
||||
location = each.value.template.location
|
||||
virtual_hub_id = each.value.template.virtual_hub_id
|
||||
scale_units = each.value.template.scale_units
|
||||
|
||||
# Optional resource attributes
|
||||
tags = each.value.template.tags
|
||||
|
||||
# Set explicit dependencies
|
||||
depends_on = [
|
||||
azurerm_resource_group.connectivity,
|
||||
azurerm_resource_group.virtual_wan,
|
||||
azurerm_virtual_wan.virtual_wan,
|
||||
azurerm_virtual_hub.virtual_wan,
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
resource "azurerm_vpn_gateway" "virtual_wan" {
|
||||
for_each = local.azurerm_vpn_gateway_virtual_wan
|
||||
|
||||
provider = azurerm.connectivity
|
||||
|
||||
# Mandatory resource attributes
|
||||
name = each.value.template.name
|
||||
resource_group_name = each.value.template.resource_group_name
|
||||
location = each.value.template.location
|
||||
virtual_hub_id = each.value.template.virtual_hub_id
|
||||
|
||||
# Optional resource attributes
|
||||
routing_preference = each.value.template.routing_preference
|
||||
scale_unit = each.value.template.scale_unit
|
||||
tags = each.value.template.tags
|
||||
|
||||
# Dynamic configuration blocks
|
||||
dynamic "bgp_settings" {
|
||||
for_each = each.value.template.bgp_settings
|
||||
content {
|
||||
# Mandatory attributes
|
||||
asn = bgp_settings.value["asn"]
|
||||
peer_weight = bgp_settings.value["peer_weight"]
|
||||
# Dynamic configuration blocks
|
||||
dynamic "instance_0_bgp_peering_address" {
|
||||
for_each = bgp_settings.value["instance_0_bgp_peering_address"]
|
||||
content {
|
||||
custom_ips = instance_0_bgp_peering_address.value["custom_ips"]
|
||||
}
|
||||
}
|
||||
dynamic "instance_1_bgp_peering_address" {
|
||||
for_each = bgp_settings.value["instance_1_bgp_peering_address"]
|
||||
content {
|
||||
custom_ips = instance_1_bgp_peering_address.value["custom_ips"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Set explicit dependencies
|
||||
depends_on = [
|
||||
azurerm_resource_group.connectivity,
|
||||
azurerm_resource_group.virtual_wan,
|
||||
azurerm_virtual_wan.virtual_wan,
|
||||
azurerm_virtual_hub.virtual_wan,
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
resource "azurerm_firewall" "virtual_wan" {
|
||||
for_each = local.azurerm_firewall_virtual_wan
|
||||
|
||||
provider = azurerm.connectivity
|
||||
|
||||
# Mandatory resource attributes
|
||||
name = each.value.template.name
|
||||
resource_group_name = each.value.template.resource_group_name
|
||||
location = each.value.template.location
|
||||
|
||||
# Optional resource attributes
|
||||
sku_name = each.value.template.sku_name
|
||||
sku_tier = each.value.template.sku_tier
|
||||
firewall_policy_id = each.value.template.firewall_policy_id
|
||||
dns_servers = each.value.template.dns_servers
|
||||
private_ip_ranges = each.value.template.private_ip_ranges
|
||||
threat_intel_mode = each.value.template.threat_intel_mode
|
||||
zones = each.value.template.zones
|
||||
tags = each.value.template.tags
|
||||
|
||||
# Dynamic configuration blocks
|
||||
dynamic "ip_configuration" {
|
||||
for_each = each.value.template.ip_configuration
|
||||
content {
|
||||
# Mandatory attributes
|
||||
name = ip_configuration.value["name"]
|
||||
public_ip_address_id = ip_configuration.value["public_ip_address_id"]
|
||||
# Optional attributes
|
||||
subnet_id = try(ip_configuration.value["subnet_id"], null)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "management_ip_configuration" {
|
||||
for_each = each.value.template.management_ip_configuration
|
||||
content {
|
||||
# Mandatory attributes
|
||||
name = management_ip_configuration.value["name"]
|
||||
public_ip_address_id = management_ip_configuration.value["public_ip_address_id"]
|
||||
# Optional attributes
|
||||
subnet_id = try(management_ip_configuration.value["subnet_id"], null)
|
||||
}
|
||||
}
|
||||
|
||||
dynamic "virtual_hub" {
|
||||
for_each = each.value.template.virtual_hub
|
||||
content {
|
||||
# Mandatory attributes
|
||||
virtual_hub_id = virtual_hub.value["virtual_hub_id"]
|
||||
# Optional attributes
|
||||
public_ip_count = try(virtual_hub.value["public_ip_count"], null)
|
||||
}
|
||||
}
|
||||
|
||||
# Set explicit dependencies
|
||||
depends_on = [
|
||||
azurerm_resource_group.connectivity,
|
||||
azurerm_resource_group.virtual_wan,
|
||||
azurerm_virtual_wan.virtual_wan,
|
||||
azurerm_virtual_hub.virtual_wan,
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
resource "azurerm_virtual_hub_connection" "virtual_wan" {
|
||||
for_each = local.azurerm_virtual_hub_connection
|
||||
|
||||
provider = azurerm.connectivity
|
||||
|
||||
# Mandatory resource attributes
|
||||
name = each.value.template.name
|
||||
virtual_hub_id = each.value.template.virtual_hub_id
|
||||
remote_virtual_network_id = each.value.template.remote_virtual_network_id
|
||||
|
||||
# Optional resource attributes
|
||||
internet_security_enabled = each.value.template.internet_security_enabled
|
||||
|
||||
# Dynamic configuration blocks
|
||||
dynamic "routing" {
|
||||
for_each = each.value.template.routing
|
||||
content {
|
||||
# Optional attributes
|
||||
associated_route_table_id = lookup(routing.value, "associated_route_table_id", null)
|
||||
dynamic "propagated_route_table" {
|
||||
for_each = lookup(routing.value, "propagated_route_table", local.empty_list)
|
||||
content {
|
||||
# Optional attributes
|
||||
labels = lookup(propagated_route_table.value, "labels", null)
|
||||
route_table_ids = lookup(propagated_route_table.value, "route_table_ids", null)
|
||||
}
|
||||
}
|
||||
dynamic "static_vnet_route" {
|
||||
for_each = lookup(routing.value, "static_vnet_route", local.empty_list)
|
||||
content {
|
||||
# Optional attributes
|
||||
name = lookup(static_vnet_route.value, "name", null)
|
||||
address_prefixes = lookup(static_vnet_route.value, "address_prefixes", null)
|
||||
next_hop_ip_address = lookup(static_vnet_route.value, "next_hop_ip_address", null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Set explicit dependencies
|
||||
depends_on = [
|
||||
azurerm_resource_group.connectivity,
|
||||
azurerm_resource_group.virtual_wan,
|
||||
azurerm_virtual_wan.virtual_wan,
|
||||
azurerm_virtual_hub.virtual_wan,
|
||||
]
|
||||
|
||||
}
|
|
@ -3,7 +3,7 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = ">= 2.77.0"
|
||||
version = ">= 2.96.0"
|
||||
configuration_aliases = [
|
||||
azurerm.connectivity,
|
||||
azurerm.management,
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
# Test Framework for the Terraform Module for Cloud Adoption Framework Enterprise-scale
|
||||
|
||||
This folder contains code relating to the test framework for this module.
|
||||
Testing is currently performed in the following stages:
|
||||
|
||||
1. Code Review (GitHub Actions)
|
||||
1. Unit Tests (Azure Pipelines)
|
||||
1. E2E Tests (Azure Pipelines)
|
||||
|
||||
The decision to break testing up in this manner was to ensure developers get quick feedback when working on bug fixes and new features, whilst providing greater assurance that the latest updates work as expected and do not break existing functionality.
|
||||
|
||||
## Code Review (GitHub Actions)
|
||||
|
||||
The first quality check ensures all code complies with recommended coding practices.
|
||||
We use [GitHub Super-Linter (v4.1.0)](https://github.com/github/super-linter/tree/v4.1.0) to perform this initial check across the code base.
|
||||
By running this within a GitHub Action, anyone contributing to the code can get quick feedback on each commit pushed to GitHub.
|
||||
|
||||
GitHub Super-Linter is configured to run checks against the full codebase using the following Linters:
|
||||
|
||||
| *Language* | *Linter* |
|
||||
| ---------- | -------- |
|
||||
| **JSON** | [jsonlint](https://github.com/zaach/jsonlint) |
|
||||
| **Markdown** | [markdownlint](https://github.com/igorshubovych/markdownlint-cli#readme) |
|
||||
| **PowerShell** | [PSScriptAnalyzer](https://github.com/PowerShell/Psscriptanalyzer) |
|
||||
| **Shell** | [Shellcheck](https://github.com/koalaman/shellcheck) / [executable bit check] / [shfmt](https://github.com/mvdan/sh) |
|
||||
| **Terraform** | [tflint](https://github.com/terraform-linters/tflint) / [terrascan](https://github.com/accurics/terrascan) |
|
||||
| **YAML** | [YamlLint](https://github.com/adrienverge/yamllint) |
|
||||
|
||||
This is also a mandatory check on all PR's being raised against the `main` branch.
|
||||
|
||||
## Unit Tests (Azure Pipelines)
|
||||
|
||||
As linting only let's you know if the code is well written (according to a pre-determined set of standards), we also need to determine whether the code generates a valid Terraform plan.
|
||||
|
||||
To verify this, we have a set of unit tests which run additional checks against the module using a series of test deployments.
|
||||
|
||||
To give assurance that the module works with the specified range of supported versions of Terraform and the Azure provider, we use a [matrix strategy](#multi_job_configuration_matrix_strategy)) to automatically generate parallel running jobs for each version combination.
|
||||
|
||||
The Unit Tests consist of the following tasks:
|
||||
|
||||
| *Task Name* | *Description* |
|
||||
| --- | --- |
|
||||
| **Install Terraform Pre-requisites** | Ensures the required version of Terraform is installed on the agent. |
|
||||
| **Prepare Terraform Environment** | Retrieves credentials for the target test environment and sets a unique value for the `root_id` input variable.<sup>1</sup> |
|
||||
| **Terraform Linting (terraform fmt)** | Runs `terraform fmt` against the entire repository in `-check` mode to ensure Terraform code is correctly formatted. |
|
||||
| **Install OPA/Conftest Pre-requisites** | Ensure the required version of `Conftest`, `jq`, `yq` and `yamllint` are installed on the agent. |
|
||||
| **Test 001 (terraform init) Baseline** | Initialize the root module for this test instance. |
|
||||
| **Test 001 (terraform plan) Baseline** | Generate a Terraform plan for this test instance. |
|
||||
| **Test 001 (conftest) Baseline** | Run Conftest to ensure the Terraform plan matches the expected configuration for this test instance. |
|
||||
| **Test 002 (terraform init) Add Custom Core** | Initialize the root module for this test instance. |
|
||||
| **Test 002 (terraform plan) Add Custom Core** | Generate a Terraform plan for this test instance. |
|
||||
| **Test 002 (conftest) Add Custom Core** | Run Conftest to ensure the Terraform plan matches the expected configuration for this test instance. |
|
||||
| **Test 003 (terraform init) Add Management and Connectivity** | Initialize the root module for this test instance. |
|
||||
| **Test 003 (terraform plan) Add Management and Connectivity** | Generate a Terraform plan for this test instance. |
|
||||
| **Test 003 (conftest) Add Management and Connectivity** | Run Conftest to ensure the Terraform plan matches the expected configuration for this test instance. |
|
||||
|
||||
<sup>1</sup> *Each job uses a dedicated SPN (with certificate based authentication) to connect to Azure.*
|
||||
*This is to minimize the risk of API rate limiting when running highly parallel resource deployments in the pipeline.*
|
||||
|
||||
## E2E Tests (Azure Pipelines)
|
||||
|
||||
The E2E Tests consist of the following tasks:
|
||||
|
||||
| *Task Name* | *Description* |
|
||||
| --- | --- |
|
||||
| **Install Terraform Pre-requisites** | Ensures the required version of Terraform is installed on the agent. |
|
||||
| **Prepare Terraform Environment** | Retrieves credentials for the target test environment and sets a unique value for the `root_id` input variable.<sup>1</sup> |
|
||||
| **Terraform Linting (terraform fmt)** | Runs `terraform fmt` against the entire repository in `-check` mode to ensure Terraform code is correctly formatted. |
|
||||
| **Test 001 (terraform init) Baseline** | Initialize the root module for this test instance. |
|
||||
| **Test 001 (terraform plan) Baseline** | Generate a Terraform plan for this test instance. |
|
||||
| **Test 001 (terraform apply) Baseline** | Apply the Terraform plan for this test instance. |
|
||||
| **Test 002 (terraform init) Add Custom Core** | Initialize the root module for this test instance. |
|
||||
| **Test 002 (terraform plan) Add Custom Core** | Generate a Terraform plan for this test instance. |
|
||||
| **Test 002 (terraform apply) Add Custom Core** | Apply the Terraform plan for this test instance. |
|
||||
| **Test 003 (terraform init) Add Management and Connectivity** | Initialize the root module for this test instance. |
|
||||
| **Test 003 (terraform plan) Add Management and Connectivity** | Generate a Terraform plan for this test instance. |
|
||||
| **Test 003 (terraform apply) Add Management and Connectivity** | Apply the Terraform plan for this test instance. |
|
||||
| **Clean-up Test Environment (terraform destroy)** | Run `terraform destroy` to clean-up the test environment.<sup>2</sup> |
|
||||
|
||||
> <sup>1</sup> *Each job uses a dedicated SPN (with certificate based authentication) to connect to Azure.*
|
||||
> *This is to minimize the risk of API rate limiting when running highly parallel resource deployments in the pipeline.*
|
||||
>
|
||||
> <sup>2</sup> *The* `terraform destroy` *task uses the* `always()` *condition to ensure the environment is cleaned-up if any of the previous tasks fail after a partial deployment.*
|
||||
|
||||
## Why Azure Pipelines?
|
||||
|
||||
The Unit Tests and E2E Tests need valid Azure credentials to authenticate with the Azure platform for Terraform to work.
|
||||
These tests are run on Azure Pipelines as a security measure, allowing contributed code from forked repositories to be reviewed before tests are manually triggered by a repository contributor using [comment triggers](https://docs.microsoft.com/azure/devops/pipelines/repos/github?view=azure-devops&tabs=yaml#comment-triggers).
|
||||
Although GitHub Actions could technically run these jobs, GitHub prevents access to secrets for jobs triggered from forks.
|
||||
|
||||
## Multi-job configuration (`matrix` strategy)
|
||||
|
||||
Azure Pipelines provides the option to define a [multi-job configuration](https://docs.microsoft.com/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml#multi-job-configuration).
|
||||
This enables multi-configuration testing to be implemented from a common set of tasks, with the benefit of running multiple jobs on multiple agents in parallel.
|
||||
|
||||
Our implementation uses a programmatically generated `matrix` strategy to ensure we can meet our testing requirements.
|
||||
This is designed to ensure the module works with different combinations of Terraform and Azure provider versions.
|
||||
The strategy is generated by a [PowerShell script](https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/blob/main/tests/scripts/azp-strategy.ps1), and is used by both the Unit and E2E tests.
|
||||
|
||||
The current strategy consists of running tests against the following version combinations:
|
||||
|
||||
- Terraform versions:
|
||||
- Minimum version supported by the module (`0.15.0`)
|
||||
- Latest `0.15.x` version
|
||||
- Latest `1.0.x` version
|
||||
- Azure provider for Terraform versions:
|
||||
- Minimum version supported by the module (`v2.77.0`)
|
||||
- Latest version
|
||||
|
||||
The latest versions are determined programmatically by querying the publisher APIs.
|
||||
This negates the need to update the code or pipeline to ensure the latest version is being tested.
|
||||
|
||||
With the frequency at which we run tests these combinations give reasonable assurance that the module will work with all version combinations up to the latest versions, not withstanding any which temporarily introduce bugs.
|
||||
|
||||
The `matrix` strategy also uses the [Microsoft.Subscription/aliases@2021-10-01](https://docs.microsoft.com/rest/api/subscription/2020-09-01/alias) API to map Subscriptions to each job within the Matrix.
|
||||
This ensures that each job has dedicated Subscriptions to deploy resources into, and place within the Management Group hierarchy.
|
||||
In combination with the dedicated SPN per job, this also increases the API rate limits available to the pipeline.
|
|
@ -1,154 +0,0 @@
|
|||
data "azurerm_client_config" "connectivity" {
|
||||
provider = azurerm.connectivity
|
||||
}
|
||||
|
||||
data "azurerm_client_config" "management" {
|
||||
provider = azurerm.management
|
||||
}
|
||||
|
||||
module "test_root_id_1" {
|
||||
source = "../../"
|
||||
|
||||
providers = {
|
||||
azurerm = azurerm.management
|
||||
azurerm.connectivity = azurerm.connectivity
|
||||
azurerm.management = azurerm.management
|
||||
}
|
||||
|
||||
# Base module configuration settings
|
||||
root_parent_id = data.azurerm_client_config.management.tenant_id
|
||||
root_id = var.root_id_1
|
||||
root_name = "${var.root_name}-1"
|
||||
default_location = var.location
|
||||
default_tags = local.default_tags
|
||||
|
||||
# Tuning delay timers to improve pipeline completion success rate
|
||||
create_duration_delay = var.create_duration_delay
|
||||
destroy_duration_delay = var.destroy_duration_delay
|
||||
|
||||
}
|
||||
|
||||
module "test_root_id_2" {
|
||||
source = "../../"
|
||||
|
||||
providers = {
|
||||
azurerm = azurerm.management
|
||||
azurerm.connectivity = azurerm.connectivity
|
||||
azurerm.management = azurerm.management
|
||||
}
|
||||
|
||||
# Base module configuration settings
|
||||
root_parent_id = data.azurerm_client_config.management.tenant_id
|
||||
root_id = var.root_id_2
|
||||
root_name = "${var.root_name}-2"
|
||||
default_location = var.location
|
||||
default_tags = local.default_tags
|
||||
|
||||
# Configuration settings for optional landing zones
|
||||
deploy_corp_landing_zones = true
|
||||
deploy_online_landing_zones = true
|
||||
deploy_sap_landing_zones = true
|
||||
deploy_demo_landing_zones = true
|
||||
|
||||
# Tuning delay timers to improve pipeline completion success rate
|
||||
create_duration_delay = var.create_duration_delay
|
||||
destroy_duration_delay = var.destroy_duration_delay
|
||||
|
||||
}
|
||||
|
||||
module "test_root_id_3" {
|
||||
source = "../../"
|
||||
|
||||
providers = {
|
||||
azurerm = azurerm.management
|
||||
azurerm.connectivity = azurerm.connectivity
|
||||
azurerm.management = azurerm.management
|
||||
}
|
||||
|
||||
# Base module configuration settings
|
||||
root_parent_id = data.azurerm_client_config.management.tenant_id
|
||||
root_id = var.root_id_3
|
||||
root_name = "${var.root_name}-3"
|
||||
library_path = "${path.root}/lib"
|
||||
default_location = var.location
|
||||
default_tags = local.default_tags
|
||||
|
||||
# Configuration settings for optional landing zones
|
||||
deploy_corp_landing_zones = true
|
||||
deploy_online_landing_zones = true
|
||||
deploy_sap_landing_zones = true
|
||||
deploy_demo_landing_zones = false
|
||||
|
||||
# Configuration settings for core resources
|
||||
custom_landing_zones = local.custom_landing_zones
|
||||
archetype_config_overrides = local.archetype_config_overrides
|
||||
subscription_id_overrides = local.subscription_id_overrides
|
||||
|
||||
# Configuration settings for management resources
|
||||
deploy_management_resources = true
|
||||
configure_management_resources = local.configure_management_resources
|
||||
subscription_id_management = data.azurerm_client_config.management.subscription_id
|
||||
|
||||
# Configuration settings for connectivity resources
|
||||
deploy_connectivity_resources = true
|
||||
configure_connectivity_resources = local.configure_connectivity_resources
|
||||
subscription_id_connectivity = data.azurerm_client_config.connectivity.subscription_id
|
||||
|
||||
# For testing custom template file variables
|
||||
template_file_variables = local.custom_template_file_variables
|
||||
|
||||
# Tuning delay timers to improve pipeline completion success rate
|
||||
create_duration_delay = var.create_duration_delay
|
||||
destroy_duration_delay = var.destroy_duration_delay
|
||||
|
||||
}
|
||||
|
||||
module "test_root_id_3_lz1" {
|
||||
source = "../../"
|
||||
|
||||
providers = {
|
||||
azurerm = azurerm.management
|
||||
azurerm.connectivity = azurerm.connectivity
|
||||
azurerm.management = azurerm.management
|
||||
}
|
||||
|
||||
root_parent_id = "${var.root_id_3}-landing-zones"
|
||||
root_id = var.root_id_3
|
||||
deploy_core_landing_zones = false
|
||||
library_path = "${path.root}/lib"
|
||||
default_location = var.location
|
||||
default_tags = local.default_tags
|
||||
|
||||
custom_landing_zones = {
|
||||
"${var.root_id_3}-scoped-lz1" = {
|
||||
display_name = "Scoped LZ1"
|
||||
parent_management_group_id = "${var.root_id_3}-landing-zones"
|
||||
subscription_ids = []
|
||||
archetype_config = {
|
||||
archetype_id = "customer_online"
|
||||
parameters = {
|
||||
Deny-Resource-Locations = {
|
||||
listOfAllowedLocations = [
|
||||
"northcentralus",
|
||||
"southcentralus",
|
||||
]
|
||||
}
|
||||
}
|
||||
access_control = {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# For testing custom template file variables
|
||||
template_file_variables = local.custom_template_file_variables
|
||||
|
||||
# Tuning delay timers to improve pipeline completion success rate
|
||||
create_duration_delay = var.create_duration_delay
|
||||
destroy_duration_delay = var.destroy_duration_delay
|
||||
|
||||
# Set dependency to ensure correct operation
|
||||
depends_on = [
|
||||
module.test_root_id_3,
|
||||
]
|
||||
|
||||
}
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,6 +0,0 @@
|
|||
# Configure shared settings.
|
||||
locals {
|
||||
default_tags = {
|
||||
deployedBy = "terraform/azure/caf-enterprise-scale/tests/deployment"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
output "connectivity" {
|
||||
value = {
|
||||
configure_connectivity_resources = local.configure_connectivity_resources
|
||||
}
|
||||
}
|
||||
|
||||
output "core" {
|
||||
value = {
|
||||
custom_landing_zones = local.custom_landing_zones
|
||||
archetype_config_overrides = local.archetype_config_overrides
|
||||
subscription_id_overrides = local.subscription_id_overrides
|
||||
custom_template_file_variables = local.custom_template_file_variables
|
||||
}
|
||||
}
|
||||
|
||||
output "management" {
|
||||
value = {
|
||||
configure_management_resources = local.configure_management_resources
|
||||
}
|
||||
}
|
||||
|
||||
output "nested" {
|
||||
value = {
|
||||
custom_landing_zones = local.nested_custom_landing_zones
|
||||
}
|
||||
}
|
||||
|
||||
output "shared" {
|
||||
value = {
|
||||
default_tags = local.default_tags
|
||||
}
|
||||
}
|
|
@ -6,8 +6,8 @@ locals {
|
|||
{
|
||||
enabled = true
|
||||
config = {
|
||||
address_space = ["10.100.0.0/16", ]
|
||||
location = var.location
|
||||
address_space = ["10.100.0.0/22", ]
|
||||
location = var.primary_location
|
||||
link_to_ddos_protection_plan = false
|
||||
dns_servers = []
|
||||
bgp_community = ""
|
||||
|
@ -16,8 +16,8 @@ locals {
|
|||
enabled = true
|
||||
config = {
|
||||
address_prefix = "10.100.1.0/24"
|
||||
gateway_sku_expressroute = "ErGw2AZ"
|
||||
gateway_sku_vpn = "VpnGw2AZ"
|
||||
gateway_sku_expressroute = "ErGw1AZ"
|
||||
gateway_sku_vpn = "VpnGw1AZ"
|
||||
}
|
||||
}
|
||||
azure_firewall = {
|
||||
|
@ -36,8 +36,106 @@ locals {
|
|||
enable_outbound_virtual_network_peering = false
|
||||
}
|
||||
},
|
||||
{
|
||||
enabled = true
|
||||
config = {
|
||||
address_space = ["10.101.0.0/22", ]
|
||||
location = var.secondary_location
|
||||
link_to_ddos_protection_plan = false
|
||||
dns_servers = []
|
||||
bgp_community = ""
|
||||
subnets = []
|
||||
virtual_network_gateway = {
|
||||
enabled = false
|
||||
config = {
|
||||
address_prefix = "10.101.1.0/24"
|
||||
gateway_sku_expressroute = "ErGw1AZ"
|
||||
gateway_sku_vpn = "VpnGw1AZ"
|
||||
}
|
||||
}
|
||||
azure_firewall = {
|
||||
enabled = false
|
||||
config = {
|
||||
address_prefix = "10.101.0.0/24"
|
||||
enable_dns_proxy = true
|
||||
availability_zones = {
|
||||
zone_1 = true
|
||||
zone_2 = true
|
||||
zone_3 = true
|
||||
}
|
||||
}
|
||||
}
|
||||
spoke_virtual_network_resource_ids = []
|
||||
enable_outbound_virtual_network_peering = false
|
||||
}
|
||||
},
|
||||
]
|
||||
vwan_hub_networks = [
|
||||
{
|
||||
enabled = true
|
||||
config = {
|
||||
address_prefix = "10.200.0.0/22"
|
||||
location = var.primary_location
|
||||
sku = ""
|
||||
routes = []
|
||||
expressroute_gateway = {
|
||||
enabled = true
|
||||
config = {
|
||||
scale_unit = 1
|
||||
}
|
||||
}
|
||||
vpn_gateway = {
|
||||
enabled = true
|
||||
config = {
|
||||
bgp_settings = []
|
||||
routing_preference = ""
|
||||
scale_unit = 1
|
||||
}
|
||||
}
|
||||
azure_firewall = {
|
||||
enabled = true
|
||||
config = {
|
||||
enable_dns_proxy = false
|
||||
sku_tier = "Standard"
|
||||
}
|
||||
}
|
||||
spoke_virtual_network_resource_ids = []
|
||||
enable_virtual_hub_connections = true
|
||||
}
|
||||
},
|
||||
{
|
||||
enabled = true
|
||||
config = {
|
||||
address_prefix = "10.201.0.0/22"
|
||||
location = var.secondary_location
|
||||
sku = ""
|
||||
routes = []
|
||||
expressroute_gateway = {
|
||||
enabled = false
|
||||
config = {
|
||||
scale_unit = 1
|
||||
}
|
||||
}
|
||||
vpn_gateway = {
|
||||
enabled = false
|
||||
config = {
|
||||
bgp_settings = []
|
||||
routing_preference = ""
|
||||
scale_unit = 1
|
||||
}
|
||||
}
|
||||
azure_firewall = {
|
||||
enabled = false
|
||||
config = {
|
||||
enable_dns_proxy = false
|
||||
sku_tier = "Standard"
|
||||
}
|
||||
}
|
||||
spoke_virtual_network_resource_ids = []
|
||||
enable_virtual_hub_connections = true
|
||||
}
|
||||
},
|
||||
]
|
||||
vwan_hub_networks = []
|
||||
ddos_protection_plan = {
|
||||
enabled = false
|
||||
config = {
|
|
@ -2,9 +2,9 @@
|
|||
# addition the core resource hierarchy.
|
||||
locals {
|
||||
custom_landing_zones = {
|
||||
"${var.root_id_3}-secure" = {
|
||||
"${var.root_id}-secure" = {
|
||||
display_name = "Secure Workloads (HITRUST/HIPAA)"
|
||||
parent_management_group_id = "${var.root_id_3}-landing-zones"
|
||||
parent_management_group_id = "${var.root_id}-landing-zones"
|
||||
subscription_ids = []
|
||||
archetype_config = {
|
||||
archetype_id = "customer_secure"
|
||||
|
@ -23,8 +23,8 @@ locals {
|
|||
}
|
||||
Deploy-HITRUST-HIPAA = {
|
||||
CertificateThumbprints = ""
|
||||
DeployDiagnosticSettingsforNetworkSecurityGroupsrgName = "${var.root_id_3}-rg"
|
||||
DeployDiagnosticSettingsforNetworkSecurityGroupsstoragePrefix = var.root_id_3
|
||||
DeployDiagnosticSettingsforNetworkSecurityGroupsrgName = "${var.root_id}-rg"
|
||||
DeployDiagnosticSettingsforNetworkSecurityGroupsstoragePrefix = var.root_id
|
||||
installedApplicationsOnWindowsVM = ""
|
||||
listOfLocations = [
|
||||
"eastus",
|
||||
|
@ -34,9 +34,9 @@ locals {
|
|||
access_control = {}
|
||||
}
|
||||
}
|
||||
"${var.root_id_3}-web-global" = {
|
||||
"${var.root_id}-web-global" = {
|
||||
display_name = "Global Web Applications"
|
||||
parent_management_group_id = "${var.root_id_3}-online"
|
||||
parent_management_group_id = "${var.root_id}-online"
|
||||
subscription_ids = []
|
||||
archetype_config = {
|
||||
archetype_id = "default_empty"
|
||||
|
@ -44,9 +44,9 @@ locals {
|
|||
access_control = {}
|
||||
}
|
||||
}
|
||||
"${var.root_id_3}-web-us" = {
|
||||
"${var.root_id}-web-us" = {
|
||||
display_name = "US Web Applications"
|
||||
parent_management_group_id = "${var.root_id_3}-online"
|
||||
parent_management_group_id = "${var.root_id}-online"
|
||||
subscription_ids = []
|
||||
archetype_config = {
|
||||
archetype_id = "customer_online"
|
||||
|
@ -67,9 +67,9 @@ locals {
|
|||
access_control = {}
|
||||
}
|
||||
}
|
||||
"${var.root_id_3}-web-emea" = {
|
||||
"${var.root_id}-web-emea" = {
|
||||
display_name = "EMEA Web Applications"
|
||||
parent_management_group_id = "${var.root_id_3}-online"
|
||||
parent_management_group_id = "${var.root_id}-online"
|
||||
subscription_ids = []
|
||||
archetype_config = {
|
||||
archetype_id = "customer_online"
|
||||
|
@ -129,8 +129,8 @@ locals {
|
|||
}
|
||||
Deploy-HITRUST-HIPAA = {
|
||||
CertificateThumbprints = ""
|
||||
DeployDiagnosticSettingsforNetworkSecurityGroupsrgName = "${var.root_id_3}-rg"
|
||||
DeployDiagnosticSettingsforNetworkSecurityGroupsstoragePrefix = var.root_id_3
|
||||
DeployDiagnosticSettingsforNetworkSecurityGroupsrgName = "${var.root_id}-rg"
|
||||
DeployDiagnosticSettingsforNetworkSecurityGroupsstoragePrefix = var.root_id
|
||||
installedApplicationsOnWindowsVM = ""
|
||||
listOfLocations = [
|
||||
"eastus",
|
|
@ -23,7 +23,7 @@ locals {
|
|||
security_center = {
|
||||
enabled = true
|
||||
config = {
|
||||
email_security_contact = "test.user@replace_me"
|
||||
email_security_contact = var.email_security_contact
|
||||
enable_defender_for_app_services = true
|
||||
enable_defender_for_arm = true
|
||||
enable_defender_for_containers = true
|
||||
|
@ -40,7 +40,7 @@ locals {
|
|||
|
||||
location = null
|
||||
tags = {
|
||||
deployedBy = "terraform/azure/caf-enterprise-scale"
|
||||
deployedBy = "${local.default_tags.deployedBy}/management"
|
||||
}
|
||||
advanced = null
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
locals {
|
||||
nested_custom_landing_zones = {
|
||||
"${var.root_id}-custom-lz1" = {
|
||||
display_name = "Nested Custom LZ1"
|
||||
parent_management_group_id = "${var.root_id}-landing-zones"
|
||||
subscription_ids = []
|
||||
archetype_config = {
|
||||
archetype_id = "customer_online"
|
||||
parameters = {
|
||||
Deny-Resource-Locations = {
|
||||
listOfAllowedLocations = [
|
||||
"northcentralus",
|
||||
"southcentralus",
|
||||
]
|
||||
}
|
||||
}
|
||||
access_control = {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
# Configure shared settings.
|
||||
locals {
|
||||
default_tags = {
|
||||
deployedBy = "terraform/azure/caf-enterprise-scale/test_framework"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
variable "root_id" {
|
||||
type = string
|
||||
default = "test"
|
||||
}
|
||||
|
||||
variable "primary_location" {
|
||||
type = string
|
||||
default = "northeurope"
|
||||
}
|
||||
|
||||
variable "secondary_location" {
|
||||
type = string
|
||||
default = "westeurope"
|
||||
}
|
||||
|
||||
variable "email_security_contact" {
|
||||
type = string
|
||||
default = "test.user@replace_me"
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
data "azurerm_client_config" "connectivity" {
|
||||
provider = azurerm.connectivity
|
||||
}
|
||||
|
||||
data "azurerm_client_config" "management" {
|
||||
provider = azurerm.management
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
module "test_core" {
|
||||
source = "../../../"
|
||||
|
||||
providers = {
|
||||
azurerm = azurerm.management
|
||||
azurerm.connectivity = azurerm.connectivity
|
||||
azurerm.management = azurerm.management
|
||||
}
|
||||
|
||||
# Base module configuration settings
|
||||
root_parent_id = data.azurerm_client_config.management.tenant_id
|
||||
root_id = var.root_id
|
||||
root_name = var.root_name
|
||||
default_location = var.primary_location
|
||||
default_tags = module.settings.shared.default_tags
|
||||
|
||||
# Tuning delay timers to improve pipeline completion success rate
|
||||
create_duration_delay = var.create_duration_delay
|
||||
destroy_duration_delay = var.destroy_duration_delay
|
||||
|
||||
}
|
|
@ -6,10 +6,7 @@
|
|||
output "resource_ids" {
|
||||
value = {
|
||||
for module_name, module_output in {
|
||||
test_root_id_1 = module.test_root_id_1
|
||||
test_root_id_2 = module.test_root_id_2
|
||||
test_root_id_3 = module.test_root_id_3
|
||||
test_root_id_3_lz1 = module.test_root_id_3_lz1
|
||||
test_core = module.test_core
|
||||
} :
|
||||
module_name => {
|
||||
for resource_type, resource_instances in module_output :
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -0,0 +1,13 @@
|
|||
provider "azurerm" {
|
||||
features {}
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
alias = "connectivity"
|
||||
features {}
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
alias = "management"
|
||||
features {}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# Obtain configuration settings.
|
||||
module "settings" {
|
||||
source = "../settings"
|
||||
|
||||
root_id = var.root_id
|
||||
primary_location = var.primary_location
|
||||
}
|
|
@ -2,25 +2,14 @@ terraform {
|
|||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = "2.77.0"
|
||||
version = "2.96.0"
|
||||
configuration_aliases = [
|
||||
azurerm.connectivity,
|
||||
azurerm.management,
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
features {}
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
alias = "connectivity"
|
||||
features {}
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
alias = "management"
|
||||
features {}
|
||||
backend "local" {
|
||||
path = "../tfstate/test_framework.tfstate"
|
||||
}
|
||||
}
|
|
@ -1,16 +1,6 @@
|
|||
variable "root_id_1" {
|
||||
variable "root_id" {
|
||||
type = string
|
||||
default = "root-1"
|
||||
}
|
||||
|
||||
variable "root_id_2" {
|
||||
type = string
|
||||
default = "root-2"
|
||||
}
|
||||
|
||||
variable "root_id_3" {
|
||||
type = string
|
||||
default = "root-3"
|
||||
default = "12345"
|
||||
}
|
||||
|
||||
variable "root_name" {
|
||||
|
@ -18,9 +8,14 @@ variable "root_name" {
|
|||
default = "Test Framework"
|
||||
}
|
||||
|
||||
variable "location" {
|
||||
variable "primary_location" {
|
||||
type = string
|
||||
default = "uksouth"
|
||||
default = "northeurope"
|
||||
}
|
||||
|
||||
variable "secondary_location" {
|
||||
type = string
|
||||
default = "westeurope"
|
||||
}
|
||||
|
||||
variable "create_duration_delay" {
|
|
@ -0,0 +1,7 @@
|
|||
data "azurerm_client_config" "connectivity" {
|
||||
provider = azurerm.connectivity
|
||||
}
|
||||
|
||||
data "azurerm_client_config" "management" {
|
||||
provider = azurerm.management
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
module "test_core" {
|
||||
source = "../../../"
|
||||
|
||||
providers = {
|
||||
azurerm = azurerm.management
|
||||
azurerm.connectivity = azurerm.connectivity
|
||||
azurerm.management = azurerm.management
|
||||
}
|
||||
|
||||
# Base module configuration settings
|
||||
root_parent_id = data.azurerm_client_config.management.tenant_id
|
||||
root_id = var.root_id
|
||||
root_name = var.root_name
|
||||
default_location = var.primary_location
|
||||
default_tags = module.settings.shared.default_tags
|
||||
|
||||
# Tuning delay timers to improve pipeline completion success rate
|
||||
create_duration_delay = var.create_duration_delay
|
||||
destroy_duration_delay = var.destroy_duration_delay
|
||||
|
||||
# Configuration settings for optional landing zones
|
||||
deploy_corp_landing_zones = true
|
||||
deploy_online_landing_zones = true
|
||||
deploy_sap_landing_zones = true
|
||||
deploy_demo_landing_zones = true
|
||||
|
||||
# Configure path for custom library folder and
|
||||
# custom template file variables
|
||||
library_path = "${path.root}/../test_lib"
|
||||
template_file_variables = module.settings.core.custom_template_file_variables
|
||||
|
||||
# Configuration settings for core resources
|
||||
deploy_core_landing_zones = true
|
||||
custom_landing_zones = module.settings.core.custom_landing_zones
|
||||
archetype_config_overrides = module.settings.core.archetype_config_overrides
|
||||
subscription_id_overrides = module.settings.core.subscription_id_overrides
|
||||
|
||||
# Configuration settings for management resources
|
||||
deploy_management_resources = false
|
||||
configure_management_resources = module.settings.management.configure_management_resources
|
||||
subscription_id_management = data.azurerm_client_config.management.subscription_id
|
||||
|
||||
# Configuration settings for connectivity resources
|
||||
deploy_connectivity_resources = false
|
||||
configure_connectivity_resources = module.settings.connectivity.configure_connectivity_resources
|
||||
subscription_id_connectivity = data.azurerm_client_config.connectivity.subscription_id
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
# The following output gives the a summary of all resources
|
||||
# created by the enterprise_scale module, formatted to allow
|
||||
# easy identification of the resource IDs as stored in the
|
||||
# Terraform state.
|
||||
|
||||
output "resource_ids" {
|
||||
value = {
|
||||
for module_name, module_output in {
|
||||
test_core = module.test_core
|
||||
} :
|
||||
module_name => {
|
||||
for resource_type, resource_instances in module_output :
|
||||
resource_type => {
|
||||
for resource_name, resource_configs in resource_instances :
|
||||
resource_name => keys(resource_configs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -0,0 +1,13 @@
|
|||
provider "azurerm" {
|
||||
features {}
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
alias = "connectivity"
|
||||
features {}
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
alias = "management"
|
||||
features {}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# Obtain configuration settings.
|
||||
module "settings" {
|
||||
source = "../settings"
|
||||
|
||||
root_id = var.root_id
|
||||
primary_location = var.primary_location
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = "2.96.0"
|
||||
configuration_aliases = [
|
||||
azurerm.connectivity,
|
||||
azurerm.management,
|
||||
]
|
||||
}
|
||||
}
|
||||
backend "local" {
|
||||
path = "../tfstate/test_framework.tfstate"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
variable "root_id" {
|
||||
type = string
|
||||
default = "12345"
|
||||
}
|
||||
|
||||
variable "root_name" {
|
||||
type = string
|
||||
default = "Test Framework"
|
||||
}
|
||||
|
||||
variable "primary_location" {
|
||||
type = string
|
||||
default = "northeurope"
|
||||
}
|
||||
|
||||
variable "secondary_location" {
|
||||
type = string
|
||||
default = "westeurope"
|
||||
}
|
||||
|
||||
variable "create_duration_delay" {
|
||||
type = map(string)
|
||||
default = {
|
||||
azurerm_management_group = "120s"
|
||||
}
|
||||
}
|
||||
|
||||
variable "destroy_duration_delay" {
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
data "azurerm_client_config" "connectivity" {
|
||||
provider = azurerm.connectivity
|
||||
}
|
||||
|
||||
data "azurerm_client_config" "management" {
|
||||
provider = azurerm.management
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
module "test_core" {
|
||||
source = "../../../"
|
||||
|
||||
providers = {
|
||||
azurerm = azurerm.management
|
||||
azurerm.connectivity = azurerm.connectivity
|
||||
azurerm.management = azurerm.management
|
||||
}
|
||||
|
||||
# Base module configuration settings
|
||||
root_parent_id = data.azurerm_client_config.management.tenant_id
|
||||
root_id = var.root_id
|
||||
root_name = var.root_name
|
||||
default_location = var.primary_location
|
||||
default_tags = module.settings.shared.default_tags
|
||||
|
||||
# Tuning delay timers to improve pipeline completion success rate
|
||||
create_duration_delay = var.create_duration_delay
|
||||
destroy_duration_delay = var.destroy_duration_delay
|
||||
|
||||
# Configuration settings for optional landing zones
|
||||
deploy_corp_landing_zones = true
|
||||
deploy_online_landing_zones = true
|
||||
deploy_sap_landing_zones = true
|
||||
deploy_demo_landing_zones = false
|
||||
|
||||
# Configure path for custom library folder and
|
||||
# custom template file variables
|
||||
library_path = "${path.root}/../test_lib"
|
||||
template_file_variables = module.settings.core.custom_template_file_variables
|
||||
|
||||
# Configuration settings for core resources
|
||||
deploy_core_landing_zones = true
|
||||
custom_landing_zones = module.settings.core.custom_landing_zones
|
||||
archetype_config_overrides = module.settings.core.archetype_config_overrides
|
||||
subscription_id_overrides = module.settings.core.subscription_id_overrides
|
||||
|
||||
# Configuration settings for management resources
|
||||
deploy_management_resources = false
|
||||
configure_management_resources = module.settings.management.configure_management_resources
|
||||
subscription_id_management = data.azurerm_client_config.management.subscription_id
|
||||
|
||||
# Configuration settings for connectivity resources
|
||||
deploy_connectivity_resources = false
|
||||
configure_connectivity_resources = module.settings.connectivity.configure_connectivity_resources
|
||||
subscription_id_connectivity = data.azurerm_client_config.connectivity.subscription_id
|
||||
|
||||
}
|
||||
|
||||
module "test_core_nested" {
|
||||
source = "../../../"
|
||||
|
||||
providers = {
|
||||
azurerm = azurerm.management
|
||||
azurerm.connectivity = azurerm.connectivity
|
||||
azurerm.management = azurerm.management
|
||||
}
|
||||
|
||||
# Base module configuration settings
|
||||
root_parent_id = "${var.root_id}-landing-zones"
|
||||
root_id = var.root_id
|
||||
root_name = var.root_name
|
||||
default_location = var.primary_location
|
||||
default_tags = module.settings.shared.default_tags
|
||||
|
||||
# Tuning delay timers to improve pipeline completion success rate
|
||||
create_duration_delay = var.create_duration_delay
|
||||
destroy_duration_delay = var.destroy_duration_delay
|
||||
|
||||
# Configure path for custom library folder and
|
||||
# custom template file variables
|
||||
library_path = "${path.root}/../test_lib"
|
||||
template_file_variables = module.settings.core.custom_template_file_variables
|
||||
|
||||
# Configuration settings for core resources
|
||||
deploy_core_landing_zones = false
|
||||
custom_landing_zones = module.settings.nested.custom_landing_zones
|
||||
|
||||
# Set dependency to ensure correct operation
|
||||
depends_on = [
|
||||
module.test_core,
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
module "test_management" {
|
||||
source = "../../../"
|
||||
|
||||
providers = {
|
||||
azurerm = azurerm.management
|
||||
azurerm.connectivity = azurerm.connectivity
|
||||
azurerm.management = azurerm.management
|
||||
}
|
||||
|
||||
# Base module configuration settings
|
||||
root_parent_id = data.azurerm_client_config.management.tenant_id
|
||||
root_id = var.root_id
|
||||
root_name = var.root_name
|
||||
default_location = var.primary_location
|
||||
default_tags = module.settings.shared.default_tags
|
||||
|
||||
# Configure path for custom library folder and
|
||||
# custom template file variables
|
||||
library_path = "${path.root}/../test_lib"
|
||||
template_file_variables = module.settings.core.custom_template_file_variables
|
||||
|
||||
# Configuration settings for core resources
|
||||
deploy_core_landing_zones = false
|
||||
|
||||
# Configuration settings for management resources
|
||||
deploy_management_resources = true
|
||||
configure_management_resources = module.settings.management.configure_management_resources
|
||||
subscription_id_management = data.azurerm_client_config.management.subscription_id
|
||||
|
||||
}
|
||||
|
||||
module "test_connectivity" {
|
||||
source = "../../../"
|
||||
|
||||
providers = {
|
||||
azurerm = azurerm.management
|
||||
azurerm.connectivity = azurerm.connectivity
|
||||
azurerm.management = azurerm.management
|
||||
}
|
||||
|
||||
# Base module configuration settings
|
||||
root_parent_id = data.azurerm_client_config.management.tenant_id
|
||||
root_id = var.root_id
|
||||
root_name = var.root_name
|
||||
default_location = var.primary_location
|
||||
default_tags = module.settings.shared.default_tags
|
||||
|
||||
# Configure path for custom library folder and
|
||||
# custom template file variables
|
||||
library_path = "${path.root}/../test_lib"
|
||||
template_file_variables = module.settings.core.custom_template_file_variables
|
||||
|
||||
# Configuration settings for core resources
|
||||
deploy_core_landing_zones = false
|
||||
|
||||
# Configuration settings for connectivity resources
|
||||
deploy_connectivity_resources = true
|
||||
configure_connectivity_resources = module.settings.connectivity.configure_connectivity_resources
|
||||
subscription_id_connectivity = data.azurerm_client_config.connectivity.subscription_id
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
# The following output gives the a summary of all resources
|
||||
# created by the enterprise_scale module, formatted to allow
|
||||
# easy identification of the resource IDs as stored in the
|
||||
# Terraform state.
|
||||
|
||||
output "resource_ids" {
|
||||
value = {
|
||||
for module_name, module_output in {
|
||||
test_core = module.test_core
|
||||
test_core_nested = module.test_core_nested
|
||||
test_management = module.test_management
|
||||
test_connectivity = module.test_connectivity
|
||||
} :
|
||||
module_name => {
|
||||
for resource_type, resource_instances in module_output :
|
||||
resource_type => {
|
||||
for resource_name, resource_configs in resource_instances :
|
||||
resource_name => keys(resource_configs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -0,0 +1,13 @@
|
|||
provider "azurerm" {
|
||||
features {}
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
alias = "connectivity"
|
||||
features {}
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
alias = "management"
|
||||
features {}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
# Obtain configuration settings.
|
||||
module "settings" {
|
||||
source = "../settings"
|
||||
|
||||
root_id = var.root_id
|
||||
primary_location = var.primary_location
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = "2.96.0"
|
||||
configuration_aliases = [
|
||||
azurerm.connectivity,
|
||||
azurerm.management,
|
||||
]
|
||||
}
|
||||
}
|
||||
backend "local" {
|
||||
path = "../tfstate/test_framework.tfstate"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
variable "root_id" {
|
||||
type = string
|
||||
default = "12345"
|
||||
}
|
||||
|
||||
variable "root_name" {
|
||||
type = string
|
||||
default = "Test Framework"
|
||||
}
|
||||
|
||||
variable "primary_location" {
|
||||
type = string
|
||||
default = "northeurope"
|
||||
}
|
||||
|
||||
variable "secondary_location" {
|
||||
type = string
|
||||
default = "westeurope"
|
||||
}
|
||||
|
||||
variable "create_duration_delay" {
|
||||
type = map(string)
|
||||
default = {
|
||||
azurerm_management_group = "120s"
|
||||
}
|
||||
}
|
||||
|
||||
variable "destroy_duration_delay" {
|
||||
type = map(string)
|
||||
default = {}
|
||||
}
|
|
@ -11,10 +11,10 @@ violation[management_group_display_name] {
|
|||
management_group_display_name := sprintf("The management_group_display_name planned values:\n \n %v \n \n are not equal to the management_group_display_name changed values:\n \n %v", [mgs_plan_display_name, mgs_change_display_name])
|
||||
}
|
||||
|
||||
# # # Compare the management_group_name and fail if they are not equal.
|
||||
violation[management_group_name] {
|
||||
# # # Compare the management_group_id and fail if they are not equal.
|
||||
violation[management_group_id] {
|
||||
mgs_plan_name != mgs_change_name
|
||||
management_group_name := sprintf("The management_group_name planned values:\n \n %v \n \n are not equal to the management_group_name changed values:\n \n %v", [mgs_plan_name, mgs_change_name])
|
||||
management_group_id := sprintf("The management_group_id planned values:\n \n %v \n \n are not equal to the management_group_id changed values:\n \n %v", [mgs_plan_name, mgs_change_name])
|
||||
}
|
||||
|
||||
########################
|
||||
|
|
|
@ -14,10 +14,10 @@ import data.child_modules
|
|||
# policy_definition_name := sprintf("The policy_definition_name planned values:\n \n %v \n \n are not equal to the policy_definition_name changed values:\n \n %v", [plc_def_plan_name, plc_def_change_name])
|
||||
# }
|
||||
|
||||
# # # # Compare the policy_definition_management_group_name and fail if they are not equal.
|
||||
# violation[policy_definition_management_group_name] {
|
||||
# plc_def_plan_management_group_name != plc_def_change_management_group_name
|
||||
# policy_definition_management_group_name := sprintf("The policy_definition_management_group_name planned values:\n \n %v \n \n are not equal to the policy_definition_management_group_name changed values:\n \n %v", [plc_def_plan_management_group_name, plc_def_change_management_group_name])
|
||||
# # # # Compare the policy_definition_management_group_id and fail if they are not equal.
|
||||
# violation[policy_definition_management_group_id] {
|
||||
# plc_def_plan_management_group_id != plc_def_change_management_group_id
|
||||
# policy_definition_management_group_id := sprintf("The policy_definition_management_group_id planned values:\n \n %v \n \n are not equal to the policy_definition_management_group_id changed values:\n \n %v", [plc_def_plan_management_group_id, plc_def_change_management_group_id])
|
||||
# }
|
||||
|
||||
# # # # Compare the policy_definition_metadata and fail if they are not equal.
|
||||
|
@ -62,24 +62,24 @@ plc_def_change_name[module_name] = pl_defs {
|
|||
]
|
||||
}
|
||||
|
||||
# # # Get the management_group_name from all policy definitions in planned_values.yml
|
||||
plc_def_plan_management_group_name[module_name] = pl_defs {
|
||||
# # # Get the management_group_id from all policy definitions in planned_values.yml
|
||||
plc_def_plan_management_group_id[module_name] = pl_defs {
|
||||
module := child_modules[_]
|
||||
module_name := module.address
|
||||
pl_defs := [pl_def |
|
||||
module.resources[i].type == "azurerm_policy_definition"
|
||||
pl_def := module.resources[i].values.management_group_name
|
||||
pl_def := module.resources[i].values.management_group_id
|
||||
]
|
||||
}
|
||||
|
||||
# # # Get the management_group_name from all policy definitions in the opa.json
|
||||
plc_def_change_management_group_name[module_name] = pl_defs {
|
||||
# # # Get the management_group_id from all policy definitions in the opa.json
|
||||
plc_def_change_management_group_id[module_name] = pl_defs {
|
||||
module := input.resource_changes[_]
|
||||
module_name := module.module_address
|
||||
pl_defs := [pl_def |
|
||||
input.resource_changes[r].type == "azurerm_policy_definition"
|
||||
input.resource_changes[r].module_address == module.module_address
|
||||
pl_def := input.resource_changes[r].change.after.management_group_name
|
||||
pl_def := input.resource_changes[r].change.after.management_group_id
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@ import data.child_modules
|
|||
# Rules
|
||||
########################
|
||||
|
||||
# # # Compare the policy_set_definition_management_group_name and fail if they are not equal.
|
||||
violation[policy_set_definition_management_group_name] {
|
||||
plc_set_def_plan_management_group_name != plc_set_def_change_management_group_name
|
||||
policy_set_definition_management_group_name := sprintf("The policy_set_definition_management_group_name planned values:\n \n %v \n \n are not equal to the policy_set_definition_management_group_name changed values:\n \n %v", [plc_set_def_plan_management_group_name, plc_set_def_change_management_group_name])
|
||||
# # # Compare the policy_set_definition_management_group_id and fail if they are not equal.
|
||||
violation[policy_set_definition_management_group_id] {
|
||||
plc_set_def_plan_management_group_id != plc_set_def_change_management_group_id
|
||||
policy_set_definition_management_group_id := sprintf("The policy_set_definition_management_group_id planned values:\n \n %v \n \n are not equal to the policy_set_definition_management_group_id changed values:\n \n %v", [plc_set_def_plan_management_group_id, plc_set_def_change_management_group_id])
|
||||
}
|
||||
|
||||
# # # Compare the policy_set_definition_metadata and fail if they are not equal.
|
||||
|
@ -40,24 +40,24 @@ violation[policy_set_definition_reference] {
|
|||
# Library
|
||||
########################
|
||||
|
||||
# # # Get the management_group_name from all policy set definitions in planned_values.yml
|
||||
plc_set_def_plan_management_group_name[module_name] = plcs {
|
||||
# # # Get the management_group_id from all policy set definitions in planned_values.yml
|
||||
plc_set_def_plan_management_group_id[module_name] = plcs {
|
||||
module := child_modules[_]
|
||||
module_name := module.address
|
||||
plcs := [plc |
|
||||
module.resources[i].type == "azurerm_policy_set_definition"
|
||||
plc := module.resources[i].values.management_group_name
|
||||
plc := module.resources[i].values.management_group_id
|
||||
]
|
||||
}
|
||||
|
||||
# # # Get the management_group_name from all policy set definitions in the opa.json
|
||||
plc_set_def_change_management_group_name[module_name] = plcs {
|
||||
# # # Get the management_group_id from all policy set definitions in the opa.json
|
||||
plc_set_def_change_management_group_id[module_name] = plcs {
|
||||
module := input.resource_changes[_]
|
||||
module_name := module.module_address
|
||||
plcs := [plc |
|
||||
input.resource_changes[r].type == "azurerm_policy_set_definition"
|
||||
input.resource_changes[r].module_address == module.module_address
|
||||
plc := input.resource_changes[r].change.after.management_group_name
|
||||
plc := input.resource_changes[r].change.after.management_group_id
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
name: 'SPN generator'
|
||||
name: "SPN generator"
|
||||
|
||||
trigger: none
|
||||
|
||||
|
@ -7,16 +7,16 @@ pool:
|
|||
vmImage: ubuntu-20.04
|
||||
|
||||
variables:
|
||||
- group: csu-tf-environment
|
||||
- group: csu-tf-environment
|
||||
|
||||
jobs:
|
||||
- job: run_spn_generator
|
||||
displayName: 'Run SPN generator'
|
||||
steps:
|
||||
- task: Bash@3
|
||||
displayName: 'Create or update SPN settings'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: 'make azp-spn-generator'
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
- job: run_spn_generator
|
||||
displayName: "Run SPN Generator"
|
||||
steps:
|
||||
- task: Bash@3
|
||||
displayName: "Create or update SPN settings"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make azp-spn-generator"
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
steps:
|
||||
- task: Bash@3
|
||||
name: prepare_backend
|
||||
displayName: "Prepare Backend Storage"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make azp-backend"
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
|
@ -1,27 +1,15 @@
|
|||
---
|
||||
steps:
|
||||
- task: Bash@3
|
||||
displayName: 'Terraform (install)'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: 'make tf-install'
|
||||
- task: Bash@3
|
||||
displayName: "Install Terraform Pre-requisites"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make tf-install"
|
||||
|
||||
- task: Bash@3
|
||||
displayName: 'Terraform (prepare)'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: 'make tf-prepare'
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
|
||||
- task: Bash@3
|
||||
displayName: 'Terraform (fmt)'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: 'make tf-fmt'
|
||||
|
||||
- task: Bash@3
|
||||
displayName: 'Terraform (init)'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: 'make tf-init'
|
||||
- task: Bash@3
|
||||
displayName: "Prepare Terraform Environment"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make tf-prepare"
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
parameters:
|
||||
- name: module_path
|
||||
type: string
|
||||
- name: run_type
|
||||
type: string
|
||||
|
||||
steps:
|
||||
- task: Bash@3
|
||||
displayName: "[terraform init]"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make tf-init"
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
TEST_MODULE_PATH: "${{ parameters.module_path }}"
|
||||
condition: and(succeeded(), in('${{ parameters.run_type }}', 'unit', 'e2e', 'destroy'))
|
||||
|
||||
- task: Bash@3
|
||||
displayName: "[terraform plan]"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make tf-plan"
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
TEST_MODULE_PATH: "${{ parameters.module_path }}"
|
||||
condition: and(succeeded(), in('${{ parameters.run_type }}', 'unit', 'e2e'))
|
||||
|
||||
- task: Bash@3
|
||||
displayName: "[conftest run]"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make opa-run-tests"
|
||||
env:
|
||||
TEST_MODULE_PATH: "${{ parameters.module_path }}"
|
||||
condition: and(succeeded(), eq('${{ parameters.run_type }}', 'unit'))
|
||||
|
||||
- task: Bash@3
|
||||
displayName: "[terraform apply]"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make tf-apply"
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
TEST_MODULE_PATH: "${{ parameters.module_path }}"
|
||||
condition: and(succeeded(), eq('${{ parameters.run_type }}', 'e2e'))
|
||||
|
||||
- task: Bash@3
|
||||
displayName: "[terraform destroy]"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make tf-destroy"
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
TEST_MODULE_PATH: "${{ parameters.module_path }}"
|
||||
condition: and(succeeded(), eq('${{ parameters.run_type }}', 'destroy'))
|
|
@ -1,11 +1,11 @@
|
|||
---
|
||||
steps:
|
||||
- task: PowerShell@2
|
||||
name: build_strategy
|
||||
displayName: "Generate Build Strategy"
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: 'make azp-strategy'
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
BILLING_SCOPE: $(BILLING_SCOPE)
|
||||
- task: PowerShell@2
|
||||
name: build_strategy
|
||||
displayName: "Generate Build Strategy"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make azp-strategy"
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
BILLING_SCOPE: $(BILLING_SCOPE)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
name: 'Tests (E2E)'
|
||||
name: "Tests (E2E)"
|
||||
|
||||
trigger: none
|
||||
|
||||
|
@ -7,43 +7,109 @@ pool:
|
|||
vmImage: ubuntu-20.04
|
||||
|
||||
variables:
|
||||
- group: csu-tf-environment
|
||||
- group: csu-tf-environment
|
||||
|
||||
jobs:
|
||||
- job: matrix_generator
|
||||
displayName: 'Matrix Generator'
|
||||
steps:
|
||||
- template: templates/tests-strategy.yml
|
||||
- job: matrix_generator
|
||||
displayName: "Matrix Generator"
|
||||
steps:
|
||||
- template: templates/tests-strategy.yml
|
||||
|
||||
- job: run_e2e_tests
|
||||
displayName: 'E2E Tests'
|
||||
dependsOn: matrix_generator
|
||||
strategy:
|
||||
matrix: $[ dependencies.matrix_generator.outputs['build_strategy.matrix_json'] ]
|
||||
steps:
|
||||
- template: templates/tests-common.yml
|
||||
- job: backend_generator
|
||||
displayName: "Backend Storage Generator"
|
||||
steps:
|
||||
- template: templates/tests-backend.yml
|
||||
|
||||
- task: Bash@3
|
||||
displayName: 'Terraform (plan)'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: 'make tf-plan'
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
- job: run_e2e_tests_001
|
||||
displayName: "E2E Tests 001"
|
||||
dependsOn:
|
||||
- matrix_generator
|
||||
- backend_generator
|
||||
strategy:
|
||||
matrix: $[ dependencies.matrix_generator.outputs['build_strategy.matrix_json'] ]
|
||||
variables:
|
||||
STORAGE_ACCOUNT_RSG_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_ACCOUNT_RSG_NAME'] ]
|
||||
STORAGE_ACCOUNT_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_ACCOUNT_NAME'] ]
|
||||
STORAGE_CONTAINER_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_CONTAINER_NAME'] ]
|
||||
timeoutInMinutes: 30
|
||||
steps:
|
||||
- template: templates/tests-common.yml
|
||||
|
||||
- task: Bash@3
|
||||
displayName: 'Terraform (apply)'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: 'make tf-apply'
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
- template: templates/tests-loop.yml
|
||||
parameters:
|
||||
module_path: "tests/modules/test_001_baseline"
|
||||
run_type: e2e
|
||||
|
||||
- task: Bash@3
|
||||
displayName: 'Terraform (destroy)'
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: 'make tf-destroy'
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
condition: always()
|
||||
- job: run_e2e_tests_002
|
||||
displayName: "E2E Tests 002"
|
||||
dependsOn:
|
||||
- matrix_generator
|
||||
- backend_generator
|
||||
- run_e2e_tests_001
|
||||
strategy:
|
||||
matrix: $[ dependencies.matrix_generator.outputs['build_strategy.matrix_json'] ]
|
||||
variables:
|
||||
STORAGE_ACCOUNT_RSG_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_ACCOUNT_RSG_NAME'] ]
|
||||
STORAGE_ACCOUNT_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_ACCOUNT_NAME'] ]
|
||||
STORAGE_CONTAINER_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_CONTAINER_NAME'] ]
|
||||
timeoutInMinutes: 30
|
||||
steps:
|
||||
- template: templates/tests-common.yml
|
||||
|
||||
- template: templates/tests-loop.yml
|
||||
parameters:
|
||||
module_path: "tests/modules/test_002_add_custom_core"
|
||||
run_type: e2e
|
||||
|
||||
- job: run_e2e_tests_003
|
||||
displayName: "E2E Tests 003"
|
||||
dependsOn:
|
||||
- matrix_generator
|
||||
- backend_generator
|
||||
- run_e2e_tests_002
|
||||
strategy:
|
||||
matrix: $[ dependencies.matrix_generator.outputs['build_strategy.matrix_json'] ]
|
||||
variables:
|
||||
STORAGE_ACCOUNT_RSG_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_ACCOUNT_RSG_NAME'] ]
|
||||
STORAGE_ACCOUNT_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_ACCOUNT_NAME'] ]
|
||||
STORAGE_CONTAINER_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_CONTAINER_NAME'] ]
|
||||
timeoutInMinutes: 60
|
||||
steps:
|
||||
- template: templates/tests-common.yml
|
||||
|
||||
- template: templates/tests-loop.yml
|
||||
parameters:
|
||||
module_path: "tests/modules/test_003_add_mgmt_conn"
|
||||
run_type: e2e
|
||||
|
||||
- job: run_e2e_clean_up
|
||||
displayName: "E2E Clean-up"
|
||||
dependsOn:
|
||||
- matrix_generator
|
||||
- backend_generator
|
||||
- run_e2e_tests_003
|
||||
strategy:
|
||||
matrix: $[ dependencies.matrix_generator.outputs['build_strategy.matrix_json'] ]
|
||||
variables:
|
||||
STORAGE_ACCOUNT_RSG_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_ACCOUNT_RSG_NAME'] ]
|
||||
STORAGE_ACCOUNT_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_ACCOUNT_NAME'] ]
|
||||
STORAGE_CONTAINER_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_CONTAINER_NAME'] ]
|
||||
timeoutInMinutes: 60
|
||||
cancelTimeoutInMinutes: 60
|
||||
condition: |
|
||||
or
|
||||
(
|
||||
and
|
||||
(
|
||||
or(failed(), canceled()),
|
||||
ne(variables.ALWAYS_DESTROY, 'false')
|
||||
),
|
||||
succeeded()
|
||||
)
|
||||
steps:
|
||||
- template: templates/tests-common.yml
|
||||
|
||||
- template: templates/tests-loop.yml
|
||||
parameters:
|
||||
module_path: "tests/modules/test_001_baseline"
|
||||
run_type: destroy
|
||||
|
|
|
@ -15,30 +15,48 @@ jobs:
|
|||
steps:
|
||||
- template: templates/tests-strategy.yml
|
||||
|
||||
- job: backend_generator
|
||||
displayName: "Backend Storage Generator"
|
||||
steps:
|
||||
- template: templates/tests-backend.yml
|
||||
|
||||
- job: run_unit_tests
|
||||
displayName: "Unit Tests"
|
||||
dependsOn: matrix_generator
|
||||
dependsOn:
|
||||
- matrix_generator
|
||||
- backend_generator
|
||||
strategy:
|
||||
matrix: $[ dependencies.matrix_generator.outputs['build_strategy.matrix_json'] ]
|
||||
variables:
|
||||
STORAGE_ACCOUNT_RSG_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_ACCOUNT_RSG_NAME'] ]
|
||||
STORAGE_ACCOUNT_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_ACCOUNT_NAME'] ]
|
||||
STORAGE_CONTAINER_NAME: $[ dependencies.backend_generator.outputs['prepare_backend.STORAGE_CONTAINER_NAME'] ]
|
||||
steps:
|
||||
- template: templates/tests-common.yml
|
||||
|
||||
- task: Bash@3
|
||||
displayName: "Terraform (plan)"
|
||||
displayName: "[terraform fmt]"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make tf-plan"
|
||||
env:
|
||||
ARM_CLIENT_SECRET: $(ARM_CLIENT_SECRET)
|
||||
script: "make tf-fmt"
|
||||
|
||||
- task: Bash@3
|
||||
displayName: "Opa Conftest (install)"
|
||||
displayName: "[conftest install]"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make opa-install"
|
||||
|
||||
- task: Bash@3
|
||||
displayName: "Conftest (run tests)"
|
||||
inputs:
|
||||
targetType: "inline"
|
||||
script: "make opa-run-tests"
|
||||
- template: templates/tests-loop.yml
|
||||
parameters:
|
||||
module_path: "tests/modules/test_001_baseline"
|
||||
run_type: unit
|
||||
|
||||
- template: templates/tests-loop.yml
|
||||
parameters:
|
||||
module_path: "tests/modules/test_002_add_custom_core"
|
||||
run_type: unit
|
||||
|
||||
- template: templates/tests-loop.yml
|
||||
parameters:
|
||||
module_path: "tests/modules/test_003_add_mgmt_conn"
|
||||
run_type: unit
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/bash
|
||||
set -e
|
||||
|
||||
#
|
||||
# Shell Script
|
||||
# - Terraform Create or Update Azure Backend Storage
|
||||
#
|
||||
|
||||
echo "==> Authenticating cli..."
|
||||
az login \
|
||||
--service-principal \
|
||||
--tenant "$ARM_TENANT_ID" \
|
||||
--username "$ARM_CLIENT_ID" \
|
||||
--password "$ARM_CLIENT_SECRET" \
|
||||
--query [?isDefault]
|
||||
|
||||
echo "==> Setting active Subscription..."
|
||||
az account set \
|
||||
--subscription "$ARM_SUBSCRIPTION_ID"
|
||||
az account list \
|
||||
--query "[?isDefault]"
|
||||
|
||||
echo "==> Create or update Resource Group..."
|
||||
RSG_NAME="$DEFAULT_PREFIX"
|
||||
az group create \
|
||||
--name "$RSG_NAME" \
|
||||
--location "$PRIMARY_LOCATION" \
|
||||
--query 'properties.provisioningState' \
|
||||
--out tsv
|
||||
|
||||
# Set STORAGE_ACCOUNT_RSG_NAME to an output variable for downstream consumption.
|
||||
echo "##vso[task.setVariable variable=STORAGE_ACCOUNT_RSG_NAME;isOutput=true]$RSG_NAME"
|
||||
|
||||
echo "==> Create or update Storage Account..."
|
||||
# Storage account name must be lowercase alphanumeric
|
||||
SA_NAME=$(
|
||||
echo "$DEFAULT_PREFIX$PRIMARY_LOCATION" |
|
||||
tr '[:upper:]' '[:lower:]' |
|
||||
tr -cd '[:alnum:]'
|
||||
)
|
||||
SA_ID=$(
|
||||
az storage account create \
|
||||
--name "$SA_NAME" \
|
||||
--resource-group "$RSG_NAME" \
|
||||
--location "$PRIMARY_LOCATION" \
|
||||
--kind 'StorageV2' \
|
||||
--access-tier 'Hot' \
|
||||
--sku 'Standard_LRS' \
|
||||
--min-tls-version 'TLS1_2' \
|
||||
--query 'id' \
|
||||
--out tsv
|
||||
)
|
||||
|
||||
# Set STORAGE_ACCOUNT_NAME to an output variable for downstream consumption.
|
||||
echo "##vso[task.setVariable variable=STORAGE_ACCOUNT_NAME;isOutput=true]$SA_NAME"
|
||||
|
||||
echo "==> Create or update Storage Account permissions..."
|
||||
az role assignment create \
|
||||
--role 'Storage Blob Data Contributor' \
|
||||
--assignee "$ARM_CLIENT_ID" \
|
||||
--scope "$SA_ID"
|
||||
|
||||
echo "==> Create or update Storage Account container..."
|
||||
SC_NAME="tfstate"
|
||||
az storage container create \
|
||||
--name "$SC_NAME" \
|
||||
--auth-mode 'login' \
|
||||
--account-name "$SA_NAME" \
|
||||
--query 'created' \
|
||||
--out tsv
|
||||
|
||||
# Set STORAGE_CONTAINER_NAME to an output variable for downstream consumption.
|
||||
echo "##vso[task.setVariable variable=STORAGE_CONTAINER_NAME;isOutput=true]$SC_NAME"
|
|
@ -24,7 +24,7 @@ echo "==> Create or update Resource Group..."
|
|||
RSG_NAME="$DEFAULT_PREFIX"
|
||||
az group create \
|
||||
--name "$RSG_NAME" \
|
||||
--location "$DEFAULT_LOCATION" \
|
||||
--location "$PRIMARY_LOCATION" \
|
||||
--query 'properties.provisioningState' \
|
||||
--out tsv
|
||||
|
||||
|
@ -44,7 +44,7 @@ if [ -z "$KV_EXISTS" ]; then
|
|||
az keyvault create \
|
||||
--resource-group "$RSG_NAME" \
|
||||
--name "$KEY_VAULT_NAME" \
|
||||
--location "$DEFAULT_LOCATION" \
|
||||
--location "$PRIMARY_LOCATION" \
|
||||
--query 'properties.provisioningState' \
|
||||
--out tsv
|
||||
else
|
||||
|
|
|
@ -23,6 +23,15 @@ $jsonDepth = 4
|
|||
$terraformUrl = "https://api.github.com/repos/hashicorp/terraform/tags"
|
||||
$azurermProviderUrl = "https://registry.terraform.io/v1/providers/hashicorp/azurerm"
|
||||
|
||||
function Get-RandomId {
|
||||
[CmdletBinding()]
|
||||
[OutputType([String])]
|
||||
param (
|
||||
[Int]$Length = 8
|
||||
)
|
||||
return -join ((48..57) + (97..122) | Get-Random -Count $Length | ForEach-Object { [char]$_ })
|
||||
}
|
||||
|
||||
########################################
|
||||
# Terraform Versions
|
||||
# - Base Version: "0.15.0"
|
||||
|
@ -44,11 +53,11 @@ $terraformVersionsCount = $terraformVersions.Count
|
|||
|
||||
#######################################
|
||||
# Terraform AzureRM Provider Versions
|
||||
# - Base Version: (2.77.0)
|
||||
# - Base Version: (2.96.0)
|
||||
# - Latest Versions: (latest 1)
|
||||
#######################################
|
||||
|
||||
$azurermProviderVersionBase = "2.77.0"
|
||||
$azurermProviderVersionBase = "2.96.0"
|
||||
$azurermProviderVersionLatest = (Invoke-RestMethod -Method Get -Uri $azurermProviderUrl).version
|
||||
|
||||
#######################################
|
||||
|
@ -149,6 +158,7 @@ for ($i = 0; $i -lt $terraformVersionsCount; $i++) {
|
|||
$matrixObject | Add-Member `
|
||||
-NotePropertyName $jobName1 `
|
||||
-NotePropertyValue @{
|
||||
TF_ROOT_ID = Get-RandomId
|
||||
TF_VERSION = $terraformVersion
|
||||
TF_AZ_VERSION = $azurermProviderVersionBase
|
||||
TF_JOB_ID = $jobId1
|
||||
|
@ -159,6 +169,7 @@ for ($i = 0; $i -lt $terraformVersionsCount; $i++) {
|
|||
$matrixObject | Add-Member `
|
||||
-NotePropertyName $jobName2 `
|
||||
-NotePropertyValue @{
|
||||
TF_ROOT_ID = Get-RandomId
|
||||
TF_VERSION = $terraformVersion
|
||||
TF_AZ_VERSION = $azurermProviderVersionLatest
|
||||
TF_JOB_ID = $jobId2
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/pwsh
|
||||
|
||||
#
|
||||
# PowerShell Script
|
||||
# - Conftest Install
|
||||
#
|
||||
|
||||
# Install Scoop
|
||||
if (Get-command -name scoop -ErrorAction SilentlyContinue) {
|
||||
Write-Output "==> Scoop exists, skip install"
|
||||
scoop --version
|
||||
scoop update
|
||||
}
|
||||
else {
|
||||
Write-Output "`n"
|
||||
Write-Output "==> To run Conftest tests on Windows, some utilities need to be installed with Scoop"
|
||||
Write-Output "==> To install Scoop on Windows, run this command from a new terminal:"
|
||||
Write-Output "`n"
|
||||
Write-Output "Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https:\\get.scoop.sh')"
|
||||
Write-Output "`n"
|
||||
Write-Output "==> After installing Scoop, run: ./opa-values-generator.ps1"
|
||||
Write-Output "`n"
|
||||
exit
|
||||
}
|
||||
|
||||
# Install Terraform
|
||||
if (Get-command -name terraform -ErrorAction SilentlyContinue) {
|
||||
Write-Output "==> Terraform exists, skip install"
|
||||
terraform version
|
||||
}
|
||||
else {
|
||||
Write-Output "==> Install Terraform on Windows..."
|
||||
scoop install terraform
|
||||
}
|
||||
|
||||
# Install jq
|
||||
if (Get-command -name jq -ErrorAction SilentlyContinue) {
|
||||
Write-Output "==> jq exists, skip install"
|
||||
jq --version
|
||||
}
|
||||
else {
|
||||
Write-Output "==> Install jq on Windows..."
|
||||
scoop install jq
|
||||
}
|
||||
|
||||
# Install yq
|
||||
if (Get-command -name yq -ErrorAction SilentlyContinue) {
|
||||
Write-Output "==> yq exists, skip install"
|
||||
yq --version
|
||||
}
|
||||
else {
|
||||
Write-Output "==> Install yq on Windows..."
|
||||
scoop install yq
|
||||
}
|
||||
|
||||
# Install Conftest
|
||||
if (Get-command -name conftest -ErrorAction SilentlyContinue) {
|
||||
Write-Output "==> conftest exists, skip install"
|
||||
conftest --version
|
||||
}
|
||||
else {
|
||||
Write-Output "==> Install conftest on Windows..."
|
||||
scoop bucket add instrumenta https://github.com/instrumenta/scoop-instrumenta
|
||||
scoop install conftest
|
||||
}
|
|
@ -6,7 +6,8 @@ set -e
|
|||
# - OPA Run Tests
|
||||
#
|
||||
# # Parameters
|
||||
TF_PLAN_JSON="terraform-plan-$TF_VERSION-$TF_AZ_VERSION"
|
||||
TF_WORKSPACE="$PIPELINE_WORKSPACE/s/$TEST_MODULE_PATH"
|
||||
TF_PLAN_OUT="$TF_WORKSPACE/terraform-plan-$TF_VERSION-$TF_AZ_VERSION"
|
||||
|
||||
# # # Store data temporarily
|
||||
TEMP_FILE_01=$(mktemp).json
|
||||
|
@ -14,43 +15,42 @@ TEMP_FILE_02=$(mktemp).json
|
|||
|
||||
# # # Update the planned_values.json with the latest parameters
|
||||
echo "==> Update planned values..."
|
||||
cd "$PIPELINE_WORKSPACE/s/tests/deployment"
|
||||
jq '(.. | strings) |= gsub("root-id-1"; "'"$TF_ROOT_ID_1"'")' planned_values.json >"$TEMP_FILE_01"
|
||||
jq '(.. | strings) |= gsub("root-id-2"; "'"$TF_ROOT_ID_2"'")' "$TEMP_FILE_01" >"$TEMP_FILE_02"
|
||||
jq '(.. | strings) |= gsub("root-id-3"; "'"$TF_ROOT_ID_3"'")' "$TEMP_FILE_02" >"$TEMP_FILE_01"
|
||||
cd "$TF_WORKSPACE"
|
||||
jq '(.. | strings) |= gsub("root-id-1"; "'"$TF_ROOT_ID"'")' planned_values.json >"$TEMP_FILE_01"
|
||||
jq '(.. | strings) |= gsub("root-name"; "ES-'"$TF_VERSION"'-'"$TF_AZ_VERSION"'")' "$TEMP_FILE_01" >"$TEMP_FILE_02"
|
||||
jq '(.. | strings) |= gsub("eastus"; "eastus")' "$TEMP_FILE_02" >"$TF_PLAN_JSON"_updated_planned_values.json
|
||||
jq '(.. | strings) |= gsub("northeurope"; "northeurope")' "$TEMP_FILE_02" >"$TEMP_FILE_01"
|
||||
jq '(.. | strings) |= gsub("westeurope"; "westeurope")' "$TEMP_FILE_01" >"$TF_PLAN_OUT"_updated_planned_values.json
|
||||
|
||||
echo "==> Module Location - $DEFAULT_LOCATION"
|
||||
echo "==> Azure {TF_ROOT_ID_1} - ${TF_ROOT_ID_1}"
|
||||
echo "==> Azure TF_ROOT_ID_1 - $TF_ROOT_ID_1"
|
||||
echo "==> Module Locations - $PRIMARY_LOCATION ($SECONDARY_LOCATION)"
|
||||
echo "==> Azure {TF_ROOT_ID} - ${TF_ROOT_ID}"
|
||||
echo "==> Azure TF_ROOT_ID - $TF_ROOT_ID"
|
||||
|
||||
wait
|
||||
|
||||
echo "==> Converting to yaml..."
|
||||
yq <"$TF_PLAN_JSON"_updated_planned_values.json e -P - >../opa/policy/"$TF_PLAN_JSON"_updated_planned_values.yml
|
||||
yq <"$TF_PLAN_OUT"_updated_planned_values.json e -P - >"$TF_PLAN_OUT"_updated_planned_values.yml
|
||||
|
||||
wait
|
||||
|
||||
echo "==> Check yaml for errors..."
|
||||
yamllint -d relaxed ../opa/policy/"$TF_PLAN_JSON"_updated_planned_values.yml
|
||||
yamllint -d relaxed "$TF_PLAN_OUT"_updated_planned_values.yml
|
||||
|
||||
echo "==> Running conftest..."
|
||||
echo
|
||||
echo "==> Testing management_groups..."
|
||||
conftest test "$TF_PLAN_JSON".json -p ../opa/policy/management_groups.rego -d ../opa/policy/"$TF_PLAN_JSON"_updated_planned_values.yml
|
||||
conftest test "$TF_PLAN_OUT".json -p ../../opa/policy/management_groups.rego -d "$TF_PLAN_OUT"_updated_planned_values.yml
|
||||
echo
|
||||
echo "==> Testing role_definitions..."
|
||||
conftest test "$TF_PLAN_JSON".json -p ../opa/policy/role_definitions.rego -d ../opa/policy/"$TF_PLAN_JSON"_updated_planned_values.yml
|
||||
conftest test "$TF_PLAN_OUT".json -p ../../opa/policy/role_definitions.rego -d "$TF_PLAN_OUT"_updated_planned_values.yml
|
||||
echo
|
||||
echo "==> Testing role_assignments..."
|
||||
conftest test "$TF_PLAN_JSON".json -p ../opa/policy/role_assignments.rego -d ../opa/policy/"$TF_PLAN_JSON"_updated_planned_values.yml
|
||||
conftest test "$TF_PLAN_OUT".json -p ../../opa/policy/role_assignments.rego -d "$TF_PLAN_OUT"_updated_planned_values.yml
|
||||
echo
|
||||
echo "==> Testing policy_set_definitions..."
|
||||
conftest test "$TF_PLAN_JSON".json -p ../opa/policy/policy_set_definitions.rego -d ../opa/policy/"$TF_PLAN_JSON"_updated_planned_values.yml
|
||||
conftest test "$TF_PLAN_OUT".json -p ../../opa/policy/policy_set_definitions.rego -d "$TF_PLAN_OUT"_updated_planned_values.yml
|
||||
echo
|
||||
echo "==> Testing policy_definitions..."
|
||||
conftest test "$TF_PLAN_JSON".json -p ../opa/policy/policy_definitions.rego -d ../opa/policy/"$TF_PLAN_JSON"_updated_planned_values.yml
|
||||
conftest test "$TF_PLAN_OUT".json -p ../../opa/policy/policy_definitions.rego -d "$TF_PLAN_OUT"_updated_planned_values.yml
|
||||
echo
|
||||
echo "==> Testing policy_assignments..."
|
||||
conftest test "$TF_PLAN_JSON".json -p ../opa/policy/policy_assignments.rego -d ../opa/policy/"$TF_PLAN_JSON"_updated_planned_values.yml
|
||||
conftest test "$TF_PLAN_OUT".json -p ../../opa/policy/policy_assignments.rego -d "$TF_PLAN_OUT"_updated_planned_values.yml
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#!/usr/bin/pwsh
|
||||
|
||||
###############################################
|
||||
# Run tests and generate testing values.
|
||||
###############################################
|
||||
|
@ -6,9 +8,7 @@
|
|||
# The script will install all the necessary components locally and run the tests.
|
||||
# After completing the tests, follow the script prompt for the next steps.
|
||||
|
||||
|
||||
# # Parameters
|
||||
$PLAN_NAME = "terraform-plan"
|
||||
$CONFIRM = "y"
|
||||
|
||||
# # #? Run a local test against a different module configuration:
|
||||
|
@ -16,142 +16,114 @@ $CONFIRM = "y"
|
|||
# # #* Copy paste the variables.tf file from deployment folder and adjust your main.tf
|
||||
###############################################
|
||||
# # #* Path of the tested _es terraform module
|
||||
$MODULE_PATH = "../deployment"
|
||||
$BASE_PATH = $(Get-Location).Path
|
||||
$MODULE_PATHS = @(
|
||||
"$($BASE_PATH)/../modules/test_001_baseline"
|
||||
"$($BASE_PATH)/../modules/test_002_add_custom_core"
|
||||
"$($BASE_PATH)/../modules/test_003_add_mgmt_conn"
|
||||
)
|
||||
###############################################
|
||||
|
||||
$PWSH_OS = $PSVersionTable.OS
|
||||
$PWSH_PLATFORM = $PSVersionTable.Platform
|
||||
|
||||
# Install Scoop
|
||||
if (Get-command -name scoop -ErrorAction SilentlyContinue) {
|
||||
Write-Output "==> Scoop exists, skip install"
|
||||
scoop --version
|
||||
scoop update
|
||||
Write-Output "################################################"
|
||||
Write-Output "==> Initiate installation of pre-requisites..."
|
||||
Write-Output "==> OS : $PWSH_OS"
|
||||
Write-Output "==> Platform : $PWSH_PLATFORM"
|
||||
Write-Output "`n"
|
||||
|
||||
if (($PWSH_OS -like "*Windows*") -and ($PWSH_PLATFORM -eq "Win32NT")) {
|
||||
./opa-install-windows.ps1
|
||||
}
|
||||
else {
|
||||
Write-Output "`n"
|
||||
Write-Output "==> To run Conftest tests on Windows, some utilities need to be installed with Scoop"
|
||||
Write-Output "==> To install Scoop on Windows, run this command from a new terminal:"
|
||||
Write-Output "`n"
|
||||
Write-Output "Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https:\\get.scoop.sh')"
|
||||
Write-Output "`n"
|
||||
Write-Output "==> After installing Scoop, run: .\opa-values-generator.ps1"
|
||||
Write-Output "`n"
|
||||
exit
|
||||
elseif (($PWSH_OS -like "Darwin*") -and ($PWSH_PLATFORM -eq "Unix")) {
|
||||
Write-Output "Support for MacOS still in development. Please ensure pre-requisites are manually installed and re-run this script if errors occur due to missing software."
|
||||
}
|
||||
elseif (($PWSH_OS -like "Linux*") -and ($PWSH_PLATFORM -eq "Unix")) {
|
||||
source opa-install-linux.sh
|
||||
}
|
||||
|
||||
# Install Terraform
|
||||
if (Get-command -name terraform -ErrorAction SilentlyContinue) {
|
||||
Write-Output "==> Terraform exists, skip install"
|
||||
terraform version
|
||||
Write-Output "`n"
|
||||
Write-Output "==> Completed installation of pre-requisites."
|
||||
Write-Output "################################################"
|
||||
Write-Output "`n"
|
||||
|
||||
foreach ($MODULE_PATH in $MODULE_PATHS) {
|
||||
|
||||
if (-not ($MODULE_PATH | Test-Path)) { Throw "The directory does not exist, check entries in MODULE_PATHS variable on .\opa-values-generator.ps1 :line 18" }
|
||||
|
||||
$TF_PLAN_OUT = "$MODULE_PATH/terraform_plan"
|
||||
$PLANNED_VALUES = "$MODULE_PATH/planned_values"
|
||||
$MODULE_NAME = Split-Path $MODULE_PATH -Leaf
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Change to the module root directory..."
|
||||
Set-Location $MODULE_PATH
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Initializing infrastructure..."
|
||||
terraform init -upgrade
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Planning infrastructure..."
|
||||
terraform plan `
|
||||
-var="root_id=root-id-1" `
|
||||
-var="root_name=root-name" `
|
||||
-var="primary_location=northeurope" `
|
||||
-var="secondary_location=westeurope" `
|
||||
-out="$TF_PLAN_OUT"
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Converting plan to *.json..."
|
||||
terraform show -json "$TF_PLAN_OUT" | Out-File -FilePath "$TF_PLAN_OUT.json"
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Removing the original plan..."
|
||||
Remove-Item -Path "$TF_PLAN_OUT"
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Saving planned values to a temporary planned_values.json..."
|
||||
Get-Content -Path "$TF_PLAN_OUT.json" | jq '.planned_values.root_module' | Out-File -FilePath "$PLANNED_VALUES.json"
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Converting to yaml..."
|
||||
Get-Content -Path "$PLANNED_VALUES.json" | yq e -P - | Tee-Object "$PLANNED_VALUES.yml"
|
||||
|
||||
# # # Run OPA Tests
|
||||
Set-Location $MODULE_PATH
|
||||
Write-Output "==> ($MODULE_NAME) - Running conftest..."
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Testing management_groups..."
|
||||
conftest test "$TF_PLAN_OUT.json" -p ../../opa/policy/management_groups.rego -d "$PLANNED_VALUES.yml"
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Testing role_definitions..."
|
||||
conftest test "$TF_PLAN_OUT.json" -p ../../opa/policy/role_definitions.rego -d "$PLANNED_VALUES.yml"
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Testing role_assignments..."
|
||||
conftest test "$TF_PLAN_OUT.json" -p ../../opa/policy/role_assignments.rego -d "$PLANNED_VALUES.yml"
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Testing policy_set_definitions..."
|
||||
conftest test "$TF_PLAN_OUT.json" -p ../../opa/policy/policy_set_definitions.rego -d "$PLANNED_VALUES.yml"
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Testing policy_definitions..."
|
||||
conftest test "$TF_PLAN_OUT.json" -p ../../opa/policy/policy_definitions.rego -d "$PLANNED_VALUES.yml"
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Testing policy_assignments..."
|
||||
conftest test "$TF_PLAN_OUT.json" -p ../../opa/policy/policy_assignments.rego -d "$PLANNED_VALUES.yml"
|
||||
|
||||
# # # Remove comments and $CONFIRM parameter for CMD prompt.
|
||||
# # # $CONFIRM = Read-Host "Do you want to prepare files for repository (y/n)?"
|
||||
if ($CONFIRM -eq 'y') {
|
||||
Write-Output "`n"
|
||||
Remove-Item -Path "$TF_PLAN_OUT.json"
|
||||
Write-Output "==> ($MODULE_NAME) - $TF_PLAN_OUT.json has been removed"
|
||||
Write-Output "`n"
|
||||
Remove-Item -Path "$PLANNED_VALUES.yml"
|
||||
Write-Output "==> ($MODULE_NAME) - $PLANNED_VALUES.yml has been removed"
|
||||
Write-Output "`n"
|
||||
}
|
||||
else {
|
||||
Write-Warning -Message "($MODULE_NAME) - $TF_PLAN_OUT.json can contain sensitive data"
|
||||
Write-Warning -Message "($MODULE_NAME) - Exposing $TF_PLAN_OUT.json in a repository can cause security breach"
|
||||
Write-Output "`n"
|
||||
Write-Output "($MODULE_NAME) - From within your terraform root module: conftest test $TF_PLAN_OUT.json -p ../../opa/policy/ -d $PLANNED_VALUES.yml"
|
||||
Write-Output "`n"
|
||||
}
|
||||
|
||||
Write-Output "==> ($MODULE_NAME) - Return to scripts directory..."
|
||||
Set-Location $BASE_PATH
|
||||
|
||||
}
|
||||
else {
|
||||
Write-Output "==> Install Terraform on Windows..."
|
||||
scoop install terraform
|
||||
}
|
||||
|
||||
# Install jq
|
||||
if (Get-command -name jq -ErrorAction SilentlyContinue) {
|
||||
Write-Output "==> jq exists, skip install"
|
||||
jq --version
|
||||
}
|
||||
else {
|
||||
Write-Output "==> Install jq on Windows..."
|
||||
scoop install jq
|
||||
}
|
||||
|
||||
# Install yq
|
||||
if (Get-command -name yq -ErrorAction SilentlyContinue) {
|
||||
Write-Output "==> yq exists, skip install"
|
||||
yq --version
|
||||
}
|
||||
else {
|
||||
Write-Output "==> Install yq on Windows..."
|
||||
scoop install yq
|
||||
}
|
||||
|
||||
# Install Conftest
|
||||
if (Get-command -name conftest -ErrorAction SilentlyContinue) {
|
||||
Write-Output "==> conftest exists, skip install"
|
||||
conftest --version
|
||||
}
|
||||
else {
|
||||
Write-Output "==> Install conftest on Windows..."
|
||||
scoop bucket add instrumenta https://github.com/instrumenta/scoop-instrumenta
|
||||
scoop install conftest
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (-not ($MODULE_PATH | Test-Path)) { Throw "The directory does not exist, check path on .\opa-values-generator.ps1 :line 18" }
|
||||
|
||||
Write-Output "==> Change to the module root directory..."
|
||||
Set-Location $MODULE_PATH
|
||||
|
||||
Write-Output "==> Initializing infrastructure..."
|
||||
terraform init
|
||||
|
||||
Write-Output "==> Planning infrastructure..."
|
||||
terraform plan `
|
||||
-var="root_id_1=root-id-1" `
|
||||
-var="root_id_2=root-id-2" `
|
||||
-var="root_id_3=root-id-3" `
|
||||
-var="root_name=root-name" `
|
||||
-var="location=eastus" `
|
||||
-out="$PLAN_NAME"
|
||||
|
||||
Write-Output "==> Converting plan to *.json..."
|
||||
terraform show -json $PLAN_NAME | Out-File -FilePath .\$PLAN_NAME.json
|
||||
|
||||
Write-Output "==> Removing the original plan..."
|
||||
Remove-Item -Path .\$PLAN_NAME
|
||||
|
||||
Write-Output "==> Saving planned values to a temporary planned_values.json..."
|
||||
Get-Content -Path .\$PLAN_NAME.json | jq '.planned_values.root_module' | Out-File -FilePath .\planned_values.json
|
||||
|
||||
Write-Output "==> Converting to yaml..."
|
||||
Get-Content -Path .\planned_values.json | yq e -P - | Tee-Object ..\opa\policy\planned_values.yml
|
||||
|
||||
|
||||
# # # Run OPA Tests
|
||||
Set-Location $MODULE_PATH
|
||||
Write-Output "==> Running conftest..."
|
||||
|
||||
Write-Output "==> Testing management_groups..."
|
||||
conftest test "$PLAN_NAME.json" -p ..\opa\policy\management_groups.rego -d ..\opa\policy\planned_values.yml
|
||||
|
||||
Write-Output "==> Testing role_definitions..."
|
||||
conftest test "$PLAN_NAME.json" -p ..\opa\policy\role_definitions.rego -d ..\opa\policy\planned_values.yml
|
||||
|
||||
Write-Output "==> Testing role_assignments..."
|
||||
conftest test "$PLAN_NAME.json" -p ..\opa\policy\role_assignments.rego -d ..\opa\policy\planned_values.yml
|
||||
|
||||
Write-Output "==> Testing policy_set_definitions..."
|
||||
conftest test "$PLAN_NAME.json" -p ..\opa\policy\policy_set_definitions.rego -d ..\opa\policy\planned_values.yml
|
||||
|
||||
Write-Output "==> Testing policy_definitions..."
|
||||
conftest test "$PLAN_NAME.json" -p ..\opa\policy\policy_definitions.rego -d ..\opa\policy\planned_values.yml
|
||||
|
||||
Write-Output "==> Testing policy_assignments..."
|
||||
conftest test "$PLAN_NAME.json" -p ..\opa\policy\policy_assignments.rego -d ..\opa\policy\planned_values.yml
|
||||
|
||||
|
||||
|
||||
# # # Remove comments and $CONFIRM parameter for CMD prompt.
|
||||
# # # $CONFIRM = Read-Host "Do you want to prepare files for repository (y/n)?"
|
||||
if ($CONFIRM -eq 'y') {
|
||||
Write-Output "`n"
|
||||
Remove-Item -Path .\$PLAN_NAME.json
|
||||
Write-Output "$PLAN_NAME.json has been removed from your root module"
|
||||
Write-Output "`n"
|
||||
Remove-Item -Path ..\opa\policy\planned_values.yml
|
||||
Write-Output "planned_values.yml has been removed from your \opa\policy\ directory"
|
||||
Write-Output "`n"
|
||||
}
|
||||
else {
|
||||
Write-Warning -Message "$PLAN_NAME.json can contain sensitive data"
|
||||
Write-Warning -Message "Exposing $PLAN_NAME.json in a repository can cause security breach"
|
||||
Write-Output "`n"
|
||||
Write-Output "From within your terraform root module: conftest test $PLAN_NAME.json -p ..\opa\policy\ -d ..\opa\policy\planned_values.yml"
|
||||
Write-Output "`n"
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
#
|
||||
# Shell Script
|
||||
# - OPA Run Tests
|
||||
###############################################
|
||||
# Run tests and generate testing values.
|
||||
###############################################
|
||||
|
||||
# # Parameters
|
||||
PLAN_NAME=terraform-plan
|
||||
CONFIRM="y"
|
||||
|
||||
# shellcheck source=tests/scripts/opa-install.sh
|
||||
source opa-install.sh
|
||||
|
||||
# Run this locally to test your terraform configuration and generate the values needed for the automation pipeline.
|
||||
# The script will install all the necessary components locally and run the tests.
|
||||
# After completing the tests, follow the script prompt for the next steps.
|
||||
#
|
||||
# # #? Run a local test against a different module configuration:
|
||||
# # #* Update the path to run the tests on a different folder (example: ../deployment_2)
|
||||
# # #* Copy paste the variables.tf file from deployment folder and adjust your main.tf
|
||||
###############################################
|
||||
# # #* Path of the tested _es terraform module
|
||||
MODULE_PATH="../deployment"
|
||||
###############################################
|
||||
|
||||
echo
|
||||
if [ ! -d "$MODULE_PATH" ]; then
|
||||
echo "The ${MODULE_PATH} directory does not exist, check path on .\opa-values-generator.sh :line 26"
|
||||
exit
|
||||
fi
|
||||
|
||||
echo "==> Change to the module root directory..."
|
||||
cd $MODULE_PATH
|
||||
|
||||
echo "==> Initializing infrastructure..."
|
||||
terraform init
|
||||
|
||||
echo "==> Planning infrastructure..."
|
||||
terraform plan \
|
||||
-var="root_id_1=root-id-1" \
|
||||
-var="root_id_2=root-id-2" \
|
||||
-var="root_id_3=root-id-3" \
|
||||
-var="root_name=root-name" \
|
||||
-var="location=eastus" \
|
||||
-out=$PLAN_NAME
|
||||
|
||||
echo "==> Converting plan to *.json..."
|
||||
terraform show -json "$PLAN_NAME" >"$PLAN_NAME".json
|
||||
|
||||
echo "==> Removing the original plan..."
|
||||
rm "$PLAN_NAME"
|
||||
|
||||
echo "==> Saving planned values to a temporary planned_values.json..."
|
||||
jq <"$PLAN_NAME.json" '.planned_values.root_module' >planned_values.json
|
||||
|
||||
echo "==> Converting to yaml..."
|
||||
yq <planned_values.json e -P - >../opa/policy/planned_values.yml
|
||||
|
||||
echo "==> Check yaml for errors..."
|
||||
yamllint -d relaxed ../opa/policy/planned_values.yml
|
||||
|
||||
echo "==> Running conftest..."
|
||||
cd $MODULE_PATH
|
||||
echo
|
||||
echo "==> Testing management_groups..."
|
||||
conftest test "$PLAN_NAME".json -p ../opa/policy/management_groups.rego -d ../opa/policy/planned_values.yml
|
||||
echo
|
||||
echo "==> Testing role_definitions..."
|
||||
conftest test "$PLAN_NAME".json -p ../opa/policy/role_definitions.rego -d ../opa/policy/planned_values.yml
|
||||
echo
|
||||
echo "==> Testing role_assignments..."
|
||||
conftest test "$PLAN_NAME".json -p ../opa/policy/role_assignments.rego -d ../opa/policy/planned_values.yml
|
||||
echo
|
||||
echo "==> Testing policy_set_definitions..."
|
||||
conftest test "$PLAN_NAME".json -p ../opa/policy/policy_set_definitions.rego -d ../opa/policy/planned_values.yml
|
||||
echo
|
||||
echo "==> Testing policy_definitions..."
|
||||
conftest test "$PLAN_NAME".json -p ../opa/policy/policy_definitions.rego -d ../opa/policy/planned_values.yml
|
||||
echo
|
||||
echo "==> Testing policy_assignments..."
|
||||
conftest test "$PLAN_NAME".json -p ../opa/policy/policy_assignments.rego -d ../opa/policy/planned_values.yml
|
||||
|
||||
# # # Remove "<<-EOF $CONFIRM EOF" for CMD prompt.
|
||||
echo
|
||||
read -r -p "Do you want to prepare files for repository (y/n)?" CONT <<-EOF
|
||||
$CONFIRM
|
||||
EOF
|
||||
if [ "$CONT" = "y" ]; then
|
||||
rm $PLAN_NAME.json
|
||||
echo
|
||||
echo "$PLAN_NAME.json has been removed from your root module"
|
||||
echo
|
||||
rm ../opa/policy/planned_values.yml
|
||||
echo "planned_values.yml has been removed from your /opa/policy/ directory"
|
||||
echo
|
||||
else
|
||||
echo
|
||||
echo "$PLAN_NAME.json can contain sensitive data"
|
||||
echo
|
||||
echo "Exposing $PLAN_NAME.json in a repository can cause security breach"
|
||||
echo
|
||||
echo "From within your terraform root module: conftest test $PLAN_NAME.json -p ../opa/policy/ -d ../opa/policy/planned_values.yml"
|
||||
fi
|
|
@ -6,12 +6,16 @@ set -e
|
|||
# - Terraform Apply
|
||||
#
|
||||
|
||||
TF_WORKSPACE="$PIPELINE_WORKSPACE/s/$TEST_MODULE_PATH"
|
||||
TF_PLAN_OUT="$TF_WORKSPACE/terraform-plan-$TF_VERSION-$TF_AZ_VERSION"
|
||||
TF_STATE="../tfstate/terraform-$TF_VERSION-$TF_AZ_VERSION.tfstate"
|
||||
|
||||
echo "==> Switching directories..."
|
||||
cd "$PIPELINE_WORKSPACE/s/tests/deployment"
|
||||
cd "$TF_WORKSPACE"
|
||||
|
||||
echo "==> Applying infrastructure..."
|
||||
terraform apply \
|
||||
-auto-approve \
|
||||
-parallelism=50 \
|
||||
-state="./terraform-$TF_VERSION-$TF_AZ_VERSION.tfstate" \
|
||||
"terraform-plan-$TF_VERSION-$TF_AZ_VERSION"
|
||||
-parallelism="$PARALLELISM" \
|
||||
-state="$TF_STATE" \
|
||||
"$TF_PLAN_OUT"
|
||||
|
|
|
@ -6,20 +6,20 @@ set -e
|
|||
# - Terraform Destroy
|
||||
#
|
||||
|
||||
TF_WORKSPACE="$PIPELINE_WORKSPACE/s/$TEST_MODULE_PATH"
|
||||
|
||||
echo "==> Switching directories..."
|
||||
cd "$PIPELINE_WORKSPACE/s/tests/deployment"
|
||||
cd "$TF_WORKSPACE"
|
||||
|
||||
echo "==> Destroying infrastructure..."
|
||||
# shellcheck disable=SC2153 # Environment variables set by pipeline
|
||||
terraform destroy \
|
||||
-var "location=$DEFAULT_LOCATION" \
|
||||
-var "root_id_1=$TF_ROOT_ID_1" \
|
||||
-var "root_id_2=$TF_ROOT_ID_2" \
|
||||
-var "root_id_3=$TF_ROOT_ID_3" \
|
||||
-var "root_id=$TF_ROOT_ID" \
|
||||
-var "root_name=ES-$TF_VERSION-$TF_AZ_VERSION" \
|
||||
-var "primary_location=$PRIMARY_LOCATION" \
|
||||
-var "secondary_location=$SECONDARY_LOCATION" \
|
||||
-auto-approve \
|
||||
-parallelism=256 \
|
||||
-state="./terraform-$TF_VERSION-$TF_AZ_VERSION.tfstate"
|
||||
-parallelism="$PARALLELISM"
|
||||
status=$?
|
||||
|
||||
if [ $status -ne 0 ]; then
|
||||
|
@ -34,7 +34,7 @@ if [ $status -ne 0 ]; then
|
|||
|
||||
IFS=$'\n'
|
||||
|
||||
TF_ROOT_ID=("$TF_ROOT_ID_1" "$TF_ROOT_ID_2" "$TF_ROOT_ID_3")
|
||||
TF_ROOT_ID=("$TF_ROOT_ID")
|
||||
for x in "${TF_ROOT_ID[@]}"; do
|
||||
echo "==> Retrieving management group structure..."
|
||||
TMP_FILE="./data.json"
|
||||
|
|
|
@ -6,8 +6,57 @@ set -e
|
|||
# - Terraform Initialize
|
||||
#
|
||||
|
||||
echo "==> Switching directories..."
|
||||
cd "$PIPELINE_WORKSPACE/s/tests/deployment"
|
||||
TF_WORKSPACE="$PIPELINE_WORKSPACE/s/$TEST_MODULE_PATH"
|
||||
|
||||
echo "==> Initializaing infrastructure..."
|
||||
echo "==> Switching directories..."
|
||||
cd "$TF_WORKSPACE"
|
||||
|
||||
echo "==> Creating terraform_override.tf with required_provider and local backend configuration..."
|
||||
tee terraform_override.tf <<TFCONFIG
|
||||
terraform {
|
||||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = "$TF_AZ_VERSION"
|
||||
configuration_aliases = [
|
||||
azurerm.connectivity,
|
||||
azurerm.management,
|
||||
]
|
||||
}
|
||||
}
|
||||
backend "azurerm" {
|
||||
resource_group_name = "$STORAGE_ACCOUNT_RSG_NAME"
|
||||
storage_account_name = "$STORAGE_ACCOUNT_NAME"
|
||||
container_name = "$STORAGE_CONTAINER_NAME"
|
||||
key = "terraform-$TF_VERSION-$TF_AZ_VERSION.tfstate"
|
||||
}
|
||||
}
|
||||
TFCONFIG
|
||||
|
||||
echo "==> Creating providers_override.tf with subscription configuration and credentials..."
|
||||
cat >providers_override.tf <<TFCONFIG
|
||||
provider "azurerm" {
|
||||
features {}
|
||||
|
||||
alias = "connectivity"
|
||||
subscription_id = "$TF_SUBSCRIPTION_ID_CONNECTIVITY"
|
||||
client_id = "$ARM_CERTIFICATE_CLIENT_ID"
|
||||
client_certificate_path = "$ARM_CERTIFICATE_PATH"
|
||||
client_certificate_password = "$ARM_CERTIFICATE_PASSWORD"
|
||||
tenant_id = "$ARM_TENANT_ID"
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
features {}
|
||||
|
||||
alias = "management"
|
||||
subscription_id = "$TF_SUBSCRIPTION_ID_MANAGEMENT"
|
||||
client_id = "$ARM_CERTIFICATE_CLIENT_ID"
|
||||
client_certificate_path = "$ARM_CERTIFICATE_PATH"
|
||||
client_certificate_password = "$ARM_CERTIFICATE_PASSWORD"
|
||||
tenant_id = "$ARM_TENANT_ID"
|
||||
}
|
||||
TFCONFIG
|
||||
|
||||
echo "==> Initializaing Terraform workspace..."
|
||||
terraform init
|
||||
|
|
|
@ -5,23 +5,25 @@ set -e
|
|||
# Shell Script
|
||||
# - Terraform Plan
|
||||
#
|
||||
TF_PLAN_JSON="terraform-plan-$TF_VERSION-$TF_AZ_VERSION"
|
||||
|
||||
TF_WORKSPACE="$PIPELINE_WORKSPACE/s/$TEST_MODULE_PATH"
|
||||
TF_PLAN_OUT="$TF_WORKSPACE/terraform-plan-$TF_VERSION-$TF_AZ_VERSION"
|
||||
TF_STATE="../tfstate/terraform-$TF_VERSION-$TF_AZ_VERSION.tfstate"
|
||||
|
||||
echo "==> Switching directories..."
|
||||
cd "$PIPELINE_WORKSPACE/s/tests/deployment"
|
||||
cd "$TF_WORKSPACE"
|
||||
|
||||
echo "==> Planning infrastructure..."
|
||||
terraform plan \
|
||||
-var "location=$DEFAULT_LOCATION" \
|
||||
-var "root_id_1=$TF_ROOT_ID_1" \
|
||||
-var "root_id_2=$TF_ROOT_ID_2" \
|
||||
-var "root_id_3=$TF_ROOT_ID_3" \
|
||||
-var "root_id=$TF_ROOT_ID" \
|
||||
-var "root_name=ES-$TF_VERSION-$TF_AZ_VERSION" \
|
||||
-state="./terraform-$TF_VERSION-$TF_AZ_VERSION.tfstate" \
|
||||
-out="terraform-plan-$TF_VERSION-$TF_AZ_VERSION"
|
||||
-var "primary_location=$PRIMARY_LOCATION" \
|
||||
-var "secondary_location=$SECONDARY_LOCATION" \
|
||||
-state="$TF_STATE" \
|
||||
-out="$TF_PLAN_OUT"
|
||||
|
||||
echo "==> Convert plan to JSON..."
|
||||
cd "$PIPELINE_WORKSPACE/s/tests/deployment" && terraform show -json "$TF_PLAN_JSON" >"$TF_PLAN_JSON".json
|
||||
terraform show -json "$TF_PLAN_OUT" >"$TF_PLAN_OUT".json
|
||||
|
||||
echo "==> List all plan to JSON..."
|
||||
cd "$PIPELINE_WORKSPACE/s/tests/deployment" && find . -name "*.json"
|
||||
find . -name "*.json"
|
||||
|
|
|
@ -6,8 +6,10 @@ set -e
|
|||
# - Terraform Prepare
|
||||
#
|
||||
|
||||
CREDENTIALS_WORKSPACE="$PIPELINE_WORKSPACE/s/tests"
|
||||
|
||||
echo "==> Switching directories..."
|
||||
cd "$PIPELINE_WORKSPACE/s/tests/deployment"
|
||||
cd "$CREDENTIALS_WORKSPACE"
|
||||
|
||||
echo "==> Authenticating cli..."
|
||||
az login \
|
||||
|
@ -51,59 +53,12 @@ openssl pkcs12 \
|
|||
echo "==> Deleting SPN certificate in PEM format..."
|
||||
shred -uz "$SPN_NAME.pem"
|
||||
|
||||
echo "==> Creating provider.tf with required_provider version and credentials..."
|
||||
cat >provider.tf <<TFCONFIG
|
||||
terraform {
|
||||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = "$TF_AZ_VERSION"
|
||||
configuration_aliases = [
|
||||
azurerm.connectivity,
|
||||
azurerm.management,
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
echo "==> Storing Client Certificate Details"
|
||||
echo "##vso[task.setvariable variable=ARM_CERTIFICATE_CLIENT_ID;]$CERTIFICATE_CLIENT_ID"
|
||||
echo "##vso[task.setvariable variable=ARM_CERTIFICATE_PATH;]$CREDENTIALS_WORKSPACE/$SPN_NAME.pfx"
|
||||
echo "##vso[task.setvariable variable=ARM_CERTIFICATE_PASSWORD;]$CERTIFICATE_PASSWORD"
|
||||
|
||||
provider "azurerm" {
|
||||
features {}
|
||||
|
||||
alias = "connectivity"
|
||||
subscription_id = "$TF_SUBSCRIPTION_ID_CONNECTIVITY"
|
||||
client_id = "$CERTIFICATE_CLIENT_ID"
|
||||
client_certificate_path = "$SPN_NAME.pfx"
|
||||
client_certificate_password = "$CERTIFICATE_PASSWORD"
|
||||
tenant_id = "$ARM_TENANT_ID"
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
features {}
|
||||
|
||||
alias = "management"
|
||||
subscription_id = "$TF_SUBSCRIPTION_ID_MANAGEMENT"
|
||||
client_id = "$CERTIFICATE_CLIENT_ID"
|
||||
client_certificate_path = "$SPN_NAME.pfx"
|
||||
client_certificate_password = "$CERTIFICATE_PASSWORD"
|
||||
tenant_id = "$ARM_TENANT_ID"
|
||||
}
|
||||
TFCONFIG
|
||||
|
||||
echo "==> Generating root id's..."
|
||||
ROOT_ID_1="${RANDOM}-es"
|
||||
ROOT_ID_2="${RANDOM}-es"
|
||||
ROOT_ID_3="${RANDOM}-es"
|
||||
|
||||
echo "==> Azure Root ID 1 - $ROOT_ID_1"
|
||||
echo "##vso[task.setvariable variable=TF_ROOT_ID_1;]$ROOT_ID_1"
|
||||
|
||||
echo "==> Azure Root ID 2 - $ROOT_ID_2"
|
||||
echo "##vso[task.setvariable variable=TF_ROOT_ID_2;]$ROOT_ID_2"
|
||||
|
||||
echo "==> Azure Root ID 3 - $ROOT_ID_3"
|
||||
echo "##vso[task.setvariable variable=TF_ROOT_ID_3;]$ROOT_ID_3"
|
||||
|
||||
echo "==> Displaying environment variables..."
|
||||
echo "==> Terraform Version - $TF_VERSION"
|
||||
echo "==> Terraform Provider Version - $TF_AZ_VERSION"
|
||||
echo "==> Terraform Variable (Root ID) - $TF_ROOT_ID"
|
||||
echo "==> Terraform Version - $TF_VERSION"
|
||||
echo "==> Terraform Provider Version - $TF_AZ_VERSION"
|
||||
echo "==> Terraform Variable (Root Name) - ES-$TF_VERSION-$TF_AZ_VERSION"
|
||||
|
|
55
variables.tf
55
variables.tf
|
@ -245,7 +245,60 @@ variable "configure_connectivity_resources" {
|
|||
})
|
||||
})
|
||||
)
|
||||
vwan_hub_networks = list(object({}))
|
||||
vwan_hub_networks = list(
|
||||
object({
|
||||
enabled = bool
|
||||
config = object({
|
||||
address_prefix = string
|
||||
location = string
|
||||
sku = string
|
||||
routes = list(
|
||||
object({
|
||||
address_prefixes = list(string)
|
||||
next_hop_ip_address = string
|
||||
})
|
||||
)
|
||||
expressroute_gateway = object({
|
||||
enabled = bool
|
||||
config = object({
|
||||
scale_unit = number
|
||||
})
|
||||
})
|
||||
vpn_gateway = object({
|
||||
enabled = bool
|
||||
config = object({
|
||||
bgp_settings = list(
|
||||
object({
|
||||
asn = number
|
||||
peer_weight = number
|
||||
instance_0_bgp_peering_address = list(
|
||||
object({
|
||||
custom_ips = list(string)
|
||||
})
|
||||
)
|
||||
instance_1_bgp_peering_address = list(
|
||||
object({
|
||||
custom_ips = list(string)
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
routing_preference = string
|
||||
scale_unit = number
|
||||
})
|
||||
})
|
||||
azure_firewall = object({
|
||||
enabled = bool
|
||||
config = object({
|
||||
enable_dns_proxy = bool
|
||||
sku_tier = string
|
||||
})
|
||||
})
|
||||
spoke_virtual_network_resource_ids = list(string)
|
||||
enable_virtual_hub_connections = bool
|
||||
})
|
||||
})
|
||||
)
|
||||
ddos_protection_plan = object({
|
||||
enabled = bool
|
||||
config = object({
|
||||
|
|
Загрузка…
Ссылка в новой задаче