https://github.com/Azure/caf-terraform-landingzones.git /tf/caf/public
-```
-
-This will clone the logic of landing zones in your local repository without committing your landing zones changes (we have put for you a filter on /public for landing zones.)
-
-2. Change the module path in your landing zone
-
-By default the landing zone will source the module from the registry.
-
-For each landing zone you want to edit, go to the ```landingzone.tf``` file:
-
-```
-module "networking" {
- source = "aztfmod/caf/azurerm"
- version = "~> 0.4"
-```
-
-You can replace it with your local path, typically here:
-
-```
-module "networking" {
- source = "../../.."
-```
-
-You should now be able to run landing zones as usual, except it will source the module locally, so you can test the features you introduced in the module.
-
-## Using the examples
-
-You can customize the examples execution by modifying the variables as follow:
-
-
-## Requirements
-
-| Name | Version |
-|------|---------|
-| terraform | >= 0.13 |
-
-## Providers
-
-No provider.
-
-## Modules
-
-| Name | Source | Version |
-|------|--------|---------|
-| example | ../.. | |
-| vm_extension_diagnostics | ../../modules/compute/virtual_machine_extensions | |
-| vm_extension_monitoring_agent | ../../modules/compute/virtual_machine_extensions | |
-
-## Resources
-
-No resources.
-
-## Inputs
-
-| Name | Description | Type | Default | Required |
-|------|-------------|------|---------|:--------:|
-| aks\_clusters | n/a | `map` | `{}` | no |
-| app\_service\_environments | n/a | `map` | `{}` | no |
-| app\_service\_plans | n/a | `map` | `{}` | no |
-| app\_services | n/a | `map` | `{}` | no |
-| application\_gateway\_applications | n/a | `map` | `{}` | no |
-| application\_gateways | n/a | `map` | `{}` | no |
-| application\_security\_groups | n/a | `map` | `{}` | no |
-| automations | n/a | `map` | `{}` | no |
-| availability\_sets | n/a | `map` | `{}` | no |
-| azure\_container\_registries | n/a | `map` | `{}` | no |
-| azuread\_api\_permissions | n/a | `map` | `{}` | no |
-| azuread\_apps | n/a | `map(any)` | `{}` | no |
-| azuread\_groups | n/a | `map` | `{}` | no |
-| azuread\_roles | n/a | `map` | `{}` | no |
-| azuread\_users | n/a | `map(any)` | `{}` | no |
-| azurerm\_application\_insights | n/a | `map` | `{}` | no |
-| azurerm\_firewall\_application\_rule\_collection\_definition | n/a | `map` | `{}` | no |
-| azurerm\_firewall\_nat\_rule\_collection\_definition | n/a | `map` | `{}` | no |
-| azurerm\_firewall\_network\_rule\_collection\_definition | n/a | `map` | `{}` | no |
-| azurerm\_firewall\_policies | n/a | `map` | `{}` | no |
-| azurerm\_firewall\_policy\_rule\_collection\_groups | n/a | `map` | `{}` | no |
-| azurerm\_firewalls | n/a | `map` | `{}` | no |
-| azurerm\_redis\_caches | n/a | `map` | `{}` | no |
-| azurerm\_routes | n/a | `map` | `{}` | no |
-| bastion\_hosts | n/a | `map` | `{}` | no |
-| container\_groups | n/a | `map` | `{}` | no |
-| cosmos\_db | n/a | `map` | `{}` | no |
-| cosmos\_dbs | n/a | `map` | `{}` | no |
-| custom\_role\_definitions | n/a | `map` | `{}` | no |
-| databricks\_workspaces | n/a | `map` | `{}` | no |
-| diagnostic\_event\_hub\_namespaces | n/a | `map` | `{}` | no |
-| diagnostic\_log\_analytics | n/a | `map` | `{}` | no |
-| diagnostic\_storage\_accounts | n/a | `map` | `{}` | no |
-| diagnostics\_definition | n/a | `any` | `null` | no |
-| diagnostics\_destinations | n/a | `map` | `{}` | no |
-| disk\_encryption\_sets | n/a | `map` | `{}` | no |
-| dns\_zone\_records | n/a | `map` | `{}` | no |
-| dns\_zones | n/a | `map` | `{}` | no |
-| domain\_name\_registrations | n/a | `map` | `{}` | no |
-| dynamic\_keyvault\_secrets | n/a | `map` | `{}` | no |
-| environment | n/a | `string` | `"sandpit"` | no |
-| event\_hub\_auth\_rules | n/a | `map` | `{}` | no |
-| event\_hub\_consumer\_groups | n/a | `map` | `{}` | no |
-| event\_hub\_namespace\_auth\_rules | n/a | `map` | `{}` | no |
-| event\_hub\_namespaces | n/a | `map` | `{}` | no |
-| event\_hubs | n/a | `map` | `{}` | no |
-| express\_route\_circuit\_authorizations | n/a | `map` | `{}` | no |
-| express\_route\_circuits | n/a | `map` | `{}` | no |
-| front\_door\_waf\_policies | n/a | `map` | `{}` | no |
-| front\_doors | n/a | `map` | `{}` | no |
-| global\_settings | n/a | `map` | {
"default_region": "region1",
"prefix": null,
"regions": {
"region1": "southeastasia",
"region2": "eastasia"
}
}
| no |
-| image\_definitions | n/a | `map` | `{}` | no |
-| ip\_groups | n/a | `map` | `{}` | no |
-| keyvault\_access\_policies | n/a | `map` | `{}` | no |
-| keyvault\_access\_policies\_azuread\_apps | n/a | `map` | `{}` | no |
-| keyvault\_certificate\_issuers | n/a | `map` | `{}` | no |
-| keyvault\_certificate\_requests | n/a | `map` | `{}` | no |
-| keyvault\_certificates | n/a | `map` | `{}` | no |
-| keyvault\_keys | n/a | `map` | `{}` | no |
-| keyvaults | n/a | `map` | `{}` | no |
-| landingzone | n/a | `map` | {
"backend_type": "azurerm",
"global_settings_key": "launchpad",
"key": "examples",
"level": "level0"
}
| no |
-| lighthouse\_definitions | n/a | `map` | `{}` | no |
-| load\_balancers | n/a | `map` | `{}` | no |
-| local\_network\_gateways | n/a | `map` | `{}` | no |
-| log\_analytics | n/a | `map` | `{}` | no |
-| logged\_aad\_app\_objectId | n/a | `any` | `null` | no |
-| logged\_user\_objectId | n/a | `any` | `null` | no |
-| machine\_learning\_workspaces | n/a | `map` | `{}` | no |
-| managed\_identities | n/a | `map` | `{}` | no |
-| mariadb\_databases | n/a | `map` | `{}` | no |
-| mariadb\_servers | n/a | `map` | `{}` | no |
-| monitoring | n/a | `map` | `{}` | no |
-| mssql\_databases | n/a | `map` | `{}` | no |
-| mssql\_elastic\_pools | n/a | `map` | `{}` | no |
-| mssql\_failover\_groups | n/a | `map` | `{}` | no |
-| mssql\_managed\_databases | n/a | `map` | `{}` | no |
-| mssql\_managed\_databases\_backup\_ltr | n/a | `map` | `{}` | no |
-| mssql\_managed\_databases\_restore | n/a | `map` | `{}` | no |
-| mssql\_managed\_instances | n/a | `map` | `{}` | no |
-| mssql\_managed\_instances\_secondary | n/a | `map` | `{}` | no |
-| mssql\_mi\_administrators | n/a | `map` | `{}` | no |
-| mssql\_mi\_failover\_groups | n/a | `map` | `{}` | no |
-| mssql\_mi\_secondary\_tdes | n/a | `map` | `{}` | no |
-| mssql\_mi\_tdes | n/a | `map` | `{}` | no |
-| mssql\_servers | n/a | `map` | `{}` | no |
-| mysql\_servers | n/a | `map` | `{}` | no |
-| netapp\_accounts | n/a | `map` | `{}` | no |
-| network\_security\_group\_definition | n/a | `map` | `{}` | no |
-| network\_watchers | n/a | `map` | `{}` | no |
-| packer\_managed\_identity | n/a | `map` | `{}` | no |
-| packer\_service\_principal | n/a | `map` | `{}` | no |
-| postgresql\_servers | n/a | `map` | `{}` | no |
-| private\_dns | n/a | `map` | `{}` | no |
-| private\_endpoints | n/a | `map` | `{}` | no |
-| provider\_azurerm\_features\_keyvault | n/a | `map` | {
"purge_soft_delete_on_destroy": true
}
| no |
-| proximity\_placement\_groups | n/a | `map` | `{}` | no |
-| public\_ip\_addresses | n/a | `map` | `{}` | no |
-| recovery\_vaults | n/a | `map` | `{}` | no |
-| resource\_groups | n/a | `map` | `{}` | no |
-| role\_mapping | n/a | `map` | `{}` | no |
-| route\_tables | n/a | `map` | `{}` | no |
-| rover\_version | n/a | `any` | `null` | no |
-| shared\_image\_galleries | n/a | `map` | `{}` | no |
-| storage\_accounts | n/a | `map` | `{}` | no |
-| synapse\_workspaces | n/a | `map` | `{}` | no |
-| tags | n/a | `map(any)` | `null` | no |
-| var\_folder\_path | n/a | `map` | `{}` | no |
-| vhub\_peerings | Use virtual\_hub\_connections instead of vhub\_peerings. It will be removed in version 6.0 | `map` | `{}` | no |
-| virtual\_hub\_connections | n/a | `map` | `{}` | no |
-| virtual\_hub\_er\_gateway\_connections | n/a | `map` | `{}` | no |
-| virtual\_hub\_route\_tables | n/a | `map` | `{}` | no |
-| virtual\_machines | n/a | `map` | `{}` | no |
-| virtual\_network\_gateway\_connections | n/a | `map` | `{}` | no |
-| virtual\_network\_gateways | n/a | `map` | `{}` | no |
-| virtual\_wans | n/a | `map` | `{}` | no |
-| vnet\_peerings | n/a | `map` | `{}` | no |
-| vnets | n/a | `map` | `{}` | no |
-
-## Outputs
-
-| Name | Description |
-|------|-------------|
-| objects | n/a |
-
diff --git a/load_balancers.tf b/load_balancers.tf
index a1e36a1eb6..707f0ce521 100755
--- a/load_balancers.tf
+++ b/load_balancers.tf
@@ -2,8 +2,8 @@ module "load_balancers" {
source = "./modules/networking/load_balancers"
for_each = try(local.networking.load_balancers, {})
- resource_group_name = local.resource_groups[each.value.resource_group_key].name
- location = lookup(each.value, "region", null) == null ? local.resource_groups[each.value.resource_group_key].location : local.global_settings.regions[each.value.region]
+ resource_group_name = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].name
+ location = lookup(each.value, "region", null) == null ? local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location : local.global_settings.regions[each.value.region]
public_ip_addresses = local.combined_objects_public_ip_addresses
client_config = local.client_config
vnets = local.combined_objects_networking
@@ -11,7 +11,7 @@ module "load_balancers" {
diagnostics = local.combined_diagnostics
global_settings = local.global_settings
settings = each.value
- base_tags = try(local.global_settings.inherit_tags, false) ? local.resource_groups[each.value.resource_group_key].tags : {}
+ base_tags = try(local.global_settings.inherit_tags, false) ? local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].tags : {}
existing_resources = {
virtual_machines = try(module.virtual_machines, {})
#vm scale set will be added later
diff --git a/locals.combined_objects.tf b/locals.combined_objects.tf
index 8f7aa4bf18..587d1c2889 100644
--- a/locals.combined_objects.tf
+++ b/locals.combined_objects.tf
@@ -11,13 +11,18 @@ locals {
combined_objects_application_security_groups = merge(tomap({ (local.client_config.landingzone_key) = module.application_security_groups }), try(var.remote_objects.application_security_groups, {}))
combined_objects_availability_sets = merge(tomap({ (local.client_config.landingzone_key) = module.availability_sets }), try(var.remote_objects.availability_sets, {}))
combined_objects_azure_container_registries = merge(tomap({ (local.client_config.landingzone_key) = module.container_registry }), try(var.remote_objects.container_registry, {}))
- combined_objects_azuread_applications = merge(tomap({ (local.client_config.landingzone_key) = module.azuread_applications }), try(var.remote_objects.azuread_applications, {}))
+ combined_objects_azuread_apps = merge(tomap({ (local.client_config.landingzone_key) = module.azuread_applications }), try(var.remote_objects.azuread_apps, {}))
+ combined_objects_azuread_applications = merge(tomap({ (local.client_config.landingzone_key) = module.azuread_applications_v1 }), try(var.remote_objects.azuread_applications, {}))
+ combined_objects_azuread_service_principals = merge(tomap({ (local.client_config.landingzone_key) = module.azuread_service_principals }), try(var.remote_objects.azuread_service_principals, {}))
combined_objects_azuread_groups = merge(tomap({ (local.client_config.landingzone_key) = module.azuread_groups }), try(var.remote_objects.azuread_groups, {}))
combined_objects_azuread_users = merge(tomap({ (local.client_config.landingzone_key) = module.azuread_users }), try(var.remote_objects.azuread_users, {}))
combined_objects_azurerm_firewalls = merge(tomap({ (local.client_config.landingzone_key) = module.azurerm_firewalls }), try(var.remote_objects.azurerm_firewalls, {}))
+ combined_objects_container_registry = merge(tomap({ (local.client_config.landingzone_key) = module.container_registry }), try(var.remote_objects.container_registry, {}))
combined_objects_diagnostic_storage_accounts = merge(tomap({ (local.client_config.landingzone_key) = module.diagnostic_storage_accounts }), try(var.remote_objects.diagnostic_storage_accounts, {}))
combined_objects_disk_encryption_sets = merge(tomap({ (local.client_config.landingzone_key) = module.disk_encryption_sets }), try(var.remote_objects.disk_encryption_sets, {}))
combined_objects_dns_zones = merge(tomap({ (local.client_config.landingzone_key) = module.dns_zones }), try(var.remote_objects.dns_zones, {}))
+ combined_objects_dedicated_hosts = merge(tomap({ (local.client_config.landingzone_key) = module.dedicated_hosts }), try(var.remote_objects.dedicated_hosts, {}))
+ combined_objects_dedicated_host_groups = merge(tomap({ (local.client_config.landingzone_key) = module.dedicated_host_groups }), try(var.remote_objects.dedicated_host_groups, {}))
combined_objects_event_hub_namespaces = merge(tomap({ (local.client_config.landingzone_key) = module.event_hub_namespaces }), try(var.remote_objects.event_hub_namespaces, {}))
combined_objects_front_door_waf_policies = merge(tomap({ (local.client_config.landingzone_key) = module.front_door_waf_policies }), try(var.remote_objects.front_door_waf_policies, {}))
combined_objects_integration_service_environment = merge(tomap({ (local.client_config.landingzone_key) = module.integration_service_environment }), try(var.remote_objects.integration_service_environment, {}))
@@ -36,17 +41,17 @@ locals {
combined_objects_mssql_managed_instances_secondary = merge(tomap({ (local.client_config.landingzone_key) = module.mssql_managed_instances_secondary }), try(var.remote_objects.mssql_managed_instances_secondary, {}))
combined_objects_mssql_servers = merge(tomap({ (local.client_config.landingzone_key) = module.mssql_servers }), try(var.remote_objects.mssql_servers, {}))
combined_objects_mysql_servers = merge(tomap({ (local.client_config.landingzone_key) = module.mysql_servers }), try(var.remote_objects.mysql_servers, {}))
+ combined_objects_network_security_groups = merge(tomap({ (local.client_config.landingzone_key) = module.network_security_groups }), try(var.remote_objects.network_security_groups, {}))
combined_objects_network_watchers = merge(tomap({ (local.client_config.landingzone_key) = module.network_watchers }), try(var.remote_objects.network_watchers, {}))
combined_objects_networking = merge(tomap({ (local.client_config.landingzone_key) = module.networking }), try(var.remote_objects.vnets, {}))
combined_objects_postgresql_servers = merge(tomap({ (local.client_config.landingzone_key) = module.postgresql_servers }), try(var.remote_objects.postgresql_servers, {}))
- combined_objects_network_security_groups = merge(tomap({ (local.client_config.landingzone_key) = module.network_security_groups }), try(var.remote_objects.network_security_groups, {}))
+ combined_objects_azurerm_firewall_policies = merge(tomap({ (local.client_config.landingzone_key) = module.azurerm_firewall_policies }), try(var.remote_objects.azurerm_firewall_policies, {}))
combined_objects_private_dns = merge(tomap({ (local.client_config.landingzone_key) = module.private_dns }), try(var.remote_objects.private_dns, {}))
combined_objects_proximity_placement_groups = merge(tomap({ (local.client_config.landingzone_key) = module.proximity_placement_groups }), try(var.remote_objects.proximity_placement_groups, {}))
combined_objects_public_ip_addresses = merge(tomap({ (local.client_config.landingzone_key) = module.public_ip_addresses }), try(var.remote_objects.public_ip_addresses, {}))
combined_objects_recovery_vaults = merge(tomap({ (local.client_config.landingzone_key) = module.recovery_vaults }), try(var.remote_objects.recovery_vaults, {}))
combined_objects_resource_groups = merge(tomap({ (local.client_config.landingzone_key) = local.resource_groups }), try(var.remote_objects.resource_groups, {}))
combined_objects_storage_accounts = merge(tomap({ (local.client_config.landingzone_key) = module.storage_accounts }), try(var.remote_objects.storage_accounts, {}))
- combined_objects_subscriptions = merge(tomap({ (local.client_config.landingzone_key) = module.subscriptions }), try(var.remote_objects.subscriptions, {}))
combined_objects_synapse_workspaces = merge(tomap({ (local.client_config.landingzone_key) = module.synapse_workspaces }), try(var.remote_objects.synapse_workspaces, {}))
combined_objects_virtual_machines = merge(tomap({ (local.client_config.landingzone_key) = module.virtual_machines }), try(var.remote_objects.virtual_machines, {}))
combined_objects_virtual_machine_scale_sets = merge(tomap({ (local.client_config.landingzone_key) = module.virtual_machine_scale_sets }), try(var.remote_objects.virtual_machine_scale_sets, {}))
@@ -54,7 +59,23 @@ locals {
combined_objects_virtual_hub_route_tables = merge(tomap({ (local.client_config.landingzone_key) = azurerm_virtual_hub_route_table.route_table }), try(var.remote_objects.virtual_hub_route_tables, {}))
combined_objects_virtual_hubs = merge(tomap({ (local.client_config.landingzone_key) = module.virtual_hubs }), try(var.remote_objects.virtual_hubs, {}))
combined_objects_virtual_wans = merge(tomap({ (local.client_config.landingzone_key) = module.virtual_wans }), try(var.remote_objects.virtual_wans, {}))
+ combined_objects_vpn_gateway_connections = merge(tomap({ (local.client_config.landingzone_key) = module.vpn_gateway_connections }), try(var.remote_objects.vpn_gateway_connections, {}))
+ combined_objects_vpn_sites = merge(tomap({ (local.client_config.landingzone_key) = module.vpn_sites }), try(var.remote_objects.vpn_sites, {}))
+ combined_objects_wvd_applications = merge(tomap({ (local.client_config.landingzone_key) = module.wvd_applications }), try(var.remote_objects.wvd_applications, {}))
combined_objects_wvd_application_groups = merge(tomap({ (local.client_config.landingzone_key) = module.wvd_application_groups }), try(var.remote_objects.wvd_application_groups, {}))
combined_objects_wvd_host_pools = merge(tomap({ (local.client_config.landingzone_key) = module.wvd_host_pools }), try(var.remote_objects.wvd_host_pools, {}))
combined_objects_wvd_workspaces = merge(tomap({ (local.client_config.landingzone_key) = module.wvd_workspaces }), try(var.remote_objects.wvd_workspaces, {}))
+
+ combined_objects_subscriptions = merge(
+ tomap(
+ {
+ (local.client_config.landingzone_key) = merge(
+ try(module.subscriptions, {}),
+ { ("logged_in_subscription") = { id = data.azurerm_subscription.primary.id } }
+ )
+ }
+ ),
+ try(var.remote_objects.subscriptions, {})
+ )
+
}
diff --git a/locals.tf b/locals.tf
index caf88c8d12..a93a564798 100755
--- a/locals.tf
+++ b/locals.tf
@@ -7,6 +7,20 @@ resource "random_string" "prefix" {
}
locals {
+ azuread = {
+ azuread_api_permissions = try(var.azuread.azuread_api_permissions, {})
+ azuread_applications = try(var.azuread.azuread_applications, {})
+ azuread_apps = try(var.azuread.azuread_apps, {})
+ azuread_credential_policies = try(var.azuread.azuread_credential_policies, {})
+ azuread_credentials = try(var.azuread.azuread_credentials, {})
+ azuread_groups = try(var.azuread.azuread_groups, {})
+ azuread_groups_membership = try(var.azuread.azuread_groups_membership, {})
+ azuread_roles = try(var.azuread.azuread_roles, {})
+ azuread_service_principal_passwords = try(var.azuread.azuread_service_principal_passwords, {})
+ azuread_service_principals = try(var.azuread.azuread_service_principals, {})
+ azuread_users = try(var.azuread.azuread_users, {})
+ }
+
client_config = var.client_config == {} ? {
client_id = data.azurerm_client_config.current.client_id
landingzone_key = var.current_landingzone_key
@@ -59,7 +73,10 @@ locals {
azure_container_registries = try(var.compute.azure_container_registries, {})
bastion_hosts = try(var.compute.bastion_hosts, {})
container_groups = try(var.compute.container_groups, {})
+ dedicated_hosts = try(var.compute.dedicated_hosts, {})
+ dedicated_host_groups = try(var.compute.dedicated_host_groups, {})
proximity_placement_groups = try(var.compute.proximity_placement_groups, {})
+ wvd_applications = try(var.compute.wvd_applications, {})
wvd_application_groups = try(var.compute.wvd_application_groups, {})
wvd_host_pools = try(var.compute.wvd_host_pools, {})
wvd_workspaces = try(var.compute.wvd_workspaces, {})
@@ -138,17 +155,15 @@ locals {
}
global_settings = merge({
- default_region = try(var.global_settings.default_region, "region1")
- environment = try(var.global_settings.environment, var.environment)
- inherit_tags = try(var.global_settings.inherit_tags, false)
- passthrough = try(var.global_settings.passthrough, false)
- prefix = try(var.global_settings.prefix, null)
- # prefix_with_hyphen = try(var.global_settings.prefix_with_hyphen, format("%s-", try(var.global_settings.prefixes[0], random_string.prefix.0.result)))
- # prefixes = var.global_settings.prefix == "" ? null : try(var.global_settings.prefixes, [random_string.prefix.0.result])
+ default_region = try(var.global_settings.default_region, "region1")
+ environment = try(var.global_settings.environment, var.environment)
+ inherit_tags = try(var.global_settings.inherit_tags, false)
+ passthrough = try(var.global_settings.passthrough, false)
+ prefix = try(var.global_settings.prefix, null)
prefix_with_hyphen = try(var.global_settings.prefix_with_hyphen, format("%s-", try(var.global_settings.prefix, try(var.global_settings.prefixes[0], random_string.prefix.0.result))))
prefixes = try(var.global_settings.prefix, null) == "" ? null : try([var.global_settings.prefix], try(var.global_settings.prefixes, [random_string.prefix.0.result]))
random_length = try(var.global_settings.random_length, 0)
- regions = var.global_settings.regions
+ regions = try(var.global_settings.regions, null)
tags = try(var.global_settings.tags, null)
use_slug = try(var.global_settings.use_slug, true)
}, var.global_settings)
@@ -202,6 +217,8 @@ locals {
virtual_wans = try(var.networking.virtual_wans, {})
vnet_peerings = try(var.networking.vnet_peerings, {})
vnets = try(var.networking.vnets, {})
+ vpn_gateway_connections = try(var.networking.vpn_gateway_connections, {})
+ vpn_sites = try(var.networking.vpn_sites, {})
}
object_id = coalesce(var.logged_user_objectId, var.logged_aad_app_objectId, try(data.azurerm_client_config.current.object_id, null), try(data.azuread_service_principal.logged_in_app.0.object_id, null))
@@ -227,8 +244,9 @@ locals {
}
storage = {
- netapp_accounts = try(var.storage.netapp_accounts, {})
- storage_account_blobs = try(var.storage.storage_account_blobs, {})
+ netapp_accounts = try(var.storage.netapp_accounts, {})
+ storage_account_blobs = try(var.storage.storage_account_blobs, {})
+ storage_account_queues = try(var.storage.storage_account_queues, {})
}
webapp = {
diff --git a/machine_learning.tf b/machine_learning.tf
index 4ce984a7be..85ce0b6d73 100755
--- a/machine_learning.tf
+++ b/machine_learning.tf
@@ -11,11 +11,11 @@ module "machine_learning_workspaces" {
storage_account_id = lookup(each.value, "storage_account_key") == null ? null : module.storage_accounts[each.value.storage_account_key].id
keyvault_id = lookup(each.value, "keyvault_key") == null ? null : module.keyvaults[each.value.keyvault_key].id
application_insights_id = lookup(each.value, "application_insights_key") == null ? null : module.azurerm_application_insights[each.value.application_insights_key].id
+ container_registry_id = try(each.value.container_registry_key, null) == null ? null : try(local.combined_objects_container_registry[each.value.lz_key][each.value.container_registry_key].id, local.combined_objects_container_registry[local.client_config.landingzone_key][each.value.container_registry_key].id)
base_tags = try(local.global_settings.inherit_tags, false) ? local.resource_groups[each.value.resource_group_key].tags : {}
}
output "machine_learning_workspaces" {
value = module.machine_learning_workspaces
-
}
diff --git a/main.tf b/main.tf
index 7aba315ca9..467a050ac8 100755
--- a/main.tf
+++ b/main.tf
@@ -3,7 +3,7 @@ terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
- version = "~> 2.55.0"
+ version = "~> 2.64.0"
}
azuread = {
source = "hashicorp/azuread"
@@ -40,7 +40,7 @@ data "azurerm_client_config" "current" {}
# 1 - running launchpad from vscode
# In this bootstrap scenario the launchpad is executed under a logged in user azure session. The rover sets the logged_user_objectId through environment variable. During that initial run an Azure AD application (refered as launchpad_app_level0) is created to support any execution from a pipeline.
# 2 - deploying a landing zone or a solution from vscode
-# Step 1 has been executed. The rover is still connect to a logged in user azure session. The rover use the user's credentials to connect the default azure subscription to identity the storage account and the keyvault holding the tfstate and the launchpad_app_level0 credentials. The rover set the terraform ARM_* variables to change the terraform provider Azure context (client id, secret, tenant and subscription). The logged_aad_app_objectId is set to the launchpad_app_level0's client_id. Note in that scenario the azure session does not change. Meaning when terraform execute some local execution scripts they are executed in the context of the logged_in_user and not the azure ad application. To simulate from vscode the execution of a local exec with the launchpad_app_level0 credentials, the rover must be executed with the parameter --impersonate (cannot be used during the launchpad initial deployment and destruciton)
+# Step 1 has been executed. The rover is still connected to a logged in user azure session. The rover use the user's credentials to connect the default azure subscription to identity the storage account and the keyvault holding the tfstate and the launchpad_app_level0 credentials. The rover set the terraform ARM_* variables to change the terraform provider Azure context (client id, secret, tenant and subscription). The logged_aad_app_objectId is set to the launchpad_app_level0's client_id. Note in that scenario the azure session does not change. Meaning when terraform execute some local execution scripts they are executed in the context of the logged_in_user and not the azure ad application. To simulate from vscode the execution of a local exec with the launchpad_app_level0 credentials, the rover must be executed with the parameter --impersonate (cannot be used during the launchpad initial deployment and destruciton)
data "azuread_service_principal" "logged_in_app" {
diff --git a/modules/analytics/databricks_workspace/workspace.tf b/modules/analytics/databricks_workspace/workspace.tf
index 5a7362ec0a..0fe6a36dc4 100644
--- a/modules/analytics/databricks_workspace/workspace.tf
+++ b/modules/analytics/databricks_workspace/workspace.tf
@@ -1,5 +1,7 @@
-# naming convention
-#TODO rename object from wp to ws for consistency
+
+# Tested with : AzureRM version 2.57.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/databricks_workspace
+
resource "azurecaf_name" "wp" {
name = var.settings.name
resource_type = "azurerm_databricks_workspace"
@@ -10,7 +12,8 @@ resource "azurecaf_name" "wp" {
use_slug = var.global_settings.use_slug
}
-# Databricks workspace
+
+
resource "azurerm_databricks_workspace" "ws" {
name = azurecaf_name.wp.result
resource_group_name = var.resource_group_name
diff --git a/modules/analytics/machine_learning/variables.tf b/modules/analytics/machine_learning/variables.tf
index 63174622b1..51659d627f 100755
--- a/modules/analytics/machine_learning/variables.tf
+++ b/modules/analytics/machine_learning/variables.tf
@@ -52,4 +52,8 @@ variable "base_tags" {
variable "vnets" {
description = "Virtual networks objects - contains all virtual networks that could potentially be used by the module."
+}
+
+variable "container_registry_id" {
+ default = ""
}
\ No newline at end of file
diff --git a/modules/analytics/machine_learning/workspace.tf b/modules/analytics/machine_learning/workspace.tf
index a8fa6b5c31..91f59d7233 100644
--- a/modules/analytics/machine_learning/workspace.tf
+++ b/modules/analytics/machine_learning/workspace.tf
@@ -9,7 +9,9 @@ resource "azurecaf_name" "ws" {
use_slug = var.global_settings.use_slug
}
-# ML Workspace
+# Tested with : AzureRM version 2.57.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/machine_learning_workspace
+
resource "azurerm_machine_learning_workspace" "ws" {
name = azurecaf_name.ws.result
location = var.location
@@ -17,8 +19,12 @@ resource "azurerm_machine_learning_workspace" "ws" {
application_insights_id = var.application_insights_id
key_vault_id = var.keyvault_id
storage_account_id = var.storage_account_id
+ container_registry_id = var.container_registry_id
tags = try(local.tags, null)
sku_name = try(var.settings.sku_name, "Basic")
+ description = try(var.settings.description, null)
+ friendly_name = try(var.settings.friendly_name, null)
+ high_business_impact = try(var.settings.high_business_impact, null)
identity {
#Hardcoded as the only supported value is SystemAssigned as per azurerm 2.40
diff --git a/modules/analytics/synapse/spark_pool/spark_pool.tf b/modules/analytics/synapse/spark_pool/spark_pool.tf
index ebc5b05dc6..fe1f6aff27 100644
--- a/modules/analytics/synapse/spark_pool/spark_pool.tf
+++ b/modules/analytics/synapse/spark_pool/spark_pool.tf
@@ -8,11 +8,18 @@ resource "azurecaf_name" "sparkpool" {
use_slug = var.global_settings.use_slug
}
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/synapse_spark_pool
+# Tested with: AzureRM provider 2.57.0
+
resource "azurerm_synapse_spark_pool" "spark_pool" {
name = azurecaf_name.sparkpool.result
synapse_workspace_id = var.synapse_workspace_id
node_size_family = var.settings.node_size_family
node_size = var.settings.node_size
+ node_count = try(var.settings.node_count, null)
+ spark_log_folder = try(var.settings.spark_log_folder, "/logs")
+ spark_events_folder = try(var.settings.spark_events_folder, "/events")
+ spark_version = try(var.settings.spark_version, "2.4")
auto_scale {
max_node_count = var.settings.auto_scale.max_node_count
@@ -23,6 +30,15 @@ resource "azurerm_synapse_spark_pool" "spark_pool" {
delay_in_minutes = var.settings.auto_pause.delay_in_minutes
}
+ dynamic "library_requirement" {
+ for_each = try(var.settings.library_requirement, {})
+
+ content {
+ content = var.settings.library_requirement.content
+ filename = var.settings.library_requirement.filename
+ }
+ }
+
tags = local.tags
}
diff --git a/modules/analytics/synapse/workspace.tf b/modules/analytics/synapse/workspace.tf
index 3dddc46271..85439034f8 100644
--- a/modules/analytics/synapse/workspace.tf
+++ b/modules/analytics/synapse/workspace.tf
@@ -9,7 +9,8 @@ resource "azurecaf_name" "ws" {
use_slug = var.global_settings.use_slug
}
-# synapse workspace
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/synapse_workspace
+# Tested with : AzureRM 2.57.0
resource "azurerm_synapse_workspace" "ws" {
name = azurecaf_name.ws.result
resource_group_name = var.resource_group_name
@@ -17,7 +18,46 @@ resource "azurerm_synapse_workspace" "ws" {
storage_data_lake_gen2_filesystem_id = var.storage_data_lake_gen2_filesystem_id
sql_administrator_login = var.settings.sql_administrator_login
sql_administrator_login_password = try(var.settings.sql_administrator_login_password, random_password.sql_admin.0.result)
+ managed_virtual_network_enabled = try(var.settings.managed_virtual_network_enabled, false)
+ sql_identity_control_enabled = try(var.settings.sql_identity_control_enabled, null)
+ managed_resource_group_name = try(var.settings.managed_resource_group_name, null)
+ customer_managed_key_versionless_id = try(var.settings.customer_managed_key_versionless_id, null)
tags = local.tags
+
+ dynamic "aad_admin" {
+ for_each = try(var.settings.aad_admin, {})
+
+ content {
+ login = var.settings.aad_admin.login
+ object_id = var.settings.aad_admin.object_id
+ tenant_id = var.settings.aad_admin.tenant_id
+ }
+ }
+
+ dynamic "azure_devops_repo" {
+ for_each = try(var.settings.azure_devops_repo, {})
+
+ content {
+ account_name = var.settings.azure_devops_repo.account_name
+ branch_name = var.settings.azure_devops_repo.branch_name
+ project_name = var.settings.azure_devops_repo.project_name
+ repository_name = var.settings.azure_devops_repo.branch_name
+ root_folder = var.settings.azure_devops_repo.root_folder
+ }
+ }
+
+ dynamic "github_repo" {
+ for_each = try(var.settings.github_repo, {})
+
+ content {
+ account_name = var.settings.github_repo.account_name
+ branch_name = var.settings.github_repo.project_name
+ repository_name = var.settings.github_repo.branch_name
+ root_folder = var.settings.github_repo.root_folder
+ git_url = var.settings.github_repo.git_url
+ }
+ }
+
}
# Generate sql server random admin password if not provided in the attribute administrator_login_password
@@ -71,6 +111,8 @@ resource "azurerm_key_vault_secret" "synapse_rg_name" {
}
# for backwards compatibility to create single firewall rule
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/synapse_firewall_rule
+# Tested with : AzureRm 2.57.0
resource "azurerm_synapse_firewall_rule" "wrkspc_firewall" {
count = try(var.settings.workspace_firewall, null) == null ? 0 : 1
@@ -81,6 +123,8 @@ resource "azurerm_synapse_firewall_rule" "wrkspc_firewall" {
}
# supports adding multiple synapse firewall rules
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/synapse_firewall_rule
+# Tested with : AzureRm 2.57.0
resource "azurerm_synapse_firewall_rule" "wrkspc_firewalls" {
for_each = try(var.settings.workspace_firewalls, {})
diff --git a/modules/azuread/applications/scripts/grant_consent.sh b/modules/azuread/applications/scripts/grant_consent.sh
index 3b80c01557..7409cde31e 100755
--- a/modules/azuread/applications/scripts/grant_consent.sh
+++ b/modules/azuread/applications/scripts/grant_consent.sh
@@ -2,29 +2,31 @@
set -e
-
user_type=$(az account show --query user.type -o tsv)
if [ "${user_type}" = "user" ]; then
az ad app permission admin-consent --id ${applicationId}
-
else
-
resourceId=$(az ad sp show --id "${resourceAppId}" --query "objectId" -o tsv)
echo " -resourceId: ${resourceId}"
microsoft_graph_endpoint=$(az cloud show | jq -r ".endpoints.microsoftGraphResourceId")
- URI=$(echo "${microsoft_graph_endpoint}beta/servicePrincipals/${resourceId}/appRoleAssignments") && echo " - uri: $URI"
+ URI=$(echo "${microsoft_graph_endpoint}v1.0/servicePrincipals/${resourceId}/appRoleAssignedTo") && echo " - uri: $URI"
- # grant consent (Application.ReadWrite.OwnedBy)
- JSON=$( jq -n \
- --arg principalId "${principalId}" \
- --arg resourceId "${resourceId}" \
- --arg appRoleId "${appRoleId}" \
- '{principalId: $principalId, resourceId: $resourceId, appRoleId: $appRoleId}' ) && echo " - body: $JSON"
+ existingAppRoleId=$(az rest --method GET --uri ${URI} \
+ --query "value[?appRoleId=='${appRoleId}' && principalId=='${principalId}' && resourceId=='${resourceId}'].appRoleId" -o tsv)
- az rest --method POST --uri $URI --header Content-Type=application/json --body "$JSON"
+ if [ -z ${existingAppRoleId} ]; then
+ JSON=$( jq -n \
+ --arg principalId "${principalId}" \
+ --arg resourceId "${resourceId}" \
+ --arg appRoleId "${appRoleId}" \
+ '{principalId: $principalId, resourceId: $resourceId, appRoleId: $appRoleId}' ) && echo " - body: $JSON"
-fi
+ az rest --method POST --uri $URI --header Content-Type=application/json --body "$JSON"
+ else
+ echo "API permission already granted."
+ fi
+fi
\ No newline at end of file
diff --git a/modules/azuread/applications/variables.tf b/modules/azuread/applications/variables.tf
index ac4e2d6244..6dee0767d5 100755
--- a/modules/azuread/applications/variables.tf
+++ b/modules/azuread/applications/variables.tf
@@ -14,6 +14,7 @@ variable "user_type" {}
variable "keyvaults" {
default = {}
}
+
variable "password_policy" {
description = "Default password policy applies when not set in tfvars."
default = {
diff --git a/modules/azuread/applications_v1/azuread_application.tf b/modules/azuread/applications_v1/azuread_application.tf
new file mode 100755
index 0000000000..c8e93d96bd
--- /dev/null
+++ b/modules/azuread/applications_v1/azuread_application.tf
@@ -0,0 +1,41 @@
+resource "azuread_application" "app" {
+
+ display_name = var.global_settings.passthrough || try(var.settings.global_settings.passthrough, false) ? var.settings.application_name : format("%v-%s", try(var.global_settings.prefixes[0], ""), var.settings.application_name)
+
+ owners = coalescelist(
+ [
+ var.client_config.object_id
+ ],
+ try(var.settings.owners, [])
+ )
+
+ available_to_other_tenants = try(var.settings.available_to_other_tenants, false)
+ homepage = try(var.settings.homepage, null)
+ group_membership_claims = try(var.settings.group_membership_claims, "All")
+ identifier_uris = try(var.settings.identifier_uris, null)
+ logout_url = try(var.settings.logout_url, null)
+ oauth2_allow_implicit_flow = try(var.settings.oauth2_allow_implicit_flow, false)
+ prevent_duplicate_names = try(var.settings.identifier_uris, false)
+ public_client = try(var.settings.public_client, false)
+ reply_urls = try(var.settings.reply_urls, null)
+
+ dynamic "required_resource_access" {
+ for_each = var.azuread_api_permissions
+
+ content {
+ resource_app_id = required_resource_access.value.resource_app_id
+
+ dynamic "resource_access" {
+ for_each = {
+ for key, resource in required_resource_access.value.resource_access : key => resource
+ }
+
+ content {
+ id = resource_access.value.id
+ type = resource_access.value.type
+ }
+ }
+ }
+ }
+
+}
diff --git a/modules/azuread/applications_v1/output.tf b/modules/azuread/applications_v1/output.tf
new file mode 100755
index 0000000000..cd8c6a2de9
--- /dev/null
+++ b/modules/azuread/applications_v1/output.tf
@@ -0,0 +1,49 @@
+
+output "id" {
+ value = azuread_application.app.id
+}
+output "tenant_id" {
+ value = var.client_config.tenant_id
+}
+output "object_id" {
+ value = azuread_application.app.object_id
+}
+output "application_id" {
+ value = azuread_application.app.application_id
+}
+output "available_to_other_tenants" {
+ value = azuread_application.app.available_to_other_tenants
+}
+output "display_name" {
+ value = azuread_application.app.display_name
+}
+output "group_membership_claims" {
+ value = azuread_application.app.group_membership_claims
+}
+output "homepage" {
+ value = azuread_application.app.homepage
+}
+output "identifier_uris" {
+ value = azuread_application.app.identifier_uris
+}
+output "logout_url" {
+ value = azuread_application.app.logout_url
+}
+output "oauth2_allow_implicit_flow" {
+ value = azuread_application.app.oauth2_allow_implicit_flow
+}
+output "owners" {
+ value = azuread_application.app.owners
+}
+output "prevent_duplicate_names" {
+ value = azuread_application.app.prevent_duplicate_names
+}
+output "public_client" {
+ value = azuread_application.app.public_client
+}
+output "reply_urls" {
+ value = azuread_application.app.reply_urls
+}
+output "type" {
+ value = azuread_application.app.type
+}
\ No newline at end of file
diff --git a/modules/azuread/applications_v1/variables.tf b/modules/azuread/applications_v1/variables.tf
new file mode 100755
index 0000000000..97532fdbf6
--- /dev/null
+++ b/modules/azuread/applications_v1/variables.tf
@@ -0,0 +1,13 @@
+variable "global_settings" {
+ default = {}
+}
+variable "settings" {
+ default = {}
+}
+variable "client_config" {
+ description = "Client configuration object (see module README.md)."
+}
+variable "azuread_api_permissions" {
+ default = {}
+}
+variable "user_type" {}
diff --git a/modules/azuread/credentials/keyvault_secrets.tf b/modules/azuread/credentials/keyvault_secrets.tf
new file mode 100755
index 0000000000..6a3aa1ed81
--- /dev/null
+++ b/modules/azuread/credentials/keyvault_secrets.tf
@@ -0,0 +1,19 @@
+
+resource "azurerm_key_vault_secret" "client_id" {
+ for_each = try(var.settings.keyvaults, {})
+
+ name = format("%s-client-id", each.value.secret_prefix)
+ key_vault_id = try(each.value.lz_key, null) == null ? var.keyvaults[var.client_config.landingzone_key][each.key].id : var.keyvaults[each.value.lz_key][each.key].id
+
+ value = coalesce(
+ try(var.resources.application.application_id, null)
+ )
+}
+
+resource "azurerm_key_vault_secret" "tenant_id" {
+ for_each = try(var.settings.keyvaults, {})
+ name = format("%s-tenant-id", each.value.secret_prefix)
+ value = try(each.value.tenant_id, var.client_config.tenant_id)
+ key_vault_id = try(each.value.lz_key, null) == null ? var.keyvaults[var.client_config.landingzone_key][each.key].id : var.keyvaults[each.value.lz_key][each.key].id
+}
+
diff --git a/modules/azuread/credentials/password.tf b/modules/azuread/credentials/password.tf
new file mode 100644
index 0000000000..ff1add2a2d
--- /dev/null
+++ b/modules/azuread/credentials/password.tf
@@ -0,0 +1,68 @@
+
+resource "azuread_application_password" "key" {
+ count = try(var.settings.azuread_application, null) != null && lower(var.settings.type) == "password" && try(var.settings.azuread_credential_policy_key, null) == null ? 1 : 0
+ description = try(var.settings.description, local.description.key)
+ value = random_password.key.0.result
+ end_date = local.expiration_date.key
+
+ application_object_id = coalesce(
+ try(var.resources.application.id, null)
+ )
+
+ lifecycle {
+ create_before_destroy = true
+ }
+}
+
+resource "azuread_application_password" "key0" {
+ count = try(var.settings.azuread_application, null) != null && lower(var.settings.type) == "password" && try(var.settings.azuread_credential_policy_key, null) != null ? 1 : 0
+ description = try(var.settings.description, local.description.key0)
+ value = random_password.key0.0.result
+ end_date = local.expiration_date.key0
+
+ application_object_id = coalesce(
+ try(var.resources.application.id, null)
+ )
+
+ lifecycle {
+ create_before_destroy = true
+ }
+}
+
+resource "azuread_application_password" "key1" {
+ count = try(var.settings.azuread_application, null) != null && lower(var.settings.type) == "password" && try(var.settings.azuread_credential_policy_key, null) != null ? 1 : 0
+ description = try(var.settings.description, local.description.key1)
+ value = random_password.key1.0.result
+ end_date = local.expiration_date.key1
+
+ application_object_id = coalesce(
+ try(var.resources.application.id, null)
+ )
+
+ lifecycle {
+ create_before_destroy = true
+ }
+}
+
+#
+# Everytime the code run it re-evalute the key to store in the keyvault secret
+#
+locals {
+ # Used to set the key with the longest expiring date into the keyvault
+ random_key = try(tonumber(formatdate("YYYYMMDDhhmmss", local.expiration_date.key0)) > tonumber(formatdate("YYYYMMDDhhmmss", local.expiration_date.key1)) ? "key0" : "key1", "key")
+}
+
+resource "azurerm_key_vault_secret" "client_secret" {
+ for_each = {
+ for key, value in try(var.settings.keyvaults, {}) : key => value
+ if try(var.settings.azuread_application, null) != null && lower(local.password_type) == "password"
+ }
+ name = format("%s-client-secret", each.value.secret_prefix)
+ value = local.random_key == "key0" ? sensitive(azuread_application_password.key0.0.value) : try(sensitive(azuread_application_password.key1.0.value), sensitive(azuread_application_password.key.0.value))
+ key_vault_id = try(each.value.lz_key, null) == null ? var.keyvaults[var.client_config.landingzone_key][each.key].id : var.keyvaults[each.value.lz_key][each.key].id
+ expiration_date = local.random_key == "key0" ? local.expiration_date.key0 : try(local.expiration_date.key1, local.expiration_date.key)
+
+ tags = {
+ key = local.random_key
+ }
+}
\ No newline at end of file
diff --git a/modules/azuread/credentials/password_rotation.tf b/modules/azuread/credentials/password_rotation.tf
new file mode 100644
index 0000000000..d213e583f4
--- /dev/null
+++ b/modules/azuread/credentials/password_rotation.tf
@@ -0,0 +1,98 @@
+#
+# key is used when
+#
+# Keys generated when using the password policy
+# Key0 password_policy.rotation.days is an odd number
+# Key1 password_policy.rotation.days is an even number
+#
+
+locals {
+ password_type = try(var.settings.type, "password")
+ password_policy = try(var.settings.azuread_credential_policy_key, null) == null ? var.policy : var.credential_policy
+
+ expiration_date = {
+ key = try(var.settings.azuread_credential_policy_key, null) == null ? timeadd(time_rotating.key.0.id, format("%sh", local.key.days * 24)) : null
+ key0 = try(var.settings.azuread_credential_policy_key, null) != null ? timeadd(time_rotating.key0.0.id, format("%sh", local.key0.days * 24)) : null
+ key1 = try(var.settings.azuread_credential_policy_key, null) != null ? timeadd(time_rotating.key1.0.id, format("%sh", local.key1.days * 24)) : null
+ }
+
+ description = {
+ key = try(format(
+ "key-%s-%s",
+ formatdate("YYMMDDhhmmss", time_rotating.key.0.id),
+ formatdate("YYMMDDhhmmss", local.expiration_date.key)
+ ), null)
+ key0 = try(format(
+ "key0-%s-%s",
+ formatdate("YYMMDDhhmmss", time_rotating.key0.0.id),
+ formatdate("YYMMDDhhmmss", local.expiration_date.key0)
+ ), null)
+ key1 = try(format(
+ "key1-%s-%s",
+ formatdate("YYMMDDhhmmss", time_rotating.key1.0.id),
+ formatdate("YYMMDDhhmmss", local.expiration_date.key1)
+ ), null)
+ }
+
+ key = {
+ # Coming from the default variables.tf
+ days = try(local.password_policy.rotation_key0.days, null)
+ }
+
+ key0 = {
+ days = try(local.password_policy.rotation_key0.days, null)
+ }
+
+ key1 = {
+ days = try(local.password_policy.rotation_key1.days, null)
+ }
+}
+
+resource "time_rotating" "key" {
+ count = lower(local.password_type) == "password" && try(var.settings.azuread_credential_policy_key, null) == null ? 1 : 0
+ rotation_days = local.key.days
+}
+
+resource "random_password" "key" {
+ count = lower(local.password_type) == "password" && try(var.settings.azuread_credential_policy_key, null) == null ? 1 : 0
+ keepers = {
+ frequency = time_rotating.key.0.id
+ }
+ length = local.password_policy.length
+ special = local.password_policy.special
+ upper = local.password_policy.upper
+ number = local.password_policy.number
+}
+
+resource "time_rotating" "key0" {
+ count = lower(local.password_type) == "password" && try(var.settings.azuread_credential_policy_key, null) != null ? 1 : 0
+ rotation_days = local.key0.days
+}
+
+resource "random_password" "key0" {
+ count = lower(local.password_type) == "password" && try(var.settings.azuread_credential_policy_key, null) != null ? 1 : 0
+ keepers = {
+ frequency = time_rotating.key0.0.id
+ }
+ length = local.password_policy.length
+ special = local.password_policy.special
+ upper = local.password_policy.upper
+ number = local.password_policy.number
+}
+
+
+resource "time_rotating" "key1" {
+ count = lower(local.password_type) == "password" && try(var.settings.azuread_credential_policy_key, null) != null ? 1 : 0
+ rotation_days = local.key1.days
+}
+
+resource "random_password" "key1" {
+ count = lower(local.password_type) == "password" && try(var.settings.azuread_credential_policy_key, null) != null ? 1 : 0
+ keepers = {
+ frequency = time_rotating.key1.0.id
+ }
+ length = local.password_policy.length
+ special = local.password_policy.special
+ upper = local.password_policy.upper
+ number = local.password_policy.number
+}
\ No newline at end of file
diff --git a/modules/azuread/credentials/variables.tf b/modules/azuread/credentials/variables.tf
new file mode 100755
index 0000000000..3e2f09f03e
--- /dev/null
+++ b/modules/azuread/credentials/variables.tf
@@ -0,0 +1,59 @@
+variable "global_settings" {
+ default = {}
+}
+variable "settings" {
+ default = {}
+}
+variable "client_config" {
+ description = "Client configuration object (see module README.md)."
+}
+variable "keyvaults" {
+ default = {}
+}
+
+variable "resources" {
+ description = "Application ID the credentials will be attached to."
+}
+
+variable "credential_policy" {
+ description = "Custom credential policy to apply."
+ default = null
+}
+
+variable "policy" {
+ description = "Default credential policy to apply."
+ default = {
+ # Length of the password
+ length = 250
+ special = false
+ upper = true
+ number = true
+
+ # Define the number of days the password is valid. It must be more than the rotation frequency
+ expire_in_days = 380
+ rotation_key0 = {
+ # Odd number
+ #
+ # Set how often the password must be rotated. When passed the renewal time, running the terraform plan / apply will change to a new password
+ # Only set one of the value
+ # Note - once set cannot switch between mins/days/months. Only the value can be adjusted.
+ #
+
+ # mins = 10 # only recommended for CI and demo
+ days = 180
+ # months = 1
+ }
+ rotation_key1 = {
+ # Even number
+ #
+ # Set how often the password must be rotated. When passed the renewal time, running the terraform plan / apply will change to a new password
+ # Only set one of the value
+ # Note - once set cannot switch between mins/days/months. Only the value can be adjusted.
+ #
+
+ # mins = 10 # only recommended for CI and demo
+ days = 361
+ # months = 1
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/azuread/groups_members/members.tf b/modules/azuread/groups_members/groups_members.tf
similarity index 68%
rename from modules/azuread/groups_members/members.tf
rename to modules/azuread/groups_members/groups_members.tf
index 197e8c1995..21e1a01267 100755
--- a/modules/azuread/groups_members/members.tf
+++ b/modules/azuread/groups_members/groups_members.tf
@@ -12,7 +12,6 @@ module "user_principal_names" {
member_object_id = data.azuread_user.upn[each.key].id
}
-
module "service_principals" {
source = "./member"
for_each = toset(try(var.settings.members.service_principal_keys, []))
@@ -21,6 +20,22 @@ module "service_principals" {
member_object_id = var.azuread_apps[each.key].azuread_service_principal.object_id
}
+module "azuread_service_principals" {
+ source = "./member"
+ for_each = toset(try(var.settings.members.azuread_service_principal_keys, []))
+
+ group_object_id = var.group_id
+ member_object_id = var.azuread_service_principals[each.key].object_id
+}
+
+module "azuread_service_principals_membership" {
+ source = "./membership"
+ for_each = try(var.settings.azuread_service_principals, {})
+
+ group_object_id = var.group_id
+ azuread_service_principals = var.azuread_service_principals[try(each.value.lz_key, var.client_config.landingzone_key)]
+ members = each.value
+}
module "object_id" {
source = "./member"
diff --git a/modules/azuread/groups_members/member/member.tf b/modules/azuread/groups_members/member/member.tf
index ad997183c3..f404596591 100755
--- a/modules/azuread/groups_members/member/member.tf
+++ b/modules/azuread/groups_members/member/member.tf
@@ -1,7 +1,4 @@
-variable "group_object_id" {}
-variable "member_object_id" {}
-
resource "azuread_group_member" "id" {
group_object_id = var.group_object_id
member_object_id = var.member_object_id
-}
+}
\ No newline at end of file
diff --git a/modules/azuread/groups_members/member/variables.tf b/modules/azuread/groups_members/member/variables.tf
new file mode 100644
index 0000000000..e81440228c
--- /dev/null
+++ b/modules/azuread/groups_members/member/variables.tf
@@ -0,0 +1,4 @@
+variable "group_object_id" {}
+variable "member_object_id" {
+ default = null
+}
\ No newline at end of file
diff --git a/modules/azuread/groups_members/membership/membership.tf b/modules/azuread/groups_members/membership/membership.tf
new file mode 100755
index 0000000000..f10cb944fa
--- /dev/null
+++ b/modules/azuread/groups_members/membership/membership.tf
@@ -0,0 +1,6 @@
+resource "azuread_group_member" "ids" {
+ for_each = toset(try(var.members.keys, []))
+
+ group_object_id = var.group_object_id
+ member_object_id = var.azuread_service_principals[each.key].object_id
+}
\ No newline at end of file
diff --git a/modules/azuread/groups_members/membership/variables.tf b/modules/azuread/groups_members/membership/variables.tf
new file mode 100644
index 0000000000..db250692e4
--- /dev/null
+++ b/modules/azuread/groups_members/membership/variables.tf
@@ -0,0 +1,10 @@
+variable "group_object_id" {}
+variable "member_object_id" {
+ default = null
+}
+variable "azuread_service_principals" {
+ default = {}
+}
+variable "members" {
+ default = {}
+}
\ No newline at end of file
diff --git a/modules/azuread/groups_members/variables.tf b/modules/azuread/groups_members/variables.tf
index 24c8ff6e87..2b13c8d9e1 100755
--- a/modules/azuread/groups_members/variables.tf
+++ b/modules/azuread/groups_members/variables.tf
@@ -1,8 +1,12 @@
+variable "settings" {}
variable "group_id" {}
+variable "client_config" {}
variable "azuread_groups" {
default = {}
}
variable "azuread_apps" {
default = {}
}
-variable "settings" {}
\ No newline at end of file
+variable "azuread_service_principals" {
+ default = {}
+}
\ No newline at end of file
diff --git a/modules/azuread/roles/scripts/set_ad_role.sh b/modules/azuread/roles/scripts/set_ad_role.sh
index 2fafd35cf5..68a822eca9 100755
--- a/modules/azuread/roles/scripts/set_ad_role.sh
+++ b/modules/azuread/roles/scripts/set_ad_role.sh
@@ -46,12 +46,12 @@ case "${METHOD}" in
az rest --method ${METHOD} --uri $URI --header Content-Type=application/json --body "$JSON"
- echo "Role '${AD_ROLE_NAME}' assigned to azure ad application"
+ echo "Role '${AD_ROLE_NAME}' assigned to azure ad principal"
;;
DELETE)
URI=$(echo "${microsoft_graph_endpoint}v1.0/directoryRoles/${ROLE_AAD}/members/${SERVICE_PRINCIPAL_OBJECT_ID}/\$ref") && echo " - uri: $URI"
- az rest --method ${METHOD} --uri ${URI}
- echo "Role '${AD_ROLE_NAME}' unassigned to azure ad application ${SERVICE_PRINCIPAL_OBJECT_ID}"
+ az rest --method ${METHOD} --uri ${URI} || true
+ echo "Role '${AD_ROLE_NAME}' unassigned to azure ad principal ${SERVICE_PRINCIPAL_OBJECT_ID}"
;;
esac
diff --git a/modules/azuread/service_principal/grant_api_permissions.tf b/modules/azuread/service_principal/grant_api_permissions.tf
new file mode 100755
index 0000000000..881ab89bb0
--- /dev/null
+++ b/modules/azuread/service_principal/grant_api_permissions.tf
@@ -0,0 +1,46 @@
+# Admin consent management is not performed in the same way if the logged in user is a service principal or a user
+# We have two local variables to accomodate that.
+locals {
+ api_permissions = {
+ for api_permission in
+ flatten(
+ [
+ for key, resources in var.azuread_api_permissions : [
+ for resource_name, resource in resources.resource_access : {
+ aad_app_key = key
+ resource_name = resource_name
+ resource_app_id = resources.resource_app_id
+ id = resource.id
+ type = resource.type
+ } if resource.type == "Role"
+ ]
+ ]
+ ) : format("%s-%s", api_permission.aad_app_key, api_permission.resource_name) => api_permission
+ }
+}
+
+
+resource "null_resource" "grant_admin_consent" {
+
+ triggers = {
+ resourceAppId = each.value.resource_app_id
+ appRoleId = each.value.id
+ principalId = azuread_service_principal.app.object_id
+ }
+
+ for_each = {
+ for key, permission in local.api_permissions : key => permission
+ }
+
+ provisioner "local-exec" {
+ command = format("%s/scripts/grant_consent.sh", path.module)
+ interpreter = ["/bin/bash"]
+ on_failure = fail
+
+ environment = {
+ resourceAppId = self.triggers.resourceAppId
+ appRoleId = self.triggers.appRoleId
+ principalId = self.triggers.principalId
+ }
+ }
+}
diff --git a/modules/azuread/service_principal/module.tf b/modules/azuread/service_principal/module.tf
new file mode 100755
index 0000000000..d9f06adbe4
--- /dev/null
+++ b/modules/azuread/service_principal/module.tf
@@ -0,0 +1,18 @@
+
+resource "azuread_service_principal" "app" {
+ application_id = var.application_id
+ app_role_assignment_required = try(var.settings.app_role_assignment_required, false)
+
+ lifecycle {
+ ignore_changes = [application_id]
+ }
+}
+
+resource "null_resource" "propagate_to_azuread" {
+ depends_on = [azuread_service_principal.app]
+
+ provisioner "local-exec" {
+ command = "/bin/bash -c '/usr/bin/sleep 30'"
+ on_failure = fail
+ }
+}
\ No newline at end of file
diff --git a/modules/azuread/service_principal/output.tf b/modules/azuread/service_principal/output.tf
new file mode 100755
index 0000000000..25c875ec7e
--- /dev/null
+++ b/modules/azuread/service_principal/output.tf
@@ -0,0 +1,28 @@
+
+output "tenant_id" {
+ value = var.client_config.tenant_id
+}
+
+output "id" {
+ value = azuread_service_principal.app.id
+}
+
+output "application_id" {
+ value = azuread_service_principal.app.application_id
+}
+
+output "object_id" {
+ value = azuread_service_principal.app.object_id
+}
+
+output "display_name" {
+ value = azuread_service_principal.app.object_id
+}
+
+output "oauth2_permissions" {
+ value = azuread_service_principal.app.oauth2_permissions
+}
+output "rbac_id" {
+ value = azuread_service_principal.app.object_id
+ description = "This attribute is used to set the role assignment"
+}
\ No newline at end of file
diff --git a/modules/azuread/service_principal/scripts/grant_consent.sh b/modules/azuread/service_principal/scripts/grant_consent.sh
new file mode 100755
index 0000000000..9a422583c9
--- /dev/null
+++ b/modules/azuread/service_principal/scripts/grant_consent.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+set -e
+
+user_type=$(az account show --query user.type -o tsv)
+
+if [ "${user_type}" = "user" ]; then
+
+ az ad app permission admin-consent --id ${applicationId}
+
+else
+ resourceId=$(az ad sp show --id "${resourceAppId}" --query "objectId" -o tsv)
+ echo " -resourceId: ${resourceId}"
+
+ microsoft_graph_endpoint=$(az cloud show | jq -r ".endpoints.microsoftGraphResourceId")
+
+ URI=$(echo "${microsoft_graph_endpoint}v1.0/servicePrincipals/${resourceId}/appRoleAssignedTo") && echo " - uri: $URI"
+
+ existingAppRoleId=$(az rest --method GET --uri ${URI} \
+ --query "value[?appRoleId=='${appRoleId}' && principalId=='${principalId}' && resourceId=='${resourceId}'].appRoleId" -o tsv)
+
+ if [ -z ${existingAppRoleId} ]; then
+ JSON=$( jq -n \
+ --arg principalId "${principalId}" \
+ --arg resourceId "${resourceId}" \
+ --arg appRoleId "${appRoleId}" \
+ '{principalId: $principalId, resourceId: $resourceId, appRoleId: $appRoleId}' ) && echo " - body: $JSON"
+
+ az rest --method POST --uri $URI --header Content-Type=application/json --body "$JSON"
+ else
+ echo "API permission already granted."
+ fi
+fi
\ No newline at end of file
diff --git a/modules/azuread/service_principal/variables.tf b/modules/azuread/service_principal/variables.tf
new file mode 100755
index 0000000000..8fe49f1612
--- /dev/null
+++ b/modules/azuread/service_principal/variables.tf
@@ -0,0 +1,16 @@
+variable "global_settings" {
+ default = {}
+}
+variable "settings" {
+ default = {}
+}
+variable "client_config" {
+ description = "Client configuration object (see module README.md)."
+}
+variable "application_id" {
+ description = "Application ID of the service principal to create."
+}
+variable "azuread_api_permissions" {
+ default = {}
+}
+variable "user_type" {}
diff --git a/modules/azuread/service_principal_password/keyvault_secrets.tf b/modules/azuread/service_principal_password/keyvault_secrets.tf
new file mode 100755
index 0000000000..826101ad1d
--- /dev/null
+++ b/modules/azuread/service_principal_password/keyvault_secrets.tf
@@ -0,0 +1,23 @@
+
+resource "azurerm_key_vault_secret" "client_id" {
+ for_each = try(var.settings.keyvaults, {})
+
+ name = format("%s-client-id", each.value.secret_prefix)
+ value = var.service_principal_application_id
+ key_vault_id = try(each.value.lz_key, null) == null ? var.keyvaults[var.client_config.landingzone_key][each.key].id : var.keyvaults[each.value.lz_key][each.key].id
+}
+
+resource "azurerm_key_vault_secret" "client_secret" {
+ for_each = try(var.settings.keyvaults, {})
+ name = format("%s-client-secret", each.value.secret_prefix)
+ value = azuread_service_principal_password.pwd.value
+ key_vault_id = try(each.value.lz_key, null) == null ? var.keyvaults[var.client_config.landingzone_key][each.key].id : var.keyvaults[each.value.lz_key][each.key].id
+ expiration_date = timeadd(time_rotating.pwd.id, format("%sh", local.password_policy.expire_in_days * 24))
+}
+
+resource "azurerm_key_vault_secret" "tenant_id" {
+ for_each = try(var.settings.keyvaults, {})
+ name = format("%s-tenant-id", each.value.secret_prefix)
+ value = var.client_config.tenant_id
+ key_vault_id = try(each.value.lz_key, null) == null ? var.keyvaults[var.client_config.landingzone_key][each.key].id : var.keyvaults[each.value.lz_key][each.key].id
+}
diff --git a/modules/azuread/service_principal_password/module.tf b/modules/azuread/service_principal_password/module.tf
new file mode 100755
index 0000000000..454c07ec32
--- /dev/null
+++ b/modules/azuread/service_principal_password/module.tf
@@ -0,0 +1,32 @@
+
+resource "azuread_service_principal_password" "pwd" {
+ service_principal_id = var.service_principal_id
+ value = random_password.pwd.result
+ end_date = timeadd(time_rotating.pwd.id, format("%sh", local.password_policy.expire_in_days * 24))
+
+ lifecycle {
+ create_before_destroy = false
+ }
+}
+
+locals {
+ password_policy = try(var.settings.password_policy, var.password_policy)
+}
+
+resource "time_rotating" "pwd" {
+ rotation_minutes = try(local.password_policy.rotation.mins, null)
+ rotation_days = try(local.password_policy.rotation.days, null)
+ rotation_months = try(local.password_policy.rotation.months, null)
+ rotation_years = try(local.password_policy.rotation.years, null)
+}
+
+# Will force the password to change every month
+resource "random_password" "pwd" {
+ keepers = {
+ frequency = time_rotating.pwd.id
+ }
+ length = local.password_policy.length
+ special = local.password_policy.special
+ upper = local.password_policy.upper
+ number = local.password_policy.number
+}
diff --git a/modules/azuread/service_principal_password/output.tf b/modules/azuread/service_principal_password/output.tf
new file mode 100755
index 0000000000..06c9d50a32
--- /dev/null
+++ b/modules/azuread/service_principal_password/output.tf
@@ -0,0 +1,28 @@
+
+output "tenant_id" {
+ value = var.client_config.tenant_id
+}
+output "key_id" {
+ value = azuread_service_principal_password.pwd.key_id
+}
+output "service_principal_id" {
+ value = azuread_service_principal_password.pwd.service_principal_id
+}
+output "end_date" {
+ value = azuread_service_principal_password.pwd.end_date
+}
+output "end_date_relative" {
+ value = azuread_service_principal_password.pwd.end_date_relative
+}
+output "start_date" {
+ value = azuread_service_principal_password.pwd.start_date
+}
+output "keyvaults" {
+ value = {
+ for key, value in try(var.settings.keyvaults, {}) : key => {
+ id = azurerm_key_vault_secret.client_id[key].key_vault_id
+ secret_name_client_secret = value.secret_prefix
+ }
+ }
+ description = "Keyvaults storing the passwords. Store the secret_prefix-client-id, secret_prefix-client-secret"
+}
\ No newline at end of file
diff --git a/modules/azuread/service_principal_password/variables.tf b/modules/azuread/service_principal_password/variables.tf
new file mode 100755
index 0000000000..edd83bd959
--- /dev/null
+++ b/modules/azuread/service_principal_password/variables.tf
@@ -0,0 +1,44 @@
+variable "global_settings" {
+ default = {}
+}
+variable "settings" {
+ default = {}
+}
+variable "client_config" {
+ description = "Client configuration object (see module README.md)."
+}
+variable "keyvaults" {
+ default = {}
+}
+
+variable "service_principal_id" {
+ description = "(Required) The ID of the Service Principal for which this password should be created."
+}
+
+variable "service_principal_application_id" {
+ description = "(Required) The App ID of the Application for which to create a Service Principal."
+}
+
+variable "password_policy" {
+ description = "Default password policy applies when not set in tfvars."
+ default = {
+ # Length of the password
+ length = 250
+ special = false
+ upper = true
+ number = true
+
+ # Define the number of days the password is valid. It must be more than the rotation frequency
+ expire_in_days = 180
+ rotation = {
+ #
+ # Set how often the password must be rotated. When passed the renewal time, running the terraform plan / apply will change to a new password
+ # Only set one of the value
+ #
+
+ # mins = 10 # only recommended for CI and demo
+ # days = 7
+ months = 1
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/compute/aks/aks.tf b/modules/compute/aks/aks.tf
index dcdd5e8c4d..1777e018b4 100644
--- a/modules/compute/aks/aks.tf
+++ b/modules/compute/aks/aks.tf
@@ -212,6 +212,7 @@ resource "azurerm_kubernetes_cluster" "aks" {
node_resource_group = azurecaf_name.rg_node.result
private_cluster_enabled = try(var.settings.private_cluster_enabled, false)
+ private_dns_zone_id = try(var.settings.private_dns_zone_id, null)
lifecycle {
ignore_changes = [
diff --git a/modules/compute/aks/variables.tf b/modules/compute/aks/variables.tf
index 7cfb14c2e3..8b704dfe74 100755
--- a/modules/compute/aks/variables.tf
+++ b/modules/compute/aks/variables.tf
@@ -14,4 +14,7 @@ variable "base_tags" {
}
variable "diagnostic_profiles" {
default = null
+}
+variable "private_dns_zone_id" {
+ default = null
}
\ No newline at end of file
diff --git a/modules/compute/container_registry/registry.tf b/modules/compute/container_registry/registry.tf
index 6f1156add0..8abd39b3f5 100755
--- a/modules/compute/container_registry/registry.tf
+++ b/modules/compute/container_registry/registry.tf
@@ -9,16 +9,15 @@ resource "azurecaf_name" "acr" {
}
resource "azurerm_container_registry" "acr" {
- name = azurecaf_name.acr.result
- resource_group_name = var.resource_group_name
- location = var.location
- sku = var.sku
- admin_enabled = var.admin_enabled
- georeplication_locations = var.georeplication_locations
- tags = local.tags
+ name = azurecaf_name.acr.result
+ resource_group_name = var.resource_group_name
+ location = var.location
+ sku = var.sku
+ admin_enabled = var.admin_enabled
+ tags = local.tags
dynamic "network_rule_set" {
- for_each = var.network_rule_set
+ for_each = try(var.network_rule_set, {})
content {
default_action = try(var.network_rule_set.default_action, "Allow")
@@ -41,5 +40,14 @@ resource "azurerm_container_registry" "acr" {
}
}
}
+
+ dynamic "georeplications" {
+ for_each = try(var.georeplications, {})
+
+ content {
+ location = var.global_settings.regions[georeplications.key]
+ tags = try(georeplications.value.tags)
+ }
+ }
}
diff --git a/modules/compute/container_registry/variables.tf b/modules/compute/container_registry/variables.tf
index 328a872b91..c6ee4d5052 100755
--- a/modules/compute/container_registry/variables.tf
+++ b/modules/compute/container_registry/variables.tf
@@ -34,9 +34,9 @@ variable "tags" {
default = {}
}
-variable "georeplication_locations" {
- description = "(Optional) A list of Azure locations where the container registry should be geo-replicated."
- default = null
+variable "georeplications" {
+ description = "(Optional) Updated structure for Azure locations where the container registry should be geo-replicated."
+ default = {}
}
variable "vnets" {
diff --git a/modules/compute/dedicated_host_groups/main.tf b/modules/compute/dedicated_host_groups/main.tf
new file mode 100755
index 0000000000..d1edf5b78b
--- /dev/null
+++ b/modules/compute/dedicated_host_groups/main.tf
@@ -0,0 +1,16 @@
+terraform {
+ required_providers {
+ azurecaf = {
+ source = "aztfmod/azurecaf"
+ }
+ }
+ required_version = ">= 0.13"
+}
+
+
+locals {
+ module_tag = {
+ "module" = basename(abspath(path.module))
+ }
+ tags = merge(var.base_tags, local.module_tag, try(var.tags, null))
+}
\ No newline at end of file
diff --git a/modules/compute/dedicated_host_groups/module.tf b/modules/compute/dedicated_host_groups/module.tf
new file mode 100644
index 0000000000..241e9ccc58
--- /dev/null
+++ b/modules/compute/dedicated_host_groups/module.tf
@@ -0,0 +1,23 @@
+resource "azurecaf_name" "dhg" {
+ name = var.settings.name
+ resource_type = "azurerm_dedicated_host_group"
+ prefixes = var.global_settings.prefixes
+ random_length = var.global_settings.random_length
+ clean_input = true
+ passthrough = var.global_settings.passthrough
+ use_slug = var.global_settings.use_slug
+}
+
+# Last review : AzureRM version 2.63.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/dedicated_host_group
+
+
+resource "azurerm_dedicated_host_group" "dhg" {
+ name = azurecaf_name.dhg.result
+ resource_group_name = var.resource_group_name
+ location = var.location
+ platform_fault_domain_count = var.settings.platform_fault_domain_count
+ automatic_placement_enabled = try(var.settings.automatic_placement_enabled, false)
+ zones = try(var.settings.zones, null)
+ tags = local.tags
+}
\ No newline at end of file
diff --git a/modules/compute/dedicated_host_groups/output.tf b/modules/compute/dedicated_host_groups/output.tf
new file mode 100644
index 0000000000..2d568029f9
--- /dev/null
+++ b/modules/compute/dedicated_host_groups/output.tf
@@ -0,0 +1,4 @@
+output "id" {
+ value = azurerm_dedicated_host_group.dhg.id
+ description = "The ID of the Dedicated Host Group."
+}
\ No newline at end of file
diff --git a/modules/compute/dedicated_host_groups/variables.tf b/modules/compute/dedicated_host_groups/variables.tf
new file mode 100644
index 0000000000..5b9e0dce63
--- /dev/null
+++ b/modules/compute/dedicated_host_groups/variables.tf
@@ -0,0 +1,21 @@
+variable "global_settings" {
+ description = "Global settings object (see module README.md)"
+}
+variable "client_config" {
+ description = "Client configuration object (see module README.md)."
+}
+variable "location" {
+ description = "(Required) Specifies the supported Azure location where to create the resource. Changing this forces a new resource to be created."
+ type = string
+}
+variable "resource_group_name" {
+ description = "Name of the existing resource group to deploy the virtual machine"
+}
+variable "base_tags" {
+ description = "Base tags for the resource to be inherited from the resource group."
+ type = map(any)
+}
+variable "settings" {}
+variable "tags" {
+ default = null
+}
\ No newline at end of file
diff --git a/modules/compute/dedicated_hosts/main.tf b/modules/compute/dedicated_hosts/main.tf
new file mode 100755
index 0000000000..d1edf5b78b
--- /dev/null
+++ b/modules/compute/dedicated_hosts/main.tf
@@ -0,0 +1,16 @@
+terraform {
+ required_providers {
+ azurecaf = {
+ source = "aztfmod/azurecaf"
+ }
+ }
+ required_version = ">= 0.13"
+}
+
+
+locals {
+ module_tag = {
+ "module" = basename(abspath(path.module))
+ }
+ tags = merge(var.base_tags, local.module_tag, try(var.tags, null))
+}
\ No newline at end of file
diff --git a/modules/compute/dedicated_hosts/module.tf b/modules/compute/dedicated_hosts/module.tf
new file mode 100644
index 0000000000..1397f5e0da
--- /dev/null
+++ b/modules/compute/dedicated_hosts/module.tf
@@ -0,0 +1,23 @@
+resource "azurecaf_name" "dh" {
+ name = var.settings.name
+ resource_type = "azurerm_dedicated_host"
+ prefixes = var.global_settings.prefixes
+ random_length = var.global_settings.random_length
+ clean_input = true
+ passthrough = var.global_settings.passthrough
+ use_slug = var.global_settings.use_slug
+}
+
+# Last review : AzureRM version 2.63.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/dedicated_host
+
+resource "azurerm_dedicated_host" "dh" {
+ name = azurecaf_name.dh.result
+ dedicated_host_group_id = var.dedicated_host_group_id
+ location = var.location
+ sku_name = var.settings.sku_name
+ platform_fault_domain = var.settings.platform_fault_domain
+ auto_replace_on_failure = try(var.settings.auto_replace_on_failure, true)
+ license_type = try(var.settings.license_type, "None")
+ tags = local.tags
+}
\ No newline at end of file
diff --git a/modules/compute/dedicated_hosts/output.tf b/modules/compute/dedicated_hosts/output.tf
new file mode 100644
index 0000000000..16cc17a66d
--- /dev/null
+++ b/modules/compute/dedicated_hosts/output.tf
@@ -0,0 +1,4 @@
+output "id" {
+ value = azurerm_dedicated_host.dh.id
+ description = "The ID of the Dedicated Host."
+}
\ No newline at end of file
diff --git a/modules/compute/dedicated_hosts/variables.tf b/modules/compute/dedicated_hosts/variables.tf
new file mode 100644
index 0000000000..83d54a6b4d
--- /dev/null
+++ b/modules/compute/dedicated_hosts/variables.tf
@@ -0,0 +1,25 @@
+variable "global_settings" {
+ description = "Global settings object (see module README.md)"
+}
+variable "client_config" {
+ description = "Client configuration object (see module README.md)."
+}
+variable "location" {
+ description = "(Required) Specifies the supported Azure location where to create the resource. Changing this forces a new resource to be created."
+ type = string
+}
+# variable "resource_group_name" {
+# description = "Name of the existing resource group to deploy the virtual machine"
+# }
+variable "base_tags" {
+ description = "Base tags for the resource to be inherited from the resource group."
+ type = map(any)
+}
+variable "settings" {}
+variable "tags" {
+ default = null
+}
+variable "dedicated_host_group_id" {
+ description = "The ID of the dedicated host group"
+ type = string
+}
\ No newline at end of file
diff --git a/modules/compute/virtual_machine/network_interface.tf b/modules/compute/virtual_machine/network_interface.tf
index 07fa742080..d8866cb54d 100755
--- a/modules/compute/virtual_machine/network_interface.tf
+++ b/modules/compute/virtual_machine/network_interface.tf
@@ -83,12 +83,12 @@ resource "azurerm_network_interface" "nic" {
# internal_dns_name_label = "nic0"
# // Prefer network_security_group orver nsg_key. Will be removed in version 6
# nsg_key = "data" // requires a version 1 nsg definition (see compute/vm/210-vm-bastion-winrm example)
-#
+#
# network_security_group = {
# # lz_key = ""
# key = "data"
# }
-#
+#
# ip_configurations = {
# conf2 = {
# name = "nic0-conf2"
diff --git a/modules/compute/virtual_machine/variables.tf b/modules/compute/virtual_machine/variables.tf
index de0d5eb2c2..f5d1d1fa63 100755
--- a/modules/compute/virtual_machine/variables.tf
+++ b/modules/compute/virtual_machine/variables.tf
@@ -81,4 +81,7 @@ variable "network_security_groups" {
description = "Require a version 1 NSG definition to be attached to a nic."
}
+variable "dedicated_hosts" {
+ default = {}
+}
diff --git a/modules/compute/virtual_machine/vm_linux.tf b/modules/compute/virtual_machine/vm_linux.tf
index d160ad2f8e..c4557ae660 100755
--- a/modules/compute/virtual_machine/vm_linux.tf
+++ b/modules/compute/virtual_machine/vm_linux.tf
@@ -68,6 +68,12 @@ resource "azurerm_linux_virtual_machine" "vm" {
custom_data = try(each.value.custom_data, null) == null ? null : filebase64(format("%s/%s", path.cwd, each.value.custom_data))
availability_set_id = try(var.availability_sets[var.client_config.landingzone_key][each.value.availability_set_key].id, var.availability_sets[each.value.availability_sets].id, null)
proximity_placement_group_id = try(var.proximity_placement_groups[var.client_config.landingzone_key][each.value.proximity_placement_group_key].id, var.proximity_placement_groups[each.value.proximity_placement_groups].id, null)
+ dedicated_host_id = try(coalesce(
+ try(each.value.dedicated_host.id, null),
+ var.dedicated_hosts[try(each.value.dedicated_host.lz_key, var.client_config.landingzone_key)][each.value.dedicated_host.key].id,
+ ),
+ null
+ )
dynamic "admin_ssh_key" {
for_each = lookup(each.value, "disable_password_authentication", true) == true ? [1] : []
diff --git a/modules/compute/virtual_machine/vm_windows.tf b/modules/compute/virtual_machine/vm_windows.tf
index e010b13068..2f9cf972b4 100755
--- a/modules/compute/virtual_machine/vm_windows.tf
+++ b/modules/compute/virtual_machine/vm_windows.tf
@@ -62,6 +62,12 @@ resource "azurerm_windows_virtual_machine" "vm" {
timezone = try(each.value.timezone, null)
availability_set_id = try(var.availability_sets[var.client_config.landingzone_key][each.value.availability_set_key].id, var.availability_sets[each.value.availability_sets].id, null)
proximity_placement_group_id = try(var.proximity_placement_groups[var.client_config.landingzone_key][each.value.proximity_placement_group_key].id, var.proximity_placement_groups[each.value.proximity_placement_groups].id, null)
+ dedicated_host_id = try(coalesce(
+ try(each.value.dedicated_host.id, null),
+ var.dedicated_hosts[try(each.value.dedicated_host.lz_key, var.client_config.landingzone_key)][each.value.dedicated_host.key].id,
+ ),
+ null
+ )
os_disk {
caching = each.value.os_disk.caching
diff --git a/modules/compute/virtual_machine_extensions/domain_join.tf b/modules/compute/virtual_machine_extensions/domain_join.tf
index 7b898081f6..716796589a 100644
--- a/modules/compute/virtual_machine_extensions/domain_join.tf
+++ b/modules/compute/virtual_machine_extensions/domain_join.tf
@@ -32,13 +32,20 @@ resource "azurerm_virtual_machine_extension" "domainjoin" {
}
data "azurerm_key_vault_secret" "domain_join_password" {
- for_each = var.extension_name == "microsoft_azure_domainJoin" ? toset(["enabled"]) : toset([])
- name = var.extension.domain_join_password_keyvault.secret_name
- key_vault_id = try(var.extension.domain_join_password_keyvault.key_vault_id, var.keyvaults[var.extension.domain_join_password_keyvault.keyvault_key].id)
+ for_each = var.extension_name == "microsoft_azure_domainJoin" ? toset(["enabled"]) : toset([])
+ name = var.extension.domain_join_password_keyvault.secret_name
+ key_vault_id = try(
+ var.extension.domain_join_password_keyvault.key_vault_id,
+ try(var.keyvaults[var.extension.domain_join_password_keyvault.lz_key][var.extension.domain_join_password_keyvault.keyvault_key].id, var.keyvaults[var.client_config.landingzone_key][var.extension.domain_join_password_keyvault.keyvault_key].id)
+ )
}
data "azurerm_key_vault_secret" "domain_join_username" {
- for_each = var.extension_name == "microsoft_azure_domainJoin" ? toset(["enabled"]) : toset([])
- name = var.extension.domain_join_username_keyvault.secret_name
- key_vault_id = try(var.extension.domain_join_username_keyvault.key_vault_id, var.keyvaults[var.extension.domain_join_username_keyvault.keyvault_key].id)
-}
\ No newline at end of file
+ for_each = var.extension_name == "microsoft_azure_domainJoin" ? toset(["enabled"]) : toset([])
+ name = var.extension.domain_join_username_keyvault.secret_name
+ key_vault_id = try(
+ var.extension.domain_join_username_keyvault.key_vault_id,
+ try(var.keyvaults[var.extension.domain_join_username_keyvault.lz_key][var.extension.domain_join_username_keyvault.keyvault_key].id, var.keyvaults[var.client_config.landingzone_key][var.extension.domain_join_username_keyvault.keyvault_key].id)
+ )
+}
+
diff --git a/modules/compute/virtual_machine_extensions/wvd_dsc.tf b/modules/compute/virtual_machine_extensions/wvd_dsc.tf
index 6dc645211a..6f843e0c76 100644
--- a/modules/compute/virtual_machine_extensions/wvd_dsc.tf
+++ b/modules/compute/virtual_machine_extensions/wvd_dsc.tf
@@ -12,7 +12,10 @@ resource "azurerm_virtual_machine_extension" "session_host_dscextension" {
"modulesURL" : format("%s/DSC/Configuration.zip", var.extension.base_url),
"configurationFunction" : "Configuration.ps1\\AddSessionHost",
"properties" : {
- "HostPoolName" : try(var.extension.host_pool_name, var.wvd_host_pools[var.extension.host_pool.host_pool_key].name)
+ "HostPoolName" : coalesce(
+ try(var.extension.host_pool_name, ""),
+ try(var.wvd_host_pools[var.extension.host_pool.lz_key][var.extension.host_pool.keyvault_key].name, var.wvd_host_pools[var.client_config.landingzone_key][var.extension.host_pool.host_pool_key].name)
+ )
}
}
)
@@ -26,7 +29,11 @@ resource "azurerm_virtual_machine_extension" "session_host_dscextension" {
}
data "azurerm_key_vault_secret" "host_pool_token" {
- for_each = var.extension_name == "session_host_dscextension" && try(var.extension.host_pool_token, null) == null ? toset(["enabled"]) : toset([])
- name = var.extension.host_pool.secret_name
- key_vault_id = try(var.extension.host_pool.key_vault_id, var.keyvaults[var.extension.host_pool.keyvault_key].id)
-}
\ No newline at end of file
+ for_each = var.extension_name == "session_host_dscextension" && try(var.extension.host_pool_token, null) == null ? toset(["enabled"]) : toset([])
+ name = var.extension.host_pool.secret_name
+ key_vault_id = try(
+ var.extension.host_pool.key_vault_id,
+ try(var.keyvaults[var.extension.host_pool.lz_key][var.extension.host_pool.keyvault_key].id, var.keyvaults[var.client_config.landingzone_key][var.extension.host_pool.keyvault_key].id)
+ )
+}
+
diff --git a/modules/compute/virtual_machine_scale_set/main.tf b/modules/compute/virtual_machine_scale_set/main.tf
index 99fbccab91..e84fec87fa 100644
--- a/modules/compute/virtual_machine_scale_set/main.tf
+++ b/modules/compute/virtual_machine_scale_set/main.tf
@@ -17,28 +17,28 @@ locals {
}
tags = merge(var.base_tags, local.module_tag, try(var.settings.tags, null))
- application_gateway_backend_address_pool_ids = flatten ([
+ application_gateway_backend_address_pool_ids = flatten([
for nic, nic_value in var.settings.network_interfaces : [
- for appgw, appgw_value in try(nic_value.appgw_backend_pools,{}): [
+ for appgw, appgw_value in try(nic_value.appgw_backend_pools, {}) : [
for pool_name in appgw_value.pool_names : [
- try(var.application_gateways[try(var.client_config.landingzone_key, appgw_value.lz_key)][appgw_value.appgw_key].backend_address_pools[pool_name],null)
+ try(var.application_gateways[try(var.client_config.landingzone_key, appgw_value.lz_key)][appgw_value.appgw_key].backend_address_pools[pool_name], null)
]
]
]
])
- load_balancer_backend_address_pool_ids = flatten ([
+ load_balancer_backend_address_pool_ids = flatten([
for nic, nic_value in var.settings.network_interfaces : [
- for lb, lb_value in try(nic_value.load_balancers,{}) : [
- try(var.load_balancers[try(var.client_config.landingzone_key, lb_value.lz_key)][lb_value.lb_key].backend_address_pool_id,null)
+ for lb, lb_value in try(nic_value.load_balancers, {}) : [
+ try(var.load_balancers[try(var.client_config.landingzone_key, lb_value.lz_key)][lb_value.lb_key].backend_address_pool_id, null)
]
]
])
-
- application_security_group_ids = flatten ([
+
+ application_security_group_ids = flatten([
for nic, nic_value in var.settings.network_interfaces : [
- for asg, asg_value in try(nic_value.application_security_groups,{}) : [
- try(var.application_security_groups[try(var.client_config.landingzone_key, asg_value.lz_key)][asg_value.asg_key].id,null)
+ for asg, asg_value in try(nic_value.application_security_groups, {}) : [
+ try(var.application_security_groups[try(var.client_config.landingzone_key, asg_value.lz_key)][asg_value.asg_key].id, null)
]
]
])
diff --git a/modules/compute/virtual_machine_scale_set/output.tf b/modules/compute/virtual_machine_scale_set/output.tf
index c4a847e507..a1ae6890fd 100644
--- a/modules/compute/virtual_machine_scale_set/output.tf
+++ b/modules/compute/virtual_machine_scale_set/output.tf
@@ -1,4 +1,4 @@
-output id {
+output "id" {
value = local.os_type == "linux" ? try(azurerm_linux_virtual_machine_scale_set.vmss["linux"].id, null) : try(azurerm_linux_virtual_machine_scale_set.vmss["windows"].id, null)
}
@@ -6,17 +6,17 @@ output "os_type" {
value = local.os_type
}
-output admin_username {
+output "admin_username" {
value = try(local.admin_username, null) == null ? var.settings.vmss_settings[local.os_type].admin_username : local.admin_username
description = "Local admin username"
}
-output admin_password_secret_id {
+output "admin_password_secret_id" {
value = try(azurerm_key_vault_secret.admin_password[local.os_type].id, null)
description = "Local admin password Key Vault secret id"
}
-output winrm {
+output "winrm" {
value = local.os_type == "windows" ? {
keyvault_id = local.keyvault.id
certificate_url = try(azurerm_key_vault_certificate.self_signed_winrm[local.os_type].secret_id, null)
diff --git a/modules/compute/virtual_machine_scale_set/vmss_linux.tf b/modules/compute/virtual_machine_scale_set/vmss_linux.tf
index 05fc02e75a..ed8e18dea7 100644
--- a/modules/compute/virtual_machine_scale_set/vmss_linux.tf
+++ b/modules/compute/virtual_machine_scale_set/vmss_linux.tf
@@ -102,12 +102,12 @@ resource "azurerm_linux_virtual_machine_scale_set" "vmss" {
network_security_group_id = try(network_interface.value.network_security_group_id, null)
ip_configuration {
- name = azurecaf_name.linux_nic[network_interface.key].result
- primary = try(network_interface.value.primary, false)
- subnet_id = try(var.vnets[var.client_config.landingzone_key][network_interface.value.vnet_key].subnets[network_interface.value.subnet_key].id, var.vnets[network_interface.value.lz_key][network_interface.value.vnet_key].subnets[network_interface.value.subnet_key].id)
- load_balancer_backend_address_pool_ids = try(local.load_balancer_backend_address_pool_ids, null)
+ name = azurecaf_name.linux_nic[network_interface.key].result
+ primary = try(network_interface.value.primary, false)
+ subnet_id = try(var.vnets[var.client_config.landingzone_key][network_interface.value.vnet_key].subnets[network_interface.value.subnet_key].id, var.vnets[network_interface.value.lz_key][network_interface.value.vnet_key].subnets[network_interface.value.subnet_key].id)
+ load_balancer_backend_address_pool_ids = try(local.load_balancer_backend_address_pool_ids, null)
application_gateway_backend_address_pool_ids = try(local.application_gateway_backend_address_pool_ids, null)
- application_security_group_ids = try(local.application_security_group_ids,null)
+ application_security_group_ids = try(local.application_security_group_ids, null)
}
}
}
diff --git a/modules/compute/virtual_machine_scale_set/vmss_windows.tf b/modules/compute/virtual_machine_scale_set/vmss_windows.tf
index 3f9e03389e..abca6a8bc1 100644
--- a/modules/compute/virtual_machine_scale_set/vmss_windows.tf
+++ b/modules/compute/virtual_machine_scale_set/vmss_windows.tf
@@ -17,7 +17,7 @@ resource "azurecaf_name" "windows_computer_name_prefix" {
for_each = local.os_type == "windows" ? var.settings.vmss_settings : {}
name = try(each.value.computer_name_prefix, each.value.name)
- resource_type = "azurerm_vm_windows_computer_name_prefix"
+ resource_type = "azurerm_vm_windows_computer_name_prefix"
prefixes = var.global_settings.prefixes
random_length = var.global_settings.random_length
clean_input = true
@@ -87,12 +87,12 @@ resource "azurerm_windows_virtual_machine_scale_set" "vmss" {
network_security_group_id = try(network_interface.value.network_security_group_id, null)
ip_configuration {
- name = azurecaf_name.windows_nic[network_interface.key].result
- primary = try(network_interface.value.primary, false)
- subnet_id = try(var.vnets[var.client_config.landingzone_key][network_interface.value.vnet_key].subnets[network_interface.value.subnet_key].id, var.vnets[network_interface.value.lz_key][network_interface.value.vnet_key].subnets[network_interface.value.subnet_key].id)
- load_balancer_backend_address_pool_ids = try(local.load_balancer_backend_address_pool_ids, null)
+ name = azurecaf_name.windows_nic[network_interface.key].result
+ primary = try(network_interface.value.primary, false)
+ subnet_id = try(var.vnets[var.client_config.landingzone_key][network_interface.value.vnet_key].subnets[network_interface.value.subnet_key].id, var.vnets[network_interface.value.lz_key][network_interface.value.vnet_key].subnets[network_interface.value.subnet_key].id)
+ load_balancer_backend_address_pool_ids = try(local.load_balancer_backend_address_pool_ids, null)
application_gateway_backend_address_pool_ids = try(local.application_gateway_backend_address_pool_ids, null)
- application_security_group_ids = try(local.application_security_group_ids,null)
+ application_security_group_ids = try(local.application_security_group_ids, null)
}
}
}
@@ -133,7 +133,7 @@ resource "azurerm_windows_virtual_machine_scale_set" "vmss" {
}
source_image_id = try(each.value.custom_image_id, var.custom_image_ids[each.value.lz_key][each.value.custom_image_key].id, null)
-
+
dynamic "plan" {
for_each = try(each.value.plan, null) != null ? [1] : []
@@ -200,10 +200,10 @@ resource "azurerm_windows_virtual_machine_scale_set" "vmss" {
for_each = try(each.value.automatic_os_upgrade_policy, false) == false ? [] : [1]
content {
- disable_automatic_rollback = each.value.automatic_os_upgrade_policy.disable_automatic_rollback
+ disable_automatic_rollback = each.value.automatic_os_upgrade_policy.disable_automatic_rollback
enable_automatic_os_upgrade = each.value.automatic_os_upgrade_policy.enable_automatic_os_upgrade
}
- }
+ }
dynamic "additional_unattend_content" {
for_each = try(each.value.additional_unattend_content, false) == false ? [] : [1]
diff --git a/modules/compute/wvd_applications/main.tf b/modules/compute/wvd_applications/main.tf
new file mode 100644
index 0000000000..b3f47d413b
--- /dev/null
+++ b/modules/compute/wvd_applications/main.tf
@@ -0,0 +1,8 @@
+terraform {
+ required_providers {
+ azurecaf = {
+ source = "aztfmod/azurecaf"
+ }
+ }
+ required_version = ">= 0.13"
+}
diff --git a/modules/compute/wvd_applications/output.tf b/modules/compute/wvd_applications/output.tf
new file mode 100644
index 0000000000..5a4aa46f95
--- /dev/null
+++ b/modules/compute/wvd_applications/output.tf
@@ -0,0 +1,5 @@
+output "id" {
+ value = azurerm_virtual_desktop_application.da.id
+ description = "The ID of the Virtual Desktop Application."
+}
+
diff --git a/modules/compute/wvd_applications/variables.tf b/modules/compute/wvd_applications/variables.tf
new file mode 100644
index 0000000000..a62a23366d
--- /dev/null
+++ b/modules/compute/wvd_applications/variables.tf
@@ -0,0 +1,11 @@
+variable "settings" {}
+variable "global_settings" {}
+
+variable "application_group_id" {
+ default = {}
+}
+
+variable "diagnostic_profiles" {
+ default = null
+}
+variable "diagnostics" {}
diff --git a/modules/compute/wvd_applications/virtual_desktop_application.tf b/modules/compute/wvd_applications/virtual_desktop_application.tf
new file mode 100644
index 0000000000..da8611a5e4
--- /dev/null
+++ b/modules/compute/wvd_applications/virtual_desktop_application.tf
@@ -0,0 +1,13 @@
+resource "azurerm_virtual_desktop_application" "da" {
+ name = var.settings.name
+ application_group_id = var.application_group_id
+ friendly_name = try(var.settings.friendly_name, null)
+ description = try(var.settings.description, null)
+ path = var.settings.path
+ command_line_argument_policy = var.settings.command_line_argument_policy
+ command_line_arguments = try(var.settings.command_line_arguments, null)
+ show_in_portal = try(var.settings.show_in_portal, null)
+ icon_path = try(var.settings.icon_path, null)
+ icon_index = try(var.settings.icon_index, null)
+}
+
diff --git a/modules/compute/wvd_host_pool/virtual_desktop_host_pool.tf b/modules/compute/wvd_host_pool/virtual_desktop_host_pool.tf
index ee17ee4cea..763d5cda46 100644
--- a/modules/compute/wvd_host_pool/virtual_desktop_host_pool.tf
+++ b/modules/compute/wvd_host_pool/virtual_desktop_host_pool.tf
@@ -8,6 +8,10 @@ resource "azurecaf_name" "wvdpool" {
use_slug = var.global_settings.use_slug
}
+
+# Last review : AzureRM version 2.63.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_desktop_host_pool
+
resource "azurerm_virtual_desktop_host_pool" "wvdpool" {
location = var.location
resource_group_name = var.resource_group_name
@@ -21,6 +25,7 @@ resource "azurerm_virtual_desktop_host_pool" "wvdpool" {
personal_desktop_assignment_type = try(var.settings.personal_desktop_assignment_type, null)
preferred_app_group_type = try(var.settings.preferred_app_group_type, null)
custom_rdp_properties = try(var.settings.custom_rdp_properties, null)
+ start_vm_on_connect = try(var.settings.start_vm_on_connect, null)
tags = local.tags
dynamic "registration_info" {
diff --git a/modules/databases/cosmos_dbs/README.md b/modules/databases/cosmos_dbs/README.md
deleted file mode 100755
index 76d36cb767..0000000000
--- a/modules/databases/cosmos_dbs/README.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# Azure Cosmos DB
-
-This submodule is part of Cloud Adoption Framework landing zones for Azure on Terraform.
-
-You can instantiate this submodule directly using the following parameters:
-
-```
-module "caf_cosmos_db" {
- source = "aztfmod/caf/azurerm//modules/databases/cosmos_db"
- version = "4.21.2"
- # insert the 5 required variables here
-}
-```
-
-
-## Requirements
-
-No requirements.
-
-## Providers
-
-| Name | Version |
-|------|---------|
-| azurecaf | n/a |
-| azurerm | n/a |
-
-## Modules
-
-| Name | Source | Version |
-|------|--------|---------|
-| cassandra_keyspaces | ./cassandra_keyspace | |
-| gremlin_databases | ./gremlin_database | |
-| mongo_databases | ./mongo_database | |
-| sql_databases | ./sql_database | |
-| tables | ./table | |
-
-## Resources
-
-| Name |
-|------|
-| [azurecaf_name](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) |
-| [azurerm_cosmosdb_account](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cosmosdb_account) |
-
-## Inputs
-
-| Name | Description | Type | Default | Required |
-|------|-------------|------|---------|:--------:|
-| base\_tags | Base tags for the resource to be inherited from the resource group. | `map(any)` | n/a | yes |
-| global\_settings | Global settings object (see module README.md) | `any` | n/a | yes |
-| location | (Required) Specifies the supported Azure location where to create the resource. Changing this forces a new resource to be created. | `string` | n/a | yes |
-| resource\_group\_name | (Required) The name of the resource group where to create the resource. | `string` | n/a | yes |
-| settings | n/a | `any` | n/a | yes |
-
-## Outputs
-
-| Name | Description |
-|------|-------------|
-| cassandra\_keyspaces | n/a |
-| connection\_string | n/a |
-| cosmos\_account | n/a |
-| endpoint | n/a |
-| gremlin\_databases | n/a |
-| mongo\_databases | n/a |
-| primary\_key | n/a |
-| sql\_databases | n/a |
-| tables | n/a |
-
\ No newline at end of file
diff --git a/modules/databases/mssql_managed_database/variables.tf b/modules/databases/mssql_managed_database/variables.tf
index f4be403b91..62423c0e05 100755
--- a/modules/databases/mssql_managed_database/variables.tf
+++ b/modules/databases/mssql_managed_database/variables.tf
@@ -17,4 +17,4 @@ variable "location" {
}
variable "sourceDatabaseId" {
default = ""
-}
+}
\ No newline at end of file
diff --git a/modules/databases/mssql_managed_instance/managed_instance.tf b/modules/databases/mssql_managed_instance/managed_instance.tf
index a7a104203b..8ef7f0228c 100644
--- a/modules/databases/mssql_managed_instance/managed_instance.tf
+++ b/modules/databases/mssql_managed_instance/managed_instance.tf
@@ -44,4 +44,4 @@ resource "null_resource" "destroy_sqlmi" {
}
}
-}
+}
\ No newline at end of file
diff --git a/modules/diagnostics/module.tf b/modules/diagnostics/module.tf
index 65d55512d3..ec7230aab7 100755
--- a/modules/diagnostics/module.tf
+++ b/modules/diagnostics/module.tf
@@ -8,7 +8,11 @@ resource "azurerm_monitor_diagnostic_setting" "diagnostics" {
name = try(format("%s%s", try(var.global_settings.prefix_with_hyphen, ""), each.value.name), format("%s%s", try(var.global_settings.prefix_with_hyphen, ""), var.diagnostics.diagnostics_definition[each.value.definition_key].name))
target_resource_id = var.resource_id
- eventhub_name = each.value.destination_type == "event_hub" ? try(var.diagnostics.event_hub_namespaces[var.diagnostics.diagnostics_destinations.event_hub_namespaces[each.value.destination_key].event_hub_namespace_key].name, null) : null
+ eventhub_name = each.value.destination_type == "event_hub" ? coalesce(
+ try(var.diagnostics.event_hub_namespaces[var.diagnostics.diagnostics_destinations.event_hub_namespaces[each.value.destination_key].event_hub_namespace_key].event_hubs[each.value.event_hub_key].name, null),
+ var.diagnostics.event_hub_namespaces[var.diagnostics.diagnostics_destinations.event_hub_namespaces[each.value.destination_key].event_hub_namespace_key].name
+ ) : null
+
eventhub_authorization_rule_id = each.value.destination_type == "event_hub" ? format("%s/authorizationRules/RootManageSharedAccessKey", var.diagnostics.event_hub_namespaces[var.diagnostics.diagnostics_destinations.event_hub_namespaces[each.value.destination_key].event_hub_namespace_key].id) : null
log_analytics_workspace_id = each.value.destination_type == "log_analytics" ? var.diagnostics.log_analytics[var.diagnostics.diagnostics_destinations.log_analytics[each.value.destination_key].log_analytics_key].id : null
diff --git a/modules/event_hubs/consumer_groups/consumer_groups.tf b/modules/event_hubs/consumer_groups/consumer_groups.tf
index 15134aabfb..a24a77dfea 100644
--- a/modules/event_hubs/consumer_groups/consumer_groups.tf
+++ b/modules/event_hubs/consumer_groups/consumer_groups.tf
@@ -8,10 +8,13 @@ resource "azurecaf_name" "evhcg_name" {
use_slug = var.global_settings.use_slug
}
+# Last reviewed : AzureRM version 2.64.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/eventhub_consumer_group
+
resource "azurerm_eventhub_consumer_group" "evhcg" {
name = azurecaf_name.evhcg_name.result
namespace_name = var.namespace_name
eventhub_name = var.eventhub_name
resource_group_name = var.resource_group_name
- user_metadata = var.settings.user_metadata
+ user_metadata = try(var.settings.user_metadata, null)
}
\ No newline at end of file
diff --git a/modules/event_hubs/consumer_groups/output.tf b/modules/event_hubs/consumer_groups/output.tf
index 441b20fe71..1cff7b3b94 100755
--- a/modules/event_hubs/consumer_groups/output.tf
+++ b/modules/event_hubs/consumer_groups/output.tf
@@ -1,3 +1,4 @@
output "id" {
- value = azurerm_eventhub_consumer_group.evhcg.id
+ description = "The ID of the EventHub Consumer Group."
+ value = azurerm_eventhub_consumer_group.evhcg.id
}
\ No newline at end of file
diff --git a/modules/event_hubs/consumer_groups/variables.tf b/modules/event_hubs/consumer_groups/variables.tf
index 9c21a58212..9e95a7073a 100755
--- a/modules/event_hubs/consumer_groups/variables.tf
+++ b/modules/event_hubs/consumer_groups/variables.tf
@@ -1,7 +1,16 @@
variable "global_settings" {}
variable "settings" {}
-variable "resource_group_name" {}
+variable "resource_group_name" {
+ description = "Name of the resource group."
+ type = string
+}
variable "client_config" {}
-variable "namespace_name" {}
-variable "eventhub_name" {}
+variable "namespace_name" {
+ description = "Name of the Event Hub Namespace."
+ type = string
+}
+variable "eventhub_name" {
+ description = "Name of the Event Hub."
+ type = string
+}
diff --git a/modules/event_hubs/hubs/auth_rules/auth_rules.tf b/modules/event_hubs/hubs/auth_rules/auth_rules.tf
index c54337bc50..537aa05e5f 100644
--- a/modules/event_hubs/hubs/auth_rules/auth_rules.tf
+++ b/modules/event_hubs/hubs/auth_rules/auth_rules.tf
@@ -8,12 +8,15 @@ resource "azurecaf_name" "evh_rule" {
use_slug = var.global_settings.use_slug
}
+# Last reviewed : AzureRM version 2.64.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/eventhub_authorization_rule
+
resource "azurerm_eventhub_authorization_rule" "evhub_rule" {
name = azurecaf_name.evh_rule.result
namespace_name = var.namespace_name
eventhub_name = var.eventhub_name
resource_group_name = var.resource_group_name
- listen = var.settings.listen
- send = var.settings.send
- manage = var.settings.manage
+ listen = try(var.settings.listen, false)
+ send = try(var.settings.send, false)
+ manage = try(var.settings.manage, false)
}
\ No newline at end of file
diff --git a/modules/event_hubs/hubs/event_hub.tf b/modules/event_hubs/hubs/event_hub.tf
index bf655a7af6..1ee6f71f12 100644
--- a/modules/event_hubs/hubs/event_hub.tf
+++ b/modules/event_hubs/hubs/event_hub.tf
@@ -8,27 +8,32 @@ resource "azurecaf_name" "evhub" {
use_slug = var.global_settings.use_slug
}
+# Last reviewed : AzureRM version 2.64.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/eventhub_authorization_rule
+
resource "azurerm_eventhub" "evhub" {
name = azurecaf_name.evhub.result
namespace_name = var.namespace_name
resource_group_name = var.resource_group_name
partition_count = var.settings.partition_count
message_retention = var.settings.message_retention
+ status = try(var.settings.status, null)
dynamic "capture_description" {
- for_each = try(var.settings.capture_description, {})
+ for_each = try(var.settings.capture_description, false) == false ? [] : [1]
content {
- enabled = capture_description.value.enabled
- encoding = capture_description.value.encoding
- interval_in_seconds = try(capture_description.value.interval_in_seconds, null)
- size_limit_in_bytes = try(capture_description.value.size_limit_in_bytes, null)
- skip_empty_archives = try(capture_description.value.skip_empty_archives, null)
+ enabled = var.settings.capture_description.enabled
+ encoding = var.settings.capture_description.encoding
+ interval_in_seconds = try(var.settings.capture_description.interval_in_seconds, null)
+ size_limit_in_bytes = try(var.settings.capture_description.size_limit_in_bytes, null)
+ skip_empty_archives = try(var.settings.capture_description.skip_empty_archives, null)
+
dynamic "destination" { # required if capture_description is set
- for_each = try(var.settings.capture_description.destination, {})
+ for_each = try(var.settings.capture_description.destination, false) == false ? [] : [1]
content {
- name = destination.value.name # At this time(12/2020), the only supported value is EventHubArchive.AzureBlockBlob
- archive_name_format = destination.value.archive_name_format # e.g. {Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}
- blob_container_name = destination.value.blob_container_name
+ name = var.settings.capture_description.destination.name # At this time(12/2020), the only supported value is EventHubArchive.AzureBlockBlob
+ archive_name_format = var.settings.capture_description.destination.archive_name_format # e.g. {Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}
+ blob_container_name = var.settings.capture_description.destination.blob_container_name
storage_account_id = var.storage_account_id
}
}
diff --git a/modules/event_hubs/hubs/output.tf b/modules/event_hubs/hubs/output.tf
index 89514334c1..bc28258e59 100755
--- a/modules/event_hubs/hubs/output.tf
+++ b/modules/event_hubs/hubs/output.tf
@@ -1,8 +1,9 @@
output "id" {
- value = azurerm_eventhub.evhub.id
+ description = "The ID of the EventHub."
+ value = azurerm_eventhub.evhub.id
}
output "name" {
- description = "The EventHub name."
+ description = "The name of the EventHub."
value = azurerm_eventhub.evhub.name
}
\ No newline at end of file
diff --git a/modules/event_hubs/hubs/variables.tf b/modules/event_hubs/hubs/variables.tf
index 7b794dae15..8113b24c8c 100755
--- a/modules/event_hubs/hubs/variables.tf
+++ b/modules/event_hubs/hubs/variables.tf
@@ -1,7 +1,16 @@
variable "global_settings" {}
variable "settings" {}
-variable "resource_group_name" {}
+variable "resource_group_name" {
+ description = "Name of the resource group."
+ type = string
+}
variable "base_tags" {}
variable "client_config" {}
-variable "namespace_name" {}
-variable "storage_account_id" {}
+variable "namespace_name" {
+ description = "Name of the Event Hub Namespace."
+ type = string
+}
+variable "storage_account_id" {
+ description = "Identifier of the storage account ID to be used."
+ type = string
+}
diff --git a/modules/event_hubs/namespaces/README.md b/modules/event_hubs/namespaces/README.md
deleted file mode 100755
index 970ecd3729..0000000000
--- a/modules/event_hubs/namespaces/README.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Azure Event Hub Namespace
-
-This submodule is part of Cloud Adoption Framework landing zones for Azure on Terraform.
-
-You can instantiate this submodule directly using the following parameters:
-
-```
-module "caf_event_hub_namespaces" {
- source = "aztfmod/caf/azurerm//modules/event_hub_namespaces"
- version = "4.21.2"
- # insert the 5 required variables here
-}
-```
-
-
-## Requirements
-
-| Name | Version |
-|------|---------|
-| terraform | >= 0.13 |
-
-## Providers
-
-| Name | Version |
-|------|---------|
-| azurecaf | n/a |
-| azurerm | n/a |
-
-## Modules
-
-| Name | Source | Version |
-|------|--------|---------|
-| event_hub_namespace_auth_rules | ./auth_rules | |
-| event_hubs | ../hubs | |
-
-## Resources
-
-| Name |
-|------|
-| [azurecaf_name](https://registry.terraform.io/providers/aztfmod/azurecaf/latest/docs/resources/name) |
-| [azurerm_eventhub_namespace](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/eventhub_namespace) |
-
-## Inputs
-
-| Name | Description | Type | Default | Required |
-|------|-------------|------|---------|:--------:|
-| base\_tags | Base tags for the resource to be inherited from the resource group. | `map(any)` | n/a | yes |
-| client\_config | Client configuration object (see module README.md). | `any` | n/a | yes |
-| global\_settings | Global settings object (see module README.md) | `any` | n/a | yes |
-| location | n/a | `any` | n/a | yes |
-| resource\_group\_name | n/a | `any` | n/a | yes |
-| settings | n/a | `any` | n/a | yes |
-| storage\_accounts | n/a | `map` | `{}` | no |
-
-## Outputs
-
-| Name | Description |
-|------|-------------|
-| id | The EventHub Namespace ID. |
-| location | Location of the service |
-| name | The EventHub Namespace name. |
-| resource\_group\_name | Name of the resource group |
-
\ No newline at end of file
diff --git a/modules/event_hubs/namespaces/event_hubs.tf b/modules/event_hubs/namespaces/event_hubs.tf
index d021a733a3..c127c05b44 100755
--- a/modules/event_hubs/namespaces/event_hubs.tf
+++ b/modules/event_hubs/namespaces/event_hubs.tf
@@ -7,6 +7,6 @@ module "event_hubs" {
global_settings = var.global_settings
settings = each.value
namespace_name = azurerm_eventhub_namespace.evh.name
- storage_account_id = var.storage_accounts[try(each.value.storage_account.lz_key, var.client_config.landingzone_key)][each.value.storage_account.key].id
+ storage_account_id = try(var.storage_accounts[try(each.value.storage_account.lz_key, var.client_config.landingzone_key)][each.value.storage_account.key].id, null)
base_tags = merge(var.base_tags, try(each.value.tags, {}))
}
\ No newline at end of file
diff --git a/modules/event_hubs/namespaces/output.tf b/modules/event_hubs/namespaces/output.tf
index d4e22e6246..c74b1be454 100755
--- a/modules/event_hubs/namespaces/output.tf
+++ b/modules/event_hubs/namespaces/output.tf
@@ -17,3 +17,7 @@ output "location" {
value = var.location
description = "Location of the service"
}
+
+output "event_hubs" {
+ value = module.event_hubs
+}
\ No newline at end of file
diff --git a/modules/networking/application_gateway/application_gateway.tf b/modules/networking/application_gateway/application_gateway.tf
index 871a8fc0b8..f7b17a7e07 100644
--- a/modules/networking/application_gateway/application_gateway.tf
+++ b/modules/networking/application_gateway/application_gateway.tf
@@ -47,6 +47,17 @@ resource "azurerm_application_gateway" "agw" {
subnet_id = local.ip_configuration["gateway"].subnet_id
}
+ dynamic "ssl_policy" {
+ for_each = try(var.settings.ssl_policy, null) == null ? [] : [1]
+ content {
+ disabled_protocols = try(var.settings.ssl_policy.disabled_protocols, null)
+ policy_type = try(var.settings.ssl_policy.policy_type, null)
+ policy_name = try(var.settings.ssl_policy.policy_name, null)
+ cipher_suites = try(var.settings.ssl_policy.cipher_suites, null)
+ min_protocol_version = try(var.settings.ssl_policy.min_protocol_version, null)
+ }
+ }
+
dynamic "autoscale_configuration" {
for_each = try(var.settings.capacity.autoscale, null) == null ? [] : [1]
diff --git a/modules/networking/application_gateway/locals.backend_pools.tf b/modules/networking/application_gateway/locals.backend_pools.tf
index 5ee6f22b74..70536a5a19 100644
--- a/modules/networking/application_gateway/locals.backend_pools.tf
+++ b/modules/networking/application_gateway/locals.backend_pools.tf
@@ -33,7 +33,7 @@ locals {
local.backend_pools_app_services[key],
local.backend_pools_fqdn[key]
]
- ),null)
+ ), null)
ip_addresses = try(value.backend_pool.ip_addresses, null)
}
}
diff --git a/modules/networking/application_gateway/locals.networking.tf b/modules/networking/application_gateway/locals.networking.tf
index 790d273582..8606f118ee 100644
--- a/modules/networking/application_gateway/locals.networking.tf
+++ b/modules/networking/application_gateway/locals.networking.tf
@@ -1,10 +1,18 @@
locals {
- gateway_vnet_local = try(var.vnets[var.client_config.landingzone_key][var.settings.vnet_key], null)
+ gateway_vnet_local = try(coalesce(
+ try(var.vnets[var.client_config.landingzone_key][var.settings.vnet_key], null),
+ try(var.vnets[var.client_config.landingzone_key][var.settings.subnet.vnet_key], null)
+ ), null )
+
private_vnet_local = try(var.vnets[var.client_config.landingzone_key][var.settings.front_end_ip_configurations.private.vnet_key], null)
public_vnet_local = try(var.vnets[var.client_config.landingzone_key][var.settings.front_end_ip_configurations.public.vnet_key], null)
- gateway_vnet_remote = try(var.vnets[var.settings.lz_key][var.settings.vnet_key], null)
+ gateway_vnet_remote = try(coalesce(
+ try(var.vnets[var.settings.lz_key][var.settings.vnet_key], null),
+ try(var.vnets[var.settings.subnet.lz_key][var.settings.subnet.vnet_key], null)
+ ), null )
+
private_vnet_remote = try(var.vnets[var.settings.front_end_ip_configurations.private.lz_key][var.settings.front_end_ip_configurations.private.vnet_key], null)
public_vnet_remote = try(var.vnets[var.settings.front_end_ip_configurations.public.lz_key][var.settings.front_end_ip_configurations.public.vnet_key], null)
diff --git a/modules/networking/domain_name_registrations/arm_domain.json b/modules/networking/domain_name_registrations/arm_domain.json
index a7e8236887..ce2dc460da 100644
--- a/modules/networking/domain_name_registrations/arm_domain.json
+++ b/modules/networking/domain_name_registrations/arm_domain.json
@@ -33,8 +33,8 @@
"agreedAt": "${consent.agreedAt}",
"agreedBy": "${consent.agreedBy}"
},
- "privacy": ${privacy},
- "autoRenew": ${autoRenew},
+ "privacy": "${privacy}",
+ "autoRenew": "${autoRenew}",
"targetDnsType": "[if(empty(parameters('targetDnsType')), variables('empty'), parameters('targetDnsType'))]",
"dnsType": "[if(empty(parameters('dnsType')), variables('empty'), parameters('dnsType'))]",
"dnsZoneId": "[if(empty(parameters('dnsZoneId')), variables('empty'), parameters('dnsZoneId'))]",
diff --git a/modules/networking/firewall/module.tf b/modules/networking/firewall/module.tf
index 4537a2859e..cf2ec6adf8 100755
--- a/modules/networking/firewall/module.tf
+++ b/modules/networking/firewall/module.tf
@@ -19,7 +19,7 @@ resource "azurerm_firewall" "fw" {
zones = try(var.settings.zones, null)
sku_name = try(var.settings.sku_name, "AZFW_VNet")
sku_tier = try(var.settings.sku_tier, "Standard")
- firewall_policy_id = try(var.settings.firewall_policy_id, null) != null ? var.settings.firewall_policy_id : try(var.firewall_policies[var.settings.firewall_policy_key].id, null)
+ firewall_policy_id = var.firewall_policy_id
dns_servers = try(var.settings.dns_servers, null)
tags = local.tags
diff --git a/modules/networking/firewall/variables.tf b/modules/networking/firewall/variables.tf
index 192997c958..44ab61f3bc 100755
--- a/modules/networking/firewall/variables.tf
+++ b/modules/networking/firewall/variables.tf
@@ -61,6 +61,6 @@ variable "client_config" {
default = {}
}
-variable "firewall_policies" {
- default = {}
+variable "firewall_policy_id" {
+ default = null
}
\ No newline at end of file
diff --git a/modules/networking/firewall_dashboard/module.tf b/modules/networking/firewall_dashboard/module.txt
similarity index 100%
rename from modules/networking/firewall_dashboard/module.tf
rename to modules/networking/firewall_dashboard/module.txt
diff --git a/modules/networking/firewall_policies/firewall_policy.tf b/modules/networking/firewall_policies/firewall_policy.tf
index f43665ac41..9faffdb6d9 100755
--- a/modules/networking/firewall_policies/firewall_policy.tf
+++ b/modules/networking/firewall_policies/firewall_policy.tf
@@ -17,7 +17,7 @@ resource "azurerm_firewall_policy" "fwpol" {
location = var.location
sku = try(var.policy_settings.sku, null)
- base_policy_id = try(var.policy_settings.base_policy_id, null)
+ base_policy_id = var.base_policy_id
threat_intelligence_mode = try(var.policy_settings.threat_intelligence_mode, "Alert")
tags = local.tags
diff --git a/modules/networking/firewall_policies/main.tf b/modules/networking/firewall_policies/main.tf
index b33020ad7e..c1945ebfeb 100644
--- a/modules/networking/firewall_policies/main.tf
+++ b/modules/networking/firewall_policies/main.tf
@@ -11,5 +11,6 @@ locals {
module_tag = {
"module" = basename(abspath(path.module))
}
- tags = merge(var.base_tags, local.module_tag, var.tags)
+ # tags = merge(var.base_tags, local.module_tag, var.tags)
+ tags = var.tags # temporal use until tag uppercase fixed
}
diff --git a/modules/networking/firewall_policies/variables.tf b/modules/networking/firewall_policies/variables.tf
index 92da17a758..5fdcd07289 100755
--- a/modules/networking/firewall_policies/variables.tf
+++ b/modules/networking/firewall_policies/variables.tf
@@ -24,3 +24,9 @@ variable "base_tags" {}
variable "name" {
}
+
+variable "base_policy_id" {
+ type = string
+ default = null
+ description = "(Optional) The ID of the base Firewall Policy."
+}
diff --git a/modules/networking/firewall_policy_rule_collection_groups/firewall_policy_rule_collection_groups.tf b/modules/networking/firewall_policy_rule_collection_groups/firewall_policy_rule_collection_groups.tf
index adaca05c7d..b496874535 100755
--- a/modules/networking/firewall_policy_rule_collection_groups/firewall_policy_rule_collection_groups.tf
+++ b/modules/networking/firewall_policy_rule_collection_groups/firewall_policy_rule_collection_groups.tf
@@ -48,7 +48,7 @@ resource "azurecaf_name" "nat_rule" {
resource "azurerm_firewall_policy_rule_collection_group" "polgroup" {
name = azurecaf_name.polgroup.result
priority = var.policy_settings.priority
- firewall_policy_id = try(var.policy_settings.firewall_policy_id, null) != null ? var.policy_settings.firewall_policy_id : try(var.firewall_policies[var.policy_settings.firewall_policy_key].id, null)
+ firewall_policy_id = var.firewall_policy_id
dynamic "application_rule_collection" {
for_each = try(var.policy_settings.application_rule_collections, {})
diff --git a/modules/networking/firewall_policy_rule_collection_groups/variables.tf b/modules/networking/firewall_policy_rule_collection_groups/variables.tf
index b358e470a3..9feff5e1e2 100755
--- a/modules/networking/firewall_policy_rule_collection_groups/variables.tf
+++ b/modules/networking/firewall_policy_rule_collection_groups/variables.tf
@@ -6,14 +6,16 @@ variable "global_settings" {
description = "Global settings object (see module README.md)"
}
-variable "firewall_policies" {
-
+variable "firewall_policy_id" {
+ description = "(Required) The ID of the Firewall Policy where the Firewall Policy Rule Collection Group should exist. Changing this forces a new Firewall Policy Rule Collection Group to be created."
}
variable "ip_groups" {
-
+ description = "(Optional) Specifies a map of source IP groups."
+ default = {}
}
variable "public_ip_addresses" {
-
+ description = "(Optional) A map of destination IP addresses (including CIDR)."
+ default = {}
}
\ No newline at end of file
diff --git a/modules/networking/front_door/front_door.tf b/modules/networking/front_door/front_door.tf
index 21270c1cd4..e28c051a15 100644
--- a/modules/networking/front_door/front_door.tf
+++ b/modules/networking/front_door/front_door.tf
@@ -8,6 +8,9 @@ resource "azurecaf_name" "frontdoor" {
use_slug = try(var.settings.global_settings.use_slug, var.global_settings.use_slug)
}
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/frontdoor
+# Tested with AzureRM 2.57.0
+
resource "azurerm_frontdoor" "frontdoor" {
name = azurecaf_name.frontdoor.result
resource_group_name = var.resource_group_name
@@ -115,20 +118,25 @@ resource "azurerm_frontdoor" "frontdoor" {
host_name = try(frontend_endpoint.value.host_name, format("%s.azurefd.net", azurecaf_name.frontdoor.result))
session_affinity_enabled = frontend_endpoint.value.session_affinity_enabled
session_affinity_ttl_seconds = frontend_endpoint.value.session_affinity_ttl_seconds
- custom_https_provisioning_enabled = try(frontend_endpoint.value.custom_https_provisioning_enabled, false)
web_application_firewall_policy_link_id = try(frontend_endpoint.value.front_door_waf_policy.key, null) == null ? null : var.front_door_waf_policies[try(frontend_endpoint.value.front_door_waf_policy.lz_key, var.client_config.landingzone_key)][frontend_endpoint.value.front_door_waf_policy.key].id
+ }
+ }
+}
- dynamic "custom_https_configuration" {
- for_each = try(frontend_endpoint.value.custom_https_provisioning_enabled, false) == true ? [frontend_endpoint.value.custom_https_configuration] : []
- content {
- certificate_source = custom_https_configuration.value.certificate_source
- azure_key_vault_certificate_vault_id = lookup(custom_https_configuration.value, "azure_key_vault_certificate_vault_id", null) == null ? try(var.keyvault_certificate_requests[var.client_config.landingzone_key][custom_https_configuration.value.certificate.key].keyvault_id, var.keyvault_certificate_requests[custom_https_configuration.value.certificate.lz_key][custom_https_configuration.value.certificate.key].keyvault_id) : custom_https_configuration.value.azure_key_vault_certificate_vault_id
- azure_key_vault_certificate_secret_name = lookup(custom_https_configuration.value, "azure_key_vault_certificate_secret_name", null) == null ? try(var.keyvault_certificate_requests[var.client_config.landingzone_key][custom_https_configuration.value.certificate.key].name, var.keyvault_certificate_requests[custom_https_configuration.value.certificate.lz_key][custom_https_configuration.value.certificate.key].name) : custom_https_configuration.value.azure_key_vault_certificate_secret_name
- azure_key_vault_certificate_secret_version = lookup(custom_https_configuration.value, "azure_key_vault_certificate_secret_version", null) == null ? try(var.keyvault_certificate_requests[var.client_config.landingzone_key][custom_https_configuration.value.certificate.key].version, var.keyvault_certificate_requests[custom_https_configuration.value.certificate.lz_key][custom_https_configuration.value.certificate.key].version) : custom_https_configuration.value.azure_key_vault_certificate_secret_version
- }
- }
- }
+resource "azurerm_frontdoor_custom_https_configuration" "frontdoor" {
+ for_each = {
+ for key, value in var.settings.frontend_endpoints : key => value
+ if try(value.custom_https_provisioning_enabled, false)
}
-}
+ frontend_endpoint_id = azurerm_frontdoor.frontdoor.frontend_endpoint[0].id
+ custom_https_provisioning_enabled = try(each.value.custom_https_provisioning_enabled, false)
+
+ custom_https_configuration {
+ certificate_source = each.value.custom_https_configuration.certificate_source
+ azure_key_vault_certificate_vault_id = try(each.value.custom_https_configuration.azure_key_vault_certificate_vault_id, null) == null ? try(var.keyvault_certificate_requests[var.client_config.landingzone_key][each.value.custom_https_configuration.certificate.key].keyvault_id, var.keyvault_certificate_requests[each.value.custom_https_configuration.certificate.lz_key][each.value.custom_https_configuration.certificate.key].keyvault_id) : each.value.custom_https_configuration.azure_key_vault_certificate_vault_id
+ azure_key_vault_certificate_secret_name = try(each.value.custom_https_configuration.azure_key_vault_certificate_secret_name, null) == null ? try(var.keyvault_certificate_requests[var.client_config.landingzone_key][each.value.custom_https_configuration.certificate.key].name, var.keyvault_certificate_requests[each.value.custom_https_configuration.certificate.lz_key][each.value.custom_https_configuration.certificate.key].name) : each.value.custom_https_configuration.azure_key_vault_certificate_secret_name
+ azure_key_vault_certificate_secret_version = try(each.value.custom_https_configuration.azure_key_vault_certificate_secret_version, null) == null ? try(var.keyvault_certificate_requests[var.client_config.landingzone_key][each.value.custom_https_configuration.certificate.key].version, var.keyvault_certificate_requests[each.value.custom_https_configuration.certificate.lz_key][each.value.custom_https_configuration.certificate.key].version) : each.value.custom_https_configuration.azure_key_vault_certificate_secret_version
+ }
+}
\ No newline at end of file
diff --git a/modules/networking/public_ip_addresses/module.tf b/modules/networking/public_ip_addresses/module.tf
index 80bce8edeb..9c26ba0c8a 100755
--- a/modules/networking/public_ip_addresses/module.tf
+++ b/modules/networking/public_ip_addresses/module.tf
@@ -1,3 +1,6 @@
+# Last review : AzureRM version 2.63.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_desktop_host_pool
+
resource "azurerm_public_ip" "pip" {
name = var.name
resource_group_name = var.resource_group_name
@@ -8,6 +11,8 @@ resource "azurerm_public_ip" "pip" {
idle_timeout_in_minutes = var.idle_timeout_in_minutes
domain_name_label = var.generate_domain_name_label ? var.name : var.domain_name_label
reverse_fqdn = var.reverse_fqdn
- zones = var.zones
+ availability_zone = var.zones
tags = local.tags
+ public_ip_prefix_id = var.public_ip_prefix_id
+ ip_tags = var.ip_tags
}
\ No newline at end of file
diff --git a/modules/networking/public_ip_addresses/output.tf b/modules/networking/public_ip_addresses/output.tf
index 540fde6702..43f512fc81 100755
--- a/modules/networking/public_ip_addresses/output.tf
+++ b/modules/networking/public_ip_addresses/output.tf
@@ -1,14 +1,17 @@
output "id" {
- value = azurerm_public_ip.pip.id
+ description = "The Public IP ID."
+ value = azurerm_public_ip.pip.id
}
output "ip_address" {
- value = azurerm_public_ip.pip.ip_address
+ description = "The IP address value that was allocated."
+ value = azurerm_public_ip.pip.ip_address
}
output "fqdn" {
- value = azurerm_public_ip.pip.fqdn
+ description = "Fully qualified domain name of the A DNS record associated with the public IP. domain_name_label must be specified to get the fqdn. This is the concatenation of the domain_name_label and the regionalized DNS zone."
+ value = azurerm_public_ip.pip.fqdn
}
diff --git a/modules/networking/public_ip_addresses/variables.tf b/modules/networking/public_ip_addresses/variables.tf
index f35702ca80..8a1fc9e5bd 100755
--- a/modules/networking/public_ip_addresses/variables.tf
+++ b/modules/networking/public_ip_addresses/variables.tf
@@ -1,4 +1,7 @@
-variable "name" {}
+variable "name" {
+ description = "(Required) Specifies the name of the Public IP resource . Changing this forces a new resource to be created."
+ type = string
+}
variable "resource_group_name" {
description = "(Required) The name of the resource group where to create the resource."
type = string
@@ -8,39 +11,104 @@ variable "location" {
type = string
}
variable "sku" {
- default = "Basic"
+ description = "(Optional) The SKU of the Public IP. Accepted values are Basic and Standard. Defaults to Basic."
+ type = string
+ default = "Basic"
+ validation {
+ condition = contains(["Basic", "Standard"], var.sku)
+ error_message = "Provide an allowed value as defined in https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip#sku."
+ }
}
+
variable "allocation_method" {
- default = "Dynamic"
+ description = "(Required) Defines the allocation method for this IP address. Possible values are Static or Dynamic."
+ type = string
+ default = "Dynamic"
+
+ validation {
+ condition = contains(["Dynamic", "Static"], var.allocation_method)
+ error_message = "Provide an allowed value as defined in https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip#allocation_method."
+ }
}
variable "ip_version" {
- default = "IPv4"
+ description = "(Optional) The IP Version to use, IPv6 or IPv4."
+ type = string
+ default = "IPv4"
+
+ validation {
+ condition = contains(["IPv4", "IPv6"], var.ip_version)
+ error_message = "Provide an allowed value as defined in https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip#ip_version."
+ }
}
+
variable "idle_timeout_in_minutes" {
- default = null
+ description = "(Optional) Specifies the timeout for the TCP idle connection. The value can be set between 4 and 30 minutes."
+ type = number
+ default = null
+
+ validation {
+ condition = (try(var.idle_timeout_in_minutes, false) == true ? (var.idle_timeout_in_minutes.value >= 4 || var.idle_timeout_in_minutes.value <= 30) : true)
+ error_message = "Provide an allowed value as defined in https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip#idle_timeout_in_minutes."
+ }
}
+
variable "domain_name_label" {
- default = null
+ description = "(Optional) Label for the Domain Name. Will be used to make up the FQDN. If a domain name label is specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system."
+ default = null
+ type = string
}
-# if set to true, automatically generate a domain name label with the name
+
variable "generate_domain_name_label" {
- default = false
+ description = "Generate automatically the domain name label, if set to true, automatically generate a domain name label with the name"
+ type = bool
+ default = false
}
+
variable "reverse_fqdn" {
- default = null
+ description = "(Optional) A fully qualified domain name that resolves to this public IP address. If the reverseFqdn is specified, then a PTR DNS record is created pointing from the IP address in the in-addr.arpa domain to the reverse FQDN."
+ type = bool
+ default = null
}
+
variable "tags" {
- default = null
+ description = "(Optional) Tags for the resource to be deployed."
+ default = null
+ type = map(any)
}
+
variable "zones" {
- default = null
+ description = "(Optional) The availability zone to allocate the Public IP in. Possible values are Zone-Redundant, 1, 2, 3, and No-Zone. Defaults to Zone-Redundant."
+ type = string
+ default = "Zone-Redundant"
+
+ validation {
+ condition = contains(["Zone-Redundant", "No-Zone", "1", "2", "3"], var.zones)
+ error_message = "Provide an allowed value as defined in https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip#availability_zone."
+ }
}
+
variable "diagnostics" {
- default = {}
+ description = "(Optional) Diagnostics objects where to deploy the diagnostics profiles."
+ default = {}
}
+
variable "diagnostic_profiles" {
- default = {}
+ description = "(Optional) Diagnostics profile settings to be deployed for the resource."
+ default = {}
+}
+
+variable "ip_tags" {
+ description = "(Optional) A mapping of IP tags to assign to the public IP."
+ default = {}
+ type = map(any)
+}
+
+variable "public_ip_prefix_id" {
+ description = "(Optional) If specified then public IP address allocated will be provided from the public IP prefix resource."
+ default = ""
+ type = string
}
+
variable "base_tags" {
description = "Base tags for the resource to be inherited from the resource group."
type = map(any)
diff --git a/modules/networking/virtual_wan/virtual_hub/site_to_site_gateway.tf b/modules/networking/virtual_wan/virtual_hub/site_to_site_gateway.tf
index 270d0091f2..da3c99ff12 100644
--- a/modules/networking/virtual_wan/virtual_hub/site_to_site_gateway.tf
+++ b/modules/networking/virtual_wan/virtual_hub/site_to_site_gateway.tf
@@ -38,7 +38,7 @@ resource "azurerm_vpn_gateway" "s2s_gateway" {
custom_ips = var.virtual_hub_config.s2s_config.bgp_settings.instance_0_bgp_peering_address.custom_ips
}
}
-
+
dynamic "instance_1_bgp_peering_address" {
for_each = try(var.virtual_hub_config.s2s_config.bgp_settings.instance_1_bgp_peering_address, null) == null ? [] : [1]
@@ -46,7 +46,7 @@ resource "azurerm_vpn_gateway" "s2s_gateway" {
custom_ips = var.virtual_hub_config.s2s_config.bgp_settings.instance_1_bgp_peering_address.custom_ips
}
}
-
+
}
}
diff --git a/modules/networking/vpn_gateway_connection/main.tf b/modules/networking/vpn_gateway_connection/main.tf
new file mode 100644
index 0000000000..1fbfa06797
--- /dev/null
+++ b/modules/networking/vpn_gateway_connection/main.tf
@@ -0,0 +1,7 @@
+terraform {
+ required_providers {
+ azurecaf = {
+ source = "aztfmod/azurecaf"
+ }
+ }
+}
diff --git a/modules/networking/vpn_gateway_connection/module.tf b/modules/networking/vpn_gateway_connection/module.tf
new file mode 100644
index 0000000000..aebdd66367
--- /dev/null
+++ b/modules/networking/vpn_gateway_connection/module.tf
@@ -0,0 +1,71 @@
+resource "azurecaf_name" "vpn_gateway_connection" {
+ name = var.settings.name
+ resource_type = "azurerm_vpn_gateway_connection"
+ prefixes = var.global_settings.prefixes
+ random_length = var.global_settings.random_length
+ clean_input = true
+ passthrough = var.global_settings.passthrough
+ use_slug = var.global_settings.use_slug
+}
+
+resource "azurerm_vpn_gateway_connection" "vpn_gateway_connection" {
+ name = azurecaf_name.vpn_gateway_connection.result
+ vpn_gateway_id = var.vpn_gateway_id
+ internet_security_enabled = var.settings.internet_security_enabled
+
+ remote_vpn_site_id = coalesce(
+ try(var.vpn_sites[try(var.settings.vpn_site.lz_key, var.client_config.landingzone_key)][var.settings.vpn_site.key].vpn_site.id, null),
+ try(var.settings.vpn_site_id, null)
+ )
+
+ dynamic "vpn_link" {
+ for_each = var.settings.vpn_links
+ content {
+ name = vpn_link.value.name
+ bandwidth_mbps = try(vpn_link.value.bandwidth_mbps, null)
+ bgp_enabled = try(vpn_link.value.bgp_enabled, null)
+ protocol = try(vpn_link.value.protocol, null)
+ ratelimit_enabled = try(vpn_link.value.ratelimit_enabled, null)
+ route_weight = try(vpn_link.value.route_weight, null)
+ shared_key = try(vpn_link.value.shared_key, null)
+ local_azure_ip_address_enabled = try(vpn_link.value.local_azure_ip_address_enabled, null)
+ policy_based_traffic_selector_enabled = try(vpn_link.value.policy_based_traffic_selector_enabled, null)
+
+ vpn_site_link_id = coalesce(
+ try(var.vpn_sites[try(var.settings.vpn_site.lz_key, var.client_config.landingzone_key)][var.settings.vpn_site.key].vpn_site.link[vpn_link.value.link_index].id, null),
+ try(vpn_link.value.vpn_link_id, null)
+ )
+
+ dynamic "ipsec_policy" {
+ for_each = vpn_link.value.ipsec_policies
+ content {
+ dh_group = ipsec_policy.value.dh_group
+ ike_encryption_algorithm = ipsec_policy.value.ike_encryption_algorithm
+ ike_integrity_algorithm = ipsec_policy.value.ike_integrity_algorithm
+ encryption_algorithm = ipsec_policy.value.encryption_algorithm
+ integrity_algorithm = ipsec_policy.value.integrity_algorithm
+ pfs_group = ipsec_policy.value.pfs_group
+ sa_data_size_kb = ipsec_policy.value.sa_data_size_kb
+ sa_lifetime_sec = ipsec_policy.value.sa_lifetime_sec
+ }
+ }
+ }
+ }
+
+ dynamic "routing" {
+ for_each = lookup(var.settings, "routing", null) == null ? [] : [1]
+ content {
+ associated_route_table = coalesce(
+ try(var.route_tables[try(var.settings.routing.associated_route_table.lz_key, var.client_config.landingzone_key)][var.settings.routing.associated_route_table.key].id, null),
+ try(var.settings.routing.associated_route_table.id, null)
+ )
+
+ propagated_route_tables = [
+ for key, value in var.settings.routing.propagated_route_tables : coalesce(
+ try(var.route_tables[try(value.lz_key, var.client_config.landingzone_key)][value.key].id, null),
+ try(value.id, null)
+ )
+ ]
+ }
+ }
+}
diff --git a/modules/networking/vpn_gateway_connection/output.tf b/modules/networking/vpn_gateway_connection/output.tf
new file mode 100755
index 0000000000..a136b5ef4b
--- /dev/null
+++ b/modules/networking/vpn_gateway_connection/output.tf
@@ -0,0 +1,4 @@
+output "vpn_gateway_connection" {
+ value = azurerm_vpn_gateway_connection.vpn_gateway_connection
+ description = "VPN Gateway Connection object"
+}
diff --git a/modules/networking/vpn_gateway_connection/variables.tf b/modules/networking/vpn_gateway_connection/variables.tf
new file mode 100755
index 0000000000..abb3037c16
--- /dev/null
+++ b/modules/networking/vpn_gateway_connection/variables.tf
@@ -0,0 +1,8 @@
+variable "settings" {}
+variable "global_settings" {
+ description = "Global settings object (see module README.md)"
+}
+variable "vpn_gateway_id" {}
+variable "vpn_sites" {}
+variable "client_config" {}
+variable "route_tables" {}
diff --git a/modules/networking/vpn_site/main.tf b/modules/networking/vpn_site/main.tf
new file mode 100644
index 0000000000..4a54194d01
--- /dev/null
+++ b/modules/networking/vpn_site/main.tf
@@ -0,0 +1,14 @@
+locals {
+ module_tag = {
+ "module" = basename(abspath(path.module))
+ }
+ tags = merge(var.base_tags, local.module_tag, try(var.settings.tags, null))
+}
+
+terraform {
+ required_providers {
+ azurecaf = {
+ source = "aztfmod/azurecaf"
+ }
+ }
+}
diff --git a/modules/networking/vpn_site/module.tf b/modules/networking/vpn_site/module.tf
new file mode 100644
index 0000000000..42014668fe
--- /dev/null
+++ b/modules/networking/vpn_site/module.tf
@@ -0,0 +1,39 @@
+resource "azurecaf_name" "vpn_site" {
+ name = var.settings.name
+ resource_type = "azurerm_vpn_site"
+ prefixes = var.global_settings.prefixes
+ random_length = var.global_settings.random_length
+ clean_input = true
+ passthrough = var.global_settings.passthrough
+ use_slug = var.global_settings.use_slug
+}
+
+resource "azurerm_vpn_site" "vpn_site" {
+ name = azurecaf_name.vpn_site.result
+ location = var.location
+ resource_group_name = var.resource_group_name
+ virtual_wan_id = var.virtual_wan_id
+ address_cidrs = try(var.settings.address_cidrs, null)
+ device_model = try(var.settings.device_model, null)
+ device_vendor = try(var.settings.device_vendor, null)
+ tags = local.tags
+
+ dynamic "link" {
+ for_each = try(var.settings.links, {})
+ content {
+ name = link.value.name
+ ip_address = try(link.value.ip_address, null)
+ fqdn = try(link.value.fqdn, null)
+ provider_name = try(link.value.provider_name, null)
+ speed_in_mbps = try(link.value.speed_in_mbps, null)
+
+ dynamic "bgp" {
+ for_each = try([link.value.bgp], []) # TODO - Check this works
+ content {
+ asn = bgp.value.asn
+ peering_address = bgp.value.peering_address
+ }
+ }
+ }
+ }
+}
diff --git a/modules/networking/vpn_site/output.tf b/modules/networking/vpn_site/output.tf
new file mode 100755
index 0000000000..36e43817e5
--- /dev/null
+++ b/modules/networking/vpn_site/output.tf
@@ -0,0 +1,4 @@
+output "vpn_site" {
+ value = azurerm_vpn_site.vpn_site
+ description = "VPN Site object"
+}
diff --git a/modules/networking/vpn_site/variables.tf b/modules/networking/vpn_site/variables.tf
new file mode 100755
index 0000000000..f494c1be93
--- /dev/null
+++ b/modules/networking/vpn_site/variables.tf
@@ -0,0 +1,17 @@
+variable "resource_group_name" {
+ description = "(Required) The name of the resource group where to create the resource."
+ type = string
+}
+variable "location" {
+ description = "(Required) Specifies the supported Azure location where to create the resource. Changing this forces a new resource to be created."
+ type = string
+}
+variable "base_tags" {
+ description = "Base tags for the resource to be inherited from the resource group."
+ type = map(any)
+}
+variable "settings" {}
+variable "global_settings" {
+ description = "Global settings object (see module README.md)"
+}
+variable "virtual_wan_id" {}
diff --git a/modules/random_string/main.tf b/modules/random_string/main.tf
new file mode 100644
index 0000000000..b3f47d413b
--- /dev/null
+++ b/modules/random_string/main.tf
@@ -0,0 +1,8 @@
+terraform {
+ required_providers {
+ azurecaf = {
+ source = "aztfmod/azurecaf"
+ }
+ }
+ required_version = ">= 0.13"
+}
diff --git a/modules/random_string/module.tf b/modules/random_string/module.tf
new file mode 100644
index 0000000000..b268a3eb1c
--- /dev/null
+++ b/modules/random_string/module.tf
@@ -0,0 +1,6 @@
+resource "random_string" "rs" {
+ length = var.random_string_length
+ special = var.random_string_allow_special_characters
+ upper = var.random_string_allow_upper_case
+ number = var.random_string_allow_numbers
+}
diff --git a/modules/random_string/output.tf b/modules/random_string/output.tf
new file mode 100755
index 0000000000..f9ecfed5fe
--- /dev/null
+++ b/modules/random_string/output.tf
@@ -0,0 +1,9 @@
+output "result" {
+ value = random_string.rs.result
+
+}
+
+output "id" {
+ value = random_string.rs.id
+
+}
diff --git a/modules/random_string/variables.tf b/modules/random_string/variables.tf
new file mode 100755
index 0000000000..5cdf002349
--- /dev/null
+++ b/modules/random_string/variables.tf
@@ -0,0 +1,15 @@
+variable "random_string_length" {
+ description = "(Required) The length of the random string to be created"
+}
+variable "random_string_allow_special_characters" {
+ description = "Allows special characters in the random string to be created"
+ default = false
+}
+variable "random_string_allow_upper_case" {
+ description = "Allows upper case letters in the random string to be created"
+ default = false
+}
+variable "random_string_allow_numbers" {
+ description = "Allows numbers in the random string to be created"
+ default = false
+}
diff --git a/modules/recovery_vault/azure_recovery_fabric.tf b/modules/recovery_vault/azure_recovery_fabric.tf
index e9d4bfc914..07a159958a 100644
--- a/modules/recovery_vault/azure_recovery_fabric.tf
+++ b/modules/recovery_vault/azure_recovery_fabric.tf
@@ -1,9 +1,12 @@
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/site_recovery_fabric
+
resource "azurerm_site_recovery_fabric" "recovery_fabric" {
- depends_on = [azurerm_recovery_services_vault.asr, time_sleep.delay_create]
+ depends_on = [time_sleep.delay_create]
for_each = try(var.settings.recovery_fabrics, {})
name = each.value.name
resource_group_name = var.resource_group_name
- recovery_vault_name = azurecaf_name.asr_rg_vault.result
+ recovery_vault_name = azurerm_recovery_services_vault.asr.name
location = var.global_settings.regions[each.value.region]
}
\ No newline at end of file
diff --git a/modules/recovery_vault/backup_policies_file_share.tf b/modules/recovery_vault/backup_policies_file_share.tf
index 3008a91298..472680fb52 100644
--- a/modules/recovery_vault/backup_policies_file_share.tf
+++ b/modules/recovery_vault/backup_policies_file_share.tf
@@ -1,10 +1,12 @@
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/backup_policy_file_share
+
resource "azurerm_backup_policy_file_share" "fs" {
- depends_on = [azurerm_recovery_services_vault.asr]
- for_each = try(var.settings.backup_policies.fs, {})
+ for_each = try(var.settings.backup_policies.fs, {})
name = each.value.name
resource_group_name = var.resource_group_name
- recovery_vault_name = azurecaf_name.asr_rg_vault.result
+ recovery_vault_name = azurerm_recovery_services_vault.asr.name
timezone = try(each.value.timezone, null)
diff --git a/modules/recovery_vault/backup_policies_vm.tf b/modules/recovery_vault/backup_policies_vm.tf
index 1bbd5a5fec..2bf21ed6ff 100644
--- a/modules/recovery_vault/backup_policies_vm.tf
+++ b/modules/recovery_vault/backup_policies_vm.tf
@@ -1,11 +1,12 @@
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/backup_policy_vm
resource "azurerm_backup_policy_vm" "vm" {
- depends_on = [azurerm_recovery_services_vault.asr]
- for_each = try(var.settings.backup_policies.vms, {})
+ for_each = try(var.settings.backup_policies.vms, {})
name = each.value.name
resource_group_name = var.resource_group_name
- recovery_vault_name = azurecaf_name.asr_rg_vault.result
+ recovery_vault_name = azurerm_recovery_services_vault.asr.name
timezone = try(each.value.timezone, null)
diff --git a/modules/recovery_vault/main.tf b/modules/recovery_vault/main.tf
index aec15841cb..49a9a5eed3 100644
--- a/modules/recovery_vault/main.tf
+++ b/modules/recovery_vault/main.tf
@@ -14,7 +14,6 @@ terraform {
}
}
-
resource "time_sleep" "delay_create" {
depends_on = [azurerm_recovery_services_vault.asr]
diff --git a/modules/recovery_vault/protection_container.tf b/modules/recovery_vault/protection_container.tf
index f97669c261..9458b43537 100644
--- a/modules/recovery_vault/protection_container.tf
+++ b/modules/recovery_vault/protection_container.tf
@@ -1,21 +1,24 @@
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/site_recovery_protection_container
+
resource "azurerm_site_recovery_protection_container" "protection_container" {
- depends_on = [azurerm_recovery_services_vault.asr, azurerm_site_recovery_fabric.recovery_fabric]
- # depends_on = [time_sleep.delay_create]
for_each = try(var.settings.protection_containers, {})
name = each.value.name
resource_group_name = var.resource_group_name
- recovery_vault_name = azurecaf_name.asr_rg_vault.result
+ recovery_vault_name = azurerm_recovery_services_vault.asr.name
recovery_fabric_name = azurerm_site_recovery_fabric.recovery_fabric[each.value.recovery_fabric_key].name
}
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/site_recovery_protection_container_mapping
+
resource "azurerm_site_recovery_protection_container_mapping" "container-mapping" {
- depends_on = [azurerm_recovery_services_vault.asr, azurerm_site_recovery_fabric.recovery_fabric]
- for_each = try(var.settings.protection_container_mapping, {})
+ for_each = try(var.settings.protection_container_mapping, {})
name = each.value.name
resource_group_name = var.resource_group_name
- recovery_vault_name = azurecaf_name.asr_rg_vault.result
+ recovery_vault_name = azurerm_recovery_services_vault.asr.name
recovery_fabric_name = azurerm_site_recovery_fabric.recovery_fabric[each.value.fabric_key].name
recovery_source_protection_container_name = azurerm_site_recovery_protection_container.protection_container[each.value.source_protection_container_key].name
recovery_target_protection_container_id = azurerm_site_recovery_protection_container.protection_container[each.value.target_protection_container_key].id
diff --git a/modules/recovery_vault/recovery_vault.tf b/modules/recovery_vault/recovery_vault.tf
index 284aaf67ac..5a7dca4c6b 100644
--- a/modules/recovery_vault/recovery_vault.tf
+++ b/modules/recovery_vault/recovery_vault.tf
@@ -1,3 +1,5 @@
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/recovery_services_vault
resource "azurecaf_name" "asr_rg_vault" {
name = var.settings.name
diff --git a/modules/recovery_vault/replication_policy.tf b/modules/recovery_vault/replication_policy.tf
index 8e4e439579..c1f941fc7b 100644
--- a/modules/recovery_vault/replication_policy.tf
+++ b/modules/recovery_vault/replication_policy.tf
@@ -1,11 +1,13 @@
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/site_recovery_replication_policy
resource "azurerm_site_recovery_replication_policy" "policy" {
- depends_on = [azurerm_recovery_services_vault.asr, time_sleep.delay_create]
+ depends_on = [time_sleep.delay_create]
for_each = try(var.settings.replication_policies, {})
name = each.value.name
resource_group_name = var.resource_group_name
- recovery_vault_name = azurecaf_name.asr_rg_vault.result
+ recovery_vault_name = azurerm_recovery_services_vault.asr.name
recovery_point_retention_in_minutes = each.value.recovery_point_retention_in_minutes
application_consistent_snapshot_frequency_in_minutes = each.value.application_consistent_snapshot_frequency_in_minutes
}
\ No newline at end of file
diff --git a/modules/resource_group/module.tf b/modules/resource_group/module.tf
index 59d8605648..c84d835a22 100644
--- a/modules/resource_group/module.tf
+++ b/modules/resource_group/module.tf
@@ -13,5 +13,8 @@ resource "azurecaf_name" "rg" {
resource "azurerm_resource_group" "rg" {
name = azurecaf_name.rg.result
location = var.global_settings.regions[lookup(var.settings, "region", var.global_settings.default_region)]
- tags = merge(var.tags, lookup(var.settings, "tags", {}))
-}
+ tags = merge(
+ var.tags,
+ lookup(var.settings, "tags", {})
+ )
+}
\ No newline at end of file
diff --git a/modules/security/keyvault/examples/101-simple/configuration.tfvars b/modules/security/keyvault/examples/101-simple/configuration.tfvars
deleted file mode 100755
index d6d0542600..0000000000
--- a/modules/security/keyvault/examples/101-simple/configuration.tfvars
+++ /dev/null
@@ -1,61 +0,0 @@
-global_settings = {
- prefix = "dsde"
- default_location = "southeastasia"
- environment = "demo"
-}
-
-resource_groups = {
- security = {
- name = "launchpad-security"
- useprefix = true
- }
-}
-
-
-keyvaults = {
- launchpad = {
- name = "launchpad"
- resource_group_key = "security"
- region = "southeastasia"
- sku_name = "standard"
- tags = {
- environment = "demo"
- tfstate = "level0"
- }
- }
-}
-
-
-## Networking configuration
-networking = {
- hub_sg = {
- resource_group_key = "vnet_sg"
- location = "southeastasia"
- vnet = {
- name = "hub"
- address_space = ["10.10.100.0/24"]
- }
- specialsubnets = {
- }
- subnets = {
- jumpbox = {
- name = "jumpbox"
- cidr = ["10.10.100.0/25"]
- nsg_name = "jumpbox_nsg"
- nsg = []
- }
-
- }
- diags = {
- log = [
- # ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
- ["VMProtectionAlerts", true, true, 7],
- ]
- metric = [
- #["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
- ["AllMetrics", true, true, 7],
- ]
- }
- }
-
-}
\ No newline at end of file
diff --git a/modules/security/keyvault/examples/101-simple/landingzone.tf b/modules/security/keyvault/examples/101-simple/landingzone.tf
deleted file mode 100755
index d255da1b20..0000000000
--- a/modules/security/keyvault/examples/101-simple/landingzone.tf
+++ /dev/null
@@ -1,8 +0,0 @@
-module "keyvault" {
- source = "/tf/caf"
-
- global_settings = var.global_settings
- resource_groups = var.resource_groups
- keyvaults = var.keyvaults
- networking = var.networking
-}
\ No newline at end of file
diff --git a/modules/security/keyvault/examples/101-simple/main.tf b/modules/security/keyvault/examples/101-simple/main.tf
deleted file mode 100755
index e1e4a52fae..0000000000
--- a/modules/security/keyvault/examples/101-simple/main.tf
+++ /dev/null
@@ -1,27 +0,0 @@
-terraform {
- required_providers {
- azurerm = {
- source = "hashicorp/azurerm"
- version = "~> 2.19.0"
- }
- null = {
- source = "hashicorp/null"
- version = "~> 2.1.0"
- }
- azurecaf = {
- source = "aztfmod/azurecaf"
- version = "~>0.4.3"
- }
- }
- required_version = ">= 0.13"
-}
-
-
-provider "azurerm" {
- features {}
-}
-
-# data "azurerm_client_config" "current" {}
-
-
-
diff --git a/modules/security/keyvault/examples/101-simple/variables.tf b/modules/security/keyvault/examples/101-simple/variables.tf
deleted file mode 100755
index 47213a4165..0000000000
--- a/modules/security/keyvault/examples/101-simple/variables.tf
+++ /dev/null
@@ -1,5 +0,0 @@
-variable "global_settings" {
- description = "Global settings object (see module README.md)"
-}
-variable "resource_groups" {}
-variable "keyvaults" {}
\ No newline at end of file
diff --git a/modules/security/keyvault/examples/102-with-networking/configuration.tfvars b/modules/security/keyvault/examples/102-with-networking/configuration.tfvars
deleted file mode 100755
index 83e46bb0c1..0000000000
--- a/modules/security/keyvault/examples/102-with-networking/configuration.tfvars
+++ /dev/null
@@ -1,26 +0,0 @@
-global_settings = {
- prefix = "dsde"
- default_location = "southeastasia"
- environment = "demo"
-}
-
-resource_groups = {
- security = {
- name = "launchpad-security"
- useprefix = true
- }
-}
-
-
-keyvaults = {
- launchpad = {
- name = "launchpad"
- resource_group_key = "security"
- region = "southeastasia"
- sku_name = "standard"
- tags = {
- environment = "demo"
- tfstate = "level0"
- }
- }
-}
\ No newline at end of file
diff --git a/modules/security/keyvault/examples/102-with-networking/landingzone.tf b/modules/security/keyvault/examples/102-with-networking/landingzone.tf
deleted file mode 100755
index eac0347dff..0000000000
--- a/modules/security/keyvault/examples/102-with-networking/landingzone.tf
+++ /dev/null
@@ -1,8 +0,0 @@
-module "keyvault" {
- source = "/tf/caf"
-
- global_settings = var.global_settings
- resource_groups = var.resource_groups
- keyvaults = var.keyvaults
- # networking = var.vnets
-}
\ No newline at end of file
diff --git a/modules/security/keyvault/examples/102-with-networking/main.tf b/modules/security/keyvault/examples/102-with-networking/main.tf
deleted file mode 100755
index e1e4a52fae..0000000000
--- a/modules/security/keyvault/examples/102-with-networking/main.tf
+++ /dev/null
@@ -1,27 +0,0 @@
-terraform {
- required_providers {
- azurerm = {
- source = "hashicorp/azurerm"
- version = "~> 2.19.0"
- }
- null = {
- source = "hashicorp/null"
- version = "~> 2.1.0"
- }
- azurecaf = {
- source = "aztfmod/azurecaf"
- version = "~>0.4.3"
- }
- }
- required_version = ">= 0.13"
-}
-
-
-provider "azurerm" {
- features {}
-}
-
-# data "azurerm_client_config" "current" {}
-
-
-
diff --git a/modules/security/keyvault/examples/102-with-networking/variables.tf b/modules/security/keyvault/examples/102-with-networking/variables.tf
deleted file mode 100755
index df07937fa5..0000000000
--- a/modules/security/keyvault/examples/102-with-networking/variables.tf
+++ /dev/null
@@ -1,7 +0,0 @@
-variable "global_settings" {
- description = "Global settings object (see module README.md)"
-}
-variable "resource_groups" {}
-variable "keyvaults" {}
-variable "keyvault_id" {}
-variable "org_id" {}
\ No newline at end of file
diff --git a/modules/security/keyvault/keyvault.tf b/modules/security/keyvault/keyvault.tf
index 93153c2bde..b6a558da2b 100755
--- a/modules/security/keyvault/keyvault.tf
+++ b/modules/security/keyvault/keyvault.tf
@@ -17,8 +17,8 @@ resource "azurecaf_name" "keyvault" {
resource "azurerm_key_vault" "keyvault" {
name = azurecaf_name.keyvault.result
- location = lookup(var.settings, "region", null) == null ? var.resource_groups[var.settings.resource_group_key].location : var.global_settings.regions[var.settings.region]
- resource_group_name = var.resource_groups[var.settings.resource_group_key].name
+ location = lookup(var.settings, "region", null) == null ? var.resource_groups[try(var.settings.resource_group.key, var.settings.resource_group_key)].location : var.global_settings.regions[var.settings.region]
+ resource_group_name = var.resource_groups[try(var.settings.resource_group.key, var.settings.resource_group_key)].name
tenant_id = var.client_config.tenant_id
sku_name = try(var.settings.sku_name, "standard")
tags = try(merge(var.base_tags, local.tags), {})
diff --git a/modules/security/keyvault/private_endpoints.tf b/modules/security/keyvault/private_endpoints.tf
index bdead77d62..82828f3eec 100755
--- a/modules/security/keyvault/private_endpoints.tf
+++ b/modules/security/keyvault/private_endpoints.tf
@@ -10,8 +10,8 @@ module "private_endpoint" {
resource_id = azurerm_key_vault.keyvault.id
name = each.value.name
- location = var.resource_groups[each.value.resource_group_key].location
- resource_group_name = var.resource_groups[each.value.resource_group_key].name
+ location = var.resource_groups[try(each.value.resource_group.key, each.value.resource_group_key)].location
+ resource_group_name = var.resource_groups[try(each.value.resource_group.key, each.value.resource_group_key)].name
subnet_id = try(var.vnets[var.client_config.landingzone_key][each.value.vnet_key].subnets[each.value.subnet_key].id, var.vnets[each.value.lz_key][each.value.vnet_key].subnets[each.value.subnet_key].id)
settings = each.value
global_settings = var.global_settings
diff --git a/modules/security/keyvault_access_policies/access_policy/access_policy.tf b/modules/security/keyvault_access_policies/access_policy/access_policy.tf
index 2a41f112b8..449cdc77cf 100755
--- a/modules/security/keyvault_access_policies/access_policy/access_policy.tf
+++ b/modules/security/keyvault_access_policies/access_policy/access_policy.tf
@@ -10,6 +10,9 @@ resource "azurerm_key_vault_access_policy" "policy" {
timeouts {
delete = "60m"
+ }
+ lifecycle {
+ ignore_changes = [key_vault_id]
}
}
diff --git a/modules/security/keyvault_access_policies/policies.tf b/modules/security/keyvault_access_policies/policies.tf
index c0c76fcbee..45b6f94d4f 100755
--- a/modules/security/keyvault_access_policies/policies.tf
+++ b/modules/security/keyvault_access_policies/policies.tf
@@ -6,12 +6,35 @@ module "azuread_apps" {
if try(access_policy.azuread_app_key, null) != null
}
- keyvault_id = var.keyvault_id == null ? var.keyvaults[try(try(each.value.keyvault_lz_key, each.value.lz_key), var.client_config.landingzone_key)][var.keyvault_key].id : var.keyvault_id
+ keyvault_id = var.keyvault_id == null ? var.keyvaults[try(each.value.keyvault_lz_key, each.value.lz_key, var.client_config.landingzone_key)][var.keyvault_key].id : var.keyvault_id
access_policy = each.value
tenant_id = var.client_config.tenant_id
object_id = var.azuread_apps[try(try(each.value.azuread_app_lz_key, each.value.lz_key), var.client_config.landingzone_key)][each.value.azuread_app_key].azuread_service_principal.object_id
}
+module "azuread_service_principals" {
+ source = "./access_policy"
+ for_each = {
+ for key, access_policy in var.access_policies : key => access_policy
+ if try(access_policy.azuread_service_principal_key, null) != null
+ }
+
+ keyvault_id = coalesce(
+ var.keyvault_id,
+ try(var.keyvaults[each.value.keyvault_lz_key][var.keyvault_key].id, null),
+ try(var.keyvaults[each.value.lz_key][var.keyvault_key].id, null),
+ try(var.keyvaults[var.client_config.landingzone_key][var.keyvault_key].id, null)
+ )
+
+ access_policy = each.value
+ tenant_id = var.resources.azuread_service_principals[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.azuread_service_principal_key].tenant_id
+
+ object_id = coalesce(
+ try(var.resources.azuread_service_principals[each.value.lz_key][each.value.azuread_service_principal_key].object_id, null),
+ try(var.resources.azuread_service_principals[var.client_config.landingzone_key][each.value.azuread_service_principal_key].object_id, null)
+ )
+}
+
module "azuread_group" {
source = "./access_policy"
for_each = {
@@ -71,10 +94,20 @@ module "managed_identity" {
if try(access_policy.managed_identity_key, null) != null
}
- keyvault_id = var.keyvault_id == null ? try(var.keyvaults[var.client_config.landingzone_key][var.keyvault_key].id, var.keyvaults[each.value.lz_key][var.keyvault_key].id) : var.keyvault_id
+ keyvault_id = coalesce(
+ var.keyvault_id,
+ try(var.keyvaults[each.value.keyvault_lz_key][var.keyvault_key].id, null),
+ try(var.keyvaults[each.value.lz_key][var.keyvault_key].id, null),
+ try(var.keyvaults[var.client_config.landingzone_key][var.keyvault_key].id, null)
+ )
+
access_policy = each.value
tenant_id = var.client_config.tenant_id
- object_id = try(each.value.lz_key, null) == null ? var.resources.managed_identities[var.client_config.landingzone_key][each.value.managed_identity_key].principal_id : var.resources.managed_identities[each.value.lz_key][each.value.managed_identity_key].principal_id
+
+ object_id = coalesce(
+ try(var.resources.managed_identities[each.value.lz_key][each.value.managed_identity_key].principal_id, null),
+ try(var.resources.managed_identities[var.client_config.landingzone_key][each.value.managed_identity_key].principal_id, null)
+ )
}
module "mssql_managed_instance" {
diff --git a/modules/security/managed_identity/managed_identity.tf b/modules/security/managed_identity/managed_identity.tf
index 6af0fc63a4..3210d7c057 100644
--- a/modules/security/managed_identity/managed_identity.tf
+++ b/modules/security/managed_identity/managed_identity.tf
@@ -4,11 +4,11 @@ locals {
resource "azurecaf_name" "msi" {
name = var.name
resource_type = "azurerm_user_assigned_identity"
- prefixes = var.global_settings.prefixes
- random_length = var.global_settings.random_length
+ prefixes = try(var.settings.naming_convention.prefixes, var.global_settings.prefixes)
+ random_length = try(var.settings.naming_convention.random_length, var.global_settings.random_length)
clean_input = true
- passthrough = var.global_settings.passthrough
- use_slug = var.global_settings.use_slug
+ passthrough = try(var.settings.naming_convention.passthrough, var.global_settings.passthrough)
+ use_slug = try(var.settings.naming_convention.use_slug, var.global_settings.use_slug)
}
resource "azurerm_user_assigned_identity" "msi" {
@@ -16,5 +16,4 @@ resource "azurerm_user_assigned_identity" "msi" {
resource_group_name = var.resource_group_name
location = var.location
tags = try(merge(var.base_tags, local.tags), {})
-}
-
+}
\ No newline at end of file
diff --git a/modules/storage_account/backup_container.tf b/modules/storage_account/backup_container.tf
index 6adfbd83de..b4601a5b6b 100644
--- a/modules/storage_account/backup_container.tf
+++ b/modules/storage_account/backup_container.tf
@@ -1,11 +1,16 @@
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/backup_container_storage_account
+
locals {
recovery_vault = try(var.storage_account.backup, null) == null ? null : try(var.recovery_vaults[var.client_config.landingzone_key][var.storage_account.backup.vault_key], var.recovery_vaults[var.storage_account.backup.lz_key][var.storage_account.backup.vault_key])
}
resource "azurerm_backup_container_storage_account" "container" {
- count = try(var.storage_account.backup, null) == null ? 0 : 1
+
+ for_each = try(var.storage_account.backup, null) == null ? toset([]) : toset(["enabled"])
+
resource_group_name = local.recovery_vault.resource_group_name
recovery_vault_name = local.recovery_vault.name
storage_account_id = azurerm_storage_account.stg.id
-}
\ No newline at end of file
+}
diff --git a/modules/storage_account/blob/module.tf b/modules/storage_account/blob/module.tf
index ed7ed2dcf3..366c765c8b 100644
--- a/modules/storage_account/blob/module.tf
+++ b/modules/storage_account/blob/module.tf
@@ -1,3 +1,5 @@
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_blob
resource "azurerm_storage_blob" "blob" {
@@ -8,6 +10,7 @@ resource "azurerm_storage_blob" "blob" {
size = try(var.settings.size, null)
access_tier = try(var.settings.access_tier, "Hot")
content_type = try(var.settings.content_type, null)
+ content_md5 = try(var.settings.content_md5, null)
source = try(var.settings.source, null)
source_content = try(var.settings.source_content, null)
source_uri = try(var.settings.source_uri, null)
diff --git a/modules/storage_account/blob/output.tf b/modules/storage_account/blob/output.tf
index 3c5e82a92f..d0947944ce 100755
--- a/modules/storage_account/blob/output.tf
+++ b/modules/storage_account/blob/output.tf
@@ -1,7 +1,9 @@
output "id" {
- value = azurerm_storage_blob.blob.id
+ description = "The ID of the Storage Blob"
+ value = azurerm_storage_blob.blob.id
}
output "url" {
- value = azurerm_storage_blob.blob.url
+ description = "The URL of the blob"
+ value = azurerm_storage_blob.blob.url
}
diff --git a/modules/storage_account/container/container.tf b/modules/storage_account/container/container.tf
index f1cd1e807a..bbc2c217cc 100644
--- a/modules/storage_account/container/container.tf
+++ b/modules/storage_account/container/container.tf
@@ -1,3 +1,6 @@
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container
+
resource "azurerm_storage_container" "stg" {
name = var.settings.name
storage_account_name = var.storage_account_name
diff --git a/modules/storage_account/container/output.tf b/modules/storage_account/container/output.tf
index 2b39e9388e..b0c70ba21e 100755
--- a/modules/storage_account/container/output.tf
+++ b/modules/storage_account/container/output.tf
@@ -1,8 +1,14 @@
output "blobs" {
- value = module.blob
+ description = "Exports the content of the blob module."
+ value = module.blob
}
-
output "name" {
- value = azurerm_storage_container.stg.name
+ description = "The ID of the Storage Container."
+ value = azurerm_storage_container.stg.name
+}
+
+output "resource_manager_id" {
+ description = "The Resource Manager ID of this Storage Container."
+ value = azurerm_storage_container.stg.resource_manager_id
}
\ No newline at end of file
diff --git a/modules/storage_account/data_lake_filesystem/gen2_filesystem.tf b/modules/storage_account/data_lake_filesystem/gen2_filesystem.tf
index 27c4dd20b2..92d53c1857 100644
--- a/modules/storage_account/data_lake_filesystem/gen2_filesystem.tf
+++ b/modules/storage_account/data_lake_filesystem/gen2_filesystem.tf
@@ -1,3 +1,6 @@
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_data_lake_gen2_filesystem
+
resource "azurerm_storage_data_lake_gen2_filesystem" "gen2" {
name = var.settings.name
storage_account_id = var.storage_account_id
diff --git a/modules/storage_account/data_lake_filesystem/output.tf b/modules/storage_account/data_lake_filesystem/output.tf
index fee227bfb3..4b852124bc 100755
--- a/modules/storage_account/data_lake_filesystem/output.tf
+++ b/modules/storage_account/data_lake_filesystem/output.tf
@@ -1,3 +1,4 @@
output "id" {
- value = azurerm_storage_data_lake_gen2_filesystem.gen2.id
+ description = "The ID of the Data Lake Gen2 File System."
+ value = azurerm_storage_data_lake_gen2_filesystem.gen2.id
}
diff --git a/modules/storage_account/examples/101-single.tfvars b/modules/storage_account/examples/101-single.tfvars
deleted file mode 100755
index b2fb99d101..0000000000
--- a/modules/storage_account/examples/101-single.tfvars
+++ /dev/null
@@ -1,14 +0,0 @@
-resource_groups = {
- test_sg = {
- name = "test-caf_storage_account-sg"
- location = "southeastasia"
- useprefix = true
- }
-}
-
-storage_accounts = {
- media = {
- name = "media"
- resource_group_key = "test_sg"
- }
-}
\ No newline at end of file
diff --git a/modules/storage_account/examples/102-storage_with_vnet.tfvars b/modules/storage_account/examples/102-storage_with_vnet.tfvars
deleted file mode 100755
index 42ba4c6975..0000000000
--- a/modules/storage_account/examples/102-storage_with_vnet.tfvars
+++ /dev/null
@@ -1,59 +0,0 @@
-resource_groups = {
- test_sg = {
- name = "test-caf_storage_account-sg"
- location = "southeastasia"
- useprefix = true
- }
- vnet_sg = {
- name = "test-networking-sg"
- location = "southeastasia"
- useprefix = true
- }
-}
-
-storage_accounts = {
- media = {
- name = "media"
- resource_group_key = "test_sg"
- network_rules = {
- default_action = "Allow"
- bypass = "Logging"
- vnet_key = "hub_sg"
- subnet_key = "jumpbox"
- }
- }
-}
-
-## Networking configuration
-networking = {
- hub_sg = {
- resource_group_key = "vnet_sg"
- location = "southeastasia"
- vnet = {
- name = "hub"
- address_space = ["10.10.100.0/24"]
- }
- specialsubnets = {
- }
- subnets = {
- jumpbox = {
- name = "jumpbox"
- cidr = ["10.10.100.0/25"]
- nsg_name = "jumpbox_nsg"
- nsg = []
- }
-
- }
- diags = {
- log = [
- # ["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
- ["VMProtectionAlerts", true, true, 7],
- ]
- metric = [
- #["Category name", "Diagnostics Enabled(true/false)", "Retention Enabled(true/false)", Retention_period]
- ["AllMetrics", true, true, 7],
- ]
- }
- }
-
-}
\ No newline at end of file
diff --git a/modules/storage_account/file_share/file_share.tf b/modules/storage_account/file_share/file_share.tf
new file mode 100644
index 0000000000..96a7814cbf
--- /dev/null
+++ b/modules/storage_account/file_share/file_share.tf
@@ -0,0 +1,21 @@
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_share
+
+resource "azurerm_storage_share" "fs" {
+ name = var.settings.name
+ storage_account_name = var.storage_account_name
+ quota = try(var.settings.quota, null)
+ metadata = try(var.settings.metadata, null)
+}
+
+# Issue open in 2.61 : https://github.com/terraform-providers/terraform-provider-azurerm/issues/11184
+resource "azurerm_backup_protected_file_share" "fs_backup" {
+ for_each = try(var.settings.backups, null) != null ? toset(["enabled"]) : toset([])
+
+ resource_group_name = var.resource_group_name
+ recovery_vault_name = var.recovery_vault.name
+ source_storage_account_id = var.storage_account_id
+ source_file_share_name = azurerm_storage_share.fs.name
+ backup_policy_id = var.recovery_vault.backup_policies.file_shares[var.settings.backups.policy_key].id
+}
+
diff --git a/modules/storage_account/file_share/output.tf b/modules/storage_account/file_share/output.tf
new file mode 100755
index 0000000000..e46ac07dcc
--- /dev/null
+++ b/modules/storage_account/file_share/output.tf
@@ -0,0 +1,19 @@
+output "id" {
+ description = "The ID of the File Share"
+ value = azurerm_storage_share.fs.id
+}
+
+output "url" {
+ description = "The URL of the File Share"
+ value = azurerm_storage_share.fs.url
+}
+
+output "resource_manager_id" {
+ description = "The Resource Manager ID of this File Share"
+ value = azurerm_storage_share.fs.resource_manager_id
+}
+
+output "file_share_directories" {
+ description = "Output of directories in the file share"
+ value = module.file_share_directory
+}
\ No newline at end of file
diff --git a/modules/storage_account/file_share/share_directory.tf b/modules/storage_account/file_share/share_directory.tf
new file mode 100644
index 0000000000..5f3310531b
--- /dev/null
+++ b/modules/storage_account/file_share/share_directory.tf
@@ -0,0 +1,8 @@
+module "file_share_directory" {
+ source = "../file_share_directory"
+ for_each = try(var.settings.directories, {})
+
+ storage_account_name = var.storage_account_name
+ share_name = azurerm_storage_share.fs.name
+ settings = each.value
+}
\ No newline at end of file
diff --git a/modules/storage_account/file_share/variables.tf b/modules/storage_account/file_share/variables.tf
new file mode 100755
index 0000000000..1774aaceba
--- /dev/null
+++ b/modules/storage_account/file_share/variables.tf
@@ -0,0 +1,9 @@
+variable "settings" {}
+variable "storage_account_name" {}
+variable "storage_account_id" {}
+variable "recovery_vault" {
+ default = {}
+}
+variable "resource_group_name" {
+ default = ""
+}
diff --git a/modules/storage_account/file_share_directory/directory.tf b/modules/storage_account/file_share_directory/directory.tf
new file mode 100644
index 0000000000..3119425c6e
--- /dev/null
+++ b/modules/storage_account/file_share_directory/directory.tf
@@ -0,0 +1,6 @@
+resource "azurerm_storage_share_directory" "share_directory" {
+ name = var.settings.name
+ share_name = var.share_name
+ storage_account_name = var.storage_account_name
+ metadata = try(var.settings.metadata, null)
+}
\ No newline at end of file
diff --git a/modules/storage_account/file_share_directory/output.tf b/modules/storage_account/file_share_directory/output.tf
new file mode 100644
index 0000000000..55ca2d98c4
--- /dev/null
+++ b/modules/storage_account/file_share_directory/output.tf
@@ -0,0 +1,4 @@
+output "id" {
+ value = azurerm_storage_share_directory.share_directory.id
+}
+
diff --git a/modules/storage_account/file_share_directory/variables.tf b/modules/storage_account/file_share_directory/variables.tf
new file mode 100644
index 0000000000..db1436f686
--- /dev/null
+++ b/modules/storage_account/file_share_directory/variables.tf
@@ -0,0 +1,3 @@
+variable "storage_account_name" {}
+variable "share_name" {}
+variable "settings" {}
\ No newline at end of file
diff --git a/modules/storage_account/output.tf b/modules/storage_account/output.tf
index 42b443a82e..bcf439eadb 100755
--- a/modules/storage_account/output.tf
+++ b/modules/storage_account/output.tf
@@ -1,36 +1,67 @@
output "id" {
- value = azurerm_storage_account.stg.id
+ description = "The ID of the Storage Account"
+ value = azurerm_storage_account.stg.id
}
output "name" {
- value = azurerm_storage_account.stg.name
+ description = "The name of the Storage Account"
+ value = azurerm_storage_account.stg.name
}
output "location" {
- value = var.location
-
+ description = "The location of the Storage Account"
+ value = var.location
}
output "resource_group_name" {
- value = var.resource_group_name
+ description = "The resource group name of the Storage Account"
+ value = var.resource_group_name
}
output "primary_blob_endpoint" {
- value = azurerm_storage_account.stg.primary_blob_endpoint
+ description = "The endpoint URL for blob storage in the primary location."
+ value = azurerm_storage_account.stg.primary_blob_endpoint
}
output "containers" {
- value = module.container
+ description = "The containers output objects as created by the container submodule."
+ value = module.container
+}
+
+output "queues" {
+ description = "The queues output objects as created by the queues submodule."
+ value = module.queue
}
output "data_lake_filesystems" {
- value = module.data_lake_filesystem
+ description = "The data lake filesystem output objects as created by the data lake filesystem submodule."
+ value = module.data_lake_filesystem
+}
+
+output "file_share" {
+ description = "The file shares output objects as created by the file shares submodule."
+ value = module.file_share
}
output "identity" {
- value = try(azurerm_storage_account.stg.identity, null)
+ description = " An identity block, which contains the Identity information for this Storage Account. Exports principal_id (The Principal ID for the Service Principal associated with the Identity of this Storage Account), tenand_id (The Tenant ID for the Service Principal associated with the Identity of this Storage Account)"
+ value = try(azurerm_storage_account.stg.identity, null)
}
output "rbac_id" {
- value = try(azurerm_storage_account.stg.identity.0, null)
-}
\ No newline at end of file
+ description = " The Principal ID for the Service Principal associated with the Identity of this Storage Account. (Extracted from the identity block)"
+ value = try(azurerm_storage_account.stg.identity.0.principal_id, null)
+}
+
+output "backup_container_id" {
+ description = "The ID of the Backup Storage Account Container"
+ value = try(azurerm_backup_container_storage_account.container["enabled"].id, null)
+}
+
+#output "primary_connection_string" {
+# value = try(azurerm_storage_account.stg.primary_connection_string, null)
+#}
+
+#output "primary_queue_endpoint" {
+# value = try(azurerm_storage_account.stg.primary_queue_endpoint, null)
+#}
\ No newline at end of file
diff --git a/modules/storage_account/queue/output.tf b/modules/storage_account/queue/output.tf
new file mode 100644
index 0000000000..962d8bef0e
--- /dev/null
+++ b/modules/storage_account/queue/output.tf
@@ -0,0 +1,9 @@
+output "name" {
+ description = "The name of the Storage Queue."
+ value = azurerm_storage_queue.queue.name
+}
+
+output "id" {
+ description = "The ID of the Storage Queue."
+ value = azurerm_storage_queue.queue.id
+}
\ No newline at end of file
diff --git a/modules/storage_account/queue/queue.tf b/modules/storage_account/queue/queue.tf
new file mode 100644
index 0000000000..4eeebba24b
--- /dev/null
+++ b/modules/storage_account/queue/queue.tf
@@ -0,0 +1,5 @@
+resource "azurerm_storage_queue" "queue" {
+ name = var.settings.name
+ storage_account_name = var.storage_account_name
+ metadata = try(var.settings.metadata, null)
+}
\ No newline at end of file
diff --git a/modules/storage_account/queue/variables.tf b/modules/storage_account/queue/variables.tf
new file mode 100644
index 0000000000..d36597c16c
--- /dev/null
+++ b/modules/storage_account/queue/variables.tf
@@ -0,0 +1,2 @@
+variable "settings" {}
+variable "storage_account_name" {}
diff --git a/modules/storage_account/storage_account.tf b/modules/storage_account/storage_account.tf
index 82e393d74e..243937c771 100755
--- a/modules/storage_account/storage_account.tf
+++ b/modules/storage_account/storage_account.tf
@@ -14,19 +14,25 @@ resource "azurecaf_name" "stg" {
use_slug = var.global_settings.use_slug
}
+# Tested with : AzureRM version 2.61.0
+# Ref : https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account
+
resource "azurerm_storage_account" "stg" {
name = azurecaf_name.stg.result
resource_group_name = var.resource_group_name
location = var.location
- account_tier = lookup(var.storage_account, "account_tier", "Standard")
- account_replication_type = lookup(var.storage_account, "account_replication_type", "LRS")
- account_kind = lookup(var.storage_account, "account_kind", "StorageV2")
- access_tier = lookup(var.storage_account, "access_tier", "Hot")
- enable_https_traffic_only = true
- min_tls_version = lookup(var.storage_account, "min_tls_version", "TLS1_2")
- allow_blob_public_access = lookup(var.storage_account, "allow_blob_public_access", false)
- is_hns_enabled = lookup(var.storage_account, "is_hns_enabled", false)
- tags = merge(var.base_tags, local.tags)
+ account_tier = try(var.storage_account.account_tier, "Standard")
+ account_replication_type = try(var.storage_account.account_replication_type, "LRS")
+ account_kind = try(var.storage_account.account_kind, "StorageV2")
+ access_tier = try(var.storage_account.access_tier, "Hot")
+ enable_https_traffic_only = try(var.storage_account.nfsv3_enabled, false) ? false : true
+ #if using nfsv3_enabled, then https must be disabled
+ min_tls_version = try(var.storage_account.min_tls_version, "TLS1_2")
+ allow_blob_public_access = try(var.storage_account.allow_blob_public_access, false)
+ is_hns_enabled = try(var.storage_account.is_hns_enabled, false)
+ nfsv3_enabled = try(var.storage_account.nfsv3_enabled, false)
+ large_file_share_enabled = try(var.storage_account.large_file_share_enabled, null)
+ tags = merge(var.base_tags, local.tags)
dynamic "custom_domain" {
@@ -34,7 +40,7 @@ resource "azurerm_storage_account" "stg" {
content {
name = var.storage_account.custom_domain.name
- use_subdomain = var.storage_account.custom_domain.use_subdomain
+ use_subdomain = try(var.storage_account.custom_domain.use_subdomain, null)
}
}
@@ -50,6 +56,11 @@ resource "azurerm_storage_account" "stg" {
for_each = lookup(var.storage_account, "blob_properties", false) == false ? [] : [1]
content {
+ versioning_enabled = try(var.storage_account.blob_properties.versioning_enabled, false)
+ change_feed_enabled = try(var.storage_account.blob_properties.change_feed_enabled, false)
+ default_service_version = try(var.storage_account.blob_properties.default_service_version, "2020-06-12")
+ last_access_time_enabled = try(var.storage_account.blob_properties.last_access_time_enabled, false)
+
dynamic "cors_rule" {
for_each = lookup(var.storage_account.blob_properties, "cors_rule", false) == false ? [] : [1]
@@ -66,11 +77,18 @@ resource "azurerm_storage_account" "stg" {
for_each = lookup(var.storage_account.blob_properties, "delete_retention_policy", false) == false ? [] : [1]
content {
- days = lookup(var.storage_account.blob_properties.delete_retention_policy, "delete_retention_policy", 7)
+ days = try(var.storage_account.blob_properties.delete_retention_policy.delete_retention_policy, 7)
}
}
- }
+ dynamic "container_delete_retention_policy" {
+ for_each = lookup(var.storage_account.blob_properties, "container_delete_retention_policy", false) == false ? [] : [1]
+
+ content {
+ days = try(var.storage_account.blob_properties.container_delete_retention_policy.container_delete_retention_policy, 7)
+ }
+ }
+ }
}
dynamic "queue_properties" {
@@ -97,7 +115,7 @@ resource "azurerm_storage_account" "stg" {
read = var.storage_account.queue_properties.logging.read
write = var.storage_account.queue_properties.logging.write
version = var.storage_account.queue_properties.logging.version
- retention_policy_days = lookup(var.storage_account.queue_properties.logging, "retention_policy_days", 7)
+ retention_policy_days = try(var.storage_account.queue_properties.logging.retention_policy_days, 7)
}
}
@@ -107,8 +125,8 @@ resource "azurerm_storage_account" "stg" {
content {
enabled = var.storage_account.queue_properties.minute_metrics.enabled
version = var.storage_account.queue_properties.minute_metrics.version
- include_apis = lookup(var.storage_account.queue_properties.minute_metrics, "include_apis", null)
- retention_policy_days = lookup(var.storage_account.queue_properties.minute_metrics, "retention_policy_days", 7)
+ include_apis = try(var.storage_account.queue_properties.minute_metrics.include_apis, null)
+ retention_policy_days = try(var.storage_account.queue_properties.minute_metrics.retention_policy_days, 7)
}
}
@@ -118,8 +136,8 @@ resource "azurerm_storage_account" "stg" {
content {
enabled = var.storage_account.queue_properties.hour_metrics.enabled
version = var.storage_account.queue_properties.hour_metrics.version
- include_apis = lookup(var.storage_account.queue_properties.hour_metrics, "include_apis", null)
- retention_policy_days = lookup(var.storage_account.queue_properties.hour_metrics, "retention_policy_days", 7)
+ include_apis = try(var.storage_account.queue_properties.hour_metrics.include_apis, null)
+ retention_policy_days = try(var.storage_account.queue_properties.hour_metrics.retention_policy_days, 7)
}
}
}
@@ -129,8 +147,8 @@ resource "azurerm_storage_account" "stg" {
for_each = lookup(var.storage_account, "static_website", false) == false ? [] : [1]
content {
- index_document = var.storage_account.static_website.index_document
- error_404_document = var.storage_account.static_website.error_404_document
+ index_document = try(var.storage_account.static_website.index_document, null)
+ error_404_document = try(var.storage_account.static_website.error_404_document, null)
}
}
@@ -145,9 +163,46 @@ resource "azurerm_storage_account" "stg" {
]
}
}
+
+ dynamic "azure_files_authentication" {
+ for_each = lookup(var.storage_account, "azure_files_authentication", false) == false ? [] : [1]
+
+ content {
+ directory_type = var.storage_account.azure_files_authentication.directory_type
+
+ dynamic "active_directory" {
+ for_each = lookup(var.storage_account.azure_files_authentication, "active_directory", false) == false ? [] : [1]
+
+ content {
+ storage_sid = var.storage_account.azure_files_authentication.active_directory.storage_sid
+ domain_name = var.storage_account.azure_files_authentication.active_directory.domain_name
+ domain_sid = var.storage_account.azure_files_authentication.active_directory.domain_sid
+ domain_guid = var.storage_account.azure_files_authentication.active_directory.domain_guid
+ forest_name = var.storage_account.azure_files_authentication.active_directory.forest_name
+ netbios_domain_name = var.storage_account.azure_files_authentication.active_directory.netbios_domain_name
+ }
+ }
+ }
+ }
+
+ dynamic "routing" {
+ for_each = lookup(var.storage_account, "routing", false) == false ? [] : [1]
+
+ content {
+ publish_internet_endpoints = try(var.storage_account.routing.publish_internet_endpoints, false)
+ publish_microsoft_endpoints = try(var.storage_account.routing.publish_microsoft_endpoints, false)
+ choice = try(var.storage_account.routing.choice, "MicrosoftRouting")
+ }
+ }
}
+module "queue" {
+ source = "./queue"
+ for_each = try(var.storage_account.queues, {})
+ storage_account_name = azurerm_storage_account.stg.name
+ settings = each.value
+}
module "container" {
source = "./container"
@@ -164,3 +219,15 @@ module "data_lake_filesystem" {
storage_account_id = azurerm_storage_account.stg.id
settings = each.value
}
+
+module "file_share" {
+ source = "./file_share"
+ for_each = try(var.storage_account.file_shares, {})
+ depends_on = [azurerm_backup_container_storage_account.container]
+
+ storage_account_name = azurerm_storage_account.stg.name
+ storage_account_id = azurerm_storage_account.stg.id
+ settings = each.value
+ recovery_vault = local.recovery_vault
+ resource_group_name = var.resource_group_name
+}
\ No newline at end of file
diff --git a/modules/subscription_billing_role_assignment/billing_role_assignment.tf b/modules/subscription_billing_role_assignment/billing_role_assignment.tf
index 5d7dc55636..b61d726a85 100755
--- a/modules/subscription_billing_role_assignment/billing_role_assignment.tf
+++ b/modules/subscription_billing_role_assignment/billing_role_assignment.tf
@@ -47,3 +47,18 @@ module "role_assignment_msi" {
cloud = var.cloud
}
+
+module "role_assignment_azuread_service_principals" {
+ source = "./role_assignment"
+ for_each = try(var.settings.principals.azuread_service_principals, {})
+ depends_on = [module.role_assignment_azuread_users, module.role_assignment_msi]
+
+ aad_user_impersonate = try(var.keyvaults[try(each.value.lz_key, var.client_config.landingzone_key)][var.settings.aad_user_impersonate.keyvault.key], null)
+ billing_scope_id = local.billing_scope_id
+ tenant_id = try(var.principals.azuread_service_principals[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.key].tenant_id, var.client_config.tenant_id)
+ principal_id = var.principals.azuread_service_principals[try(each.value.lz_key, var.client_config.landingzone_key)][each.value.key].object_id
+ role_definition_id = data.external.role_definition.result.id
+ settings = each.value
+ cloud = var.cloud
+}
+
diff --git a/modules/subscriptions/README.md b/modules/subscriptions/README.md
index d10f3a630c..0c9c3af64f 100755
--- a/modules/subscriptions/README.md
+++ b/modules/subscriptions/README.md
@@ -44,14 +44,14 @@ principalId=""
billing_role_definition_id=$(az rest --method GET --url https://management.azure.com${enrollmentAccount}/billingRoleDefinitions?api-version=2019-10-01-preview --query "value[?properties.roleName=='Enrollment account subscription creator'].{id:id}" -o tsv)
-az rest --method PUT --url https://management.azure.com/${enrollmentAccount}/billingRoleAssignments/0525cbc2-c84e-4279-b639-adab918a96b8?api-version=2019-10-01-preview --body "{\"properties\": {\"principalId\": \"${principalId}\",\"principalTenantId\": \"${tenantId}\",\"roleDefinitionId\": \"${enrollmentAccount}/billingRoleDefinitions/${billing_role_definition_id}\"}}
+az rest --method PUT --url https://management.azure.com/${enrollmentAccount}/billingRoleAssignments/${principalId}?api-version=2019-10-01-preview --body "{\"properties\": {\"principalId\": \"${principalId}\",\"principalTenantId\": \"${tenantId}\",\"roleDefinitionId\": \"${enrollmentAccount}/billingRoleDefinitions/${billing_role_definition_id}\"}}"
# Login as the principalId and create a subscription to confirm the delegation of permission is effective.
az account alias create \
- --name "alias_name" \
+ --name "spike1" \
--billing-scope "${enrollmentAccount}" \
- --display-name "name of the subscription" \
+ --display-name "spike1" \
--workload "Production"
```
diff --git a/modules/subscriptions/output.tf b/modules/subscriptions/output.tf
index 9656a3e852..67508007d3 100755
--- a/modules/subscriptions/output.tf
+++ b/modules/subscriptions/output.tf
@@ -1,3 +1,6 @@
+output "id" {
+ value = format("/subscriptions/%s", try(azurerm_subscription.sub.0.subscription_id, var.client_config.subscription_id))
+}
output "subscription_id" {
value = try(azurerm_subscription.sub.0.subscription_id, var.client_config.subscription_id)
}
diff --git a/modules/subscriptions/scripts/refresh_access_token.sh b/modules/subscriptions/scripts/refresh_access_token.sh
index 8b20e3b629..8361ce4366 100755
--- a/modules/subscriptions/scripts/refresh_access_token.sh
+++ b/modules/subscriptions/scripts/refresh_access_token.sh
@@ -9,8 +9,20 @@ tenant_id=$(az account show --query tenantId -o tsv)
subscription_id=$(az account show --query id -o tsv)
if [ ${user_type} == "user" ]; then
-
- az login --tenant ${tenant_id} --use-device-code > /dev/null
+ echo "User type ${user_type}"
+ if [ "${ROVER_RUNNER}" == "true" ]; then
+ echo "Rover is runner mode."
+ if [ -z "${ACCOUNT_OWNER_USERNAME}" ] || [ -z "${ACCOUNT_OWNER_PASSWORD}" ] || [ -z "${tenant-id}" ]; then
+ echo "Subscription creation from pipeline with AE account owner requires the variables ACCOUNT_OWNER_USERNAME, ACCOUNT_OWNER_PASSWORD to be set in the bash pipeline context."
+ exit 3001
+ else
+ echo "Login to ${ACCOUNT_OWNER_USERNAME} in tenant ${tenant_id}."
+ az login -u ${ACCOUNT_OWNER_USERNAME} -p "${ACCOUNT_OWNER_PASSWORD}" --tenant ${tenant_id} -o table
+ fi
+ else
+ echo "Rover is running in interactive mode."
+ az login --tenant ${tenant_id} --use-device-code > /dev/null
+ fi
else
diff --git a/modules/webapps/appservice/output.tf b/modules/webapps/appservice/output.tf
index b3b9a8b4df..3f92cade91 100755
--- a/modules/webapps/appservice/output.tf
+++ b/modules/webapps/appservice/output.tf
@@ -14,3 +14,7 @@ output "possible_outbound_ip_addresses" {
value = azurerm_app_service.app_service.possible_outbound_ip_addresses
description = "A comma separated list of outbound IP addresses. not all of which are necessarily in use"
}
+output "rbac_id" {
+ value = try(azurerm_app_service.app_service.identity.0.principal_id, null)
+ description = "The Principal ID of the App Service."
+}
\ No newline at end of file
diff --git a/networking.tf b/networking.tf
index aefc05c88e..e210eb971f 100755
--- a/networking.tf
+++ b/networking.tf
@@ -21,19 +21,20 @@ module "networking" {
for_each = local.networking.vnets
application_security_groups = local.combined_objects_application_security_groups
- base_tags = try(local.global_settings.inherit_tags, false) ? local.resource_groups[each.value.resource_group_key].tags : {}
client_config = local.client_config
ddos_id = try(azurerm_network_ddos_protection_plan.ddos_protection_plan[each.value.ddos_services_key].id, "")
diagnostics = local.combined_diagnostics
global_settings = local.global_settings
- location = lookup(each.value, "region", null) == null ? local.resource_groups[each.value.resource_group_key].location : local.global_settings.regions[each.value.region]
network_security_groups = module.network_security_groups
network_security_group_definition = local.networking.network_security_group_definition
- network_watchers = try(local.combined_objects_network_watchers, null)
- resource_group_name = local.resource_groups[each.value.resource_group_key].name
+ network_watchers = try(local.combined_objects_network_watchers, null)
route_tables = module.route_tables
settings = each.value
tags = try(each.value.tags, null)
+
+ resource_group_name = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].name
+ location = lookup(each.value, "region", null) == null ? local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location : local.global_settings.regions[each.value.region]
+ base_tags = try(local.global_settings.inherit_tags, false) ? local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].tags : {}
}
#
@@ -60,8 +61,8 @@ module "public_ip_addresses" {
for_each = local.networking.public_ip_addresses
name = azurecaf_name.public_ip_addresses[each.key].result
- resource_group_name = local.resource_groups[each.value.resource_group_key].name
- location = lookup(each.value, "region", null) == null ? local.resource_groups[each.value.resource_group_key].location : local.global_settings.regions[each.value.region]
+ resource_group_name = local.combined_objects_resource_groups[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.resource_group_key].name
+ location = lookup(each.value, "region", null) == null ? local.combined_objects_resource_groups[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.resource_group_key].location : local.global_settings.regions[each.value.region]
sku = try(each.value.sku, "Basic")
allocation_method = try(each.value.allocation_method, "Dynamic")
ip_version = try(each.value.ip_version, "IPv4")
@@ -70,10 +71,16 @@ module "public_ip_addresses" {
reverse_fqdn = try(each.value.reverse_fqdn, null)
generate_domain_name_label = try(each.value.generate_domain_name_label, false)
tags = try(each.value.tags, null)
- zones = try(each.value.zones, null)
- diagnostic_profiles = try(each.value.diagnostic_profiles, {})
- diagnostics = local.combined_diagnostics
- base_tags = try(local.global_settings.inherit_tags, false) ? local.resource_groups[each.value.resource_group_key].tags : {}
+ ip_tags = try(each.value.ip_tags, null)
+ public_ip_prefix_id = try(each.value.public_ip_prefix_id, null)
+ zones = coalesce(
+ try(each.value.availability_zone, ""),
+ try(tostring(each.value.zones[0]), ""),
+ try(each.value.sku, "Basic") == "Basic" ? "No-Zone" : "Zone-Redundant"
+ )
+ diagnostic_profiles = try(each.value.diagnostic_profiles, {})
+ diagnostics = local.combined_diagnostics
+ base_tags = try(local.global_settings.inherit_tags, false) ? local.combined_objects_resource_groups[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.resource_group_key].tags : {}
}
@@ -133,11 +140,11 @@ module "route_tables" {
for_each = local.networking.route_tables
name = azurecaf_name.route_tables[each.key].result
- resource_group_name = local.resource_groups[each.value.resource_group_key].name
- location = lookup(each.value, "region", null) == null ? local.resource_groups[each.value.resource_group_key].location : local.global_settings.regions[each.value.region]
+ resource_group_name = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].name
+ location = lookup(each.value, "region", null) == null ? local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location : local.global_settings.regions[each.value.region]
+ base_tags = try(local.global_settings.inherit_tags, false) ? local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].tags : {}
disable_bgp_route_propagation = try(each.value.disable_bgp_route_propagation, null)
tags = try(each.value.tags, null)
- base_tags = try(local.global_settings.inherit_tags, false) ? local.resource_groups[each.value.resource_group_key].tags : {}
}
resource "azurecaf_name" "routes" {
@@ -157,17 +164,17 @@ module "routes" {
source = "./modules/networking/routes"
for_each = local.networking.azurerm_routes
- name = azurecaf_name.routes[each.key].result
- resource_group_name = local.resource_groups[each.value.resource_group_key].name
- route_table_name = module.route_tables[each.value.route_table_key].name
- address_prefix = each.value.address_prefix
- next_hop_type = each.value.next_hop_type
- next_hop_in_ip_address = try(lower(each.value.next_hop_type), null) == "virtualappliance" ? try(each.value.next_hop_in_ip_address, null) : null
+ name = azurecaf_name.routes[each.key].result
+ resource_group_name = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].name
+ route_table_name = module.route_tables[each.value.route_table_key].name
+ address_prefix = each.value.address_prefix
+ next_hop_type = each.value.next_hop_type
+ next_hop_in_ip_address = try(lower(each.value.next_hop_type), null) == "virtualappliance" ? try(each.value.next_hop_in_ip_address, null) : null
next_hop_in_ip_address_fw = try(lower(each.value.next_hop_type), null) == "virtualappliance" ? coalesce(
try(local.combined_objects_azurerm_firewalls[try(each.value.private_ip_keys.azurerm_firewall.lz_key, local.client_config.landingzone_key)][each.value.private_ip_keys.azurerm_firewall.key].ip_configuration[each.value.private_ip_keys.azurerm_firewall.interface_index].private_ip_address, null),
try(local.combined_objects_azurerm_firewalls[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.private_ip_keys.azurerm_firewall.key].ip_configuration[each.value.private_ip_keys.azurerm_firewall.interface_index].private_ip_address, null)
) : null
-
+
}
#
@@ -193,9 +200,9 @@ resource "azurerm_network_ddos_protection_plan" "ddos_protection_plan" {
for_each = local.networking.ddos_services
name = azurecaf_name.ddos_protection_plan[each.key].result
- location = lookup(each.value, "region", null) == null ? local.resource_groups[each.value.resource_group_key].location : local.global_settings.regions[each.value.region]
- resource_group_name = local.resource_groups[each.value.resource_group_key].name
- tags = try(local.global_settings.inherit_tags, false) ? merge(local.resource_groups[each.value.resource_group_key].tags, each.value.tags) : try(each.value.tags, null)
+ location = lookup(each.value, "region", null) == null ? local.combined_objects_resource_groups[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.resource_group_key].location : local.global_settings.regions[each.value.region]
+ resource_group_name = local.combined_objects_resource_groups[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.resource_group_key].name
+ tags = try(local.global_settings.inherit_tags, false) ? merge(local.combined_objects_resource_groups[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.resource_group_key].tags, each.value.tags) : try(each.value.tags, null)
}
#
@@ -207,10 +214,10 @@ module "network_watchers" {
source = "./modules/networking/network_watcher"
for_each = local.networking.network_watchers
- resource_group_name = local.resource_groups[each.value.resource_group_key].name
- location = lookup(each.value, "region", null) == null ? local.resource_groups[each.value.resource_group_key].location : local.global_settings.regions[each.value.region]
+ resource_group_name = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].name
+ location = lookup(each.value, "region", null) == null ? local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location : local.global_settings.regions[each.value.region]
+ base_tags = try(local.global_settings.inherit_tags, false) ? local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].tags : {}
settings = each.value
tags = try(each.value.tags, null)
- base_tags = try(local.global_settings.inherit_tags, false) ? local.resource_groups[each.value.resource_group_key].tags : {}
global_settings = local.global_settings
}
\ No newline at end of file
diff --git a/networking_firewall.tf b/networking_firewall.tf
index fac9d2ca09..eff8a93982 100755
--- a/networking_firewall.tf
+++ b/networking_firewall.tf
@@ -6,27 +6,31 @@ module "azurerm_firewalls" {
source = "./modules/networking/firewall"
for_each = local.networking.azurerm_firewalls
+ base_tags = try(local.global_settings.inherit_tags, false) ? local.resource_groups[each.value.resource_group_key].tags : {}
client_config = local.client_config
+ diagnostics = local.combined_diagnostics
+ diagnostic_profiles = try(each.value.diagnostic_profiles, null)
+ firewall_policy_id = try(each.value.firewall_policy_key, null) == null ? null : local.combined_objects_azurerm_firewall_policies[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.firewall_policy_key].id
global_settings = local.global_settings
- name = each.value.name
- resource_group_name = local.resource_groups[each.value.resource_group_key].name
location = lookup(each.value, "region", null) == null ? local.resource_groups[each.value.resource_group_key].location : local.global_settings.regions[each.value.region]
- tags = try(each.value.tags, null)
- base_tags = try(local.global_settings.inherit_tags, false) ? local.resource_groups[each.value.resource_group_key].tags : {}
- subnet_id = module.networking[each.value.vnet_key].subnets["AzureFirewallSubnet"].id
- public_ip_id = try(module.public_ip_addresses[each.value.public_ip_key].id, null)
+ name = each.value.name
public_ip_addresses = try(module.public_ip_addresses, null)
+ public_ip_id = try(module.public_ip_addresses[each.value.public_ip_key].id, null)
public_ip_keys = try(each.value.public_ip_keys, null)
- diagnostics = local.combined_diagnostics
+ resource_group_name = local.resource_groups[each.value.resource_group_key].name
settings = each.value
- virtual_wans = module.virtual_wans
+ subnet_id = module.networking[each.value.vnet_key].subnets["AzureFirewallSubnet"].id
+ tags = try(each.value.tags, null)
virtual_networks = local.combined_objects_networking
- firewall_policies = module.azurerm_firewall_policies
+ virtual_wans = module.virtual_wans
}
module "azurerm_firewall_policies" {
- source = "./modules/networking/firewall_policies"
- for_each = local.networking.azurerm_firewall_policies
+ source = "./modules/networking/firewall_policies"
+ for_each = {
+ for key, value in local.networking.azurerm_firewall_policies : key => value
+ if try(value.base_policy, null) == null
+ }
global_settings = local.global_settings
name = each.value.name
@@ -37,17 +41,22 @@ module "azurerm_firewall_policies" {
policy_settings = each.value
}
+
module "azurerm_firewall_policy_rule_collection_groups" {
source = "./modules/networking/firewall_policy_rule_collection_groups"
for_each = local.networking.azurerm_firewall_policy_rule_collection_groups
global_settings = local.global_settings
- policy_settings = each.value
- firewall_policies = module.azurerm_firewall_policies
ip_groups = module.ip_groups
+ policy_settings = each.value
public_ip_addresses = module.public_ip_addresses
+ firewall_policy_id = coalesce(
+ try(local.combined_objects_azurerm_firewall_policies[try(each.value.firewall_policy.lz_key, local.client_config.landingzone_key)][each.value.firewall_policy.key].id, null),
+ try(local.combined_objects_azurerm_firewall_policies[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.firewall_policy_key].id, null)
+ )
}
+
module "azurerm_firewall_network_rule_collections" {
source = "./modules/networking/firewall_network_rule_collections"
for_each = {
@@ -102,7 +111,6 @@ output "azurerm_firewalls" {
output "azurerm_firewall_policies" {
value = module.azurerm_firewall_policies
-
}
output "azurerm_firewall_policy_rule_collection_groups" {
diff --git a/networking_vpn_gateway_connection.tf b/networking_vpn_gateway_connection.tf
new file mode 100644
index 0000000000..592833dbec
--- /dev/null
+++ b/networking_vpn_gateway_connection.tf
@@ -0,0 +1,30 @@
+
+#
+#
+# VPN Gateway Connection
+#
+#
+
+output "vpn_gateway_connections" {
+ value = module.vpn_gateway_connections
+}
+
+module "vpn_gateway_connections" {
+ depends_on = [module.virtual_wans, module.vpn_sites, module.virtual_hubs]
+ source = "./modules/networking/vpn_gateway_connection"
+ for_each = local.networking.vpn_gateway_connections
+
+ settings = each.value
+ global_settings = local.global_settings
+ client_config = local.client_config
+ vpn_sites = local.combined_objects_vpn_sites
+ route_tables = local.combined_objects_virtual_hub_route_tables
+
+ vpn_gateway_id = coalesce(
+ try(local.combined_objects_virtual_hubs[try(each.value.virtual_hub.lz_key, local.client_config.landingzone_key)][each.value.virtual_hub.key].s2s_gateway.id, null),
+ try(local.combined_objects_virtual_wans[try(each.value.virtual_wan.lz_key, local.client_config.landingzone_key)][each.value.virtual_wan.key].virtual_hubs[each.value.virtual_hub.key].s2s_gateway.id, null),
+ try(local.combined_objects_virtual_wans[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.virtual_wan_key].virtual_hubs[each.value.virtual_hub_key].s2s_gateway.id, null),
+ try(local.combined_objects_virtual_wans[try(each.value.vhub.lz_key, local.client_config.landingzone_key)][each.value.vhub.virtual_wan_key].virtual_hubs[each.value.vhub.virtual_hub_key].s2s_gateway.id, null),
+ try(each.value.virtual_hub_gateway_id, null)
+ )
+}
diff --git a/networking_vpn_site.tf b/networking_vpn_site.tf
new file mode 100644
index 0000000000..d5e73347f8
--- /dev/null
+++ b/networking_vpn_site.tf
@@ -0,0 +1,42 @@
+
+#
+#
+# VPN Sites
+#
+#
+
+output "vpn_sites" {
+ value = module.vpn_sites
+}
+
+module "vpn_sites" {
+ depends_on = [module.virtual_wans]
+ source = "./modules/networking/vpn_site"
+ for_each = local.networking.vpn_sites
+
+ global_settings = local.global_settings
+ settings = each.value
+
+ base_tags = try(local.global_settings.inherit_tags, false) ? coalesce(
+ try(local.resource_groups[each.value.resource_group_key].tags, null),
+ try(local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][each.value.resource_group.key].tags, null),
+ ) : {}
+
+ location = lookup(each.value, "region", null) == null ? coalesce(
+ try(local.resource_groups[each.value.resource_group_key].location, null),
+ try(local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][each.value.resource_group.key].location, null),
+ ) : local.global_settings.regions[each.value.region]
+
+ resource_group_name = coalesce(
+ try(local.resource_groups[each.value.resource_group_key].name, null),
+ try(local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][each.value.resource_group.key].name, null),
+ )
+
+ virtual_wan_id = coalesce(
+ try(local.combined_objects_virtual_wans[try(each.value.virtual_wan.lz_key, local.client_config.landingzone_key)][each.value.virtual_wan.key].virtual_wan.id, null),
+ try(local.combined_objects_virtual_wans[try(each.value.lz_key, local.client_config.landingzone_key)][each.value.virtual_wan_key].virtual_wan.id, null),
+ try(each.value.virtual_wan.resource_id, null),
+ try(each.value.virtual_wan.id, null),
+ try(each.value.virtual_wan_id, null)
+ )
+}
diff --git a/random_string.tf b/random_string.tf
new file mode 100755
index 0000000000..4aff80455d
--- /dev/null
+++ b/random_string.tf
@@ -0,0 +1,15 @@
+
+module "random_strings" {
+ source = "./modules/random_string"
+ for_each = try(var.random_strings, {})
+
+ random_string_length = each.value.length
+ random_string_allow_special_characters = try(each.value.special, false)
+ random_string_allow_upper_case = try(each.value.upper, false)
+ random_string_allow_numbers = try(each.value.number, false)
+}
+
+output "random_strings" {
+ value = module.random_strings
+
+}
diff --git a/roles.tf b/roles.tf
index 3336ae4392..410b5bf582 100755
--- a/roles.tf
+++ b/roles.tf
@@ -25,21 +25,45 @@ resource "azurerm_role_assignment" "for" {
ignore_changes = [
principal_id
]
+
+ create_before_destroy = true
+ }
+
+}
+
+data "azurerm_management_group" "level" {
+ for_each = {
+ for key, value in try(var.role_mapping.built_in_role_mapping.management_group, {}) : key => value
}
+ name = lower(each.key) == "root" ? data.azurerm_client_config.current.tenant_id : each.key
}
locals {
+
+ management_groups = tomap(
+ {
+ (var.current_landingzone_key) = {
+ for key, value in try(var.role_mapping.built_in_role_mapping.management_group, {}) :
+ key => {
+ id = data.azurerm_management_group.level[key].id
+ }
+ }
+ }
+ )
+
services_roles = {
aks_clusters = local.combined_objects_aks_clusters
app_config = local.combined_objects_app_config
- app_services = local.combined_objects_app_services
- app_service_plans = local.combined_objects_app_service_plans
app_service_environments = local.combined_objects_app_service_environments
+ app_service_plans = local.combined_objects_app_service_plans
+ app_services = local.combined_objects_app_services
availability_sets = local.combined_objects_availability_sets
azure_container_registries = local.combined_objects_azure_container_registries
+ azuread_applications = local.combined_objects_azuread_applications
+ azuread_apps = local.combined_objects_azuread_apps
azuread_groups = local.combined_objects_azuread_groups
- azuread_apps = local.combined_objects_azuread_applications
+ azuread_service_principals = local.combined_objects_azuread_service_principals
azuread_users = local.combined_objects_azuread_users
azurerm_firewalls = local.combined_objects_azurerm_firewalls
dns_zones = local.combined_objects_dns_zones
@@ -48,14 +72,15 @@ locals {
logged_in = local.logged_in
machine_learning_workspaces = local.combined_objects_machine_learning
managed_identities = local.combined_objects_managed_identities
+ management_group = local.management_groups
mssql_databases = local.combined_objects_mssql_databases
mssql_elastic_pools = local.combined_objects_mssql_elastic_pools
mssql_managed_databases = local.combined_objects_mssql_managed_databases
mssql_managed_instances = local.combined_objects_mssql_managed_instances
mssql_servers = local.combined_objects_mssql_servers
mysql_servers = local.combined_objects_mysql_servers
- networking = local.combined_objects_networking
network_watchers = local.combined_objects_network_watchers
+ networking = local.combined_objects_networking
postgresql_servers = local.combined_objects_postgresql_servers
private_dns = local.combined_objects_private_dns
proximity_placement_groups = local.combined_objects_proximity_placement_groups
@@ -63,20 +88,23 @@ locals {
recovery_vaults = local.combined_objects_recovery_vaults
resource_groups = local.combined_objects_resource_groups
storage_accounts = local.combined_objects_storage_accounts
+ subscriptions = local.combined_objects_subscriptions
synapse_workspaces = local.combined_objects_synapse_workspaces
- subscriptions = tomap({ (var.current_landingzone_key) = merge(try(var.subscriptions, {}), { "logged_in_subscription" = { id = data.azurerm_subscription.primary.id } }) })
}
- logged_in = tomap({
- (var.current_landingzone_key) = {
- user = {
- rbac_id = local.client_config.logged_user_objectId
- }
- app = {
- rbac_id = local.client_config.logged_aad_app_objectId
+
+ logged_in = tomap(
+ {
+ (var.current_landingzone_key) = {
+ user = {
+ rbac_id = local.client_config.logged_user_objectId
+ }
+ app = {
+ rbac_id = local.client_config.logged_aad_app_objectId
+ }
}
}
- })
+ )
roles_to_process = {
for mapping in
@@ -103,9 +131,8 @@ locals {
]
]
]
- ) : format("%s_%s_%s", mapping.scope_key_resource, replace(mapping.role_definition_name, " ", "_"), mapping.object_id_key_resource) => mapping
+ ) : format("%s_%s_%s_%s", mapping.object_id_resource_type, mapping.scope_key_resource, replace(mapping.role_definition_name, " ", "_"), mapping.object_id_key_resource) => mapping
}
-
}
# The code transform this input format to
diff --git a/storage_account_queues.tf b/storage_account_queues.tf
new file mode 100644
index 0000000000..feaebe4d67
--- /dev/null
+++ b/storage_account_queues.tf
@@ -0,0 +1,12 @@
+module "storage_account_queues" {
+ source = "./modules/storage_account/queue"
+ for_each = local.storage.storage_account_queues
+ storage_account_name = module.storage_accounts[each.value.storage_account_key].name
+ settings = each.value
+
+}
+
+output "storage_account_queues" {
+ value = module.storage_account_queues
+
+}
\ No newline at end of file
diff --git a/subscriptions.tf b/subscriptions.tf
index d17b6146df..aac0ae8969 100755
--- a/subscriptions.tf
+++ b/subscriptions.tf
@@ -1,7 +1,6 @@
module "subscriptions" {
- source = "./modules/subscriptions"
- depends_on = [azurerm_role_assignment.for]
+ source = "./modules/subscriptions"
for_each = var.subscriptions
@@ -22,8 +21,9 @@ module "subscription_billing_role_assignments" {
keyvaults = local.combined_objects_keyvaults
settings = each.value
principals = {
- azuread_users = local.combined_objects_azuread_users
- managed_identities = local.combined_objects_managed_identities
+ azuread_users = local.combined_objects_azuread_users
+ managed_identities = local.combined_objects_managed_identities
+ azuread_service_principals = local.combined_objects_azuread_service_principals
}
}
diff --git a/variables.tf b/variables.tf
index d985ff2c7e..6d8d9bed71 100755
--- a/variables.tf
+++ b/variables.tf
@@ -18,12 +18,47 @@ variable "client_config" {
## Cloud variables
variable "cloud" {
- description = "Cloud configuration objects"
- default = {}
+ description = "Configuration object - Cloud resources defaults to Azure public, allows you to switch to other Azure endpoints."
+ default = {
+ acrLoginServerEndpoint = ".azurecr.io"
+ attestationEndpoint = ".attest.azure.net"
+ azureDatalakeAnalyticsCatalogAndJobEndpoint = "azuredatalakeanalytics.net"
+ azureDatalakeStoreFileSystemEndpoint = "azuredatalakestore.net"
+ keyvaultDns = ".vault.azure.net"
+ mariadbServerEndpoint = ".mariadb.database.azure.com"
+ mhsmDns = ".managedhsm.azure.net"
+ mysqlServerEndpoint = ".mysql.database.azure.com"
+ postgresqlServerEndpoint = ".postgres.database.azure.com"
+ sqlServerHostname = ".database.windows.net"
+ storageEndpoint = "core.windows.net"
+ storageSyncEndpoint = "afs.azure.net"
+ synapseAnalyticsEndpoint = ".dev.azuresynapse.net"
+ activeDirectory = "https://login.microsoftonline.com"
+ activeDirectoryDataLakeResourceId = "https://datalake.azure.net/"
+ activeDirectoryGraphResourceId = "https://graph.windows.net/"
+ activeDirectoryResourceId = "https://management.core.windows.net/"
+ appInsightsResourceId = "https://api.applicationinsights.io"
+ appInsightsTelemetryChannelResourceId = "https://dc.applicationinsights.azure.com/v2/track"
+ attestationResourceId = "https://attest.azure.net"
+ azmirrorStorageAccountResourceId = "null"
+ batchResourceId = "https://batch.core.windows.net/"
+ gallery = "https://gallery.azure.com/"
+ logAnalyticsResourceId = "https://api.loganalytics.io"
+ management = "https://management.core.windows.net/"
+ mediaResourceId = "https://rest.media.azure.net"
+ microsoftGraphResourceId = "https://graph.microsoft.com/"
+ ossrdbmsResourceId = "https://ossrdbms-aad.database.windows.net"
+ portal = "https://portal.azure.com"
+ resourceManager = "https://management.azure.com/"
+ sqlManagement = "https://management.core.windows.net:8443/"
+ synapseAnalyticsResourceId = "https://dev.azuresynapse.net"
+ vmImageAliasDoc = "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/arm-compute/quickstart-templates/aliases.json"
+ }
}
variable "tenant_id" {
description = "Azure AD Tenant ID for the current deployment."
+ type = string
default = null
}
@@ -54,10 +89,12 @@ variable "environment" {
variable "logged_user_objectId" {
description = "Used to set access policies based on the value 'logged_in_user'. Can only be used in interactive execution with vscode."
+ type = string
default = null
}
variable "logged_aad_app_objectId" {
description = "Used to set access policies based on the value 'logged_in_aad_app'"
+ type = string
default = null
}
@@ -74,90 +111,85 @@ variable "tags" {
}
variable "resource_groups" {
- description = "Resource groups configuration objects"
+ description = "Configuration object - Resource groups."
default = {}
}
variable "subscriptions" {
- default = {}
+ description = "Configuration object - Subscriptions resources."
+ default = {}
}
variable "subscription_billing_role_assignments" {
- default = {}
+ description = "Configuration object - subscription billing roleassignments."
+ default = {}
}
variable "billing" {
- description = "Billing information"
+ description = "Configuration object - Billing information."
default = {}
}
variable "remote_objects" {
- description = "Remote objects is used to allow the landing zone to retrieve remote tfstate objects and pass them to the caf module"
+ description = "Allow the landing zone to retrieve remote tfstate objects and pass them to the CAF module."
default = {}
}
## Diagnostics settings
variable "diagnostics_definition" {
default = null
- description = "Shared diadgnostics settings that can be used by the services to enable diagnostics"
+ description = "Configuration object - Shared diadgnostics settings that can be used by the services to enable diagnostics."
}
variable "diagnostics_destinations" {
- default = null
+ description = "Configuration object - Describes the destinations for the diagnostics."
+ default = null
}
variable "log_analytics" {
- default = {}
+ description = "Configuration object - Log Analytics resources."
+ default = {}
}
variable "diagnostics" {
- default = {}
+ description = "Configuration object - Diagnostics object."
+ default = {}
}
variable "event_hub_namespaces" {
- default = {}
+ description = "Configuration object - Diagnostics object."
+ default = {}
}
-variable "subnet_id" {
- default = {}
-}
+# variable "subnet_id" {
+# default = {}
+# }
variable "user_type" {
- description = "The rover set this value to user or serviceprincipal. It is used to handle Azure AD api consents."
+ description = "The rover set this value to user or serviceprincipal. It is used to handle Azure AD API consents."
default = {}
}
## Azure AD
-variable "azuread_apps" {
- default = {}
-}
-
-variable "azuread_groups" {
- default = {}
-}
-
-variable "azuread_roles" {
- default = {}
-}
-
-variable "azuread_users" {
- default = {}
+variable "azuread" {
+ description = "Configuration object - Azure Active Directory resources"
+ default = {}
}
-variable "azuread_api_permissions" {
- default = {}
-}
+# variable "azuread_api_permissions" {
+# default = {}
+# }
## Compute variables
variable "compute" {
- description = "Compute configuration objects"
+ description = "Configuration object - Azure compute resources"
default = {
virtual_machines = {}
}
}
variable "webapp" {
- description = "Web applications configuration objects"
+ description = "Configuration object - Web Applications"
default = {
# app_services = {}
# app_service_environments = {}
@@ -167,53 +199,60 @@ variable "webapp" {
}
variable "data_factory" {
- default = {}
+ description = "Configuration object - Azure Data Factory resources"
+ default = {}
}
variable "logic_app" {
- default = {}
+ description = "Configuration object - Azure Logic App resources"
+ default = {}
}
## Databases variables
variable "database" {
- description = "Database configuration objects"
+ description = "Configuration object - databases resources"
default = {}
}
## Networking variables
variable "networking" {
- description = "Networking configuration objects"
+ description = "Configuration object - networking resources"
default = {}
}
## Security variables
variable "security" {
- default = {}
+ description = "Configuration object - security resources"
+ default = {}
}
variable "managed_identities" {
- description = "Managed Identity configuration objects"
+ description = "Configuration object - Azure managed identity resources"
default = {}
}
variable "keyvaults" {
- description = "Key Vault configuration objects"
+ description = "Configuration object - Azure Key Vault resources"
default = {}
}
variable "keyvault_access_policies" {
- default = {}
+ description = "Configuration object - Azure Key Vault policies"
+ default = {}
}
variable "keyvault_access_policies_azuread_apps" {
- default = {}
+ description = "Configuration object - Azure Key Vault policy for azure ad applications"
+ default = {}
}
variable "custom_role_definitions" {
- description = "Custom role definitions configuration objects"
+ description = "Configuration object - Custom role definitions"
default = {}
}
+
variable "role_mapping" {
+ description = "Configuration object - Role mapping"
default = {
built_in_role_mapping = {}
custom_role_mapping = {}
@@ -226,19 +265,21 @@ variable "dynamic_keyvault_secrets" {
## Storage variables
variable "storage_accounts" {
- default = {}
+ description = "Configuration object - Storage account resources"
+ default = {}
}
variable "storage" {
- description = "Storage configuration objects"
+ description = "Configuration object - Storage account resources"
default = {}
}
variable "diagnostic_storage_accounts" {
- default = {}
+ description = "Configuration object - Storage account for diagnostics resources"
+ default = {}
}
# Shared services
variable "shared_services" {
- description = "Shared services configuration objects"
+ description = "Configuration object - Shared services resources"
default = {
# automations = {}
# monitoring = {}
@@ -246,61 +287,70 @@ variable "shared_services" {
}
}
-variable "virtual_network_gateways" {
- default = {}
-}
+# variable "virtual_network_gateways" {
+# default = {}
+# }
-variable "virtual_network_gateway_connections" {
- default = {}
-}
+# variable "virtual_network_gateway_connections" {
+# default = {}
+# }
-variable "shared_image_galleries" {
- default = {}
-}
+# variable "shared_image_galleries" {
+# default = {}
+# }
-variable "image_definitions" {
- default = {}
-}
+# variable "image_definitions" {
+# default = {}
+# }
-variable "packer_service_principal" {
- default = {}
-}
+# variable "packer_service_principal" {
+# default = {}
+# }
-variable "packer_managed_identity" {
- default = {}
-}
+# variable "packer_managed_identity" {
+# default = {}
+# }
variable "keyvault_certificate_issuers" {
- default = {}
-}
-variable "cosmos_dbs" {
- default = {}
+ description = "Configuration object - Azure Key Vault Certificate Issuers resources"
+ default = {}
}
+# variable "cosmos_dbs" {
+# default = {}
+# }
-variable "app_config" {
- default = {}
-}
+# variable "app_config" {
+# default = {}
+# }
-variable "local_network_gateways" {
- default = {}
-}
+# variable "local_network_gateways" {
+# default = {}
+# }
-variable "application_security_groups" {
- default = {}
-}
+# variable "application_security_groups" {
+# default = {}
+# }
variable "event_hubs" {
- default = {}
+ description = "Configuration object - Event Hub resources"
+ default = {}
}
variable "event_hub_auth_rules" {
- default = {}
+ description = "Configuration object - Event Hub authentication rules"
+ default = {}
}
variable "event_hub_namespace_auth_rules" {
- default = {}
+ description = "Configuration object - Event Hub namespaces authentication rules"
+ default = {}
}
variable "event_hub_consumer_groups" {
- default = {}
+ description = "Configuration object - Event Hub consumer group rules"
+ default = {}
}
+variable "random_strings" {
+ description = "Configuration object - Random string generator resources"
+ default = {}
+}
diff --git a/virtual_machines.tf b/virtual_machines.tf
index 322b71e5d7..abafcec583 100755
--- a/virtual_machines.tf
+++ b/virtual_machines.tf
@@ -14,7 +14,6 @@ module "virtual_machines" {
application_security_groups = local.combined_objects_application_security_groups
availability_sets = local.combined_objects_availability_sets
- base_tags = try(local.global_settings.inherit_tags, false) ? module.resource_groups[each.value.resource_group_key].tags : {}
# if boot_diagnostics_storage_account_key is points to a valid storage account, pass the endpoint
# if boot_diagnostics_storage_account_key is empty string, pass empty string
# if boot_diagnostics_storage_account_key not defined, pass null
@@ -26,16 +25,19 @@ module "virtual_machines" {
diagnostics = local.combined_diagnostics
disk_encryption_sets = local.combined_objects_disk_encryption_sets
global_settings = local.global_settings
- keyvaults = local.combined_objects_keyvaults
- location = lookup(each.value, "region", null) == null ? local.resource_groups[each.value.resource_group_key].location : local.global_settings.regions[each.value.region]
+ keyvaults = local.combined_objects_keyvaults
managed_identities = local.combined_objects_managed_identities
network_security_groups = local.combined_objects_network_security_groups
proximity_placement_groups = local.combined_objects_proximity_placement_groups
public_ip_addresses = local.combined_objects_public_ip_addresses
recovery_vaults = local.combined_objects_recovery_vaults
- resource_group_name = local.resource_groups[each.value.resource_group_key].name
settings = each.value
vnets = local.combined_objects_networking
+ dedicated_hosts = local.combined_objects_dedicated_hosts
+
+ resource_group_name = local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].name
+ location = lookup(each.value, "region", null) == null ? local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].location : local.global_settings.regions[each.value.region]
+ base_tags = try(local.global_settings.inherit_tags, false) ? local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][try(each.value.resource_group.key, each.value.resource_group_key)].tags : {}
}
diff --git a/virtual_machines_scale_sets.tf b/virtual_machines_scale_sets.tf
index c386ff181e..5cb13d16ee 100644
--- a/virtual_machines_scale_sets.tf
+++ b/virtual_machines_scale_sets.tf
@@ -1,6 +1,6 @@
-module virtual_machine_scale_sets {
+module "virtual_machine_scale_sets" {
source = "./modules/compute/virtual_machine_scale_set"
depends_on = [
module.availability_sets,
@@ -37,7 +37,7 @@ module virtual_machine_scale_sets {
}
-output virtual_machine_scale_sets {
+output "virtual_machine_scale_sets" {
value = module.virtual_machine_scale_sets
}
diff --git a/wvd_applications.tf b/wvd_applications.tf
new file mode 100644
index 0000000000..25514bbdca
--- /dev/null
+++ b/wvd_applications.tf
@@ -0,0 +1,14 @@
+module "wvd_applications" {
+ source = "./modules/compute/wvd_applications"
+ for_each = local.compute.wvd_applications
+
+ global_settings = local.global_settings
+ settings = each.value
+ application_group_id = try(local.combined_objects_wvd_application_groups[local.client_config.landingzone_key][each.value.application_group_key].id, local.combined_objects_wvd_application_groups[each.value.lz_key][each.value.application_group_key].id)
+ diagnostics = local.combined_diagnostics
+ diagnostic_profiles = try(each.value.diagnostic_profiles, {})
+}
+
+output "wvd_applications" {
+ value = module.wvd_applications
+}
\ No newline at end of file