diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index ce4d97d6d..5f6c5efea 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -6,7 +6,7 @@ version: '3.7' services: rover: - image: aztfmod/rover:1.1.3-2201.2106 + image: aztfmod/rover:1.1.6-2202.2503 user: vscode labels: diff --git a/.github/workflows/landingzones-tf100.yml b/.github/workflows/landingzones-tf100.yml index ed53e56d1..a38e9363b 100644 --- a/.github/workflows/landingzones-tf100.yml +++ b/.github/workflows/landingzones-tf100.yml @@ -39,7 +39,7 @@ jobs: random_length: ['5'] container: - image: aztfmod/rover:1.1.3-2201.2106 + image: aztfmod/rover:1.1.6-2202.2503 options: --user 0 steps: @@ -92,7 +92,7 @@ jobs: ] container: - image: aztfmod/rover:1.1.3-2201.2106 + image: aztfmod/rover:1.1.6-2202.2503 options: --user 0 steps: @@ -135,7 +135,7 @@ jobs: random_length: ['5'] container: - image: aztfmod/rover:1.1.3-2201.2106 + image: aztfmod/rover:1.1.6-2202.2503 options: --user 0 steps: @@ -186,7 +186,7 @@ jobs: ] container: - image: aztfmod/rover:1.1.3-2201.2106 + image: aztfmod/rover:1.1.6-2202.2503 options: --user 0 steps: @@ -228,7 +228,7 @@ jobs: random_length: ['5'] container: - image: aztfmod/rover:1.1.3-2201.2106 + image: aztfmod/rover:1.1.6-2202.2503 options: --user 0 steps: diff --git a/.github/workflows/landingzones-tf15.yml b/.github/workflows/landingzones-tf15.yml index 4722c3c46..81af3e1aa 100644 --- a/.github/workflows/landingzones-tf15.yml +++ b/.github/workflows/landingzones-tf15.yml @@ -33,7 +33,7 @@ jobs: random_length: ['5'] container: - image: aztfmod/rover:0.15.5-2201.2106 + image: aztfmod/rover:0.15.5-2202.2503 options: --user 0 steps: @@ -86,7 +86,7 @@ jobs: ] container: - image: aztfmod/rover:0.15.5-2201.2106 + image: aztfmod/rover:0.15.5-2202.2503 options: --user 0 steps: @@ -129,7 +129,7 @@ jobs: random_length: ['5'] container: - image: aztfmod/rover:0.15.5-2201.2106 + image: aztfmod/rover:0.15.5-2202.2503 options: --user 0 steps: @@ -180,7 +180,7 @@ jobs: ] container: - image: aztfmod/rover:0.15.5-2201.2106 + image: aztfmod/rover:0.15.5-2202.2503 options: --user 0 steps: @@ -222,7 +222,7 @@ jobs: random_length: ['5'] container: - image: aztfmod/rover:0.15.5-2201.2106 + image: aztfmod/rover:0.15.5-2202.2503 options: --user 0 steps: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5b8d832d2..5c8e56012 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See http://pre-commit.com/hooks.html for more hooks repos: - repo: git://github.com/antonbabenko/pre-commit-terraform - rev: v1.62.3 + rev: v1.64.0 hooks: - id: terraform_fmt - id: terraform_docs @@ -14,8 +14,13 @@ repos: hooks: - id: check-merge-conflict - id: trailing-whitespace - # - id: check-yaml + # - id: check-yaml + - id: detect-private-key - id: check-added-large-files + # - repo: git://github.com/ansible-community/ansible-lint + # rev: v5.3.2 + # hooks: + # - id: ansible-lint # - repo: git://github.com/markdownlint/markdownlint # rev: v0.9.0 # hooks: diff --git a/README.md b/README.md index 57663bcd9..1ff0861e8 100644 --- a/README.md +++ b/README.md @@ -6,46 +6,30 @@ Microsoft [Cloud Adoption Framework for Azure](https://docs.microsoft.com/azure/cloud-adoption-framework/overview) provides you with guidance and best practices to adopt Azure. -A landing zone is a segment of a cloud environment, that has been pre-provisioned through code, and is dedicated to the support of one or more workloads. Landing zones provide access to foundational tools and controls to establish a compliant place to innovate and build new workloads in the cloud, or to migrate existing workloads to the cloud. Landing zones use defined sets of cloud services and best practices to set you up for success. +CAF Terraform landing zones team mission statement is to: -We leverage Azure enterprise-scale landing zones and propose a Terraform-native structure, set of mechanisms and artifacts to get started to deploy workloads fast. - -You can review the different components parts of the Cloud Adoption Framework for Azure Terraform landing zones and look at the quick intro :vhs: below: - -[![caf_elements](./_pictures/caf_elements.png)](https://www.youtube.com/watch?v=FlQ17u4NNts "CAF Introduction") - -## Goals - -Cloud Adoption Framework for Azure Terraform landing zones is an open-source project equipping the Site Reliability Engineers on Azure with: - -* Reusable community artifacts. -* Standardize deployments using battlefield-proven components. -* Accelerate the setup of complex environments on Azure. +* Equip the Site Reliability Engineering teams for Terraform on Azure. +* Democratize an IaC: Infrastructure-as-Configuration. +* Commoditize state management and enterprise-wide composition. +* Standardize deployments using Azure enterprise-scale landing zones. * Implement Azure enterprise-scale design and approach with native Terraform and DevOps. * Propose a prescriptive guidance on how to enable DevOps for infrastructure as code on Microsoft Azure. -* Develop configuration-based "infrastructure-as-data" as a democratization of "infrastructure-as-code". +* Foster a community of Azure *Terraformers* using a common set of practices and sharing best practices. -## :rocket: Getting started -When starting an enterprise deployment, we recommend you start creating a configuration repository where you craft the configuration files for your environments. +You can review the different components parts of the Cloud Adoption Framework for Azure Terraform landing zones and look at the quick intro video below: -The best way to start is to clone the [starter repository](https://github.com/Azure/caf-terraform-landingzones-starter) and getting started with the configuration files, you can find a quick [onboarding video here](https://www.youtube.com/watch?v=M5BXm30IpdY) +[![caf_elements](./_pictures/caf_elements.png)](https://www.youtube.com/watch?v=FlQ17u4NNts "CAF Introduction") -## :books: Documentation -You can refer to our new integrated documentation: [GitHub Pages documentation](https://aztfmod.github.io/documentation) +## :rocket: Getting started -## Repositories +When starting an enterprise deployment, we recommend you start creating a configuration repository where you craft the configuration files for your environments. -In CAF Terraform landing zones, we use multiple projects in a modular way so you can leverage all of them or some of them depending on where you are in your DevOps and GitOps journey. The main repositories are listed below, feel free to evaluate, use them and contribute to them also! +The best way to start is to clone the [platform starter repository](https://github.com/Azure/caf-terraform-landingzones-platform-starter) and getting started with the configuration files. -| Repo | Description | -|---------------------------------------------------------------------------------------------------|------------------------------------------------------------| -| [starter kit](https://github.com/azure/caf-terraform-landingzones-starter) | landing zones configuration repository | -| [caf-terraform-landingzones](https://github.com/azure/caf-terraform-landingzones) (You are here!) | landing zones repo with sample and core documentations | -| [rover](https://github.com/aztfmod/rover) | devops toolset for operating landing zones | -| [azure_caf_provider](https://github.com/aztfmod/terraform-provider-azurecaf) | custom provider for naming conventions | -| [module](https://github.com/aztfmod/terraform-azurerm-caf) | CAF universal module available in the Terraform registry | +If you are reading this, you are probably interested also in reading the doc as below: +:books: Read our [centralized documentation page](https://aka.ms/caf/terraform) ## Community diff --git a/caf_launchpad/dynamic_secrets.tf b/caf_launchpad/dynamic_secrets.tf index 278997136..27a5a63d2 100644 --- a/caf_launchpad/dynamic_secrets.tf +++ b/caf_launchpad/dynamic_secrets.tf @@ -1,9 +1,9 @@ module "dynamic_keyvault_secrets" { source = "aztfmod/caf/azurerm//modules/security/dynamic_keyvault_secrets" - version = "5.5.1" + version = "5.5.4" - #source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git//modules/security/dynamic_keyvault_secrets?ref=master" + # source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git//modules/security/dynamic_keyvault_secrets?ref=patch.5.5.4" for_each = try(var.dynamic_keyvault_secrets, {}) diff --git a/caf_launchpad/landingzone.tf b/caf_launchpad/landingzone.tf index 64ce2a226..0a63a0460 100644 --- a/caf_launchpad/landingzone.tf +++ b/caf_launchpad/landingzone.tf @@ -1,9 +1,9 @@ module "launchpad" { source = "aztfmod/caf/azurerm" - version = "5.5.1" + version = "5.5.4" - - # source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git?ref=master" + # during dev cycles for the module, you can pick dev branches from GitHub, or from a local fork + # source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git?ref=patch.5.5.4" # source = "../../aztfmod" providers = { @@ -59,11 +59,12 @@ module "launchpad" { } networking = { - vnets = try(var.networking.vnets, var.vnets) + azurerm_routes = try(var.networking.azurerm_routes, var.azurerm_routes) + network_profiles = var.network_profiles network_security_group_definition = try(var.networking.network_security_group_definition, var.network_security_group_definition) public_ip_addresses = try(var.networking.public_ip_addresses, var.public_ip_addresses) - azurerm_routes = try(var.networking.azurerm_routes, var.azurerm_routes) route_tables = try(var.networking.route_tables, var.route_tables) + vnets = try(var.networking.vnets, var.vnets) } security = { diff --git a/caf_launchpad/variables.tf b/caf_launchpad/variables.tf index dfe7937a9..172fb0b2e 100644 --- a/caf_launchpad/variables.tf +++ b/caf_launchpad/variables.tf @@ -239,4 +239,8 @@ variable "propagate_launchpad_identities" { variable "container_groups" { default = {} +} + +variable "network_profiles" { + default = {} } \ No newline at end of file diff --git a/caf_solution/add-ons/caf_eslz/enterprise_scale.tf b/caf_solution/add-ons/caf_eslz/enterprise_scale.tf index d5e4237e6..3b21b9777 100644 --- a/caf_solution/add-ons/caf_eslz/enterprise_scale.tf +++ b/caf_solution/add-ons/caf_eslz/enterprise_scale.tf @@ -2,9 +2,9 @@ module "enterprise_scale" { source = "Azure/caf-enterprise-scale/azurerm" - version = "1.1.1" + version = "1.1.3" - # source = "../../../../eslz" + # source = "/tf/caf/alz" providers = { azurerm = azurerm @@ -12,7 +12,7 @@ module "enterprise_scale" { azurerm.management = azurerm } - root_parent_id = data.azurerm_client_config.current.tenant_id + root_parent_id = var.root_parent_id == null ? data.azurerm_client_config.current.tenant_id : var.root_parent_id default_location = local.global_settings.regions[local.global_settings.default_region] #path to the policies definition and assignment repo diff --git a/caf_solution/add-ons/caf_eslz/variables.tf b/caf_solution/add-ons/caf_eslz/variables.tf index 1e3ce879c..701bced5a 100644 --- a/caf_solution/add-ons/caf_eslz/variables.tf +++ b/caf_solution/add-ons/caf_eslz/variables.tf @@ -85,6 +85,12 @@ variable "root_name" { } } +variable "root_parent_id" { + type = string + description = "If specified, will deploy the Enterprise scale bellow the root_parent_id." + default = null +} + variable "deploy_core_landing_zones" { type = bool description = "If set to true, will include the core Enterprise-scale Management Group hierarchy." @@ -233,4 +239,4 @@ variable "reconcile_vending_subscriptions" { type = bool default = false description = "Will reconcile the subrisciptions created outside of enterprise scale to prevent them to be revoved by the execution of this module." -} \ No newline at end of file +} diff --git a/caf_solution/dynamic_secrets.tf b/caf_solution/dynamic_secrets.tf index e5185523b..f7bd289a7 100644 --- a/caf_solution/dynamic_secrets.tf +++ b/caf_solution/dynamic_secrets.tf @@ -1,8 +1,8 @@ module "dynamic_keyvault_secrets" { source = "aztfmod/caf/azurerm//modules/security/dynamic_keyvault_secrets" - version = "5.5.1" + version = "5.5.4" - #source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git//modules/security/dynamic_keyvault_secrets?ref=master" + # source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git//modules/security/dynamic_keyvault_secrets?ref=patch.5.5.4" for_each = { for keyvault_key, secrets in try(var.dynamic_keyvault_secrets, {}) : keyvault_key => { diff --git a/caf_solution/landingzone.tf b/caf_solution/landingzone.tf index 9899b41ae..6496b10e2 100644 --- a/caf_solution/landingzone.tf +++ b/caf_solution/landingzone.tf @@ -1,8 +1,9 @@ module "solution" { source = "aztfmod/caf/azurerm" - version = "5.5.1" + version = "5.5.4" - # source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git?ref=master" + # during dev cycles for the module, you can pick dev branches from GitHub, or from a local fork + # source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git?ref=patch.5.5.4" # source = "../../aztfmod" providers = { diff --git a/caf_solution/local.database.tf b/caf_solution/local.database.tf index 0bca77e4b..0dbc1dd59 100644 --- a/caf_solution/local.database.tf +++ b/caf_solution/local.database.tf @@ -26,6 +26,7 @@ locals { mysql_databases = var.mysql_databases mysql_servers = var.mysql_servers postgresql_servers = var.postgresql_servers + postgresql_flexible_servers = var.postgresql_flexible_servers synapse_workspaces = var.synapse_workspaces } ) diff --git a/caf_solution/local.networking.tf b/caf_solution/local.networking.tf index c27380a3f..f0bfeed6a 100644 --- a/caf_solution/local.networking.tf +++ b/caf_solution/local.networking.tf @@ -2,9 +2,9 @@ locals { networking = merge( var.networking, { - application_gateway_platforms = var.application_gateway_platforms - application_gateway_applications_v1 = var.application_gateway_applications_v1 application_gateway_applications = var.application_gateway_applications + application_gateway_applications_v1 = var.application_gateway_applications_v1 + application_gateway_platforms = var.application_gateway_platforms application_gateway_waf_policies = var.application_gateway_waf_policies application_gateways = var.application_gateways application_security_groups = var.application_security_groups @@ -15,8 +15,8 @@ locals { azurerm_firewall_policy_rule_collection_groups = var.azurerm_firewall_policy_rule_collection_groups azurerm_firewalls = var.azurerm_firewalls azurerm_routes = var.azurerm_routes - cdn_profiles = var.cdn_profiles cdn_endpoints = var.cdn_endpoints + cdn_profiles = var.cdn_profiles ddos_services = var.ddos_services dns_zone_records = var.dns_zone_records dns_zones = var.dns_zones @@ -46,10 +46,11 @@ locals { virtual_hubs = var.virtual_hubs virtual_network_gateway_connections = var.virtual_network_gateway_connections virtual_network_gateways = var.virtual_network_gateways + virtual_subnets = var.virtual_subnets virtual_wans = var.virtual_wans vnet_peerings = var.vnet_peerings vnets = var.vnets - virtual_subnets = var.virtual_subnets + vpn_gateway_connections = var.vpn_gateway_connections vpn_sites = var.vpn_sites } ) diff --git a/caf_solution/local.remote.tf b/caf_solution/local.remote.tf index 3817d6fd6..9a42943a0 100644 --- a/caf_solution/local.remote.tf +++ b/caf_solution/local.remote.tf @@ -86,6 +86,9 @@ locals { dns_zones = { for key, value in try(var.landingzone.tfstates, {}) : key => merge(try(data.terraform_remote_state.remote[key].outputs.objects[key].dns_zones, {})) } + domain_name_registrations = { + for key, value in try(var.landingzone.tfstates, {}) : key => merge(try(data.terraform_remote_state.remote[key].outputs.objects[key].domain_name_registrations, {})) + } event_hub_namespaces = { for key, value in try(var.landingzone.tfstates, {}) : key => merge(try(data.terraform_remote_state.remote[key].outputs.objects[key].event_hub_namespaces, {})) } diff --git a/caf_solution/variables.database.tf b/caf_solution/variables.database.tf index cdb357439..cabeaf701 100644 --- a/caf_solution/variables.database.tf +++ b/caf_solution/variables.database.tf @@ -71,6 +71,9 @@ variable "mysql_databases" { variable "mysql_servers" { default = {} } +variable "postgresql_flexible_servers" { + default = {} +} variable "postgresql_servers" { default = {} } diff --git a/caf_solution/vm_extensions.tf b/caf_solution/vm_extensions.tf index 9bb84b770..4f0c74cff 100644 --- a/caf_solution/vm_extensions.tf +++ b/caf_solution/vm_extensions.tf @@ -4,7 +4,7 @@ module "vm_extension_monitoring_agent" { source = "aztfmod/caf/azurerm//modules/compute/virtual_machine_extensions" - version = "5.5.1" + version = "5.5.4" #source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git//modules/compute/virtual_machine_extensions?ref=master" @@ -26,7 +26,7 @@ module "vm_extension_monitoring_agent" { module "vm_extension_diagnostics" { source = "aztfmod/caf/azurerm//modules/compute/virtual_machine_extensions" - version = "5.5.1" + version = "5.5.4" #source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git//modules/compute/virtual_machine_extensions?ref=master" @@ -51,7 +51,7 @@ module "vm_extension_diagnostics" { module "vm_extension_microsoft_azure_domainjoin" { source = "aztfmod/caf/azurerm//modules/compute/virtual_machine_extensions" - version = "5.5.1" + version = "5.5.4" #source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git//modules/compute/virtual_machine_extensions?ref=master" @@ -71,7 +71,7 @@ module "vm_extension_microsoft_azure_domainjoin" { module "vm_extension_session_host_dscextension" { source = "aztfmod/caf/azurerm//modules/compute/virtual_machine_extensions" - version = "5.5.1" + version = "5.5.4" #source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git//modules/compute/virtual_machine_extensions?ref=master" @@ -93,7 +93,7 @@ module "vm_extension_session_host_dscextension" { module "vm_extension_custom_scriptextension" { source = "aztfmod/caf/azurerm//modules/compute/virtual_machine_extensions" - version = "5.5.1" + version = "5.5.4" #source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git//modules/compute/virtual_machine_extensions?ref=master" @@ -104,10 +104,11 @@ module "vm_extension_custom_scriptextension" { if try(value.virtual_machine_extensions.custom_script, null) != null } - client_config = module.solution.client_config - virtual_machine_id = module.solution.virtual_machines[each.key].id - extension = each.value.virtual_machine_extensions.custom_script - extension_name = "custom_script" - managed_identities = merge(tomap({ (var.landingzone.key) = module.solution.managed_identities }), try(local.remote.managed_identities, {})) - storage_accounts = merge(tomap({ (var.landingzone.key) = module.solution.storage_accounts }), try(local.remote.storage_accounts, {})) -} \ No newline at end of file + client_config = module.solution.client_config + virtual_machine_id = module.solution.virtual_machines[each.key].id + virtual_machine_os_type = module.solution.virtual_machines[each.key].os_type + extension = each.value.virtual_machine_extensions.custom_script + extension_name = "custom_script" + managed_identities = merge(tomap({ (var.landingzone.key) = module.solution.managed_identities }), try(local.remote.managed_identities, {})) + storage_accounts = merge(tomap({ (var.landingzone.key) = module.solution.storage_accounts }), try(local.remote.storage_accounts, {})) +} diff --git a/caf_solution/vmss_extensions.tf b/caf_solution/vmss_extensions.tf index e82ecf21d..2ce0cf371 100644 --- a/caf_solution/vmss_extensions.tf +++ b/caf_solution/vmss_extensions.tf @@ -1,6 +1,6 @@ module "vmss_extension_microsoft_azure_domainjoin" { source = "aztfmod/caf/azurerm//modules/compute/virtual_machine_scale_set_extensions" - version = "5.5.1" + version = "5.5.4" # source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git//modules/compute/virtual_machine_scale_set_extensions?ref=master" @@ -21,7 +21,7 @@ module "vmss_extension_microsoft_azure_domainjoin" { module "vmss_extension_custom_scriptextension" { source = "aztfmod/caf/azurerm//modules/compute/virtual_machine_scale_set_extensions" - version = "5.5.1" + version = "5.5.4" # source = "git::https://github.com/aztfmod/terraform-azurerm-caf.git//modules/compute/virtual_machine_scale_set_extensions?ref=master" diff --git a/rover_on_ssh_host.yml b/rover_on_ssh_host.yml index 958a7824b..ea73d966f 100644 --- a/rover_on_ssh_host.yml +++ b/rover_on_ssh_host.yml @@ -11,7 +11,7 @@ version: '3.7' services: rover: - image: aztfmod/rover:1.1.3-2201.2106 + image: aztfmod/rover:1.1.6-2202.2503 user: vscode diff --git a/templates/applications/action_plugins/__pycache__/merge_vars.cpython-39.pyc b/templates/ansible/action_plugins/__pycache__/merge_vars.cpython-39.pyc similarity index 95% rename from templates/applications/action_plugins/__pycache__/merge_vars.cpython-39.pyc rename to templates/ansible/action_plugins/__pycache__/merge_vars.cpython-39.pyc index fdb1cae7f..a0f3b5a62 100644 Binary files a/templates/applications/action_plugins/__pycache__/merge_vars.cpython-39.pyc and b/templates/ansible/action_plugins/__pycache__/merge_vars.cpython-39.pyc differ diff --git a/templates/applications/action_plugins/merge_vars.py b/templates/ansible/action_plugins/merge_vars.py similarity index 100% rename from templates/applications/action_plugins/merge_vars.py rename to templates/ansible/action_plugins/merge_vars.py diff --git a/templates/ansible/ansible.yaml b/templates/ansible/ansible.yaml new file mode 100644 index 000000000..b3d70eb01 --- /dev/null +++ b/templates/ansible/ansible.yaml @@ -0,0 +1,137 @@ +- name: Process deployment based on ignite.yaml + hosts: localhost + + tasks: + + - name: "Set variables" + set_fact: + job_cache_base_path: "/home/vscode/.terraform.cache" + destination_base_path: '{{ platform_configuration_folder }}' + resource_template_folder: "{{ public_templates_folder }}/resources" + platform_service_folder: "{{ public_templates_folder }}/platform/services" + + - name: "load {{ template_folder | default(platform_definition_folder)}}/ignite.yaml" + include_vars: + name: bootstrap + dir: "{{ template_folder | default(platform_definition_folder)}}" + depth: 1 + ignore_unknown_extensions: true + files_matching: "ignite.yaml" + + - name: "load _variables files" + include_vars: + name: variables + dir: "{{ template_folder | default(platform_service_folder)}}" + depth: 1 + ignore_unknown_extensions: true + files_matching: "_variables" + + - name: "Load variable for {{deployment_mode}} config from {{definition_folder}}" + include_vars: + name: asvm_resource__to_merge + dir: "{{definition_folder | default(platform_definition_folder)}}" + depth: 0 + # ignore_unknown_extensions: true + files_matching: ".yaml" + when: deployment_mode == 'asvm' + + - name: "Load variable for ignite.yaml config from {{platform_definition_folder}}" + include_vars: + name: ignite_resource__to_merge + dir: "{{platform_definition_folder}}" + depth: 0 + files_matching: "ignite.yaml" + when: deployment_mode == 'asvm' + + - name: "Load variable for tfstates.yaml config from {{platform_definition_folder}}" + include_vars: + name: tfstates_resource__to_merge + dir: "{{platform_definition_folder}}" + depth: 0 + files_matching: "tfstates.yaml" + when: deployment_mode == 'asvm' + + - name: "Load variable for platform config from {{platform_definition_folder}}" + include_vars: + name: platform_resource__to_merge + dir: "{{platform_definition_folder | default(template_folder)}}" + depth: 0 + ignore_unknown_extensions: true + files_matching: ".yaml" + when: deployment_mode == 'platform' + + - name: Merge resources variables + merge_vars: + suffix_to_merge: _resource__to_merge + merged_var_name: merged_resources + expected_type: 'dict' + recursive_dict_merge: True + + - set_fact: + resources: "{{ merged_resources }}" + + - name: "Creates destination directory - {{destination_base_path}}" + file: + path: "{{destination_base_path}}" + state: directory + + - debug: + msg: + - "bootstrap: {{bootstrap}}" + - "resources: {{resources}}" + +# +# Generate the foundation services +# + + - name: Process core deployments + include_tasks: "process_regions.yaml" + loop: "{{bootstrap.deployments[deployment_mode].root.keys()}}" + loop_control: + loop_var: region + vars: + lz_type: "{{deployment_mode}}" + stage: root + + - name: Process alz deployments + include_tasks: "process_regions.yaml" + loop: "{{bootstrap.deployments[deployment_mode].alz.keys()}}" + loop_control: + loop_var: region + when: + - bootstrap.deployments[deployment_mode].alz is defined and launchpad_tfstate_exists.rc == 0 + vars: + lz_type: "{{deployment_mode}}" + stage: alz + +# +# Process the deployments folders +# + + - find: + paths: "{{definition_folder | default(platform_definition_folder)}}/scale_out_domains" + recurse: yes + patterns: "*.yaml" + file_type: file + register: files_to_process + + - name: "Process deployments" + include_tasks: "process_regions.yaml" + loop: "{{bootstrap.deployments[deployment_mode].scale_out_domains.keys()}}" + loop_control: + loop_var: region + when: + - bootstrap.deployments[deployment_mode].scale_out_domains is defined + - (launchpad_tfstate_exists is defined and launchpad_tfstate_exists.rc == 0) or (storage_account_level3 is defined and storage_account_level3.rc == 0) + vars: + lz_type: "{{deployment_mode}}" + stage: scale_out_domains + + +# +# Formatting & Linters +# + + - name: Terraform Formatting + shell: | + terraform fmt -recursive {{ destination_base_path }} diff --git a/templates/ansible/asvm_definition.yaml b/templates/ansible/asvm_definition.yaml new file mode 100644 index 000000000..2c84d92e0 --- /dev/null +++ b/templates/ansible/asvm_definition.yaml @@ -0,0 +1,70 @@ +- name: Process deployment based on ignite.yaml + hosts: localhost + + tasks: + + - debug: + msg: "{{landingzone_definition}}" + + - set_fact: + scale_out_domains: "{{scale_out_domains_input.split(',') }}" + + - name: Load templates + set_fact: + subscriptions_asvm: "{{ lookup('template', '{{ template_folder }}/subscriptions.asvm.yaml') }}" + tfstates: "{{ lookup('template', '{{ template_folder }}/tfstates.asvm.yaml') }}" + + - name: Load resources template + set_fact: + resources_{{env}}: "{{ lookup('template', '{{ template_folder }}/resources.asvm.yaml') }}" + loop: "{{scale_out_domains}}" + loop_control: + loop_var: env + + - debug: + msg: + - "subscriptions_asvm: {{subscriptions_asvm}}" + - "tfstates: {{tfstates}}" + + - debug: + msg: + - "{{'resources_' + env}}: {{lookup('vars', 'resources_' + env)}}" + loop: "{{scale_out_domains}}" + loop_control: + loop_var: env + +# +# Create definition folder structure +# + + - name: "Creates definition directory - {{definition_folder}}" + file: + path: "{{definition_folder}}" + state: directory + + - name: "definition - tfstates" + copy: + content: "{{ tfstates }}" + dest: "{{ definition_folder }}/tfstates.asvm.yaml" + + - name: "definition - subscriptions_asvm" + copy: + content: "{{ subscriptions_asvm }}" + dest: "{{ definition_folder }}/subscriptions.asvm.yaml" + + - name: "definition - resources" + copy: + content: "{{lookup('vars', 'resources_' + env)}}" + dest: "{{ definition_folder }}/{{landingzone_definition}}_{{env}}.asvm.yaml" + loop: "{{scale_out_domains}}" + loop_control: + loop_var: env + + - name: "definition - readme" + ansible.builtin.template: + src: "{{ topology_folder }}/readme_definition.md" + dest: "{{ definition_folder }}/readme.md" + + - debug: + msg: + - "next steps: {{definition_folder}}/readme.md" \ No newline at end of file diff --git a/templates/ansible/load_alz.yaml b/templates/ansible/load_alz.yaml new file mode 100644 index 000000000..d9e1a4149 --- /dev/null +++ b/templates/ansible/load_alz.yaml @@ -0,0 +1,7 @@ + +- include_tasks: "load_deployments_alz.yaml" + loop: "{{topology.deployments[deployment_mode][stage][region].keys()}}" + loop_control: + loop_var: service + when: stage == 'alz' + diff --git a/templates/ansible/load_deployments.yaml b/templates/ansible/load_deployments.yaml new file mode 100644 index 000000000..c4a87afaf --- /dev/null +++ b/templates/ansible/load_deployments.yaml @@ -0,0 +1,50 @@ +- debug: + msg: + - "{{deployment_mode}}" + - "{{stage}}" + - "{{region}}" + - "topology: {{topology}}" + +- name: "Process 1 deployment file {{stage}}/{{region}}" + set_fact: + "{{stage}}_{{region}}_{{item}}_deployment__to_merge": "{{ lookup('template', '{{ platform_service_folder + \"/\" + topology.deployments[deployment_mode][stage][region][item]}}') | from_yaml }}" + loop: "{{topology.deployments[deployment_mode][stage][region].keys()}}" + when: + - stage == 'root' or stage == 'alz' + - topologies is not defined + +- name: "Copy file {{stage}} from {{platform_service_folder}}" + ansible.builtin.template: + src: "{{platform_service_folder}}/{{topology.deployments[deployment_mode][stage][region][item]}}" + dest: "{{destination_path}}/{{topologies[item].tfstate.config_file}}" + loop: "{{topology.deployments[deployment_mode][stage][region].keys()}}" + when: + - stage == 'root' + - topologies is defined + +- name: "Copy file {{stage}} from {{platform_service_folder}}" + ansible.builtin.template: + src: "{{platform_service_folder}}/{{topology.deployments[deployment_mode][stage][region][item]}}" + dest: "{{destination_path}}/{{topologies[stage + '_' + item].tfstate.config_file}}" + loop: "{{topology.deployments[deployment_mode][stage][region].keys()}}" + when: + - stage == 'alz' + - topologies is defined + + +- name: "Process 2 deployment file {{stage}}" + include_tasks: "load_deployments_alz.yaml" + loop: "{{topology.deployments[deployment_mode][stage][region].keys()}}" + loop_control: + loop_var: service + when: + - stage == 'alz' + - topologies is defined + +- name: "Process 2 deployment file {{stage}}" + include_tasks: "load_deployments_env.yaml" + loop: "{{topology.deployments[deployment_mode][stage][region].keys()}}" + loop_control: + loop_var: service + when: + - stage == 'scale_out_domains' diff --git a/templates/ansible/load_deployments_alz.yaml b/templates/ansible/load_deployments_alz.yaml new file mode 100644 index 000000000..a5e06c096 --- /dev/null +++ b/templates/ansible/load_deployments_alz.yaml @@ -0,0 +1,77 @@ +- debug: + msg: + - "{{deployment_mode}}" + - "{{stage}}" + - "{{region}}" + - "{{service}}" + +- name: "{{destination_alz_path}} - Set tfstate_object" + set_fact: + tfstate_object: "{{topologies['alz_' + service].tfstate}}" + +- name: "{{destination_path}}/{{stage}} - Set landingzone file_path" + set_fact: + destination_alz_path: "{{destination_path}}/{{stage}}/{{service}}" + alz_template_folder: "{{public_templates_folder}}/{{ tfstate_object.template_lib_folder}}" + +- name: "{{destination_alz_path}} - Set landingzone file_path" + set_fact: + template_lib_folder: "{{alz_template_folder}}/lib/{{ tfstate_object.alz_version }}" + +- name: "{{destination_alz_path}} - Set landingzone file_path" + set_fact: + mg: "{{ lookup('template', '{{ template_lib_folder }}/archetype_config_overrides.caf.platform.yaml') | from_yaml }}" + mg_custom: "{{ lookup('template', '{{ template_lib_folder }}/custom_landing_zones.caf.platform.yaml') | from_yaml }}" + +- debug: + msg: "{{destination_alz_path}}" + +- name: "Clean-up destination directory" + shell: | + rm -rf "{{ destination_alz_path }}" + when: + - topology.management_groups[region][service].clean_up_destination_folder | default(True) + +- name: "Creates directory structure - {{template_lib_folder}}" + shell: mkdir -p "{{ destination_alz_path }}/lib/{{ item.path }}" + with_filetree: "{{ template_lib_folder }}" + when: + - item.state == 'directory' + +- name: " Lib" + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ destination_alz_path }}/lib/{{ item.path }}" + force: yes + with_filetree: "{{ template_lib_folder }}" + when: + - item.state == 'file' + - item.path is not search(".j2") + - item.path is not search(".yaml") or item.path is search(".json") or item.path is search(".md") + - topology.management_groups[region][service].update_lib_folder | default(False) + + +- name: " Lib" + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ destination_alz_path }}/{{ item.path }}" + force: yes + with_filetree: "{{ template_lib_folder }}" + when: + - item.state == 'file' + - item.path is search(".yaml") + - topology.management_groups[region][service].update_lib_folder | default(False) + +# - name: "{{deployment_mode}}/{{stage}}/{{region}}/{{service}} to {{destination_path}}/{{'alz_' + service}}.yaml" +# ansible.builtin.template: +# src: "{{ lookup('template', '{{ platform_service_folder + \"/\" + topology.deployments[deployment_mode][stage][region][service]}}') | from_yaml }}" +# dest: "{{destination_path}}/{{'alz_' + service}}.yaml" +# force: yes +# vars: +# item: "{{service}}" + +- name: "{{deployment_mode}}/{{stage}}/{{region}}/{{service}} to {{destination_path}}/{{'alz_' + service}}.yaml" + ansible.builtin.template: + src: "{{platform_service_folder}}/{{topology.deployments[deployment_mode][stage][region][item]}}" + dest: "{{destination_path}}/{{topologies[stage + '_' + item].tfstate.config_file}}" + loop: "{{topology.deployments[deployment_mode][stage][region].keys()}}" \ No newline at end of file diff --git a/templates/ansible/load_deployments_env.yaml b/templates/ansible/load_deployments_env.yaml new file mode 100644 index 000000000..0c197a12d --- /dev/null +++ b/templates/ansible/load_deployments_env.yaml @@ -0,0 +1,38 @@ +- debug: + msg: + - "{{deployment_mode}}" + - "{{stage}}" + - "{{region}}" + - "{{service}}" + +- name: "Process 3 deployment file {{stage}}/{{service}}" + set_fact: + "{{service}}_{{env}}_deployment__to_merge": "{{ lookup('template', '{{ platform_service_folder + \"/\" + topology.deployments[deployment_mode][stage][region][service][env]}}') | from_yaml }}" + loop: "{{topology.deployments[deployment_mode][stage][region][service].keys()}}" + loop_control: + loop_var: env + when: + - topologies is not defined + + +- name: "Creates directory" + file: + path: "{{destination_path}}/{{stage}}/{{env}}" + state: directory + loop: "{{topology.deployments[deployment_mode][stage][region][service].keys()}}" + loop_control: + loop_var: env + when: + - topologies is defined + +- name: "Copy file {{stage}}/{{service}}" + ansible.builtin.template: + src: "{{platform_service_folder}}/{{topology.deployments[deployment_mode][stage][region][service][env]}}" + dest: "{{destination_path}}/{{stage}}/{{env}}/{{topologies[service + '_' + env].tfstate.config_file}}" + loop: "{{topology.deployments[deployment_mode][stage][region][service].keys()}}" + loop_control: + loop_var: env + when: + - topologies is defined + + diff --git a/templates/ansible/load_regions.yaml b/templates/ansible/load_regions.yaml new file mode 100644 index 000000000..72fa0a100 --- /dev/null +++ b/templates/ansible/load_regions.yaml @@ -0,0 +1,22 @@ +- include_tasks: "load_deployments.yaml" + loop: "{{topology.deployments[deployment_mode][stage].keys()}}" + loop_control: + loop_var: region + when: stage != 'alz' + +- include_tasks: "load_deployments.yaml" + loop: "{{topology.deployments[deployment_mode][stage].keys()}}" + loop_control: + loop_var: region + when: + - stage == 'alz' + - topologies is not defined + +- include_tasks: "load_alz.yaml" + loop: "{{topology.deployments[deployment_mode][stage].keys()}}" + loop_control: + loop_var: region + when: + - stage == 'alz' + - topologies is defined + diff --git a/templates/ansible/process_deployments.yaml b/templates/ansible/process_deployments.yaml new file mode 100644 index 000000000..38a14f354 --- /dev/null +++ b/templates/ansible/process_deployments.yaml @@ -0,0 +1,13 @@ + +- debug: + msg: + - "{{deployment_mode}}" + - "{{region}}" + - "{{tfstate}}" + + +- name: "Including tasks process_tfstate.yaml" + include_tasks: "process_tfstate.yaml" + loop: "{{bootstrap.deployments[deployment_mode].scale_out_domains[region][tfstate].keys()}}" + loop_control: + loop_var: env \ No newline at end of file diff --git a/templates/ansible/process_regions.yaml b/templates/ansible/process_regions.yaml new file mode 100644 index 000000000..fe0483643 --- /dev/null +++ b/templates/ansible/process_regions.yaml @@ -0,0 +1,19 @@ +- debug: + msg: + - "{{deployment_mode}}" + - "{{lz_type}}" + - "{{stage}}" + +- name: Process core deployments + include_tasks: "process_stages.yaml" + loop: "{{bootstrap.deployments[deployment_mode][stage][region].keys()}}" + loop_control: + loop_var: tfstate + when: stage != 'scale_out_domains' + +- name: Process core deployments + include_tasks: "process_deployments.yaml" + loop: "{{bootstrap.deployments[deployment_mode][stage][region].keys()}}" + loop_control: + loop_var: tfstate + when: stage == 'scale_out_domains' diff --git a/templates/ansible/process_resources.yaml b/templates/ansible/process_resources.yaml new file mode 100644 index 000000000..beca98235 --- /dev/null +++ b/templates/ansible/process_resources.yaml @@ -0,0 +1,30 @@ +- name: "resources - {{resource_type}} - check file to process" + stat: + path: "{{ansible_to_process}}/{{resource_type}}.tfvars.j2" + register: override_file + +- name: "{{deployment}} - Set resource_type file_path" + set_fact: + resource_type_template: "{{resource_template_folder}}/{{resource_type}}.tfvars.j2" + resource_type_override: "{{ansible_to_process }}/{{resource_type}}.tfvars.j2" + verbosity: 2 + +- debug: + msg: + - "resource_type_template for {{resource_type_template}}" + - "{{resource_type_override}}" + - "{{override_file}}" + verbosity: 2 + + +# +# resources +# +- name: "resources - {{resource_type}}" + ansible.builtin.template: + src: "{{ item }}" + dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" + force: yes + with_fileglob: + - "{{resource_type_override if override_file.stat.exists else resource_type_template}}" + diff --git a/templates/ansible/process_stages.yaml b/templates/ansible/process_stages.yaml new file mode 100644 index 000000000..8307079ee --- /dev/null +++ b/templates/ansible/process_stages.yaml @@ -0,0 +1,34 @@ + +- debug: + msg: + - "tfstate {{tfstate}}" + - "{{lz_type}}" + - "{{stage}}" + - "{{region}}" + - "{{tfstate}}" + +- name: "Set tfstate_object" + set_fact: + tfstate_object: "{{resources.tfstates[lz_type]['alz_' + tfstate] if stage == 'alz' else resources.tfstates[lz_type][tfstate] }}" + env: '' + +- name: "Set config_folder" + set_fact: + config_folder: '{{ tfstate_object.sub_template_folder | default() }}' + +- debug: + msg: + - "{{lz_type}}" + - "{{tfstate}}" + - "{{tfstate_object}}" + - "{{config_folder}}" + verbosity: 2 + +- name: "Including tasks process_tfstate.yaml" + include_tasks: "process_tfstate.yaml" + loop: ["{{tfstate}}"] + loop_control: + loop_var: deployment + vars: + config_file: "{{config_folder + '/' + tfstate_object.config_file }}" + when: stage != 'scale_out_domains' diff --git a/templates/ansible/process_subscription_resources.yaml b/templates/ansible/process_subscription_resources.yaml new file mode 100644 index 000000000..38278ea07 --- /dev/null +++ b/templates/ansible/process_subscription_resources.yaml @@ -0,0 +1,86 @@ + +- debug: + msg: + - "subscription_key {{subscription_key}}" + - "{{deployment_mode}}" + - "{{tfstate}}" + - "{{env}}" + +- name: "{{deployment_mode}} - Set ansible_to_process" + set_fact: + ansible_to_process: "{{public_templates_folder + '/' + tfstate_object.sub_template_folder if tfstate_object.sub_template_folder is defined else public_templates_folder + '/platform/generic'}}" + tfstate_resource: "{{ 'alz_' + tfstate if stage == 'alz' else tfstate if env == '' else tfstate + '_' + env }}" + verbosity: 2 + + +- debug: + msg: + - "{{env}}" + - "{{tfstate_resource}}" + + +- name: "{{tfstate_resource}} - Set landingzone file_path" + set_fact: + landingzone_template: "{{resource_template_folder}}/landingzone.tfvars.j2" + landingzone_override: "{{ansible_to_process}}/landingzone.tfvars.j2" + destination_path: "{{destination_base_path}}/{{resources['alz_' + tfstate].relative_destination_folder if stage == 'alz' else resources[tfstate_resource].relative_destination_folder}}" + level: "{{tfstate_object.level}}" + verbosity: 2 + + +- name: "[{{tfstate_resource}}] - landingzone - check overrides to process in {{ansible_to_process}}" + stat: + path: "{{landingzone_override}}" + register: landingzone_override_file + + +- name: "[{{tfstate_resource}}] - landingzone - Clean-up directory" + file: + path: "{{destination_path}}" + state: absent + when: resources.configuration_folders[deployment_mode].cleanup_destination | default(true) + +- name: "[{{tfstate_resource}}] - landingzone - Creates directory" + file: + path: "{{destination_path}}" + state: directory + + + +- name: "{{tfstate_resource}} - process custom yaml process" + include_tasks: "{{public_templates_folder}}/{{tfstate_object.yaml}}" + when: tfstate_object.yaml is defined + +# +# landingzone.tfvars +# +- name: "{{tfstate_resource}} - landingzone" + ansible.builtin.template: + src: "{{ item }}" + dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" + force: yes + with_fileglob: + - "{{landingzone_override if landingzone_override_file.stat.exists else landingzone_template}}" + +# +# Resources +# + +- name: "{{tfstate_resource}} - process resources" + include_tasks: "process_resources.yaml" + loop: "{{resources[tfstate_resource].resources[subscription_key] | list if resources[tfstate_resource].resources[subscription_key] is mapping else [] }}" + loop_control: + loop_var: resource_type + +# +# overrides +# +- name: "[{{tfstate_resource}} - {{resources[tfstate_resource].relative_destination_folder}}] - resources - overrides from path {{ ansible_to_process }} to {{ destination_path }}" + ansible.builtin.template: + src: "{{ item }}" + dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" + force: yes + with_fileglob: + - "{{ ansible_to_process }}/*.j2" + - "{{ ansible_to_process }}/*.md" + diff --git a/templates/ansible/process_tfstate.yaml b/templates/ansible/process_tfstate.yaml new file mode 100644 index 000000000..36908567e --- /dev/null +++ b/templates/ansible/process_tfstate.yaml @@ -0,0 +1,31 @@ +- debug: + msg: + - "{{deployment_mode}}" + - "{{stage}}" + - "{{tfstate}}" + - "{{env}}" + + +- name: "Set tfstate_object" + set_fact: + tfstate_object: "{{resources.tfstates[deployment_mode]['alz_' + tfstate] if stage == 'alz' else resources.tfstates[deployment_mode][tfstate] if env == '' else resources.tfstates[deployment_mode][tfstate][env]}}" + +- name: "Verify {{deployment_mode}}/{{stage}}/{{tfstate}}/{{env | default('')}} is defined under tfstates/{{deployment_mode}} in {{platform_definition_folder}}/tfstates.yaml :" + debug: + msg: + - "{{tfstate_object}}" + +- name: "{{deployment_mode}} - tfstate_object sub_template_folder- {{env | default('')}}" + debug: + msg: + - 'sub_template_folder - {{tfstate_object.sub_template_folder | default()}}' + - 'tfstate_object - {{tfstate_object}}' + # - "{{resources}}" + +- name: "{{deployment_mode}}/{{stage}}/{{tfstate}} - process subscription resources" + include_tasks: "process_subscription_resources.yaml" + loop: "{{resources['alz_' + tfstate].resources.keys() if stage == 'alz' else resources[tfstate].resources.keys() if env == '' else resources[tfstate + '_' + env].resources.keys() }}" + loop_control: + loop_var: subscription_key + vars: + level: "{{tfstate_object.level}}" diff --git a/templates/ansible/walk-through-single.yaml b/templates/ansible/walk-through-single.yaml new file mode 100644 index 000000000..f6160614d --- /dev/null +++ b/templates/ansible/walk-through-single.yaml @@ -0,0 +1,61 @@ +# +# Initial script to select a topology and create the base templates for the definitions folder +# +# ansible-playbook /tf/caf/landingzones/templates/platform/walk-through-single.yaml \ +# -e topology_file=/tf/caf/landingzones/templates/platform/alz_single_subscription.yaml \ +# -e config_folder_platform_templates=/tf/caf/landingzones/templates/platform \ +# -e landingzones_folder=/tf/caf/landingzones \ +# -e destination_base_path=/tf/caf \ +# -e definitions_relative_path=definitions/v1 \ +# -e configuration_relative_path=configuration/demo +# + +- name: Setup platform template repository + hosts: localhost + vars_prompt: + - name: customer_name + prompt: Set the short version of your customer name with no spaces + private: no + default: contoso + + - name: caf_environment + prompt: Set the CAF Environment value + private: no + default: contoso + + - name: prefix + prompt: Set the prefix to add to all resource. + private: no + default: caf + + - name: alz_mg_prefix + prompt: Management group prefix (value must be between 2 to 10 characters long and can only contain alphanumeric characters and hyphens). + private: no + default: es + + - name: alz_mg_name + prompt: Management group name + private: no + default: Contoso + + - name: default_email_address + prompt: Email address to send all notifications + private: no + default: email@address.com + + - name: azure_regions + prompt: Azure regions (lowercase, short version) + private: no + default: + region1: southeastasia + region2: eastasia + + - name: default_region_key + prompt: Default CAF Azure region key + private: no + default: region1 + + + tasks: + + - include_tasks: "walk-through.yaml" diff --git a/templates/ansible/walk-through.yaml b/templates/ansible/walk-through.yaml new file mode 100644 index 000000000..e4f73cceb --- /dev/null +++ b/templates/ansible/walk-through.yaml @@ -0,0 +1,147 @@ +# +# Get launchpad subscription details +# + +- name: Get deployment user object_id (make sure you are logged-in to the launchpad Azure subscription first.) + shell: az ad signed-in-user show --query objectId -o tsv + register: object_id + +- name: Get deployment user UPN + shell: az ad signed-in-user show --query userPrincipalName -o tsv + register: upn + +- name: Get default user's tenant name + shell: az rest --method get --url "https://graph.microsoft.com/v1.0/organization" --query "value[0].verifiedDomains[?isDefault].name" -o tsv + register: tenant_name + +- name: Get default user's tenant guid + shell: az account show --query tenantId -o tsv + register: tenant_id + +- name: Get default subscription id + shell: az account show --query id -o tsv + register: subscription_id + +- name: Get default subscription name + shell: az account show --query name -o tsv + register: subscription_name + + +- set_fact: + regions: "{{ azure_regions }}" + deployment_mode: "platform" + topology: "{{bootstrap | default()}}" + +- set_fact: + topology: "{{ lookup('template', '{{ topology_file }}') | from_yaml }}" + destination_path: "{{definition_folder | default(platform_definition_folder)}}" + resource_template_folder: "{{ public_templates_folder }}/resources" + platform_service_folder: "{{ public_templates_folder }}/platform/services" + public_templates_variables_folder: "{{ public_templates_folder }}/variables" + +- name: "Creates directory - {{destination_path}}" + file: + path: "{{destination_path}}" + state: directory + +# +# Load the files into variables +# +- name: "load _variables files" + include_vars: + name: variables + dir: "{{ public_templates_variables_folder}}" + depth: 1 + ignore_unknown_extensions: true + files_matching: "_variables" + + +- debug: + msg: + - "variables: {{variables}}" + - "{{topology}}" + +- include_tasks: "load_regions.yaml" + loop: "{{topology.deployments[deployment_mode].keys()}}" + loop_control: + loop_var: stage + +- name: Merge deployment files into topologies variable + merge_vars: + suffix_to_merge: _deployment__to_merge + merged_var_name: merged_topologies + expected_type: 'dict' + recursive_dict_merge: True + +- name: "Topologies merged" + set_fact: + topologies: "{{ merged_topologies }}" + +# Need topologies to render the following templates +- name: "load tfstates" + set_fact: + "tfstates_deployment__to_merge": "{{ lookup('template', '{{platform_service_folder}}/tfstates.yaml') | from_yaml }}" + +- name: Merge deployment files into topologies variable + merge_vars: + suffix_to_merge: _deployment__to_merge + merged_var_name: merged_topologies + expected_type: 'dict' + recursive_dict_merge: True + +- set_fact: + topologies: "{{ merged_topologies }}" + +- debug: + msg: "topologies: {{topologies}}" + +# +# Generate target folder structure and files +# + +- name: Copy files + include_tasks: "load_regions.yaml" + loop: "{{topology.deployments[deployment_mode].keys()}}" + loop_control: + loop_var: stage + +- find: + paths: "{{public_templates_variables_folder}}" + recurse: no + patterns: "_variables*.yaml" + file_type: file + register: variable_files_to_process + +- name: copy variables files + ansible.builtin.copy: + src: "{{ item.path }}" + dest: "{{destination_path}}/{{ item.path | basename }}" + loop: "{{variable_files_to_process.files}}" + +- name: tfstates.yaml + ansible.builtin.template: + src: "{{platform_service_folder}}/tfstates.yaml" + dest: "{{destination_path}}/tfstates.yaml" + +- name: ignite.yaml + ansible.builtin.template: + src: "{{public_templates_folder}}/platform/single_subscription.yaml" + dest: "{{destination_path}}/ignite.yaml" + +# - name: template.caf.platform.yaml +# ansible.builtin.template: +# src: "{{platform_service_folder}}/template.caf.platform.yaml" +# dest: "{{destination_path}}/{{topology.customer_name}}.caf.platform.yaml" + +- name: readme.md + ansible.builtin.template: + src: "{{platform_service_folder}}/README.md" + dest: "{{destination_path}}/GETTING-STARTED.md" + + +- debug: + msg: + - "You have now initialized the definition of the platform" + - "You can review and adjust the yaml files." + - "configuration folder: - {{destination_path}}" + - "readme: {{destination_path}}/GETTING-STARTED.md" \ No newline at end of file diff --git a/templates/applications/ansible-get-platform-details.yaml b/templates/applications/ansible-get-platform-details.yaml deleted file mode 100644 index 0f24f413d..000000000 --- a/templates/applications/ansible-get-platform-details.yaml +++ /dev/null @@ -1,80 +0,0 @@ -# Get Platform subscriptions - -- name: "Get platform subscriptions tfstate details" - register: subscription_tfstate_file_name - shell: | - az storage account list \ - --subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - --query "[?tags.caf_tfstate=='{{ config.tfstates["platform"].platform_subscriptions.level | default('level1') }}' && tags.caf_environment=='{{ config.caf_terraform.launchpad.caf_environment }}'].{name:name}[0]" -o json | jq -r .name - -- debug: - msg: "{{ subscription_tfstate_file_name.stdout }}" - -- name: "Download platform subscriptions tfstate details" - register: platform_subscription_tfstate_exists - shell: | - az storage blob download \ - --name "{{ config.tfstates["platform"].platform_subscriptions.tfstate | default('platform_subscriptions.tfstate') }}" \ - --account-name "{{ subscription_tfstate_file_name.stdout }}" \ - --container-name "tfstate" \ - --auth-mode "login" \ - --file "{{ job_cache_base_path }}/{{ config.tfstates["platform"].platform_subscriptions.tfstate | default('platform_subscriptions.tfstate') }}" - -- name: "Get platform_subscriptions details" - when: platform_subscription_tfstate_exists.rc == 0 - shell: "cat {{ job_cache_base_path }}/{{ config.tfstates[\"platform\"].platform_subscriptions.tfstate | default('platform_subscriptions.tfstate') }}" - register: platform_subscriptions - -- name: "Get platform_subscriptions json data" - when: platform_subscription_tfstate_exists.rc == 0 - set_fact: - platform_sub_jsondata: "{{ platform_subscriptions.stdout | from_json }}" - -- name: "Get subscriptions list" - when: platform_subscription_tfstate_exists.rc == 0 - set_fact: - platform_subscriptions_details: "{{ platform_sub_jsondata | json_query(path) }}" - vars: - path: 'outputs.objects.value.{{ config.tfstates["platform"].platform_subscriptions.lz_key_name }}.subscriptions' - - -# Get Platform keyvaults -- name: "Get tfstate keyvaults account name" - register: launchpad_storage_account - ignore_errors: yes - shell: | - az storage account list \ - --subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - --query "[?tags.caf_tfstate=='{{ config.tfstates["platform"].launchpad.level | default('level0') }}' && tags.caf_environment=='{{ config.caf_terraform.launchpad.caf_environment }}'].{name:name}[0]" -o json | jq -r .name - -- debug: - msg: "{{launchpad_storage_account}}" - -- name: "Get tfstate keyvaults details" - register: credentials_tfstate_exists - when: launchpad_storage_account.stderr == "" - ignore_errors: yes - shell: | - az storage blob download \ - --name "{{ config.tfstates["platform"].launchpad_credentials.tfstate | default('launchpad_credentials.tfstate') }}" \ - --account-name "{{ launchpad_storage_account.stdout }}" \ - --container-name "{{ config.tfstates["platform"].launchpad.workspace | default('tfstate') }}" \ - --auth-mode "login" \ - --file "~/.terraform.cache/launchpad/{{ config.tfstates["platform"].launchpad_credentials.tfstate | default('launchpad_credentials.tfstate') }}" - -- name: "Get launchpad_credentials details" - when: credentials_tfstate_exists is not skipped - shell: "cat ~/.terraform.cache/launchpad/{{ config.tfstates[\"platform\"].launchpad_credentials.tfstate | default('launchpad_credentials.tfstate') }}" - register: launchpad_credentials - -- name: "Get launchpad_credentials json data" - when: credentials_tfstate_exists is not skipped - set_fact: - credjsondata: "{{ launchpad_credentials.stdout | from_json }}" - -- name: "Set keyvaults variable" - when: credentials_tfstate_exists is not skipped - set_fact: - keyvaults: "{{ credjsondata | json_query(path) }}" - vars: - path: 'outputs.objects.value.launchpad_credentials_rotation.keyvaults' diff --git a/templates/applications/ansible.yaml b/templates/applications/ansible.yaml deleted file mode 100644 index c25bbbd50..000000000 --- a/templates/applications/ansible.yaml +++ /dev/null @@ -1,84 +0,0 @@ -- name: CAF Terraform - Generate configuration files - hosts: localhost - vars: - base_templates_folder: "{{ base_templates_folder }}/asvm" - resource_template_folder: "{{ base_templates_folder }}/resources" - level: level3 - - - tasks: - - - name: "Load variable for landingzones config" - include_vars: - name: asvm_config__to_merge - dir: "{{config_folder}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "config.asvm.yaml|tfstates.asvm.yaml|deployments.yaml" - - - name: "Set base variables" - set_fact: - job_cache_base_path: "/home/vscode/.terraform.cache" - config: "{{asvm_config__to_merge}}" - - - name: "Content of asvm_config__to_merge" - debug: - msg: "{{asvm_config__to_merge}}" - - - name: "Load variable for platform config" - include_vars: - name: platform_config__to_merge - dir: "{{config_folder_platform | default(config_folder)}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "caf.platform.yaml|tfstates.caf.yaml|tfstates.yaml" - - - name: "Content of platform_config__to_merge" - debug: - msg: "{{platform_config__to_merge}}" - - - name: Merge asvm and platform variables - merge_vars: - suffix_to_merge: config__to_merge - merged_var_name: config - expected_type: 'dict' - recursive_dict_merge: True - - - name: "Set base config variables" - set_fact: - config: "{{ ansible_facts.config }}" - - - name: "Content of config" - debug: - msg: "{{config}}" - - - - name: "Creates cache directory" - file: - path: "{{ job_cache_base_path }}/launchpad" - state: directory - - - - name: "{{ level }} | Get platform details (requires '-e config_folder_platform=path to yamls' path to be set)" - include_tasks: "ansible-get-platform-details.yaml" - when: config_folder_platform is defined - -# -# Level 3 -# - - # landingzones deployments - - - name: "{{ level }} | landingzones" - include_tasks: "{{ level }}/ansible.yaml" - loop: "{{asvm_config__to_merge.deployments.keys()}}" - loop_control: - loop_var: asvm_long_folder - -# -# Linters -# - - - name: Terraform linter - shell: | - terraform fmt -recursive {{ destination_base_path }} diff --git a/templates/applications/level3/ansible-subscription-id.yaml b/templates/applications/level3/ansible-subscription-id.yaml deleted file mode 100644 index 571777bb6..000000000 --- a/templates/applications/level3/ansible-subscription-id.yaml +++ /dev/null @@ -1,66 +0,0 @@ -- name: "Load variable for subscriptions" - include_vars: - name: subscriptions - dir: "{{config_folder}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "subscriptions.asvm.yaml|subscription.asvm.yaml" - -- name: "Content of subscriptions" - debug: - msg: "{{subscriptions}}" - -- name: "[{{ level }}-{{ subscription_key }}] Get tfstate details" - register: subscription_tfstate_storage_account_name - shell: | - az storage account list \ - --subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - --query "[?tags.caf_tfstate=='{{ config.tfstates['asvm'][subscription_key].level }}' && tags.caf_environment=='{{ config.caf_terraform.launchpad.caf_environment }}'].{name:name}[0]" -o json | jq -r .name - -- debug: - msg: "{{ subscription_tfstate_storage_account_name.stdout }}" - -- name: "[{{ level }}-{{ subscription_key }}] Download tfstate details" - register: subscription_tfstate_exists - ignore_errors: true - shell: | - az storage blob download \ - --name "{{ config.tfstates['asvm'][subscription_key].subscriptions.tfstate }}" \ - --account-name "{{ subscription_tfstate_storage_account_name.stdout }}" \ - --container-name "{{ config.tfstates['asvm'][subscription_key].workspace }}" \ - --auth-mode "login" \ - --file "{{ job_cache_base_path }}/{{ config.tfstates['asvm'][subscription_key].subscriptions.tfstate }}" - -- debug: - msg: "{{ subscription_tfstate_exists }}" - when: subscriptions.subscriptions[subscription_key] is defined - -- name: "[{{ level }}-{{ subscription_key }}] Get landingzones_subscriptions details" - shell: "cat {{ job_cache_base_path }}/{{ config.tfstates['asvm'][subscription_key].subscriptions.tfstate }}" - register: platform_subscriptions - when: - - subscriptions.subscriptions[subscription_key] is defined - - subscription_tfstate_exists.rc == 0 - -- name: "[{{ level }}-{{ subscription_key }}] Get subscriptions data" - when: - - subscriptions.subscriptions[subscription_key] is defined - - subscription_tfstate_exists.rc == 0 - set_fact: - asvm_subscriptions_details: "{{ platform_subscriptions.stdout | from_json | json_query(path) }}" - vars: - path: 'outputs.objects.value."{{ config.tfstates["asvm"][subscription_key].subscriptions.lz_key_name }}".subscriptions' - -- name: "[{{ level }}-{{ subscription_key }}] cleanup" - when: - - subscriptions.subscriptions[subscription_key] is defined - - subscription_tfstate_exists.rc == 0 - file: - path: "{{ job_cache_base_path }}/{{ config.tfstates['asvm'][subscription_key].subscriptions.tfstate }}" - state: absent - -- debug: - msg: "Platform subscriptions - {{ asvm_subscriptions_details }}" - when: - - subscriptions.subscriptions[subscription_key] is defined - - subscription_tfstate_exists.rc == 0 diff --git a/templates/applications/level3/ansible-subscription.yaml b/templates/applications/level3/ansible-subscription.yaml deleted file mode 100644 index da33410fe..000000000 --- a/templates/applications/level3/ansible-subscription.yaml +++ /dev/null @@ -1,62 +0,0 @@ - -- name: set destination paths - set_fact: - destination_path: "{{ destination_base_path }}/{{ subscription_key }}/subscription" - deployment: "subscriptions" - -- name: "Clean-up directory - subscription - {{ destination_path }}" - file: - path: "{{ destination_path }}" - state: absent - -- name: "Content of subscriptions' resources" - debug: - msg: "{{resources}}" - -- name: "[{{ level }} {{ subscription_key }}] Creates directory" - file: - path: "{{ destination_path }}" - state: directory - -# -# global_settings -# -- name: "[{{ level }} {{ subscription_key }}] - subscription - global_settings" - when: resources.subscriptions[subscription_key].global_settings is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/global_settings.tfvars.j2" -# -# landingzone -# -- name: "[{{ level }} {{ subscription_key }}] - subscription - landingzone" - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/landingzone.tfvars.j2" -# -# subscription -# -- name: "[{{ level }} {{ subscription_key }}] - subscription - subscription" - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/subscriptions.tfvars.j2" - -# -# Readme -# -- name: "[{{ level }}-{{ subscription_key }}] - subscription - *.md" - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ base_templates_folder }}/{{ level }}/subscription/*.md" diff --git a/templates/applications/level3/ansible.yaml b/templates/applications/level3/ansible.yaml deleted file mode 100644 index ed6688cfb..000000000 --- a/templates/applications/level3/ansible.yaml +++ /dev/null @@ -1,58 +0,0 @@ -- name: set asvm context - set_fact: - asvm_folder: "{{ asvm_long_folder if 'path' not in asvm_long_folder else asvm_long_folder.path | regex_search('[^\/]+(?=\/$|$)') }}" - -- name: "[{{ level }}-{{ asvm_folder }}] Set cache folder" - set_fact: - # job_cache_base_path: "/home/vscode/.terraform.cache" - subscription_key: "{{ asvm_folder }}" - -- name: "Load variable for deployments" - include_vars: - name: deployments - dir: "{{config_folder}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "deployments.asvm.yaml|deployments.yaml" - -- debug: - msg: "{{deployments}}" - -### Generate remote state storage containers - -- name: "[{{ level }} {{ subscription_key }}] - remote state container" - include_tasks: "{{ level }}/storage_containers/ansible.yaml" - when: - - deployments.deployments[subscription_key].storage_containers is defined - -#### Get subscription_id - -- name: "[{{ level }} {{ subscription_key }}] - subscription" - include_tasks: "{{ level }}/ansible-subscription-id.yaml" - when: - - config.tfstates['asvm'][subscription_key].subscriptions is defined - - config.tfstates['asvm'][subscription_key].subscriptions.subscription_id is not defined - -### Subscription - -- name: "Load variable for subscriptions" - include_vars: - name: resources - dir: "{{config_folder}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "subscriptions.asvm.yaml|subscription.asvm.yaml|tfstates.asvm.yaml" - -- name: "[{{ level }} {{ subscription_key }}] - subscription" - include_tasks: "{{ level }}/ansible-subscription.yaml" - when: - - resources.subscriptions[subscription_key] is defined - - config.tfstates['asvm'][subscription_key].subscriptions.subscription_id is not defined - - -#### Privileged resources to deploy in the landingzone - -- name: "[{{ level }} {{ subscription_key }}] - resources" - include_tasks: "{{ level }}/resources/ansible.yaml" - when: - - config.tfstates['asvm'][subscription_key].resources is defined diff --git a/templates/applications/level3/resources/ansible.yaml b/templates/applications/level3/resources/ansible.yaml deleted file mode 100644 index 5eb5ae7b2..000000000 --- a/templates/applications/level3/resources/ansible.yaml +++ /dev/null @@ -1,262 +0,0 @@ - -- name: set destination paths - set_fact: - destination_path: "{{ destination_base_path }}/{{ subscription_key }}/resources" - deployment: "resources" - -- name: "Clean-up directory - subscription - {{ destination_path }}" - file: - path: "{{ destination_path }}" - state: absent - when: config.configuration_folders.asvm.cleanup_destination | default(true) | bool - -- name: "Load variable for resources" - include_vars: - name: resources - dir: "{{config_folder}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "resources.asvm.yaml" - -- name: "Content of resources" - debug: - msg: "{{resources}}" - -- name: "[{{ level }} {{ asvm_folder }}] - resources - Creates directory" - file: - path: "{{ destination_path }}" - state: directory -# -# azuread_credentials -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - azuread_credentials" - when: - - resources.subscriptions[subscription_key].azuread_credentials is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/azuread_credentials.tfvars.j2" - -# -# azuread_applications -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - azuread_applications" - when: - - resources.subscriptions[subscription_key].azuread_applications is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/azuread_applications.tfvars.j2" - -# -# azuread_credential_policies -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - azuread_credential_policies" - when: - - resources.subscriptions[subscription_key].azuread_credential_policies is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/azuread_credential_policies.tfvars.j2" - -# -# azuread_groups -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - azuread_groups" - when: - - resources.subscriptions[subscription_key].azuread_groups is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/azuread_groups.tfvars.j2" - -# -# azuread_groups_membership -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - azuread_groups_membership" - when: - - resources.subscriptions[subscription_key].azuread_groups_membership is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/azuread_groups_membership.tfvars.j2" - -# -# azuread_service_principals -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - azuread_service_principals" - when: - - resources.subscriptions[subscription_key].azuread_service_principals is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/azuread_service_principals.tfvars.j2" - -# -# custom_role_definitions -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - custom_role_definitions" - when: - - resources.subscriptions[subscription_key].custom_role_definitions is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/custom_role_definitions.tfvars.j2" - -# -# keyvaults -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - keyvaults" - when: - - resources.subscriptions[subscription_key].keyvaults is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/keyvaults.tfvars.j2" - -# -# keyvault_access_policies -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - keyvault_access_policies" - when: - - resources.subscriptions[subscription_key].keyvault_access_policies is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/keyvault_access_policies.tfvars.j2" - -# -# landingzone -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - landingzone" - when: - - deployments.deployments[subscription_key][deployment].landingzone is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/landingzone.tfvars.j2" - -# -# managed_identities -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - managed_identities" - when: - - resources.subscriptions[subscription_key].managed_identities is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/managed_identities.tfvars.j2" - -# -# network_security_group_definition -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - network_security_group_definition" - when: - - resources.subscriptions[subscription_key].network_security_group_definition is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/network_security_group_definition.tfvars.j2" - -# -# recovery_vaults -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - recovery_vaults" - when: - - resources.subscriptions[subscription_key].recovery_vaults is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/recovery_vaults.tfvars.j2" - -# -# resource_groups -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - resource_groups" - when: - - resources.subscriptions[subscription_key].resource_groups is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/resource_groups.tfvars.j2" - -# -# role_mapping -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - role_mapping" - when: - - resources.subscriptions[subscription_key].role_mapping is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/role_mapping.tfvars.j2" - -# -# virtual_hub_connections -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - virtual_hub_connections" - when: - - resources.subscriptions[subscription_key].virtual_hub_connections is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/virtual_hub_connections.tfvars.j2" - - -# -# virtual_networks -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - virtual_networks" - when: - - resources.subscriptions[subscription_key].virtual_networks is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/virtual_networks.tfvars.j2" - - -# -# Readme -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - *.md" - when: subscription_tfstate_exists.rc == 0 - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ base_templates_folder }}/{{ level }}/resources/*.md" diff --git a/templates/applications/level3/resources/readme.md b/templates/applications/level3/resources/readme.md deleted file mode 100644 index 01f97b9cf..000000000 --- a/templates/applications/level3/resources/readme.md +++ /dev/null @@ -1,31 +0,0 @@ - -### Deploy base resources in {{ asvm_folder }} - -```bash -rover login -t {{ config.platform_identity.tenant_name }} - -unset ARM_SKIP_PROVIDER_REGISTRATION - -cd /tf/caf/landingzones -git pull -git checkout {{ resources.gitops.landingzones }} - -rover \ -{% if config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_subscription_creation_landingzones.vault_uri }} \ -{% endif %} - -lz /tf/caf/landingzones/caf_solution \ - -var-folder {{ destination_path }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -target_subscription {{ asvm_subscriptions_details[asvm_folder].subscription_id }} \ - -tfstate {{ config.tfstates['asvm'][asvm_folder].resources.tfstate }} \ - --workspace {{ config.tfstates['asvm'][asvm_folder].workspace }} \ - -log-severity {{ config.gitops.rover_log_error }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates['asvm'][asvm_folder].resources.tfstate }}.tfplan \ - -a plan - -rover logout - -``` diff --git a/templates/applications/level3/storage_containers/ansible.yaml b/templates/applications/level3/storage_containers/ansible.yaml deleted file mode 100644 index 903064ad1..000000000 --- a/templates/applications/level3/storage_containers/ansible.yaml +++ /dev/null @@ -1,80 +0,0 @@ -- name: set destination paths - set_fact: - destination_path: "{{ destination_base_path }}/storage_containers" - deployment: "storage_containers" - -- name: "Load variable for resources" - include_vars: - name: resources - dir: "{{config_folder}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "tfstates.asvm.yaml|subscriptions.asvm.yaml|subscription.asvm.yaml" - -- name: "Content of resources" - debug: - msg: "{{resources}}" - -- name: "[{{ level }} {{ asvm_folder }}] - storage_containers - Creates directory" - file: - path: "{{ destination_path }}" - state: directory - -# -# Get storage account names -# - -- name: "[{{ level }}-{{ subscription_key }}] - storage_containers - launchpad level3" - register: storage_account_level3 - shell: | - az storage account list \ - --subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - --query "[?tags.caf_tfstate=='level3' && tags.caf_environment=='{{ config.caf_terraform.launchpad.caf_environment }}'].{name:name, resource_group:resourceGroup}[0]" -o json | jq -r - -- debug: - msg: "{{storage_account_level3.stdout}}" - -- name: "[{{ level }}-{{ subscription_key }}] - storage_containers - launchpad level4" - register: storage_account_level4 - shell: | - az storage account list \ - --subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - --query "[?tags.caf_tfstate=='level4' && tags.caf_environment=='{{ config.caf_terraform.launchpad.caf_environment }}'].{name:name, resource_group:resourceGroup}[0]" -o json | jq -r - -- debug: - msg: "{{storage_account_level4.stdout}}" - - -# -# landingzone -# -- name: "[{{ level }}-{{ subscription_key }}] - storage_containers - landingzone" - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/landingzone.tfvars.j2" - -# -# storage_containers -# -- name: "[{{ level }}-{{ subscription_key }}] - storage_containers - storage_containers" - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ base_templates_folder }}/{{ level }}/storage_containers/storage_containers.tfvars.j2" - - -# -# Readme -# -- name: "[{{ level }}-{{ subscription_key }}] - storage_containers - *.md" - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ base_templates_folder }}/{{ level }}/storage_containers/*.md" diff --git a/templates/applications/level3/storage_containers/readme.md b/templates/applications/level3/storage_containers/readme.md deleted file mode 100644 index ad1f01be9..000000000 --- a/templates/applications/level3/storage_containers/readme.md +++ /dev/null @@ -1,28 +0,0 @@ - -### Create storage containers for the landingzone - -```bash -rover login -t {{ config.platform_identity.tenant_name }} - -cd /tf/caf/landingzones -git pull -git checkout {{ resources.gitops.landingzones }} - -rover \ -{% if config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_subscription_creation_landingzones.vault_uri }} \ -{% endif %} - -lz /tf/caf/landingzones/caf_solution \ - -var-folder {{ destination_path }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -target_subscription {{config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ config.tfstates.asvm[asvm_folder].subscriptions.tfstate }} \ - --workspace {{ config.tfstates.asvm[asvm_folder].subscriptions.workspace | default('tfstate') }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.asvm[asvm_folder].subscriptions.tfstate }}.tfplan \ - -a plan - -rover logout - -``` diff --git a/templates/applications/level3/storage_containers/storage_containers.tfvars.j2 b/templates/applications/level3/storage_containers/storage_containers.tfvars.j2 deleted file mode 100644 index 8784606bf..000000000 --- a/templates/applications/level3/storage_containers/storage_containers.tfvars.j2 +++ /dev/null @@ -1,16 +0,0 @@ -storage_containers = { -{% for key in resources.subscriptions.keys() %} - {{ key }}_level3 = { - name = "{{ resources.tfstates.asvm[key].workspace }}" - storage_account = { - name = "{{storage_account_level3.stdout|from_json|json_query('name')}}" - } - } - {{ key }}_level4 = { - name = "{{ resources.tfstates.asvm[key].workspace }}" - storage_account = { - name = "{{storage_account_level4.stdout|from_json|json_query('name')}}" - } - } -{% endfor %} -} \ No newline at end of file diff --git a/templates/applications/level3/subscription/readme.md b/templates/applications/level3/subscription/readme.md deleted file mode 100644 index 8f1ad09ab..000000000 --- a/templates/applications/level3/subscription/readme.md +++ /dev/null @@ -1,40 +0,0 @@ - -### Generate asvm for {{ asvm_folder }} - -```bash -rover login -t {{ config.platform_identity.tenant_name }} - -ARM_SKIP_PROVIDER_REGISTRATION=true && rover \ -{% if config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_subscription_creation_landingzones.vault_uri }} \ -{% endif %} - -lz /tf/caf/landingzones/caf_solution \ - -var-folder {{ destination_path }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ config.tfstates["asvm"][asvm_folder].subscriptions.tfstate }} \ - --workspace {{ config.tfstates["asvm"][asvm_folder].workspace }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates["asvm"][asvm_folder].subscriptions.tfstate }}.tfplan \ - -a plan - -rover logout - -``` -Once you have executed the rover apply to create the subscription, you need to re-execute the rover ignite to generate the instructions for the next steps. - -Note you need to logout and login as a caf_maintainer group member - -```bash -rover login -t {{ config.platform_identity.tenant_name }} - -rover ignite \ - --playbook /tf/caf/starter/templates/landingzones/ansible.yaml \ - -e base_templates_folder={{ base_templates_folder }} \ - -e resource_template_folder={{ resource_template_folder }} \ - -e config_folder={{ config_folder }} \ - -e destination_base_path={{ destination_base_path }} \ - -e config_folder_platform={{ config_folder_platform }} - -``` - diff --git a/templates/applications/level4/readme.md b/templates/applications/level4/readme.md deleted file mode 100644 index b3905517b..000000000 --- a/templates/applications/level4/readme.md +++ /dev/null @@ -1 +0,0 @@ -yaml support for level coming soon. \ No newline at end of file diff --git a/templates/asvm/orion/deploy_template.sh b/templates/asvm/orion/deploy_template.sh new file mode 100755 index 000000000..ba8ae633c --- /dev/null +++ b/templates/asvm/orion/deploy_template.sh @@ -0,0 +1,17 @@ +#! /bin/bash + +echo -n "Name of the landingzone group definition (no spaces) to create: " +read -r landingzone_definition + +export ANSIBLE_DISPLAY_SKIPPED_HOSTS=False + +ansible-playbook /tf/caf/landingzones/templates/asvm/orion/walk-through.yaml \ + -e topology_folder=/tf/caf/landingzones/templates/asvm/orion \ + -e public_templates_folder=/tf/caf/landingzones/templates \ + -e landingzones_folder=/tf/caf/landingzones \ + -e template_folder=/tf/caf/asvm/${landingzone_definition} \ + -e definition_folder=/tf/caf/asvm/${landingzone_definition}/definition \ + -e platform_configuration_folder=/tf/caf/configuration \ + -e platform_definition_folder=/tf/caf/platform/definition \ + -e deployment_mode=asvm \ + --extra-vars landingzone_definition=${landingzone_definition} \ No newline at end of file diff --git a/templates/asvm/orion/ignite.yaml b/templates/asvm/orion/ignite.yaml new file mode 100644 index 000000000..05c3a2745 --- /dev/null +++ b/templates/asvm/orion/ignite.yaml @@ -0,0 +1,66 @@ + +landingzone_definition: {{landingzone_definition}} + +subscriptions: +{% for env in scale_out_domains %} + {{landingzone_definition}}_{{env}}: + name: {{landingzone_definition}}-{{env}} + # Set to false if you do not have permissions to create an alias + create_alias: false + subscription_id: {{subscription_id}} +{% endfor %} + +# +# deployments +# + +deployments: + asvm: + root: + region1: + asvm_subscriptions: subscriptions.asvm.yaml +{% for env in scale_out_domains %} + {{landingzone_definition}}_{{env}}: subscriptions.asvm.yaml +{% endfor %} + +platform_mappings: +{%for key, value in platform_domain_mapping.items() %} + {{key}}: {{value}} +{% endfor %} + +# +# If platform folder and config not accessible to the asvm repo you need to add the following variables +# + +# caf_terraform: +# launchpad: +# caf_environment: cont0226 +# subscription_id: + +# cleanup_destination - recommended to clean and recreated a clean state from template. +configuration_folders: + asvm: + cleanup_destination: true + +# +# paths +# +topology_folder: {{topology_folder}} +public_templates_folder: {{public_templates_folder}} +landingzones_folder: {{landingzones_folder}} +template_folder: {{template_folder}} +definition_folder: {{definition_folder}} +platform_configuration_folder: {{platform_configuration_folder}} +platform_definition_folder: {{platform_definition_folder}} + +deployment_mode: {{deployment_mode}} + +# +# Ansible input responses +# + +# don't change the structure of the values for ansible to process them properly. +# you can update the values following the structure. +scale_out_domains_input: {{scale_out_domains_input}} +platform_domain_mapping_input: {{platform_domain_mapping_input}} +generate_new_subscriptions: {{generate_new_subscriptions}} \ No newline at end of file diff --git a/templates/asvm/orion/readme.md b/templates/asvm/orion/readme.md new file mode 100644 index 000000000..af29014eb --- /dev/null +++ b/templates/asvm/orion/readme.md @@ -0,0 +1,20 @@ +# Cloud Adoption Framework landing zones for Terraform - Starter template for Azure Subscription Vending Machine (ASVM) + +## Generate the definition files + +```bash + +ansible-playbook {{public_templates_folder}}/ansible/asvm_definition.yaml \ + --extra-vars "@{{template_folder}}/ignite.yaml" + +``` + +### Regenerate the template + +Note: This playbook will override the customization you have performed in your {{platform_configuration_folder}} folder. + +```bash +ansible-playbook {{public_templates_folder}}/asvm/orion/walk-through.yaml \ + --extra-vars "@{{template_folder}}/ignite.yaml" + +``` \ No newline at end of file diff --git a/templates/asvm/orion/readme_definition.md b/templates/asvm/orion/readme_definition.md new file mode 100644 index 000000000..e7946f6eb --- /dev/null +++ b/templates/asvm/orion/readme_definition.md @@ -0,0 +1,17 @@ +# Cloud Adoption Framework landing zones for Terraform - Starter template for Azure Subscription Vending Machine (ASVM) + +## Generate the configuration files + +```bash +ansible-playbook {{public_templates_folder}}/ansible/ansible.yaml \ + --extra-vars "@{{template_folder}}/ignite.yaml" + +``` + +## Regenerate the definition folder + +```bash +ansible-playbook {{public_templates_folder}}/ansible/asvm_definition.yaml \ + --extra-vars "@{{template_folder}}/ignite.yaml" + +``` \ No newline at end of file diff --git a/templates/asvm/orion/resources.asvm.yaml b/templates/asvm/orion/resources.asvm.yaml new file mode 100644 index 000000000..95ca63066 --- /dev/null +++ b/templates/asvm/orion/resources.asvm.yaml @@ -0,0 +1,526 @@ +{{landingzone_definition}}_{{env}}: + gitops: + caf_landingzone_branch: 2203.0 + + relative_destination_folder: level3/{{landingzone_definition}}/{{env}} + + deployments: + landingzone: + global_settings_key: + platform: + virtual_hubs: {{platform_mappings[env]}} + remote_tfstates: + asvm: + asvm_subscriptions: + platform: + virtual_hubs: {{platform_mappings[env]}} + virtual_hubs_route_tables: {{platform_mappings[env]}} + secure_firewalls: {{platform_mappings[env]}} + identity_level2: {{platform_mappings[env]}} + asvm: + + resources: + {{landingzone_definition}}_{{env}}: + resource_groups: + rg: + name: {{landingzone_definition}}-{{env}} + backup: + name: {{landingzone_definition}}-{{env}}-backup + networking: + name: {{landingzone_definition}}-{{env}}-networking + preparation: + name: {{landingzone_definition}}-{{env}}-preparation + modeling: + name: {{landingzone_definition}}-{{env}}-modeling + consumption: + name: {{landingzone_definition}}-{{env}}-consumption + analytics: + name: {{landingzone_definition}}-{{env}}-analytics + + virtual_networks: + vnet: + name: {{landingzone_definition}}-{{env}} + resource_group_key: networking + region_key: region1 + dns_servers_keys: + fw_secure_{{platform_mappings[env]}}: + resource_type: azurerm_firewall + lz_key: connectivity_secure_firewalls_{{platform_mappings[env]}} + key: fw_secure_{{platform_mappings[env]}} + address_space: + - 10.101.8.0/23 + subnets: + databricks_preparation_egress: + name: databricks-preparation-egress + nsg_key: databricks_egress + delegation: + name: databricks + service_delegation: Microsoft.Databricks/workspaces + actions: + - Microsoft.Network/virtualNetworks/subnets/join/action + - Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action + - Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action + cidr: + - 10.101.8.0/26 + databricks_preparation_private: + name: databricks-preparation-private + nsg_key: databricks_private + delegation: + name: databricks + service_delegation: Microsoft.Databricks/workspaces + actions: + - Microsoft.Network/virtualNetworks/subnets/join/action + - Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action + - Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action + cidr: + - 10.101.8.64/26 + databricks_modeling_egress: + name: databricks-modeling-egress + nsg_key: databricks_egress + delegation: + name: databricks + service_delegation: Microsoft.Databricks/workspaces + actions: + - Microsoft.Network/virtualNetworks/subnets/join/action + - Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action + - Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action + cidr: + - 10.101.9.0/26 + databricks_modeling_private: + name: databricks-modeling-private + nsg_key: databricks_private + delegation: + name: databricks + service_delegation: Microsoft.Databricks/workspaces + actions: + - Microsoft.Network/virtualNetworks/subnets/join/action + - Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action + - Microsoft.Network/virtualNetworks/subnets/unprepareNetworkPolicies/action + cidr: + - 10.101.9.64/26 + consumption: + name: consumption + enforce_private_link_endpoint_network_policies: true + cidr: + - 10.101.8.128/25 + databricks_notebooks: + name: databricks-notebooks + service_endpoints: + - Microsoft.Storage + - Microsoft.KeyVault + nsg_key: databricks_notebooks + cidr: + - 10.101.9.128/27 + private_endpoints: + name: private-endpoints + enforce_private_link_endpoint_network_policies: true + cidr: + - 10.101.9.192/27 + + network_security_group_definition: + databricks_egress: + version: 1 + resource_group_key: networking + name: databricks-egress + nsg: + Inbound: + 400: + name: Microsoft.Databricks-workspaces_UseOnly_databricks-control-plane-to-worker-proxy + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "AzureDatabricks" + destination_port_range: 5557 + destination_address_prefix: "*" + 401: + name: Microsoft.Databricks-workspaces_UseOnly_databricks-control-plane-to-worker-ssh + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "AzureDatabricks" + destination_port_range: 22 + destination_address_prefix: "*" + Outbound: + 400: + name: Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-databricks-webapp + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "VirtualNetwork" + destination_port_range: 443 + destination_address_prefix: "AzureDatabricks" + 401: + name: Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-sql + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "VirtualNetwork" + destination_port_range: 3306 + destination_address_prefix: "Sql" + 402: + name: Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-storage + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "VirtualNetwork" + destination_port_range: 443 + destination_address_prefix: "Storage" + 403: + name: Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-worker-outbound + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "VirtualNetwork" + destination_port_range: "*" + destination_address_prefix: "VirtualNetwork" + 404: + name: Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-eventhub + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "VirtualNetwork" + destination_port_range: 9093 + destination_address_prefix: "EventHub" + 405: + name: ICMP + access: Allow + protocol: icmp + source_port_range: "*" + source_address_prefix: "*" + destination_port_range: "*" + destination_address_prefix: "*" + databricks_private: + version: 1 + resource_group_key: networking + name: databricks-private + nsg: + Inbound: + 400: + name: Batch Node Management + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "BatchNodeManagement" + destination_address_prefix: "*" + destination_port_ranges: + - 29876 + - 29877 + 401: + name: Azure Machine Learning + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "AzureMachineLearning" + destination_address_prefix: "*" + destination_port_ranges: + - 44224 + Outbound: + 400: + name: Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-webapp + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "VirtualNetwork" + destination_port_range: 443 + destination_address_prefix: "AzureDatabricks" + 401: + name: Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-sql + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "VirtualNetwork" + destination_port_range: 3306 + destination_address_prefix: "Sql" + 402: + name: Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-storage + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "VirtualNetwork" + destination_port_range: 443 + destination_address_prefix: "Storage" + 403: + name: Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-worker-outbound + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "VirtualNetwork" + destination_port_range: "*" + destination_address_prefix: "VirtualNetwork" + 404: + name: Microsoft.Databricks-workspaces_UseOnly_databricks-worker-to-eventhub + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "VirtualNetwork" + destination_port_range: 9093 + destination_address_prefix: "EventHub" + consumption: + version: 1 + resource_group_key: networking + name: consumption + databricks_notebooks: + version: 1 + resource_group_key: networking + name: databricks-notebooks + nsg: + Inbound: + 500: + name: Batch Node Management + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "BatchNodeManagement" + destination_address_prefix: "*" + destination_port_ranges: + - 29876 + - 29877 + 501: + name: Azure Machine Learning + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "AzureMachineLearning" + destination_address_prefix: "*" + destination_port_ranges: + - 44224 + Outbound: + 500: + name: AzureActiveDirectory + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "*" + destination_address_prefix: "AzureActiveDirectory" + destination_port_ranges: + - 80 + - 443 + 501: + name: AzureMachineLearning + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "*" + destination_address_prefix: "AzureMachineLearning" + destination_port_ranges: + - 443 + 502: + name: AzureResourceManager + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "*" + destination_address_prefix: "AzureResourceManager" + destination_port_ranges: + - 443 + 503: + name: Storage + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "*" + destination_address_prefix: "Storage" + destination_port_ranges: + - 443 + 504: + name: AzureFrontDoor Frontend + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "*" + destination_address_prefix: "AzureFrontDoor.Frontend" + destination_port_ranges: + - 443 + 505: + name: Container Registry + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "*" + destination_address_prefix: "AzureContainerRegistry" + destination_port_ranges: + - 443 + 506: + name: Microsoft Container Registry + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "*" + destination_address_prefix: "MicrosoftContainerRegistry" + destination_port_ranges: + - 443 + 507: + name: Keyvault + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "*" + destination_address_prefix: "AzureKeyVault" + destination_port_ranges: + - 443 + 508: + name: AzureFrontDoor FirstParty + access: Allow + protocol: tcp + source_port_range: "*" + source_address_prefix: "*" + destination_address_prefix: "AzureFrontDoor.FirstParty" + destination_port_range: "*" + + virtual_hub_connections: + vnet_to_{{platform_mappings[env]}}: + name: vnet-{{landingzone_definition}}-{{env}}-TO-{{platform_mappings[env]}} + virtual_hub: + lz_key: connectivity_virtual_hubs_{{platform_mappings[env]}} + key: {{platform_mappings[env]}} + vnet: + vnet_key: vnet + routing: + egress: + lz_key: virtual_hubs_route_tables_{{platform_mappings[env]}} + + recovery_vaults: + asr: + name: vault-{{landingzone_definition}}-{{env}} + resource_group_key: backup + backup_policies: + vms: + default: + name: vm-default-policy + timezone: "SE Asia Standard Time" + backup: + frequency: Daily + time: "23:00" + retention_daily: + count: 7 + + keyvaults: + kv_delegated_sp: + name: {{landingzone_definition}}{{env}}001 + resource_group_key: rg + creation_policies: + logged_in_user: + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + landingzone_maintainers_{{platform_mappings[env]}}: + lz_key: asvm + azuread_group_key: caf_ac_landingzone_maintainers_{{platform_mappings[env]}} + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + + keyvault_access_policies: + kv_delegated_sp: + app_LZContributors: + azuread_service_principal_key: sp_LZContributors + secret_permissions: + - Get + + azuread_applications: + app_LZContributors: + application_name: app-asvm-{{landingzone_definition}}-{{env}}-Contributors + + azuread_service_principals: + sp_LZContributors: + azuread_application: + key: app_LZContributors + + azuread_credentials: + app_LZContributors: + type: password + azuread_credential_policy_key: default_policy + azuread_application: + key: app_LZContributors + keyvaults: + kv_delegated_sp: + secret_prefix: sp + + azuread_credential_policies: + default_policy: + length: 250 + special: false + upper: true + number: true + expire_in_days: 70 + rotation_key0: + days: 33 + rotation_key1: + days: 58 + + azuread_groups_membership: + caf_{{platform_mappings[env]}}_landingzones_dns_contributors: + azuread_service_principals: + sp_LZContributors: + group_lz_key: identity_level2_{{platform_mappings[env]}} + keys: + - sp_LZContributors + caf_ac_landingzone_maintainers_{{platform_mappings[env]}}: + azuread_service_principals: + sp_LZContributors: + group_lz_key: asvm + keys: + - sp_LZContributors + + custom_role_definitions: + contributors_extended: + name: lz-{{landingzone_definition}}-{{env}}-contributors-extended + useprefix: true + description: "Provides additional permissions for the level4 principal to perform activies on the level3 landingzone services." + permissions: + actions: + - Microsoft.Network/privateDnsZones/join/action + - Microsoft.Network/virtualNetworks/join/action + + role_mapping: + custom_role_mapping: + networking: + vnet: + contributors_extended: + azuread_service_principals: + keys: + - sp_LZContributors + + built_in_role_mapping: + resource_groups: + preparation: + Owner: + azuread_service_principals: + keys: + - sp_LZContributors + modeling: + Owner: + azuread_service_principals: + keys: + - sp_LZContributors + consumption: + Owner: + azuread_service_principals: + keys: + - sp_LZContributors + analytics: + Owner: + azuread_service_principals: + keys: + - sp_LZContributors + storage_containers: + {{landingzone_definition}}_{{env}}_level3: + lz_key: {{landingzone_definition}}_subscriptions + Storage Blob Data Contributor: + azuread_service_principals: + keys: + - sp_LZContributors + {{landingzone_definition}}_{{env}}_level4: + lz_key: {{landingzone_definition}}_subscriptions + Storage Blob Data Contributor: + azuread_service_principals: + keys: + - sp_LZContributors diff --git a/templates/asvm/orion/subscriptions.asvm.yaml b/templates/asvm/orion/subscriptions.asvm.yaml new file mode 100644 index 000000000..c0e2cb134 --- /dev/null +++ b/templates/asvm/orion/subscriptions.asvm.yaml @@ -0,0 +1,28 @@ +asvm_subscriptions: + gitops: + caf_landingzone_branch: 2203.0 + + relative_destination_folder: level3/{{landingzone_definition}}/subscriptions + + deployments: + landingzone: + global_settings_key: + platform: + asvm: + remote_tfstates: + platform: + asvm: + + resources: + asvm_subscriptions: + subscriptions: +{% for region, value in deployments.asvm['root'].items() %} +{% for env, env_value in value.items() %} +{% if env != "asvm_subscriptions" %} + {{env}}: +{% for key, kv in subscriptions[env].items() %} + {{key}}: {{kv}} +{% endfor %} +{% endif %} +{% endfor %} +{% endfor %} \ No newline at end of file diff --git a/templates/asvm/orion/tfstates.asvm.yaml b/templates/asvm/orion/tfstates.asvm.yaml new file mode 100644 index 000000000..3033ddc66 --- /dev/null +++ b/templates/asvm/orion/tfstates.asvm.yaml @@ -0,0 +1,23 @@ + +tfstates: + asvm: + asvm_subscriptions: + lz_key_name: {{landingzone_definition}}_subscriptions + tfstate: {{landingzone_definition}}_subscriptions.tfstate + workspace: tfstate + level: level3 + sub_template_folder: platform/level3/subscriptions + yaml: platform/level3/ansible.yaml + +{% for region, value in deployments.asvm['root'].items() %} +{% for env in value.keys() %} +{% if env != "asvm_subscriptions" %} + {{env}}: + lz_key_name: {{env}}_level3 + tfstate: {{env}}_level3.tfstate + workspace: {{env | replace('_', '-')}} + level: level3 + +{% endif %} +{% endfor %} +{% endfor %} diff --git a/templates/asvm/orion/walk-through.yaml b/templates/asvm/orion/walk-through.yaml new file mode 100644 index 000000000..1de97aa31 --- /dev/null +++ b/templates/asvm/orion/walk-through.yaml @@ -0,0 +1,81 @@ +# +# Initial script to select a topology and create the base templates for the definition folder +# + + +- name: Deploy template to definition's folder + hosts: localhost + vars_prompt: + - name: landingzone_definition + prompt: Name of the landingzone group definition (no spaces) + private: no + + - name: scale_out_domains_input + prompt: List of the scale-out domains. Will create one landingzone per domain. + private: no + default: dev,prod + + - name: platform_domain_mapping_input + prompt: Mapping between the landingzones and platform scale-out domains. + private: no + default: + dev: non_prod + prod: prod + + - name: generate_new_subscriptions + prompt: Do you want to deploy in the current logged_in subscription (True) or create new one (False)? + private: no + default: True + + + tasks: + + - name: Get default subscription id + shell: az account show --query id -o tsv + register: subscription_id_cmd + when: generate_new_subscriptions + + - set_fact: + scale_out_domains: "{{scale_out_domains_input.split(',') }}" + platform_domain_mapping: "{{platform_domain_mapping_input}}" + subscription_id: "{{subscription_id_cmd.stdout}}" + + - name: Get template files + register: asvm_files + find: + paths: "{{topology_folder}}" + file_type: file + excludes: + - "readme_definition.md" + - "deploy_template.sh" + + - debug: + msg: + - "{{asvm_files}}" + - "{{playbook_dir}}" + verbosity: 1 + + - name: "Creates template_folder directory - {{template_folder}}" + file: + path: "{{template_folder}}" + state: directory + + - name: Deploy files + ansible.builtin.copy: + src: "{{item.path}}" + dest: "{{template_folder}}/{{ item.path | basename }}" + loop: "{{asvm_files.files}}" + + - name: Save parameters + ansible.builtin.template: + src: "{{topology_folder}}/ignite.yaml" + dest: "{{template_folder}}/ignite.yaml" + + - name: readme + ansible.builtin.template: + src: "{{topology_folder}}/readme.md" + dest: "{{template_folder}}/readme.md" + + - debug: + msg: + - "next steps: {{template_folder}}/readme.md" \ No newline at end of file diff --git a/templates/asvm/readme.md b/templates/asvm/readme.md new file mode 100644 index 000000000..0efc05382 --- /dev/null +++ b/templates/asvm/readme.md @@ -0,0 +1,7 @@ + +## Template to generate the defitions for the Orion data and ai landingzones + +```bash +/tf/caf/landingzones/templates/asvm/orion/deploy_template.sh + +``` \ No newline at end of file diff --git a/templates/enterprise-scale/contoso/platform/README.md b/templates/enterprise-scale/contoso/platform/README.md deleted file mode 100644 index a0a3c91ad..000000000 --- a/templates/enterprise-scale/contoso/platform/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# Cloud Adoption Framework landing zones for Terraform - Starter template for Azure Platform - - -## Commands - -### clone the landingzone project (Terraform base code) -```bash -cd /tf/caf/landingzones -git pull -git checkout 2112.int - -``` - -### Rover ignite the platform -Rover ignite will now process the yaml files and start building the configuration structure of the tfvars. Note during the creation of the platform landingones you will have to run rover ignite many times as some deployments are required to be completed before you can perform the next steps. -Rover ignite creates the tfvars and also the documentation. - -```bash -rover login -t tenantname -s - -rover ignite \ - --playbook /tf/caf/landingzones/templates/platform/ansible.yaml \ - -e base_templates_folder=/tf/caf/landingzones/templates/platform \ - -e resource_template_folder=/tf/caf/landingzones/templates/resources \ - -e config_folder=/tf/caf/orgs/contoso/platform - -``` - -### Next step - -Once the rover ignite command has been executed, go to your configuration folder when the platform launchpad configuration has been created. \ No newline at end of file diff --git a/templates/enterprise-scale/contoso/platform/asvm.yaml b/templates/enterprise-scale/contoso/platform/asvm.yaml deleted file mode 100644 index 658826a33..000000000 --- a/templates/enterprise-scale/contoso/platform/asvm.yaml +++ /dev/null @@ -1,35 +0,0 @@ -subscriptions: - asvm: - resource_groups: - level3: - name: caf-level3 - tags: - level: level3 - level4: - name: caf-level4 - tags: - level: level4 - - storage_accounts: - level3: - name: l3 - resource_group_key: level3 - level4: - name: l4 - resource_group_key: level4 - - keyvaults: - level3: - name: l3 - resource_group_key: level3 - level4: - name: l4 - resource_group_key: level4 - - - azuread_groups: - caf_ac_landingzone_maintainers_non_prod: - name: caf_ac_landingzone_maintainers_non_prod - - caf_ac_landingzone_maintainers_prod: - name: caf_ac_landingzone_maintainers_prod diff --git a/templates/enterprise-scale/contoso/platform/connectivity.yaml b/templates/enterprise-scale/contoso/platform/connectivity.yaml deleted file mode 100644 index 77210f19d..000000000 --- a/templates/enterprise-scale/contoso/platform/connectivity.yaml +++ /dev/null @@ -1,34 +0,0 @@ -virtual_networks: - connectivity_hub1_firewall_egress: - name: firewall-egress-re1 - resource_group_key: contoso_global_firewall - region_key: region1 - address_space: - - - specialsubnets: - AzureFirewallSubnet: - name: AzureFirewallSubnet - cidr: - - - - -azurerm_firewalls: - egress_fw_region1: - name: egress-firewall - resource_group_key: contoso_global_firewall - region_key: region1 - # egress_fw_region2: - # name: egress-firewall - # resource_group_key: contoso_global_wan - # region_key: region2 - -resource_groups: - contoso_global_dns: - name: contoso-connectivity-global-dns - region_key: region1 - contoso_global_firewall: - name: contoso-connectivity-global-firewall - region_key: region1 - contoso_global_er_circuits: - name: contoso-connectivity-global-er-circuits - region_key: region1 diff --git a/templates/enterprise-scale/contoso/platform/connectivity_express_routes.yaml b/templates/enterprise-scale/contoso/platform/connectivity_express_routes.yaml deleted file mode 100644 index 46eb0a79f..000000000 --- a/templates/enterprise-scale/contoso/platform/connectivity_express_routes.yaml +++ /dev/null @@ -1,39 +0,0 @@ -gitops: - caf_landingzone_branch: 2112.int - -express_route_circuits: - prod: - name: er-1-prod - resource_group_key: prod - service_provider_name: XL Axiata - peering_location: Jakarta - tier: Standard - family: MeteredData - bandwidth_in_mbps: 50 - non_prod: - name: er-1-nonprod - resource_group_key: non_prod - service_provider_name: XL Axiata - peering_location: Jakarta - tier: Standard - family: MeteredData - bandwidth_in_mbps: 50 - -express_route_circuit_authorizations: - prod: - vhub-prod: - name: er-auth-vhub-prod - resource_group_key: prod - non_prod: - vhub-non-prod: - name: er-auth-vhub-non-prod - resource_group_key: dev - - -resource_groups: - prod: - name: connectivity-express-route-prod - region_key: region1 - non_prod: - name: connectivity-express-route-non-prod - region_key: region1 diff --git a/templates/enterprise-scale/contoso/platform/connectivity_firewall.yaml b/templates/enterprise-scale/contoso/platform/connectivity_firewall.yaml deleted file mode 100644 index c4c3a8cbd..000000000 --- a/templates/enterprise-scale/contoso/platform/connectivity_firewall.yaml +++ /dev/null @@ -1,5 +0,0 @@ - -resource_groups: - contoso_global_firewall: - name: contoso-connectivity-global-firewall - region_key: region1 \ No newline at end of file diff --git a/templates/enterprise-scale/contoso/platform/connectivity_virtual_hub.yaml b/templates/enterprise-scale/contoso/platform/connectivity_virtual_hub.yaml deleted file mode 100644 index 821036a2f..000000000 --- a/templates/enterprise-scale/contoso/platform/connectivity_virtual_hub.yaml +++ /dev/null @@ -1,59 +0,0 @@ -virtual_hubs: - prod: - name: Production - virtual_wan: - lz_key: virtual_wan - key: global_wan - region_key: region1 - hub_address_prefix: - deploy_s2s: false - s2s_config: - name: prod - scale_unit: 1 - deploy_er: false - enable_er_connections: false - er_config: - name: prod - scale_units: 1 - - non_prod: - name: Non Production - virtual_wan: - lz_key: virtual_wan - key: global_wan - region_key: region1 - hub_address_prefix: - deploy_s2s: false - s2s_config: - name: non-prod - scale_unit: 1 - deploy_er: false - enable_er_connections: false - er_config: - name: non-prod - scale_units: 1 - - -express_route_connections: - prod: - name: erc-er-1-prod - virtual_hub: - key: prod - circuit_peering: - tfstate_key: prod - key: private_peering - express_route_circuit_authorization: - tfstate_key: prod - key: vhub-prod - - non_prod: - name: er-1-non-prod - virtual_hub: - key: non_prod - circuit_peering: - tfstate_key: non_prod - key: private_peering - express_route_circuit_authorization: - tfstate_key: non_prod - key: vhub-non-prod - diff --git a/templates/enterprise-scale/contoso/platform/connectivity_virtual_wan.yaml b/templates/enterprise-scale/contoso/platform/connectivity_virtual_wan.yaml deleted file mode 100644 index 6de263ee3..000000000 --- a/templates/enterprise-scale/contoso/platform/connectivity_virtual_wan.yaml +++ /dev/null @@ -1,10 +0,0 @@ -virtual_wans: - global_wan: - name: vwan - resource_group_key: global_wan - region_key: region1 - -resource_groups: - global_wan: - name: connectivity-global-wan - region_key: region1 diff --git a/templates/enterprise-scale/contoso/platform/contoso.caf.platform.yaml b/templates/enterprise-scale/contoso/platform/contoso.caf.platform.yaml deleted file mode 100644 index 65f8dd692..000000000 --- a/templates/enterprise-scale/contoso/platform/contoso.caf.platform.yaml +++ /dev/null @@ -1,118 +0,0 @@ -caf_terraform: - naming_convention: - # When set to false use the CAF provider to generate names aligned to CAF guidance - # true: use the name as defined in the configuration files. You may have to iterate multiple times to prevent conflicts with Azure unique names with servides like storage account, keyvault or log analytics workspace. - passthrough: false - inherit_tags: false - # set: define the prefix to add to all resource names - # unset: if passthrough is set to false, generate a random prefix - prefix: cont - # if passthrough is set to false, add random suffix to name, up to the random_lenght value. - random_length: 5 - launchpad: - caf_environment: contoso - account_replication_type: GRS - regions: - region1: - # set the short form of the Azure region - name: southeastasia # Use the lower-case region's name, short version with no space - slug: sea - region2: - name: eastasia # Use the lower-case region's name, short version with no space - slug: ea - default_region_key: region1 - # Define the number of CAF levels to use. Recommeded is 3 for the platform. - number_of_levels: 3 - blob_versioning_enabled: true - container_delete_retention_policy: 7 - delete_retention_policy: 7 - # Subscription_id to deploy the launchpad. Note 1 existing manual subscription is required to deploy the launhchapd. - subscription_id: - subscription_name: contoso-caf-launchpad - tenant_id: - - billing_subscription_role_delegations: - # true: enable this deployment. The remaining attributes are required. - # false: disable this deployment. - # azuread_user_ea_account_owner: set the upn of the user doing the manual deployment of the platform - # azuread_user_ea_account_owner_object_id: if that user is already loged-in to an azure cli session you can get the object_id by running: - # az ad signed-in-user show --query objectId -o tsv - # The remaining attributes are ignored: [billing_account_name, enrollment_account_name] - enable: false - # Azure Active Directory User (UPN) that is Account Owner in the EA portal - # if enable=false, set the upn of the user doing the manual deployment - azuread_user_ea_account_owner: - # see comments above to get the object_id - azuread_user_ea_account_owner_object_id: - # Only set the following two attributes when enable=true - billing_account_name: - enrollment_account_name: - -# cleanup_destination - recommended to clean and recreated a clean state from template. -configuration_folders: - platform: - # true: force the destination folder to be deleted and re-created before the files are created. - # false: create the target folder structure if it does not exist. On sub-sequent executions, the folder structure is reused as is. - cleanup_destination: true - # base destination folder where rover ignite will store the tfvars files. No / at the end - destination_base_path: /tf/caf - # destination relative path to destination_base_path folder where rover ignite will store the tfvars files. No / at begining and end - destination_relative_path: configuration/contoso/platform - - -platform_core_setup: - sku: - keyvault: standard - enterprise_scale: - enable: true - scenario: contoso - model: demo - management_group_name: "Contoso Industries" - management_group_prefix: contoso - deploy_core_landing_zones: true - enable_azure_subscription_vending_machine: true - clean_up_destination_folder: false - update_lib_folder: true - subscription_deployment_mode: dedicated_new - private_lib: - version_to_deploy: v1.1.1 - v0.1.x: - caf_landingzone_branch: "2107.1" - v0.3.3: - caf_landingzone_branch: "patch.5.4.4" - v1.1.1: - caf_landingzone_branch: "2112.int" - -platform_management: - enable: true - -networking_topology: - deployment_option: virtual_wan - -platform_identity: - # Set the Azure Active Directory tenant name (primary domain name) - # has to be the default domain name (custom dns name or tenantname.onmicrosoft.com) - # check the AAD property - tenant_name: - # only service_principal supported with rover ignite at the moment - azuread_identity_mode: service_principal - # UPNs you want to add in the caf_platform_maintainers Azure AD group - # Can use user or guest accounts - # Those users will have full permissions on platform. - # Once setup, you can remove them from here or add them from - # Check in Azure AD the User Principal Name attribute value. Note there is a special convention for guest accounts. - caf_platform_maintainers: - - - -notifications: - service_health_alerts: - emails: - support1: - name: - email_address: - security_center_email_contact: - -gitops: - caf_landingzone_branch: "2112.int" - deployment_mode: interactive - rover_log_error: ERROR diff --git a/templates/enterprise-scale/contoso/platform/deployments/non_prod/connectivity_firewall_policies.yaml b/templates/enterprise-scale/contoso/platform/deployments/non_prod/connectivity_firewall_policies.yaml deleted file mode 100644 index e9c4e245d..000000000 --- a/templates/enterprise-scale/contoso/platform/deployments/non_prod/connectivity_firewall_policies.yaml +++ /dev/null @@ -1,34 +0,0 @@ -gitops: - landingzones: 2112.int - -deployments: - connectivity: - landingzone: - key: - platform: - private_dns: non_prod - global_settings_key: - platform: - management: - remote_tfstates: - platform: - management: - asvm: - -subscriptions: - connectivity: - resource_groups: - firewall_policies: - name: connectivity-non-prod-firewall-policies - region_key: region1 - - azurerm_firewall_policies: - root: - name: "non-prod-root-policy" - region_key: region1 - resource_group: - key: firewall_policies - dns: - proxy_enabled: true - threat_intelligence_mode: "Alert" - diff --git a/templates/enterprise-scale/contoso/platform/deployments/non_prod/connectivity_firewalls.yaml b/templates/enterprise-scale/contoso/platform/deployments/non_prod/connectivity_firewalls.yaml deleted file mode 100644 index b89bb2a17..000000000 --- a/templates/enterprise-scale/contoso/platform/deployments/non_prod/connectivity_firewalls.yaml +++ /dev/null @@ -1,77 +0,0 @@ -gitops: - landingzones: 2112.int - -deployments: - connectivity: - landingzone: - key: - platform: - azurerm_firewalls: non_prod - global_settings_key: - platform: - management: - remote_tfstates: - platform: - virtual_hubs: non_prod - azurerm_firewall_policies: non_prod - - -subscriptions: - connectivity: - resource_groups: - firewall_policies: - name: connectivity-non-prod-firewall - region_key: region1 - - - virtual_networks: - vnet: - name: vnet-connectivity-non-prod-fw-plinks - resource_group_key: firewall_policies - region_key: region1 - address_space: - - 10.51.4.0/26 - specialsubnets: - AzureFirewallSubnet: - name: AzureFirewallSubnet - cidr: - - 10.51.4.0/26 - - public_ip_addresses: - fw_pip1: - name: pip-non-prod-fw-01 - resource_group_key: firewall_policies - sku: Standard - allocation_method: Static - ip_version: IPv4 - idle_timeout_in_minutes: 4 - - azurerm_firewalls: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - resource_group_key: firewall_policies - vnet_key: vnet - sku_tier: Standard - firewall_policy: - key: root - lz_key: connectivity_firewall_policies_non_prod - zones: - - 1 - - 2 - - 3 - public_ips: - ip1: - name: pip1 - public_ip_key: fw_pip1 - vnet_key: vnet - subnet_key: AzureFirewallSubnet - - - virtual_hub_connections: - vnet_to_hub: - name: vnet-connectivity-non-prod-fw-plinks-TO-vhub-non_prod - virtual_hub: - lz_key: connectivity_virtual_hub_non_prod - key: non_prod - vnet: - vnet_key: vnet \ No newline at end of file diff --git a/templates/enterprise-scale/contoso/platform/deployments/non_prod/connectivity_private_dns.yaml b/templates/enterprise-scale/contoso/platform/deployments/non_prod/connectivity_private_dns.yaml deleted file mode 100644 index b1218f556..000000000 --- a/templates/enterprise-scale/contoso/platform/deployments/non_prod/connectivity_private_dns.yaml +++ /dev/null @@ -1,189 +0,0 @@ -gitops: - landingzones: 2112.int - -deployments: - connectivity: - landingzone: - key: - platform: - private_dns: non_prod - global_settings_key: - platform: - management: - remote_tfstates: - platform: - management: - asvm: - - -subscriptions: - connectivity: - resource_groups: - dns_connectivity_non_prod: - name: dns-connectivity-non-prod - private_dns: - privatelink.adf.azure.com: - name: privatelink.adf.azure.com - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.datafactory.azure.net: - name: privatelink.datafactory.azure.net - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.blob.core.windows.net: - name: privatelink.blob.core.windows.net - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.file.core.windows.net: - name: privatelink.file.core.windows.net - resource_group_key: dns_connectivity_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.notebooks.azure.net: - name: privatelink.notebooks.azure.net - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.dfs.core.windows.net: - name: privatelink.dfs.core.windows.net - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.vaultcore.azure.net: - name: privatelink.vaultcore.azure.net - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.southeastasia.azmk8s.io: - name: privatelink.southeastasia.azmk8s.io - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.azurecr.io: - name: privatelink.azurecr.io - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.southeastasia.backup.windowsazure.com: - name: privatelink.southeastasia.backup.windowsazure.com - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.siterecovery.windowsazure.com: - name: privatelink.siterecovery.windowsazure.com - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.servicebus.windows.net: - name: privatelink.servicebus.windows.net - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.api.azureml.ms: - name: privatelink.api.azureml.ms - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.monitor.azure.com: - name: privatelink.monitor.azure.com - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.oms.opinsights.non_prod.com: - name: privatelink.oms.opinsights.azure.com - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.ods.opinsights.azure.com: - name: privatelink.ods.opinsights.azure.com - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - privatelink.agentsvc.azure-automation.net: - name: privatelink.agentsvc.azure-automation.net - resource_group_key: dns_connectivity_non_prod - vnet_links: - fw_non_prod_plinks_01: - name: fw-non-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_non_prod - - custom_role_definitions: - landgingzone_extended: - name: landingzone-networking-non-prod-private-dns-extended - useprefix: true - description: "(non-prod) Provides additional permissions for the level4 principal to perform activies on the level2 private dns zones for private links." - permissions: - actions: - - Microsoft.Network/privateDnsZones/join/action - - Microsoft.Network/privateEndpoints/privateDnsZoneGroups/read - - Microsoft.Network/privateEndpoints/privateDnsZoneGroups/write - - role_mapping: - custom_role_mapping: - resource_groups: - dns_connectivity_prod: - landgingzone_extended: - azuread_groups: - lz_key: identity_level2 - keys: - - caf_non_prod_landingzones_dns_contributors - built_in_role_mapping: - resource_groups: - dns_connectivity_non_prod: - Private DNS Zone Contributor: - azuread_groups: - lz_key: identity_level2 - keys: - - caf_non_prod_landingzones_dns_contributors diff --git a/templates/enterprise-scale/contoso/platform/deployments/prod/connectivity_firewall_policies.yaml b/templates/enterprise-scale/contoso/platform/deployments/prod/connectivity_firewall_policies.yaml deleted file mode 100644 index 720fc7954..000000000 --- a/templates/enterprise-scale/contoso/platform/deployments/prod/connectivity_firewall_policies.yaml +++ /dev/null @@ -1,33 +0,0 @@ -gitops: - landingzones: 2112.int - -deployments: - connectivity: - landingzone: - key: - platform: - private_dns: prod - global_settings_key: - platform: - management: - remote_tfstates: - platform: - management: - asvm: - -subscriptions: - connectivity: - resource_groups: - firewall_policies: - name: connectivity-prod-firewall-policies - region_key: region1 - - azurerm_firewall_policies: - root: - name: "prod-root-policy" - region_key: region1 - resource_group: - key: firewall_policies - dns: - proxy_enabled: true - threat_intelligence_mode: "Alert" diff --git a/templates/enterprise-scale/contoso/platform/deployments/prod/connectivity_firewalls.yaml b/templates/enterprise-scale/contoso/platform/deployments/prod/connectivity_firewalls.yaml deleted file mode 100644 index 54639c529..000000000 --- a/templates/enterprise-scale/contoso/platform/deployments/prod/connectivity_firewalls.yaml +++ /dev/null @@ -1,77 +0,0 @@ -gitops: - landingzones: 2112.int - -deployments: - connectivity: - landingzone: - key: - platform: - azurerm_firewalls: prod - global_settings_key: - platform: - management: - remote_tfstates: - platform: - virtual_hubs: prod - azurerm_firewall_policies: prod - - -subscriptions: - connectivity: - resource_groups: - firewall_policies: - name: connectivity-prod-firewall - region_key: region1 - - - virtual_networks: - vnet: - name: vnet-connectivity-prod-fw-plinks - resource_group_key: firewall_policies - region_key: region1 - address_space: - - 10.51.196.0/26 - specialsubnets: - AzureFirewallSubnet: - name: AzureFirewallSubnet - cidr: - - 10.51.196.0/26 - - public_ip_addresses: - fw_pip1: - name: pip-prod-fw-01 - resource_group_key: firewall_policies - sku: Standard - allocation_method: Static - ip_version: IPv4 - idle_timeout_in_minutes: 4 - - azurerm_firewalls: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - resource_group_key: firewall_policies - vnet_key: vnet - sku_tier: Standard - firewall_policy: - key: root - lz_key: connectivity_firewall_policies_prod - zones: - - 1 - - 2 - - 3 - public_ips: - ip1: - name: pip1 - public_ip_key: fw_pip1 - vnet_key: vnet - subnet_key: AzureFirewallSubnet - - - virtual_hub_connections: - vnet_to_hub: - name: vnet-connectivity-prod-fw-plinks-TO-vhub-prod - virtual_hub: - lz_key: connectivity_virtual_hub_prod - key: prod - vnet: - vnet_key: vnet \ No newline at end of file diff --git a/templates/enterprise-scale/contoso/platform/deployments/prod/connectivity_private_dns.yaml b/templates/enterprise-scale/contoso/platform/deployments/prod/connectivity_private_dns.yaml deleted file mode 100644 index 4bfa756d6..000000000 --- a/templates/enterprise-scale/contoso/platform/deployments/prod/connectivity_private_dns.yaml +++ /dev/null @@ -1,188 +0,0 @@ -gitops: - landingzones: 2112.int - -deployments: - connectivity: - landingzone: - key: - platform: - private_dns: prod - global_settings_key: - platform: - management: - remote_tfstates: - platform: - management: - -subscriptions: - connectivity: - resource_groups: - dns_connectivity_prod: - name: dns-connectivity-prod - private_dns: - privatelink.adf.azure.com: - name: privatelink.adf.azure.com - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.datafactory.azure.net: - name: privatelink.datafactory.azure.net - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.blob.core.windows.net: - name: privatelink.blob.core.windows.net - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.file.core.windows.net: - name: privatelink.file.core.windows.net - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.notebooks.azure.net: - name: privatelink.notebooks.azure.net - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.dfs.core.windows.net: - name: privatelink.dfs.core.windows.net - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.vaultcore.azure.net: - name: privatelink.vaultcore.azure.net - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.southeastasia.azmk8s.io: - name: privatelink.southeastasia.azmk8s.io - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.azurecr.io: - name: privatelink.azurecr.io - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.southeastasia.backup.windowsazure.com: - name: privatelink.southeastasia.backup.windowsazure.com - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.siterecovery.windowsazure.com: - name: privatelink.siterecovery.windowsazure.com - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.servicebus.windows.net: - name: privatelink.servicebus.windows.net - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.api.azureml.ms: - name: privatelink.api.azureml.ms - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.monitor.azure.com: - name: privatelink.monitor.azure.com - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.oms.opinsights.azure.com: - name: privatelink.oms.opinsights.azure.com - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.ods.opinsights.azure.com: - name: privatelink.ods.opinsights.azure.com - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - privatelink.agentsvc.azure-automation.net: - name: privatelink.agentsvc.azure-automation.net - resource_group_key: dns_connectivity_prod - vnet_links: - fw_prod_plinks_01: - name: fw-prod-plinks-01 - vnet_key: vnet - lz_key: connectivity_firewalls_prod - - custom_role_definitions: - landgingzone_extended: - name: landingzone-networking-private-dns-extended - useprefix: true - description: "(prod) Provides additional permissions for the level4 principal to perform activies on the level2 private dns zones for private links." - permissions: - actions: - - Microsoft.Network/privateDnsZones/join/action - - Microsoft.Network/privateEndpoints/privateDnsZoneGroups/read - - Microsoft.Network/privateEndpoints/privateDnsZoneGroups/write - - role_mapping: - custom_role_mapping: - resource_groups: - dns_connectivity_prod: - landgingzone_extended: - azuread_groups: - lz_key: identity_level2 - keys: - - caf_prod_landingzones_dns_contributors - built_in_role_mapping: - resource_groups: - dns_connectivity_prod: - Private DNS Zone Contributor: - azuread_groups: - lz_key: identity_level2 - keys: - - caf_prod_landingzones_dns_contributors - diff --git a/templates/enterprise-scale/contoso/platform/deployments/prod/identity_level2.yaml b/templates/enterprise-scale/contoso/platform/deployments/prod/identity_level2.yaml deleted file mode 100644 index 5edab1e12..000000000 --- a/templates/enterprise-scale/contoso/platform/deployments/prod/identity_level2.yaml +++ /dev/null @@ -1,13 +0,0 @@ -gitops: - landingzones: 2112.int - -deployments: - identity: - -subscriptions: - identity: - azuread_groups: - caf_non_prod_landingzones_dns_contributors: - name: caf ac non_prod landingzones dns contributors - caf_prod_landingzones_dns_contributors: - name: caf ac prod landingzones dns contributors \ No newline at end of file diff --git a/templates/enterprise-scale/contoso/platform/deployments/prod/identity_level2_aadds.yaml b/templates/enterprise-scale/contoso/platform/deployments/prod/identity_level2_aadds.yaml deleted file mode 100644 index 3e3ab8a7c..000000000 --- a/templates/enterprise-scale/contoso/platform/deployments/prod/identity_level2_aadds.yaml +++ /dev/null @@ -1,170 +0,0 @@ -gitops: - landingzones: 2112.int - -deployments: - identity: - landingzone: - key: - platform: - identity_aadds: prod - global_settings_key: - platform: - management: - remote_tfstates: - platform: - management: - virtual_hubs: prod - - -subscriptions: - identity: - resource_groups: - rg: - name: identity-prod-aadds - region_key: region1 - - - virtual_networks: - vnet: - name: vnet-identity-prod-aadds - resource_group_key: rg - region_key: region1 - address_space: - - 10.10.100.0/27 - dns_servers: - - 10.10.100.4 - - 10.10.100.5 - subnets: - aadds: - name: snet-aadds - cidr: - - 10.10.100.0/28 - nsg_key: aadds_re1 - management: - name: snet-aadds-management - cidr: - - 10.10.100.16/28 - - virtual_hub_connections: - vnet_to_hub: - name: vnet-identity-prod-aadds-TO-vhub-prod - virtual_hub: - lz_key: connectivity_virtual_hub_prod - key: prod - vnet: - vnet_key: vnet - - active_directory_domain_service: - aadds: - name: aadds - region: region1 - resource_group: - key: rg - domain_name: aadds-contoso.net - sku: Standard - filtered_sync_enabled: false - initial_replica_set: - region: region1 - subnet: - vnet_key: vnet - key: aadds - notifications: - additional_recipients: - - notifyA@example.net - - notifyB@example.net - notify_dc_admins: true - notify_global_admins: false - security: - ntlm_v1_enabled: false - sync_kerberos_passwords: true - sync_ntlm_passwords: false - sync_on_prem_passwords: true - tls_v1_enabled: false - - azuread_groups: - aad_dc_administrators: - name: AAD DC Administrators - prevent_duplicate_name: true - - network_security_group_definition: - aadds_re1: - version: 1 - resource_group_key: rg - region: region1 - name: nsg-aadds-re1 - nsg: - Inbound: - 400: - name: Debugging for support. - access: Allow - protocol: tcp - source_port_range: "*" - destination_port_range: "3389" - source_address_prefix: CorpNetSaw - destination_address_prefix: "*" - 401: - name: Powershell remoting. - access: Allow - protocol: tcp - source_port_range: "*" - destination_port_range: "5986" - source_address_prefix: AzureActiveDirectoryDomainServices - destination_address_prefix: "*" - Outbound: - 400: - name: Communication with the Azure AD Domain Services management service. - access: Allow - protocol: tcp - source_port_range: "*" - destination_port_range: "443" - source_address_prefix: "*" - destination_address_prefix: "AzureActiveDirectoryDomainServices" - 401: - name: Monitoring of the virtual machines. - access: Allow - protocol: tcp - source_port_range: "*" - destination_port_range: "443" - source_address_prefix: "*" - destination_address_prefix: "AzureMonitor" - 402: - name: Communication with Azure Storage. - access: Allow - protocol: tcp - source_port_range: "*" - destination_port_range: "443" - source_address_prefix: "*" - destination_address_prefix: "Storage" - 403: - name: Communication with Azure Active Directory. - access: Allow - protocol: tcp - source_port_range: "*" - destination_port_range: "443" - source_address_prefix: "*" - destination_address_prefix: "AzureActiveDirectory" - 404: - name: Communication with Windows Update. - access: Allow - protocol: tcp - source_port_range: "*" - destination_port_range: "443" - source_address_prefix: "*" - destination_address_prefix: "AzureUpdateDelivery" - 405: - name: Download of patches from Windows Update. - access: Allow - protocol: tcp - source_port_range: "*" - destination_port_range: "443" - source_address_prefix: "*" - destination_address_prefix: "AzureFrontDoor.FirstParty" - 406: - name: Automated management of security patches. - access: Allow - protocol: tcp - source_port_range: "*" - destination_port_range: "443" - source_address_prefix: "*" - destination_address_prefix: "GuestAndHybridManagement" - diff --git a/templates/enterprise-scale/contoso/platform/eslz/lib/readme.md b/templates/enterprise-scale/contoso/platform/eslz/lib/readme.md deleted file mode 100644 index 187ef6e20..000000000 --- a/templates/enterprise-scale/contoso/platform/eslz/lib/readme.md +++ /dev/null @@ -1,2 +0,0 @@ -# Custom ESLZ library -In this folder you can store the custom definition and assignment objects you need to add to augment your custom governance. \ No newline at end of file diff --git a/templates/enterprise-scale/contoso/platform/identity.yaml b/templates/enterprise-scale/contoso/platform/identity.yaml deleted file mode 100644 index aa201e898..000000000 --- a/templates/enterprise-scale/contoso/platform/identity.yaml +++ /dev/null @@ -1,69 +0,0 @@ -subscriptions: - identity: - resource_groups: - management: - name: management - alerts: - name: alerts - - service_health_alerts: - enable_service_health_alerts: true - name: alerts - shortname: HealthAlerts - resource_group_key: alerts - action_group_name: actiongrp - email_alert_settings: - support1: - name: email_alert_support1 - email_address: lalesle@microsoft.com - use_common_alert_schema: false - - recovery_vaults: - asr: - name: asr - resource_group_key: management - soft_delete_enabled: true - backup_policies: - vms: - default: - name: vm-default-policy - # Default to UTC - # possible values - https://jackstromberg.com/2017/01/list-of-time-zones-consumed-by-azure/ - timezone: "SE Asia Standard Time" - backup: - frequency: Daily - time: "23:00" - retention_daily: - count: 7 - retention_weekly: - count: 2 - weekdays: - - Sunday - retention_monthly: - count: 2 - weeks: - - First - weekdays: - - Sunday - retention_yearly: - count: 1 - weeks: - - First - months: - - January - weekdays: - - Sunday - - -# Bring here you existing active directory security groups. -# Those are the groups you will inject to RBAC in the Enterprise Scale deployment. -# Note Terraform will create a new Azure AD group and add the existing as a member -# -# level1: -# azuread_groups: -# network_ops_team: -# name: netops -# members: -# # Set the list of the existing groups -# objects_ids: -# - existing_azure_ad_group_object_id diff --git a/templates/enterprise-scale/contoso/platform/launchpad.yaml b/templates/enterprise-scale/contoso/platform/launchpad.yaml deleted file mode 100644 index c9cf11fea..000000000 --- a/templates/enterprise-scale/contoso/platform/launchpad.yaml +++ /dev/null @@ -1,37 +0,0 @@ -subscriptions: - launchpad: - resource_groups: - level0: - name: caf-level0 - tags: - level: level0 - level1: - name: caf-level1 - tags: - level: level1 - level2: - name: caf-level2 - tags: - level: level2 - - storage_accounts: - level0: - name: l0 - resource_group_key: level0 - level1: - name: l1 - resource_group_key: level1 - level2: - name: l2 - resource_group_key: level2 - - keyvaults: - level0: - name: l0 - resource_group_key: level0 - level1: - name: l1 - resource_group_key: level1 - level2: - name: l2 - resource_group_key: level2 diff --git a/templates/enterprise-scale/contoso/platform/launchpad_credentials.yaml b/templates/enterprise-scale/contoso/platform/launchpad_credentials.yaml deleted file mode 100644 index 7d843436b..000000000 --- a/templates/enterprise-scale/contoso/platform/launchpad_credentials.yaml +++ /dev/null @@ -1,415 +0,0 @@ -subscriptions: - launchpad_credentials: - resource_groups: - sp_credentials: - name: credentials - - keyvaults: - cred_ea_account_owner: - name: eaowner - resource_group_key: sp_credentials - purge_protection_enabled: false - creation_policies: - caf_platform_maintainers: - lz_key: launchpad - azuread_group_key: caf_platform_maintainers - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - identity_azuread_group: - lz_key: launchpad - azuread_group_key: identity - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - cred_level0: - name: idl0 - resource_group_key: sp_credentials - purge_protection_enabled: false - creation_policies: - caf_platform_maintainers: - lz_key: launchpad - azuread_group_key: caf_platform_maintainers - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - identity_azuread_group: - lz_key: launchpad - azuread_group_key: identity - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - level0: - lz_key: launchpad - azuread_group_key: level0 - secret_permissions: - - Get - cred_identity: - name: id - resource_group_key: sp_credentials - purge_protection_enabled: false - creation_policies: - caf_platform_maintainers: - lz_key: launchpad - azuread_group_key: caf_platform_maintainers - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - identity_azuread_group: - lz_key: launchpad - azuread_group_key: identity - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - cred_management: - name: mg - resource_group_key: sp_credentials - purge_protection_enabled: false - creation_policies: - caf_platform_maintainers: - lz_key: launchpad - azuread_group_key: caf_platform_maintainers - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - identity_azuread_group: - lz_key: launchpad - azuread_group_key: identity - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - management_azuread_group: - lz_key: launchpad - azuread_group_key: management - secret_permissions: - - Get - cred_eslz: - name: es - resource_group_key: sp_credentials - purge_protection_enabled: false - creation_policies: - caf_platform_maintainers: - lz_key: launchpad - azuread_group_key: caf_platform_maintainers - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - identity_azuread_group: - lz_key: launchpad - azuread_group_key: identity - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - eslz_azuread_group: - lz_key: launchpad - azuread_group_key: eslz - secret_permissions: - - Get - cred_connectivity: - name: co - resource_group_key: sp_credentials - purge_protection_enabled: false - creation_policies: - caf_platform_maintainers: - lz_key: launchpad - azuread_group_key: caf_platform_maintainers - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - identity_azuread_group: - lz_key: launchpad - azuread_group_key: identity - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - connectivity_azuread_group: - lz_key: launchpad - azuread_group_key: connectivity - secret_permissions: - - Get - cred_subscription_creation_platform: - name: scp - resource_group_key: sp_credentials - purge_protection_enabled: false - creation_policies: - caf_platform_maintainers: - lz_key: launchpad - azuread_group_key: caf_platform_maintainers - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - identity_azuread_group: - lz_key: launchpad - azuread_group_key: identity - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - subscription_creation_platform_azuread_group: - lz_key: launchpad - azuread_group_key: subscription_creation_platform - secret_permissions: - - Get - cred_subscription_creation_landingzones: - name: scl - resource_group_key: sp_credentials - purge_protection_enabled: false - creation_policies: - caf_platform_maintainers: - lz_key: launchpad - azuread_group_key: caf_platform_maintainers - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - identity_azuread_group: - lz_key: launchpad - azuread_group_key: identity - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - subscription_creation_platform_azuread_group: - lz_key: launchpad - azuread_group_key: subscription_creation_landingzones - secret_permissions: - - Get - cred_gitops: - name: gitops - resource_group_key: sp_credentials - purge_protection_enabled: false - creation_policies: - caf_platform_maintainers: - lz_key: launchpad - azuread_group_key: caf_platform_maintainers - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - identity_azuread_group: - lz_key: launchpad - azuread_group_key: identity - secret_permissions: - - Set - - Get - - List - - Delete - - Purge - - Recover - - keyvault_access_policies: - cred_ea_account_owner: - gitops: - azuread_service_principal_key: gitops - secret_permissions: - - Get - cred_level0: - gitops: - azuread_service_principal_key: gitops - secret_permissions: - - Get - cred_identity: - gitops: - azuread_service_principal_key: gitops - secret_permissions: - - Get - cred_management: - gitops: - azuread_service_principal_key: gitops - secret_permissions: - - Get - cred_eslz: - gitops: - azuread_service_principal_key: gitops - secret_permissions: - - Get - cred_connectivity: - gitops: - azuread_service_principal_key: gitops - secret_permissions: - - Get - cred_subscription_creation_platform: - gitops: - azuread_service_principal_key: gitops - secret_permissions: - - Get - cred_subscription_creation_landingzones: - gitops: - azuread_service_principal_key: gitops - secret_permissions: - - Get - cred_gitops: - gitops: - azuread_service_principal_key: gitops - secret_permissions: - - Get - - - azuread_applications: - gitops: - application_name: app-azure-platform-credentials-for-gitops - - azuread_service_principals: - gitops: - azuread_application: - key: gitops - - azuread_credentials: - gitops: - type: password - azuread_credential_policy_key: gitops - azuread_application: - key: gitops - keyvaults: - cred_gitops: - secret_prefix: sp - level0: - type: password - azuread_credential_policy_key: default_policy - azuread_application: - lz_key: launchpad - key: level0 - keyvaults: - cred_level0: - secret_prefix: sp - identity: - type: password - azuread_credential_policy_key: default_policy - azuread_application: - lz_key: launchpad - key: identity - keyvaults: - cred_identity: - secret_prefix: sp - management: - type: password - azuread_credential_policy_key: default_policy - azuread_application: - lz_key: launchpad - key: management - keyvaults: - cred_management: - secret_prefix: sp - eslz: - type: password - azuread_credential_policy_key: default_policy - azuread_application: - lz_key: launchpad - key: eslz - keyvaults: - cred_eslz: - secret_prefix: sp - connectivity: - type: password - azuread_credential_policy_key: default_policy - azuread_application: - lz_key: launchpad - key: connectivity - keyvaults: - cred_connectivity: - secret_prefix: sp - subscription_creation_platform: - type: password - azuread_credential_policy_key: default_policy - azuread_application: - lz_key: launchpad - key: subscription_creation_platform - keyvaults: - cred_subscription_creation_platform: - secret_prefix: sp - subscription_creation_landingzones: - type: password - azuread_credential_policy_key: default_policy - azuread_application: - lz_key: launchpad - key: subscription_creation_landingzones - keyvaults: - cred_subscription_creation_landingzones: - secret_prefix: sp - - azuread_credential_policies: - gitops: - length: 250 - special: false - upper: true - number: true - expire_in_days: 360 - rotation_key0: - days: 181 - rotation_key1: - days: 300 - default_policy: - length: 250 - special: false - upper: true - number: true - expire_in_days: 65 - rotation_key0: - days: 33 - rotation_key1: - days: 58 - diff --git a/templates/enterprise-scale/contoso/platform/management.yaml b/templates/enterprise-scale/contoso/platform/management.yaml deleted file mode 100644 index 773853f28..000000000 --- a/templates/enterprise-scale/contoso/platform/management.yaml +++ /dev/null @@ -1,83 +0,0 @@ -subscriptions: - management: - resource_groups: - management: - name: management - alerts: - name: alerts - - diagnostic_log_analytics: - # if you change this key you also need to change it in the ESLZ deployment - # eslz/archetype_config_overrides.caf.platform.yaml - # eslz/custom_landing_zones.caf.platform.yaml - region1: - name: logre1 - resource_group_key: management - - monitor_action_groups: - networking_operations: - action_group_name: Networking Operations - shortname: netops - arm_role_alert: - contributors: - name: contributors - role_name: servicehealth-alerts-contributors - use_common_alert_schema: false - email_receiver: - noc: - name: email_alert_support1 - email_address: - use_common_alert_schema: false - - service_health_alerts: - enable_service_health_alerts: true - name: alerts - shortname: HealthAlerts - resource_group_key: alerts - action_group_name: actiongrp - email_alert_settings: - support1: - name: email_alert_support1 - email_address: - use_common_alert_schema: false - - automation_accounts: - account1: - name: automationAccount1 - resource_group_key: management - - recovery_vaults: - asr: - name: asr - resource_group_key: management - soft_delete_enabled: true - backup_policies: - vms: - default: - name: vm-default-policy - # Default to UTC - # possible values - https://jackstromberg.com/2017/01/list-of-time-zones-consumed-by-azure/ - timezone: "SE Asia Standard Time" - backup: - frequency: Daily - time: "23:00" - retention_daily: - count: 7 - retention_weekly: - count: 2 - weekdays: - - Sunday - retention_monthly: - count: 2 - weeks: - - First - weekdays: - - Sunday - retention_yearly: - count: 1 - weeks: - - First - months: - - January - weekdays: - - Sunday diff --git a/templates/enterprise-scale/contoso/platform/subscriptions.yaml b/templates/enterprise-scale/contoso/platform/subscriptions.yaml deleted file mode 100644 index 66b633780..000000000 --- a/templates/enterprise-scale/contoso/platform/subscriptions.yaml +++ /dev/null @@ -1,16 +0,0 @@ -platform_subscriptions: - management: - alias: "management" - name: "-management" - # Do not set the subscription_id when using the automated subscripiton creation - # In that case delete the following attribute. - # When re-using an existing subscripiton, set the GUID of the subscripiton. - subscription_id: - identity: - alias: "identity" - name: "-identity" - subscription_id: - connectivity: - alias: "connectivity" - name: "-connectivity" - subscription_id: \ No newline at end of file diff --git a/templates/enterprise-scale/contoso/platform/tfstates.yaml b/templates/enterprise-scale/contoso/platform/tfstates.yaml deleted file mode 100644 index a85b401da..000000000 --- a/templates/enterprise-scale/contoso/platform/tfstates.yaml +++ /dev/null @@ -1,148 +0,0 @@ -tfstates: - platform: - ### Level0 ### - launchpad: - lz_key_name: launchpad - tfstate: caf_launchpad.tfstate - workspace: tfstate - base_config_path: launchpad - level: level0 - billing_subscription_role_delegations: - lz_key_name: billing_subscription_role_delegations - tfstate: billing_subscription_role_delegations.tfstate - base_config_path: billing_subscription_role_delegations - level: level0 - launchpad_credentials: - lz_key_name: launchpad_credentials_rotation - tfstate: launchpad_credentials_rotation.tfstate - base_config_path: credentials - level: level0 - - ### Level1 ### - management: - lz_key_name: management - tfstate: management.tfstate - base_config_path: management - level: level1 - identity: - lz_key_name: identity - tfstate: identity.tfstate - base_config_path: identity - level: level1 - eslz: - lz_key_name: eslz - tfstate: eslz.tfstate - base_config_path: eslz - level: level1 - platform_subscriptions: - lz_key_name: platform_subscriptions - tfstate: platform_subscriptions.tfstate - base_config_path: subscriptions - level: level1 - - ## Level2 ## - identity_level2: - prod: - lz_key_name: identity_level2 - tfstate: identity_level2.tfstate - level: level2 - non_prod: - lz_key_name: identity_level2 - tfstate: identity_level2.tfstate - level: level2 - - identity_level2_aadds: - prod: - lz_key_name: identity_level2_aadds - tfstate: identity_level2_aadds.tfstate - level: level2 - - virtual_wan: - lz_key_name: connectivity_virtual_wan - tfstate: connectivity_virtual_wan.tfstate - base_config_path: connectivity/virtual_wan - level: level2 - - virtual_hubs: - prod: - lz_key_name: connectivity_virtual_hub_prod - tfstate: connectivity_virtual_hub_prod.tfstate - workspace: tfstate - base_config_path: connectivity/virtual_hub - level: level2 - non_prod: - lz_key_name: connectivity_virtual_hub_non_prod - tfstate: connectivity_virtual_hub_non_prod.tfstate - workspace: tfstate - base_config_path: connectivity/virtual_hub - level: level2 - - vpn_sites: - prod: - lz_key_name: connectivity_vpn_sites_prod - tfstate: connectivity_vpn_sites_prod.tfstate - base_config_path: connectivity/vpn_sites - level: level2 - non_prod: - lz_key_name: connectivity_vpn_sites_non_prod - tfstate: connectivity_vpn_sites_non_prod.tfstate - base_config_path: connectivity/vpn_sites - level: level2 - - express_route_circuits: - prod: - lz_key_name: connectivity_express_route_prod - tfstate: connectivity_express_route_prod.tfstate - base_config_path: connectivity/express_route - level: level2 - non_prod: - lz_key_name: connectivity_express_route_non_prod - tfstate: connectivity_express_route_non_prod.tfstate - base_config_path: connectivity/express_route - level: level2 - - express_route_circuit_peerings: - prod: - lz_key_name: connectivity_express_route_peerings_prod - tfstate: connectivity_express_route_peerings_prod.tfstate - level: level2 - non_prod: - lz_key_name: connectivity_express_route_peerings_non_prod - tfstate: connectivity_express_route_peerings_non_prod.tfstate - level: level2 - - azurerm_firewalls: - prod: - lz_key_name: connectivity_firewalls_prod - tfstate: connectivity_firewalls_prod.tfstate - level: level2 - non_prod: - lz_key_name: connectivity_firewalls_non_prod - tfstate: connectivity_firewalls_non_prod.tfstate - level: level2 - - azurerm_firewall_policies: - prod: - lz_key_name: connectivity_firewall_policies_prod - tfstate: connectivity_firewall_policies_prod.tfstate - level: level2 - non_prod: - lz_key_name: connectivity_firewall_policies_non_prod - tfstate: connectivity_firewall_policies_non_prod.tfstate - level: level2 - - private_dns: - prod: - lz_key_name: connectivity_private_dns_prod - tfstate: connectivity_private_dns_prod.tfstate - level: level2 - non_prod: - lz_key_name: connectivity_private_dns_non_prod - tfstate: connectivity_private_dns_non_prod.tfstate - level: level2 - - - asvm: - lz_key_name: asvm - tfstate: asvm_subscription_vending_machine.tfstate - level: level2 diff --git a/templates/platform/IP Address Plan.xlsx b/templates/platform/IP Address Plan.xlsx new file mode 100644 index 000000000..a5b02dd59 Binary files /dev/null and b/templates/platform/IP Address Plan.xlsx differ diff --git a/templates/platform/ansible.yaml b/templates/platform/ansible.yaml deleted file mode 100644 index d6d4feb8f..000000000 --- a/templates/platform/ansible.yaml +++ /dev/null @@ -1,287 +0,0 @@ -- name: CAF Terraform - Generate Azure Subscription Vending Machine (asvm) configuration files - hosts: localhost - vars: - connectivity_virtual_wan: "{{ lookup('file', '{{ config_folder }}/connectivity_virtual_wan.yaml') | from_yaml }}" - connectivity_virtual_hub: "{{ lookup('file', '{{ config_folder }}/connectivity_virtual_hub.yaml') | from_yaml }}" - connectivity_firewall: "{{ lookup('file', '{{ config_folder }}/connectivity_firewall.yaml') | from_yaml }}" - connectivity_firewall_policies: "{{ lookup('file', '{{ config_folder }}/connectivity_firewall_policies.yaml') | from_yaml }}" - connectivity_vpn_sites: "{{ lookup('file', '{{ config_folder }}/connectivity_vpn_sites.yaml') | from_yaml }}" - connectivity_vpn_gateway_connections: "{{ lookup('file', '{{ config_folder }}/connectivity_vpn_gateway_connections.yaml') | from_yaml }}" - connectivity_express_routes: "{{ lookup('file', '{{ config_folder }}/connectivity_express_routes.yaml') | from_yaml }}" - connectivity_express_route_peerings: "{{ lookup('file', '{{ config_folder }}/connectivity_express_route_peerings.yaml') | from_yaml }}" - identity: "{{ lookup('file', '{{ config_folder }}/identity.yaml') | from_yaml }}" - management: "{{ lookup('file', '{{ config_folder }}/management.yaml') | from_yaml }}" - subscriptions: "{{ lookup('file', '{{ config_folder }}/subscriptions.yaml') | from_yaml }}" - mg: "{{ lookup('file', '{{ config_folder }}/eslz/archetype_config_overrides.caf.platform.yaml') | from_yaml }}" - mg_custom: "{{ lookup('file', '{{ config_folder }}/eslz/custom_landing_zones.caf.platform.yaml') | from_yaml }}" - mg_struture: "{{ lookup('file', '{{ config_folder }}/eslz/structure.caf.platform.yaml') | from_yaml }}" - tfstates: "{{ lookup('file', '{{ config_folder }}/tfstates.yaml') | from_yaml }}" - base_templates_folder: "{{ base_templates_folder }}" - boostrap_launchpad: boostrap_launchpad | default(false) - deploy_subscriptions: deploy_subscriptions | default(false) - - - tasks: - - - name: "Load variable for platform config" - include_vars: - name: config - dir: "{{config_folder_platform | default(config_folder)}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "caf.platform.yaml|tfstates.caf.yaml|tfstates.yaml" - - - name: "Get latest cache folder" - set_fact: - job_cache_base_path: "/home/vscode/.terraform.cache" - destination_base: "{{ destination_base_path | default(config.configuration_folders.platform.destination_base_path) }}" - - - name: "Creates cache directory" - file: - path: "{{ job_cache_base_path }}/launchpad" - state: directory - - - name: "Destination folder" - debug: - msg: "{{destination_base}}" - - - name: "Content of config" - debug: - msg: "{{config}}" - -# -# Level 0 -# - -## launchpad - - - name: "[{{ level }}-{{ base_folder }}] launchpad" - import_tasks: "{{ level }}/{{ base_folder }}/ansible.yaml" - vars: - base_folder: "launchpad" - level: "level0" - subscription_key: launchpad - -## credentials - - name: "[{{ level }}-{{ base_folder }}] Setup credentials" - import_tasks: "{{ level }}/{{ base_folder }}/ansible.yaml" - when: - - config.platform_identity.azuread_identity_mode == "service_principal" - - launchpad_tfstate_exists.rc == 0 - vars: - base_folder: "credentials" - level: "level0" - subscription_key: launchpad_credentials - - - name: "[{{ level }}-{{ base_folder }}] Clean-up directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: absent - when: - - config.platform_identity.azuread_identity_mode == "logged_in_user" - - launchpad_tfstate_exists.rc == 0 - vars: - base_folder: "credentials" - level: "level0" - -## billing_subscription_role_delegations - - name: "[{{ level }}-{{ base_folder }}] Configure subscription role delegations" - import_tasks: "{{ level }}/{{ base_folder }}/ansible.yaml" - when: ((config.caf_terraform.billing_subscription_role_delegations is defined) and (config.platform_identity.azuread_identity_mode == "service_principal") and (launchpad_tfstate_exists.rc == 0) and (credentials_tfstate_exists is not skipped)) - vars: - base_folder: "billing_subscription_role_delegations" - level: "level0" - - - name: "[{{ level }}-{{ base_folder }}] Clean-up directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: absent - when: - - level0_billing_subscription_role_delegations is skipped - vars: - base_folder: "billing_subscription_role_delegations" - level: "level0" - - -# -# Level 1 -# - -## subscriptions - - name: "{{ level }}-{{ base_folder }} | Create platform subscriptions" - import_tasks: "{{ level }}/{{ base_folder }}/ansible.yaml" - when: (config.platform_core_setup.enterprise_scale.subscription_deployment_mode == "dedicated_new" and config.platform_identity.azuread_identity_mode != "logged_in_user" and launchpad_tfstate_exists is succeeded and credentials_tfstate_exists is succeeded) - vars: - base_folder: "subscriptions" - level: "level1" - - - name: "{{ level }}-{{ base_folder }} | Clean-up directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: absent - when: - - level1_subscriptions is skipped - vars: - base_folder: "subscriptions" - level: "level1" - -## management - - name: "{{ level }}-{{ base_folder }} | Management services" - import_tasks: "{{ level }}/{{ base_folder }}/ansible.yaml" - when: - - (config.platform_management.enable | bool) - - level1_subscriptions is not skipped - - platform_subscriptions_details is defined - - vars: - base_folder: "management" - level: "level1" - subscription_key: management - -## identity - - name: "{{ level }}-{{ base_folder }} | Identity services" - import_tasks: "{{ level }}/{{ base_folder }}/ansible.yaml" - when: - # - config.platform_core_setup.enterprise_scale.subscription_deployment_mode != "single_reuse" - - launchpad_tfstate_exists is not skipped - - credentials_tfstate_exists is not skipped - - level1_subscriptions is not skipped - - platform_subscriptions_details is defined - - identity.subscriptions is defined - - vars: - base_folder: "identity" - level: "level1" - subscription_key: identity - -## eslz - - name: "{{ level }}-{{ base_folder }} | Enterprise-scale services" - import_tasks: "{{ level }}/{{ base_folder }}/ansible.yaml" - when: - - (config.platform_core_setup.enterprise_scale.enable | bool) - - ( (config.platform_core_setup.enterprise_scale.enable | bool) and (level1_subscriptions is not skipped) ) or (config.platform_core_setup.enterprise_scale.subscription_deployment_mode == "single_reuse") - - (platform_subscriptions_details is defined) or (config.platform_core_setup.enterprise_scale.subscription_deployment_mode == "single_reuse") - - platform_subscriptions_details.identity is defined - - platform_subscriptions_details.management is defined - - vars: - base_folder: "eslz" - level: "level1" - - -# -# Level 2 -# - -## asvm - - name: "{{ level }}-{{ base_folder }} | Azure Subscription Vending Machine (asvm)" - import_tasks: "{{ level }}/{{ base_folder }}/ansible.yaml" - when: - - config.platform_core_setup.enterprise_scale.enable_azure_subscription_vending_machine - - launchpad_azuread_groups is defined - - platform_subscriptions_details is defined - vars: - base_folder: "asvm" - level: "level2" - subscription_key: asvm - -## Connectivity - - name: "{{ level }}-{{ base_folder }} | Connectivity services" - import_tasks: "{{ level }}/{{ base_folder }}/ansible.yaml" - when: - - ( (config.networking_topology.deployment_option == "virtual_wan") or (config.platform_identity.azuread_identity_mode == 'logged_in_user') ) - - (platform_subscriptions_details is defined) or (config.platform_core_setup.enterprise_scale.subscription_deployment_mode == "single_reuse") - vars: - base_folder: "connectivity" - level: "level2" - folders: - - virtual_wan - -## identity - - name: "{{ level }}-{{ base_folder }} | Identity services" - import_tasks: "{{ level }}/{{ base_folder }}/ansible.yaml" - when: - - config.platform_core_setup.enterprise_scale.subscription_deployment_mode != "single_reuse" - - launchpad_tfstate_exists is not skipped - - credentials_tfstate_exists is not skipped - - level1_subscriptions is not skipped - - (platform_subscriptions_details is defined) or (config.platform_core_setup.enterprise_scale.subscription_deployment_mode == "single_reuse") - - vars: - base_folder: "identity" - level: "level2" - -## Platform readme - - - name: "[{{ base_templates_folder }}] readme" - ansible.builtin.template: - src: "{{ base_templates_folder }}/readme.md" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/readme.md" - force: yes - -# -# Formatting & Linters -# - - - name: Terraform Formatting - shell: | - terraform fmt -recursive {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }} - -# - name: Level 2 - identity -# hosts: localhost -# vars: -# config: "{{ lookup('file', '{{ config_folder }}/platform.yaml') | from_yaml }}" -# identity: "{{ lookup('file', '{{ config_folder }}/identity.yaml') | from_yaml }}" -# connectivity_virtual_wan: "{{ lookup('file', '{{ config_folder }}/connectivity_virtual_wan.yaml') | from_yaml }}" -# connectivity_virtual_hub: "{{ lookup('file', '{{ config_folder }}/connectivity_virtual_hub.yaml') | from_yaml }}" -# connectivity_firewall: "{{ lookup('file', '{{ config_folder }}/connectivity_firewall.yaml') | from_yaml }}" -# connectivity_firewall_policies: "{{ lookup('file', '{{ config_folder }}/connectivity_firewall_policies.yaml') | from_yaml }}" -# cidr: "{{ lookup('file', '{{ config_folder }}/cidr.yaml') | from_yaml }}" -# tfstates: "{{ lookup('file', '{{ config_folder }}/tfstates.yaml') | from_yaml }}" -# base_templates_folder: /tf/caf/templates/platform -# base_folder: identity -# level: level2 -# folders: -# - virtual_wan - - -# tasks: -# - name: Creates {{ level }} directory -# file: -# path: "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ level }}" -# state: directory - -# - name: Creates {{ base_folder }} directory strcture -# file: -# path: "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ level }}/{{ base_folder }}" -# state: directory - -# - name: "{{ base_folder }} - Readme" -# ansible.builtin.template: -# src: "{{ item }}" -# dest: "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" -# force: yes -# with_fileglob: -# - "{{ level }}/{{ base_folder }}/*.md" - -# - name: "{{ base_folder }} - adds" -# include_tasks: "{{ base_templates_folder }}/{{ level }}/{{ base_folder }}/platform.yaml" - - - -# # -# # Pipelines -# # -# - name: Pipelines -# hosts: localhost -# vars: -# config: "{{ lookup('file', '{{ config_folder }}/platform.yaml') | from_yaml }}" -# connectivity: "{{ lookup('file', '{{ config_folder }}/connectivity.yaml') | from_yaml }}" -# cidr: "{{ lookup('file', '{{ config_folder }}/cidr.yaml') | from_yaml }}" -# tfstates: "{{ lookup('file', '{{ config_folder }}/tfstates.yaml') | from_yaml }}" -# base_templates_folder: /tf/caf/templates/platform -# base_folder: pipelines - -# tasks: -# - import_tasks: "{{ base_folder }}/platform.yaml" -# - debug: msg="You can now proceed to the next steps and execute the deployment. Refer to the readme in {{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/README.md" diff --git a/templates/platform/deploy_platform.sh b/templates/platform/deploy_platform.sh new file mode 100755 index 000000000..853a96326 --- /dev/null +++ b/templates/platform/deploy_platform.sh @@ -0,0 +1,12 @@ +#! /bin/bash + +export ANSIBLE_DISPLAY_SKIPPED_HOSTS=False + +ansible-playbook /tf/caf/landingzones/templates/ansible/walk-through-single.yaml \ + -e topology_file=/tf/caf/landingzones/templates/platform/single_subscription.yaml \ + -e public_templates_folder=/tf/caf/landingzones/templates \ + -e landingzones_folder=/tf/caf/landingzones \ + -e platform_configuration_folder=/tf/caf/configuration \ + -e platform_definition_folder=/tf/caf/platform/definition \ + -e platform_template_folder=/tf/caf/platform/template \ + --extra-vars "@/tf/caf/landingzones/templates/platform/template_topology.yaml" diff --git a/templates/platform/generic/readme.md b/templates/platform/generic/readme.md new file mode 100644 index 000000000..175e52d88 --- /dev/null +++ b/templates/platform/generic/readme.md @@ -0,0 +1,33 @@ + +```bash +#Note: close previous session if you logged with a different service principal using --impersonate-sp-from-keyvault-url +rover logout + +# login a with a user member of the caf-maintainers group +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} + +rover \ +{% if resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" and keyvaults is defined %} + --impersonate-sp-from-keyvault-url {{ keyvaults[ tfstate_object.identity_aad_key].vault_uri }} \ +{% elif resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" and keyvault_scl is defined %} + --impersonate-sp-from-keyvault-url {{ keyvault_scl.stdout }} \ +{% endif %} + -lz /tf/caf/landingzones/caf_solution \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ +{% if platform_subscriptions_details is defined %} + -target_subscription {{ platform_subscriptions_details[resources.subscriptions.keys() | first].subscription_id }} \ +{% elif subscriptions.platform_subscriptions[resources.subscriptions.keys() | first].subscription_id is defined %} + -target_subscription {{ subscriptions.platform_subscriptions[resources.subscriptions.keys() | first].subscription_id }} \ +{% else %} + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ +{% endif %} + -tfstate {{ tfstate_object.tfstate }} \ + -env {{ resources.caf_environment }} \ + -level {{ level }} \ + -w {{ tfstate_object.workspace | default('tfstate') }} \ + -p ${TF_DATA_DIR}/{{ tfstate_object.tfstate }}.tfplan \ + -a plan + +``` + diff --git a/templates/platform/level0/README.md b/templates/platform/level0/README.md index 49212d2d2..29aea9e3e 100644 --- a/templates/platform/level0/README.md +++ b/templates/platform/level0/README.md @@ -1,5 +1,5 @@ ## Introduction -This directory contains details around the configurations which are deployed to the config. All the components are deployed in a layered approach. +This directory contains details around the configurations which are deployed to the resources. All the components are deployed in a layered approach. ### Level 0 Deployment Elements | Resources Deployed @@ -15,7 +15,7 @@ Platform- Subscriptions | Deploys platform subscriptions such as managemen management | Foundation resources to management subscription such as service health alerts, log analytics gitops | This directory hosts the Azure DevOps configurations such as Azure DevOps projects, pipelines variable groups Identity | This hosts the identities for the pipelines and identies are pushed to vault after created -Enterprise scale - Platform | Deploys eslz resources suych as management groups, custom roles, policies, and map that to management groups +Azure Landing zone - Platform | Deploys Azure landing zone resources such as management groups, custom roles, policies, and map that to management groups ### Level 2 diff --git a/templates/platform/level0/billing_subscription_role_delegations/ansible.yaml b/templates/platform/level0/billing_subscription_role_delegations/ansible.yaml index bdcf02efd..e63cc182d 100644 --- a/templates/platform/level0/billing_subscription_role_delegations/ansible.yaml +++ b/templates/platform/level0/billing_subscription_role_delegations/ansible.yaml @@ -1,21 +1,21 @@ - name: "[{{ level }}-{{ base_folder }}] Clean-up directory" file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" + path: "{{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" state: absent - when: config.configuration_folders.platform.cleanup_destination | bool + when: resources.configuration_folders.platform.cleanup_destination | bool - name: "[{{ level }}-{{ base_folder }}] Creates directory" - when: config.caf_terraform.billing_subscription_role_delegations.enable == true + when: resources.billing_subscription_role_delegations.enable == true register: level0_billing_subscription_role_delegations file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" + path: "{{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" state: directory - name: "[{{ level }}-{{ base_folder }}] subscription role delegation" - when: config.caf_terraform.billing_subscription_role_delegations.enable == true + when: resources.billing_subscription_role_delegations.enable == true ansible.builtin.template: src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" + dest: "{{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" force: yes with_fileglob: - "{{ level }}/{{ base_folder }}/*.tfvars.j2" diff --git a/templates/platform/level0/billing_subscription_role_delegations/landingzone.tfvars.j2 b/templates/platform/level0/billing_subscription_role_delegations/landingzone.tfvars.j2 index 3d6c53658..810f750d0 100644 --- a/templates/platform/level0/billing_subscription_role_delegations/landingzone.tfvars.j2 +++ b/templates/platform/level0/billing_subscription_role_delegations/landingzone.tfvars.j2 @@ -1,12 +1,12 @@ landingzone = { backend_type = "{{ caf_terraform.launchpad.backend_type | default("azurerm")}}" - global_settings_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" - level = "{{ config.tfstates.platform.launchpad.level }}" - key = "{{ config.tfstates.platform.billing_subscription_role_delegations.lz_key_name }}" + global_settings_key = "{{ resources.tfstates.platform.launchpad.lz_key_name }}" + level = "{{ resources.tfstates.platform.launchpad.level }}" + key = "{{ resources.tfstates.platform.billing_subscription_role_delegations.lz_key_name }}" tfstates = { - {{ config.tfstates.platform.launchpad.lz_key_name }} = { + {{ resources.tfstates.platform.launchpad.lz_key_name }} = { level = "current" - tfstate = "{{ config.tfstates.platform.launchpad.tfstate }}" + tfstate = "{{ resources.tfstates.platform.launchpad.tfstate }}" } } } diff --git a/templates/platform/level0/billing_subscription_role_delegations/readme.md b/templates/platform/level0/billing_subscription_role_delegations/readme.md index 5e25a441a..478e1ff46 100644 --- a/templates/platform/level0/billing_subscription_role_delegations/readme.md +++ b/templates/platform/level0/billing_subscription_role_delegations/readme.md @@ -3,20 +3,19 @@ Set-up the subscription delegations for platform and landingzone subscriptions ```bash -# Login to the subscription {{ config.caf_terraform.launchpad.subscription_name }} with the user {{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner }} -rover login -t {{ config.platform_identity.tenant_name }} +# Login to the subscription {{ resources.caf_launchpad.subscription_name }} with the user {{ resources.billing_subscription_role_delegations.azuread_user_ea_account_owner }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} rover \ - -lz /tf/caf/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/level0/billing_subscription_role_delegations \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ config.tfstates.platform.billing_subscription_role_delegations.tfstate }} \ - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - -log-severity {{ config.gitops.rover_log_error }} \ + -lz {{ landingzones_folder }}/caf_solution \ + -var-folder {{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/level0/billing_subscription_role_delegations \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ + -tfstate {{ resources.tfstates.platform.billing_subscription_role_delegations.tfstate }} \ + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ -launchpad \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.billing_subscription_role_delegations.tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.billing_subscription_role_delegations.tfstate }}.tfplan \ -a plan rover logout @@ -26,19 +25,20 @@ rover logout # Run rover ignite to generate the next level configuration files To execute this step you need to login with on of the CAF maintainers: -{% for maintainer in config.platform_identity.caf_platform_maintainers %} +{% for maintainer in resources.azure_landing_zones.identity.caf_platform_maintainers %} - {{ maintainer }} {% endfor %} ```bash -rover login -t {{ config.platform_identity.tenant_name }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} rover ignite \ - --playbook /tf/caf/starter/templates/platform/ansible.yaml \ + --playbook {{ landingzones_folder }}/ansible.yaml \ -e base_templates_folder={{ base_templates_folder }} \ -e resource_template_folder={{resource_template_folder}} \ - -e config_folder={{ config_folder }} + -e config_folder={{ config_folder }} \ + -e landingzones_folder={{ landingzones_folder }} ``` diff --git a/templates/platform/level0/billing_subscription_role_delegations/subscription_creation_roles.tfvars.j2 b/templates/platform/level0/billing_subscription_role_delegations/subscription_creation_roles.tfvars.j2 index af20cb1ea..ec1470b08 100644 --- a/templates/platform/level0/billing_subscription_role_delegations/subscription_creation_roles.tfvars.j2 +++ b/templates/platform/level0/billing_subscription_role_delegations/subscription_creation_roles.tfvars.j2 @@ -2,18 +2,18 @@ subscription_billing_role_assignments = { # Delegated accounts who can create subscriptions. # Used by Gitops pipelines subscription_creators = { - billing_account_name = "{{ config.caf_terraform.billing_subscription_role_delegations.billing_account_name }}" - enrollment_account_name = "{{ config.caf_terraform.billing_subscription_role_delegations.enrollment_account_name }}" + billing_account_name = "{{ resources.billing_subscription_role_delegations.billing_account_name }}" + enrollment_account_name = "{{ resources.billing_subscription_role_delegations.enrollment_account_name }}" billing_role_definition_name = "Enrollment account subscription creator" principals = { azuread_service_principals = { subscription_creation_platform = { - lz_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.launchpad.lz_key_name }}" key = "subscription_creation_platform" } subscription_creation_landingzones = { - lz_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.launchpad.lz_key_name }}" key = "subscription_creation_landingzones" } } diff --git a/templates/platform/level0/credentials/ansible.yaml b/templates/platform/level0/credentials/ansible.yaml deleted file mode 100644 index f5abc0fed..000000000 --- a/templates/platform/level0/credentials/ansible.yaml +++ /dev/null @@ -1,154 +0,0 @@ -- name: "[{{ level }}-{{ base_folder }}] - Set variables" - set_fact: - destination_path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - -- name: "[{{ level }}-{{ base_folder }}] - Load variable for launchpad" - include_vars: - name: resources - dir: "{{config_folder}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "launchpad_credentials.yaml" - -- debug: - msg: "{{resources}}" - -- name: "[{{ level }}-{{ base_folder }}] Clean-up directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: absent - when: config.configuration_folders.platform.cleanup_destination | bool - -- name: "[{{ level }}-{{ base_folder }}] Creates directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: directory - -# -# resource_groups -# -- name: "[{{ level }}-{{ base_folder }}] - resource_groups" - when: - - resources.subscriptions[subscription_key].resource_groups is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/resource_groups.tfvars.j2" -# -# azuread_credentials -# -- name: "[{{ level }}-{{ subscription_key }}] - credentials - azuread_credentials" - when: - - resources.subscriptions[subscription_key].azuread_credentials is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/azuread_credentials.tfvars.j2" - -# -# azuread_applications -# -- name: "[{{ level }}-{{ subscription_key }}] - credentials - azuread_applications" - when: - - resources.subscriptions[subscription_key].azuread_applications is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/azuread_applications.tfvars.j2" - -# -# azuread_credential_policies -# -- name: "[{{ level }}-{{ subscription_key }}] - credentials - azuread_credential_policies" - when: - - resources.subscriptions[subscription_key].azuread_credential_policies is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/azuread_credential_policies.tfvars.j2" - -# -# azuread_service_principals -# -- name: "[{{ level }}-{{ subscription_key }}] - credentials - azuread_service_principals" - when: - - resources.subscriptions[subscription_key].azuread_service_principals is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/azuread_service_principals.tfvars.j2" - - -# -# keyvaults -# -- name: "[{{ level }}-{{ subscription_key }}] - credentials - keyvaults" - when: - - resources.subscriptions[subscription_key].keyvaults is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/keyvaults.tfvars.j2" - -# -# keyvault_access_policies -# -- name: "[{{ level }}-{{ subscription_key }}] - credentials - keyvault_access_policies" - when: - - resources.subscriptions[subscription_key].keyvault_access_policies is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/keyvault_access_policies.tfvars.j2" - - -- name: "[{{ level }}-{{ base_folder }}] generate configuration files." - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/*.tfvars.j2" - -- name: "[{{ level }}-{{ base_folder }}] deploy." - when: boostrap_launchpad | bool - shell: | - /tf/rover/rover.sh \ - -lz /tf/caf/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ tfstates.launchpad_credentials.tfstate }} \ - -launchpad \ - -log-severity {{ config.gitops.rover_log_error }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -a apply - args: - warn: no - -- debug: - msg: "{{ keyvaults.cred_subscription_creation_platform.vault_uri }}" - when: credentials_tfstate_exists.rc == 0 - -- name: "[{{ level }}-{{ base_folder }}] generate configuration files." - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/*.md" diff --git a/templates/platform/level0/credentials/dynamic_secrets.tfvars.j2 b/templates/platform/level0/credentials/dynamic_secrets.tfvars.j2 index 3ac296361..0966415cb 100644 --- a/templates/platform/level0/credentials/dynamic_secrets.tfvars.j2 +++ b/templates/platform/level0/credentials/dynamic_secrets.tfvars.j2 @@ -14,7 +14,7 @@ dynamic_keyvault_secrets = { } tenant_id = { secret_name = "tenant-id" - value = "{{ config.caf_terraform.launchpad.tenant_id }}" # {{ config.platform_identity.tenant_name }} Tenant + value = "{{ resources.caf_launchpad.tenant_id }}" # {{ resources.azure_landing_zones.identity.tenant_name }} Tenant } } diff --git a/templates/platform/level0/credentials/landingzone.tfvars.j2 b/templates/platform/level0/credentials/landingzone.tfvars.j2 index 30d5e3f8f..f65598b8f 100644 --- a/templates/platform/level0/credentials/landingzone.tfvars.j2 +++ b/templates/platform/level0/credentials/landingzone.tfvars.j2 @@ -1,12 +1,12 @@ landingzone = { backend_type = "{{ caf_terraform.launchpad.backend_type | default("azurerm")}}" - global_settings_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" - level = "{{ config.tfstates.platform.launchpad.level }}" - key = "{{ config.tfstates.platform.launchpad_credentials.lz_key_name }}" + global_settings_key = "{{ resources.tfstates.platform.launchpad.lz_key_name }}" + level = "{{ resources.tfstates.platform.launchpad.level }}" + key = "{{ resources.tfstates.platform.launchpad_credentials.lz_key_name }}" tfstates = { - {{ config.tfstates.platform.launchpad.lz_key_name }} = { + {{ resources.tfstates.platform.launchpad.lz_key_name }} = { level = "current" - tfstate = "{{ config.tfstates.platform.launchpad.tfstate }}" + tfstate = "{{ resources.tfstates.platform.launchpad.tfstate }}" } } } diff --git a/templates/platform/level0/credentials/readme.md b/templates/platform/level0/credentials/readme.md index 23353e464..1f88a380e 100644 --- a/templates/platform/level0/credentials/readme.md +++ b/templates/platform/level0/credentials/readme.md @@ -3,47 +3,45 @@ ```bash # For manual bootstrap: -# Login to the subscription {{ config.caf_terraform.launchpad.subscription_name }} with the user {{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner }} -rover login -t {{ config.platform_identity.tenant_name }} +# Login to the subscription {{ resources.caf_launchpad.subscription_name }} with the user {{ resources.billing_subscription_role_delegations.azuread_user_ea_account_owner }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} rover \ -{% if ((config.platform_identity.azuread_identity_mode != "logged_in_user") and (credentials_tfstate_exists.rc == 0)) %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_identity.vault_uri }} \ +{% if resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" and keyvaults is defined %} + --impersonate-sp-from-keyvault-url {{ keyvaults[tfstate_object.identity_aad_key].vault_uri }} \ {% endif %} - -lz /tf/caf/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ config.tfstates.platform.launchpad_credentials.tfstate }} \ + -lz {{ landingzones_folder }}/caf_solution \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ + -tfstate {{ resources.tfstates.platform.launchpad_credentials.tfstate }} \ -launchpad \ - -log-severity {{ config.gitops.rover_log_error }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.launchpad_credentials.tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.launchpad_credentials.tfstate }}.tfplan \ -a plan ``` -If the plan is not successfull you need to come back to the yaml contoso.caf.platform.yaml, fix the values, re-execute the rover ignite and then rover plan. +If the plan is not successfull you need to come back to the yaml ignite.yaml, fix the values, re-execute the rover ignite and then rover plan. ```bash # On success plan, execute rover \ -{% if ((config.platform_identity.azuread_identity_mode != "logged_in_user") and (credentials_tfstate_exists.rc == 0)) %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_identity.vault_uri }} \ +{% if resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" and keyvaults is defined %} + --impersonate-sp-from-keyvault-url {{ keyvaults[tfstate_object.identity_aad_key].vault_uri }} \ {% endif %} - -lz /tf/caf/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ config.tfstates.platform.launchpad_credentials.tfstate }} \ + -lz {{ landingzones_folder }}/caf_solution \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ + -tfstate {{ resources.tfstates.platform.launchpad_credentials.tfstate }} \ -launchpad \ - -log-severity {{ config.gitops.rover_log_error }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.launchpad_credentials.tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.launchpad_credentials.tfstate }}.tfplan \ -a apply ``` @@ -51,11 +49,8 @@ rover \ ```bash # On success, re-execute the rover ignite -rover ignite \ - --playbook /tf/caf/landingzones/templates/platform/ansible.yaml \ - -e base_templates_folder={{ base_templates_folder }} \ - -e resource_template_folder={{resource_template_folder}} \ - -e config_folder={{ config_folder }} +ansible-playbook {{public_templates_folder}}/ansible/ansible.yaml \ + --extra-vars "@{{platform_definition_folder}}/ignite.yaml" ``` @@ -67,7 +62,7 @@ Just re-execute the plan/apply command as above and you will notice the rover wi When you have successfully deployed the launchpad you can move to the next step. -{% if config.caf_terraform.billing_subscription_role_delegations.enable %} +{% if resources.billing_subscription_role_delegations.enable %} [[Deploy the billing subscription role delegation](../billing_subscription_role_delegations/readme.md) {% else %} [Deploy the subscription services](../../level1/subscriptions/readme.md) diff --git a/templates/platform/level0/credentials/role_mappings.tfvars.j2 b/templates/platform/level0/credentials/role_mappings.tfvars.j2 index 16b3339f7..cb7c67a3e 100644 --- a/templates/platform/level0/credentials/role_mappings.tfvars.j2 +++ b/templates/platform/level0/credentials/role_mappings.tfvars.j2 @@ -6,7 +6,7 @@ role_mapping = { built_in_role_mapping = { -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' %} resource_groups = { sp_credentials = { "Contributor" = { @@ -14,7 +14,7 @@ role_mapping = { keys = [ "identity" ] - lz_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.launchpad.lz_key_name }}" } } } diff --git a/templates/platform/level0/launchpad/ansible.yaml b/templates/platform/level0/launchpad/ansible.yaml index bd329f53c..096b68067 100644 --- a/templates/platform/level0/launchpad/ansible.yaml +++ b/templates/platform/level0/launchpad/ansible.yaml @@ -1,188 +1,115 @@ -- name: "[{{ level }}-{{ base_folder }}] - Set variables" - set_fact: - destination_path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - -- name: "[{{ level }}-{{ base_folder }}] - Load variable for launchpad" - include_vars: - name: resources - dir: "{{config_folder}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "launchpad.yaml|level0.yaml|configuration.caf.platform.yaml" - -- debug: - msg: "{{resources}}" - -- name: "[{{ level }}-{{ base_folder }}] Clean-up directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: absent - when: config.configuration_folders.platform.cleanup_destination | bool - -- name: "[{{ level }}-{{ base_folder }}] Creates directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: directory - - # -# resource_groups +# Check if the launchpad and the credentials for service principal have been deployed. # -- name: "[{{ level }}-{{ base_folder }}] - resources - resource_groups" - when: - - resources.subscriptions[subscription_key].resource_groups is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/resource_groups.tfvars.j2" - - -- name: "[{{ level }}-{{ base_folder }}] launchpad" - ansible.builtin.template: - src: "{{ level }}/{{ base_folder }}/{{ item }}.tfvars.j2" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item }}.tfvars" - force: yes - loop: - - dynamic_secrets - - global_settings - - keyvaults - - landingzone - - role_mappings - - storage_accounts - -- name: "[{{ level }}-{{ base_folder }}] Clean-up identity files" +- name: "Creates cache directory" file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item }}.tfvars" - state: absent - when: config.platform_identity.azuread_identity_mode == "logged_in_user" - loop: - - azuread_api_permissions - - azuread_applications - - azuread_group_members - - azuread_groups - - azuread_roles - - keyvault_policies - - service_principals - -- name: "[{{ level }}-{{ base_folder }}] lauchpad - identity - service_principal" - ansible.builtin.template: - src: "{{ level }}/{{ base_folder }}/{{ item }}.tfvars.j2" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item }}.tfvars" - force: yes - when: config.platform_identity.azuread_identity_mode != 'logged_in_user' - loop: - - azuread_api_permissions - - azuread_applications - - azuread_group_members - - azuread_groups - - azuread_roles - - keyvault_policies - - service_principals - -- name: "[{{ level }}-{{ base_folder }}] Deploy the launchpad" - when: boostrap_launchpad | bool | default(false) - shell: | - /tf/rover/rover.sh \ - -lz /tf/caf/landingzones/caf_launchpad \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ config.tfstates.platform.launchpad.tfstate }} \ - -log-severity {{ config.gitops.rover_log_error }} \ - -launchpad \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -a apply + path: "{{ job_cache_base_path }}/launchpad" + state: directory -- name: "[{{ level }}-{{ base_folder }}] Get tfstate account name" +- name: "[{{resources[tfstate].relative_destination_folder}}] Get tfstate account name" register: launchpad_storage_account shell: | az storage account list \ - --subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - --query "[?tags.caf_tfstate=='{{ config.tfstates.platform.launchpad.level }}' && tags.caf_environment=='{{ config.caf_terraform.launchpad.caf_environment }}'].{name:name}[0]" -o json | jq -r .name + --subscription {{ resources.caf_launchpad.subscription_id }} \ + --query "[?tags.caf_tfstate=='{{ tfstate_object.level }}' && tags.caf_environment=='{{ resources.caf_environment }}'].{name:name}[0]" -o json | jq -r .name - debug: msg: "{{launchpad_storage_account}}" -- name: "[{{ level }}-{{ base_folder }}] Get launchpad tfstate details" +- name: "[{{resources[tfstate].relative_destination_folder}}] Get launchpad tfstate details" register: launchpad_tfstate_exists ignore_errors: true shell: | az storage blob download \ - --name "{{ config.tfstates.platform.launchpad.tfstate }}" \ + --name "{{ resources.tfstates.platform.launchpad.tfstate }}" \ --account-name "{{ launchpad_storage_account.stdout | default('') }}" \ - --container-name "{{ config.tfstates.platform.launchpad.workspace | default('tfstate') }}" \ + --container-name "{{ resources.tfstates.platform.launchpad.workspace | default('tfstate') }}" \ --auth-mode "login" \ - --file "~/.terraform.cache/launchpad/{{ config.tfstates.platform.launchpad.tfstate }}" + --file "~/.terraform.cache/launchpad/{{ resources.tfstates.platform.launchpad.tfstate }}" -- name: "[{{ level }}-{{ base_folder }}] Get subscription_creation_landingzones details" +- debug: + msg: "{{launchpad_tfstate_exists}}" + +- name: "[{{resources[tfstate].relative_destination_folder}}] Get subscription_creation_landingzones details" when: - launchpad_tfstate_exists.rc == 0 - - config.platform_core_setup.enterprise_scale.enable_azure_subscription_vending_machine - shell: "cat ~/.terraform.cache/launchpad/{{ config.tfstates.platform.launchpad.tfstate }}" + - resources.enable_azure_subscription_vending_machine + shell: "cat ~/.terraform.cache/launchpad/{{ resources.tfstates.platform.launchpad.tfstate }}" register: launchpad_tfstate -- name: "[{{ level }}-{{ base_folder }}] Get launchpad json data" +- name: "[{{resources[tfstate].relative_destination_folder}}] Get launchpad json data" when: - launchpad_tfstate_exists.rc == 0 - - config.platform_core_setup.enterprise_scale.enable_azure_subscription_vending_machine + - resources.enable_azure_subscription_vending_machine set_fact: scljsondata: "{{ launchpad_tfstate.stdout | from_json }}" -- name: "[{{ level }}-{{ base_folder }}] set launchpad_azuread_groups" +- name: "[{{resources[tfstate].relative_destination_folder}}] set launchpad_azuread_groups" when: - launchpad_tfstate_exists.rc == 0 - - config.platform_core_setup.enterprise_scale.enable_azure_subscription_vending_machine + - resources.enable_azure_subscription_vending_machine set_fact: launchpad_azuread_groups: "{{ scljsondata | json_query(path) }}" vars: path: 'outputs.objects.value.launchpad.azuread_groups' -- name: "[{{ level }}-{{ base_folder }}] Get credentials tfstate details" +- name: "[{{resources[tfstate].relative_destination_folder}}] Get credentials tfstate details for {{ resources.tfstates.platform.launchpad_credentials.tfstate }} from {{ launchpad_storage_account.stdout }}/{{ resources.tfstates.platform.launchpad.workspace | default('tfstate') }}" register: credentials_tfstate_exists ignore_errors: true shell: | az storage blob download \ - --name "{{ config.tfstates.platform.launchpad_credentials.tfstate }}" \ + --name "{{ resources.tfstates.platform.launchpad_credentials.tfstate }}" \ --account-name "{{ launchpad_storage_account.stdout }}" \ - --container-name "{{ config.tfstates.platform.launchpad.workspace | default('tfstate') }}" \ + --container-name "{{ resources.tfstates.platform.launchpad.workspace | default('tfstate') }}" \ --auth-mode "login" \ - --file "~/.terraform.cache/launchpad/{{ config.tfstates.platform.launchpad_credentials.tfstate }}" + --file "~/.terraform.cache/launchpad/{{ resources.tfstates.platform.launchpad_credentials.tfstate }}" -- name: "[{{ level }}-{{ base_folder }}] Get launchpad_credentials details" - when: credentials_tfstate_exists.rc == 0 - shell: "cat ~/.terraform.cache/launchpad/{{ config.tfstates.platform.launchpad_credentials.tfstate }}" +- name: "[{{resources[tfstate].relative_destination_folder}}] Get launchpad_credentials details" + when: + - launchpad_tfstate_exists.rc == 0 + - credentials_tfstate_exists.rc == 0 + shell: "cat ~/.terraform.cache/launchpad/{{ resources.tfstates.platform.launchpad_credentials.tfstate }}" register: launchpad_credentials -- name: "[{{ level }}-{{ base_folder }}] Get launchpad_credentials json data" - when: credentials_tfstate_exists.rc == 0 +- name: "Keyvaults" + debug: + msg: + - "{{credentials_tfstate_exists}}" + - "{{ resources.tfstates.platform.launchpad_credentials.tfstate }}" + - "{{launchpad_credentials}}" + verbosity: 2 + when: + - launchpad_tfstate_exists.rc == 0 + - credentials_tfstate_exists.rc == 0 + +- name: "[{{resources[tfstate].relative_destination_folder}}] Get launchpad_credentials json data" + when: + - launchpad_tfstate_exists.rc == 0 + - credentials_tfstate_exists.rc == 0 set_fact: credjsondata: "{{ launchpad_credentials.stdout | from_json }}" -- name: "[{{ level }}-{{ base_folder }}] set keyvaults" - when: credentials_tfstate_exists.rc == 0 +- name: "[{{resources[tfstate].relative_destination_folder}}] set keyvaults" + when: + - launchpad_tfstate_exists.rc == 0 + - credentials_tfstate_exists.rc == 0 set_fact: keyvaults: "{{ credjsondata | json_query(path) }}" vars: - path: 'outputs.objects.value.launchpad_credentials_rotation.keyvaults' + path: 'outputs.objects.value.launchpad_credentials.keyvaults' -- name: "[{{ level }}-{{ base_folder }}] cleanup" - when: credentials_tfstate_exists.rc == 0 +- name: "[{{resources[tfstate].relative_destination_folder}}] cleanup" + when: + - launchpad_tfstate_exists.rc == 0 + - credentials_tfstate_exists.rc == 0 file: - path: "~/.terraform.cache/launchpad/{{ config.tfstates.platform.launchpad_credentials.tfstate }}" + path: "~/.terraform.cache/launchpad/{{ resources.tfstates.platform.launchpad_credentials.tfstate }}" state: absent -- name: "[{{ level }}-{{ base_folder }}] cleanup" - when: launchpad_tfstate_exists.rc == 0 +- name: "[{{resources[tfstate].relative_destination_folder}}] cleanup" + when: + - launchpad_tfstate_exists.rc == 0 + - credentials_tfstate_exists.rc == 0 file: - path: "~/.terraform.cache/launchpad/{{ config.tfstates.platform.launchpad.tfstate }}" + path: "~/.terraform.cache/launchpad/{{ resources.tfstates.platform.launchpad.tfstate }}" state: absent - -# Update readme -- name: "[{{ level }}-{{ base_folder }}] launchpad - readme" - ansible.builtin.template: - src: "{{ level }}/{{ base_folder }}/readme.md" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/readme.md" - force: yes \ No newline at end of file diff --git a/templates/platform/level0/launchpad/azuread_api_permissions.tfvars.j2 b/templates/platform/level0/launchpad/azuread_api_permissions.tfvars.j2 deleted file mode 100644 index 01e3e4656..000000000 --- a/templates/platform/level0/launchpad/azuread_api_permissions.tfvars.j2 +++ /dev/null @@ -1,60 +0,0 @@ - - -azuread_api_permissions = { - level0 = { - microsoft_graph = { - resource_app_id = "00000003-0000-0000-c000-000000000000" - resource_access = { - AppRoleAssignment_ReadWrite_All = { - id = "06b708a9-e830-4db3-a914-8e69da51d44f" - type = "Role" - } - DelegatedPermissionGrant_ReadWrite_All = { - id = "8e8e4742-1d95-4f68-9d56-6ee75648c72a" - type = "Role" - } - DelegatedPermissionGrant_ReadWrite_All = { - id = "18a4783c-866b-4cc7-a460-3d5e5662c884" - type = "Role" - } - } - } - } - identity = { - active_directory_graph = { - resource_app_id = "00000002-0000-0000-c000-000000000000" - resource_access = { - Application_ReadWrite_OwnedBy = { - id = "824c81eb-e3f8-4ee6-8f6d-de7f50d565b7" - type = "Role" - } - Directory_ReadWrite_All = { - id = "78c8a3c8-a07e-4b9e-af1b-b5ccab50a175" - type = "Role" - } - } - } - microsoft_graph = { - resource_app_id = "00000003-0000-0000-c000-000000000000" - resource_access = { - AppRoleAssignment_ReadWrite_All = { - id = "06b708a9-e830-4db3-a914-8e69da51d44f" - type = "Role" - } - DelegatedPermissionGrant_ReadWrite_All = { - id = "8e8e4742-1d95-4f68-9d56-6ee75648c72a" - type = "Role" - } - GroupReadWriteAll = { - id = "62a82d76-70ea-41e2-9197-370581804d09" - type = "Role" - } - RoleManagement_ReadWrite_Directory = { - id = "9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8" - type = "Role" - } - } - } - } - -} diff --git a/templates/platform/level0/launchpad/azuread_applications.tfvars.j2 b/templates/platform/level0/launchpad/azuread_applications.tfvars.j2 deleted file mode 100644 index f929fa977..000000000 --- a/templates/platform/level0/launchpad/azuread_applications.tfvars.j2 +++ /dev/null @@ -1,44 +0,0 @@ -azuread_applications = { - level0 = { - application_name = "sp-caf-level0" -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - } - identity = { - application_name = "sp-caf-identity" -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - } - management = { - application_name = "sp-caf-management" -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - } - eslz = { - application_name = "sp-caf-eslz" -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - } - connectivity = { - application_name = "sp-caf-connectivity" -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - } - subscription_creation_platform = { - application_name = "sp-caf-subscription-creation-platform" -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - } - subscription_creation_landingzones = { - application_name = "sp-caf-subscription-creation-landingzones" -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - } -} \ No newline at end of file diff --git a/templates/platform/level0/launchpad/azuread_group_members.tfvars.j2 b/templates/platform/level0/launchpad/azuread_group_members.tfvars.j2 index ec156a815..0779f818d 100644 --- a/templates/platform/level0/launchpad/azuread_group_members.tfvars.j2 +++ b/templates/platform/level0/launchpad/azuread_group_members.tfvars.j2 @@ -1,34 +1,38 @@ +{% if bootstrap.enable_azuread_groups %} azuread_groups_membership = { caf_platform_maintainers = { -{% if config.platform_identity.azuread_identity_mode == 'logged_in_user' %} +{% if bootstrap.azure_landing_zones.identity.azuread_identity_mode == 'logged_in_user' %} object_ids = { logged_in = { keys = ["user"] } } {% endif %} -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} +{% if bootstrap.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' %} members = { +{% if bootstrap.azure_landing_zones.identity.caf_platform_maintainers.user_principal_names is defined %} user_principal_names = [ - "{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner }}", -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user'%} -{% for user in config.platform_identity.caf_platform_maintainers %} + "{{ bootstrap.billing_subscription_role_delegations.azuread_user_ea_account_owner }}", +{% if bootstrap.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' and bootstrap.azure_landing_zones.identity.caf_platform_maintainers.user_principal_names is mapping%} +{% for user in bootstrap.azure_landing_zones.identity.caf_platform_maintainers.user_principal_names %} "{{ user }}", {% endfor %} {% endif %} ] +{% endif %} } {% endif %} } caf_platform_contributors = { members = { - user_principal_names = [ -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' and config.platform_identity.caf_platform_contributors is defined %} -{% for user in config.platform_identity.caf_platform_contributors %} - "{{ user }}", -{% endfor %} +{% if bootstrap.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' %} +{% if bootstrap.azure_landing_zones.identity.caf_platform_maintainers.user_principal_names is mapping %} + user_principal_names = {{ bootstrap.azure_landing_zones.identity.caf_platform_maintainers.user_principal_names | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% endif %} {% endif %} - ] } } -} \ No newline at end of file +} +{% else %} +# Azure AD Groups in bootstrap.enable_azuread_groups is not set to true +{% endif %} \ No newline at end of file diff --git a/templates/platform/level0/launchpad/azuread_groups.tfvars.j2 b/templates/platform/level0/launchpad/azuread_groups.tfvars.j2 deleted file mode 100644 index a551a004a..000000000 --- a/templates/platform/level0/launchpad/azuread_groups.tfvars.j2 +++ /dev/null @@ -1,97 +0,0 @@ -azuread_groups = { - caf_platform_maintainers = { - name = "caf-platform-maintainers" - description = "High privileged group to run all CAF deployments from vscode. Can be used to bootstrap or troubleshoot deployments." - prevent_duplicate_name = true -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - } - - caf_platform_contributors = { - name = "caf-platform-contributors" - description = "Can only execute terraform plans for level1 and level2. They can test platform improvements and propose PR." - prevent_duplicate_name = true -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - } - - level0 = { - name = "caf-level0" - prevent_duplicate_name = true -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - members = { - azuread_service_principal_keys = ["level0"] - } - } - - eslz = { - name = "caf-eslz" - prevent_duplicate_name = true -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - members = { - azuread_service_principal_keys = ["eslz"] - } - } - - identity = { - name = "caf-identity" - prevent_duplicate_name = true -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - members = { - azuread_service_principal_keys = ["identity"] - } - } - - management = { - name = "caf-management" - prevent_duplicate_name = true -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - members = { - azuread_service_principal_keys = ["management"] - } - } - - connectivity = { - name = "caf-connectivity" - prevent_duplicate_name = true -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - members = { - azuread_service_principal_keys = ["connectivity"] - } - } - - subscription_creation_platform = { - name = "caf-subscription_creation_platform" - prevent_duplicate_name = true -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - members = { - azuread_service_principal_keys = ["subscription_creation_platform"] - } - } - - subscription_creation_landingzones = { - name = "caf-subscription_creation_landingzones" - prevent_duplicate_name = true -{% if config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id is defined %} - owners = ["{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] // EA account -{% endif %} - members = { - azuread_service_principal_keys = ["subscription_creation_landingzones"] - } - } - -} diff --git a/templates/platform/level0/launchpad/azuread_roles.tfvars.j2 b/templates/platform/level0/launchpad/azuread_roles.tfvars.j2 deleted file mode 100644 index 88162fee6..000000000 --- a/templates/platform/level0/launchpad/azuread_roles.tfvars.j2 +++ /dev/null @@ -1,28 +0,0 @@ -# -# Available roles: -# az rest --method Get --uri https://graph.microsoft.com/v1.0/directoryRoleTemplates -o json | jq -r .value[].displayName -# -azuread_roles = { - azuread_service_principals = { - level0 = { - roles = [ - "Privileged Role Administrator", - "Application Administrator", - "Groups Administrator" - ] - } - identity = { - roles = [ - "User Administrator", - "Application Administrator", - "Groups Administrator" - ] - } - subscription_creation_landingzones = { - roles = [ - "Application Administrator", - "Groups Administrator" - ] - } - } -} \ No newline at end of file diff --git a/templates/platform/level0/launchpad/dynamic_secrets.tfvars.j2 b/templates/platform/level0/launchpad/dynamic_secrets.tfvars.j2 deleted file mode 100644 index 0b967297e..000000000 --- a/templates/platform/level0/launchpad/dynamic_secrets.tfvars.j2 +++ /dev/null @@ -1,67 +0,0 @@ - -# Store output attributes into keyvault secret -# Those values are used by the rover to connect the current remote state and -# identity the lower level -dynamic_keyvault_secrets = { - level0 = { - subscription_id = { - output_key = "client_config" - attribute_key = "subscription_id" - secret_name = "subscription-id" - } - tenant_id = { - output_key = "client_config" - attribute_key = "tenant_id" - secret_name = "tenant-id" - } - } - level1 = { - lower_stg = { - output_key = "storage_accounts" - resource_key = "level0" - attribute_key = "name" - secret_name = "lower-storage-account-name" - } - lower_rg = { - output_key = "resource_groups" - resource_key = "level0" - attribute_key = "name" - secret_name = "lower-resource-group-name" - } - subscription_id = { - output_key = "client_config" - attribute_key = "subscription_id" - secret_name = "subscription-id" - } - tenant_id = { - output_key = "client_config" - attribute_key = "tenant_id" - secret_name = "tenant-id" - } - } - level2 = { - lower_stg = { - output_key = "storage_accounts" - resource_key = "level1" - attribute_key = "name" - secret_name = "lower-storage-account-name" - } - lower_rg = { - output_key = "resource_groups" - resource_key = "level1" - attribute_key = "name" - secret_name = "lower-resource-group-name" - } - subscription_id = { - output_key = "client_config" - attribute_key = "subscription_id" - secret_name = "subscription-id" - } - tenant_id = { - output_key = "client_config" - attribute_key = "tenant_id" - secret_name = "tenant-id" - } - } - -} \ No newline at end of file diff --git a/templates/platform/level0/launchpad/global_settings.tfvars.j2 b/templates/platform/level0/launchpad/global_settings.tfvars.j2 index 6bd04bfce..4818ef650 100644 --- a/templates/platform/level0/launchpad/global_settings.tfvars.j2 +++ b/templates/platform/level0/launchpad/global_settings.tfvars.j2 @@ -3,26 +3,26 @@ # # passthrough means the default CAF naming convention is not applied and you are responsible # of the unicity of the names you are giving. the CAF provider will clear out -passthrough = {{ config.caf_terraform.naming_convention.passthrough | string | lower }} +passthrough = {{ bootstrap.naming_convention.passthrough | string | lower }} # adds random chars at the end of the names produced by the provider # Do not change the following values once the launchpad deployed. # Enable tag inheritance (can be changed) -inherit_tags = {{ config.caf_terraform.naming_convention.inherit_tags | string | lower }} +inherit_tags = {{ bootstrap.naming_convention.inherit_tags | string | lower }} # When passthrough is set to false, define the number of random characters to add to the names -random_length = {{ config.caf_terraform.naming_convention.random_length }} +random_length = {{ bootstrap.naming_convention.random_length }} # Set the prefix that will be added to all azure resources. # if not set and passthrough=false, the CAF module generates a random one. -{% if config.caf_terraform.naming_convention.prefix is defined %} -prefix = "{{ config.caf_terraform.naming_convention.prefix }}" +{% if bootstrap.naming_convention.prefix is defined %} +prefix = "{{ bootstrap.naming_convention.prefix }}" {% endif %} # Default region. When not set to a resource it will use that value -default_region = "{{ config.caf_terraform.launchpad.default_region_key }}" +default_region = "{{ bootstrap.default_region_key }}" # You can reference the regions by using region1, region2 or set your own keys regions = { -{% for key in config.caf_terraform.launchpad.regions.keys() %} - {{ key }} = "{{ config.caf_terraform.launchpad.regions[key].name }}" +{% for key, value in bootstrap.caf_regions.items() %} + {{ key }} = "{{ value }}" {% endfor %} } @@ -36,8 +36,11 @@ launchpad_key_names = { ] } +{% if bootstrap.launchpad.tags is defined %} # Global tags tags = { - ApplicationOwner = "sre" - BusinessUnit = "sre" -} \ No newline at end of file +{% for tag_key, tag_value in bootstrap.launchpad.tags.items() %} + {{ tag_key }} = "{{ tag_value }}" +{% endfor %} + } +{% endif %} diff --git a/templates/platform/level0/launchpad/keyvault_policies.tfvars.j2 b/templates/platform/level0/launchpad/keyvault_policies.tfvars.j2 deleted file mode 100644 index 0835a0d73..000000000 --- a/templates/platform/level0/launchpad/keyvault_policies.tfvars.j2 +++ /dev/null @@ -1,64 +0,0 @@ -keyvault_access_policies = { - # A maximum of 16 access policies per keyvault - level0 = { - sp_level0 = { - azuread_group_key = "level0" - secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] - } - identity = { - azuread_group_key = "identity" - secret_permissions = ["Get"] - } - } - - # A maximum of 16 access policies per keyvault - level1 = { - sp_level0 = { - # Allow level1 devops agent to be managed from agent pool level0 - azuread_group_key = "level0" - secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] - } - identity = { - azuread_group_key = "identity" - secret_permissions = ["Get"] - } - management = { - azuread_group_key = "management" - secret_permissions = ["Get"] - } - eslz = { - azuread_group_key = "eslz" - secret_permissions = ["Get"] - } - subscription_creation_platform = { - azuread_group_key = "subscription_creation_platform" - secret_permissions = ["Get"] - } - } - # A maximum of 16 access policies per keyvault - level2 = { - sp_level0 = { - azuread_group_key = "level0" - secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] - } - connectivity = { - azuread_group_key = "connectivity" - secret_permissions = ["Get"] - } - identity = { - azuread_group_key = "identity" - secret_permissions = ["Get"] - } - management = { - azuread_group_key = "management" - secret_permissions = ["Get"] - } -{% if config.platform_core_setup.enterprise_scale.enable_azure_subscription_vending_machine %} - subscription_creation_landingzones = { - azuread_group_key = "subscription_creation_landingzones" - secret_permissions = ["Get"] - } -{% endif %} - } - -} \ No newline at end of file diff --git a/templates/platform/level0/launchpad/keyvaults.tfvars.j2 b/templates/platform/level0/launchpad/keyvaults.tfvars.j2 index 7bc86e60e..6f9e6600f 100644 --- a/templates/platform/level0/launchpad/keyvaults.tfvars.j2 +++ b/templates/platform/level0/launchpad/keyvaults.tfvars.j2 @@ -1,27 +1,31 @@ keyvaults = { level0 = { - name = "{{ resources.subscriptions[subscription_key].keyvaults.level0.name }}" - resource_group_key = "{{ resources.subscriptions[subscription_key].keyvaults.level0.resource_group_key }}" - sku_name = "{{ config.platform_core_setup.sku.keyvault}}" + name = "{{ resources[tfstate].resources[subscription_key].keyvaults.level0.name }}" + resource_group_key = "{{ resources[tfstate].resources[subscription_key].keyvaults.level0.resource_group_key }}" + sku_name = "{{ resources[tfstate].resources[subscription_key].keyvaults.level1.sku_name | default('standard') }}" tags = { caf_tfstate = "level0" - caf_environment = "{{ config.caf_terraform.launchpad.caf_environment }}" + caf_environment = "{{ bootstrap.caf_environment }}" } creation_policies = { - // {{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner }} + // {{ bootstrap.billing_subscription_role_delegations.azuread_user_ea_account_owner }} bootstrap_user = { - object_id = "{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}" + object_id = "{{ bootstrap.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}" secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] } -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} +{% if bootstrap.azure_landing_zones.identity.enable_azuread_groups %} caf_platform_maintainers = { azuread_group_key = "caf_platform_maintainers" secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] } + caf_platform_contributors = { + azuread_group_key = "caf_platform_contributors" + secret_permissions = ["Get"] + } {% endif %} -{% if config.platform_identity.azuread_identity_mode == 'logged_in_user' %} +{% if bootstrap.azure_landing_zones.identity.azuread_identity_mode == 'logged_in_user' %} logged_in_user = { # if the key is set to "logged_in_user" add the user running terraform in the keyvault policy # More examples in /examples/keyvault @@ -33,27 +37,31 @@ keyvaults = { } level1 = { - name = "{{ resources.subscriptions[subscription_key].keyvaults.level1.name }}" - resource_group_key = "{{ resources.subscriptions[subscription_key].keyvaults.level1.resource_group_key }}" - sku_name = "{{ config.platform_core_setup.sku.keyvault}}" + name = "{{ resources[tfstate].resources[subscription_key].keyvaults.level1.name }}" + resource_group_key = "{{ resources[tfstate].resources[subscription_key].keyvaults.level1.resource_group_key }}" + sku_name = "{{ resources[tfstate].resources[subscription_key].keyvaults.level1.sku_name | default('standard') }}" tags = { caf_tfstate = "level1" - caf_environment = "{{ config.caf_terraform.launchpad.caf_environment }}" + caf_environment = "{{ bootstrap.caf_environment }}" } creation_policies = { - // {{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner }} + // {{ bootstrap.billing_subscription_role_delegations.azuread_user_ea_account_owner }} bootstrap_user = { - object_id = "{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}" + object_id = "{{ bootstrap.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}" secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] } -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} +{% if bootstrap.azure_landing_zones.identity.enable_azuread_groups %} caf_platform_maintainers = { azuread_group_key = "caf_platform_maintainers" secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] } + caf_platform_contributors = { + azuread_group_key = "caf_platform_contributors" + secret_permissions = ["Get"] + } {% endif %} -{% if config.platform_identity.azuread_identity_mode == 'logged_in_user' %} +{% if bootstrap.azure_landing_zones.identity.azuread_identity_mode == 'logged_in_user' %} logged_in_user = { # if the key is set to "logged_in_user" add the user running terraform in the keyvault policy # More examples in /examples/keyvault @@ -65,27 +73,31 @@ keyvaults = { } level2 = { - name = "{{ resources.subscriptions[subscription_key].keyvaults.level2.name }}" - resource_group_key = "{{ resources.subscriptions[subscription_key].keyvaults.level2.resource_group_key }}" - sku_name = "{{ config.platform_core_setup.sku.keyvault}}" + name = "{{ resources[tfstate].resources[subscription_key].keyvaults.level2.name }}" + resource_group_key = "{{ resources[tfstate].resources[subscription_key].keyvaults.level2.resource_group_key }}" + sku_name = "{{ resources[tfstate].resources[subscription_key].keyvaults.level1.sku_name | default('standard') }}" tags = { caf_tfstate = "level2" - caf_environment = "{{ config.caf_terraform.launchpad.caf_environment }}" + caf_environment = "{{ bootstrap.caf_environment }}" } creation_policies = { - // {{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner }} + // {{ bootstrap.billing_subscription_role_delegations.azuread_user_ea_account_owner }} bootstrap_user = { - object_id = "{{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}" + object_id = "{{ bootstrap.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}" secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] } -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} +{% if bootstrap.azure_landing_zones.identity.enable_azuread_groups %} caf_platform_maintainers = { azuread_group_key = "caf_platform_maintainers" secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] } + caf_platform_contributors = { + azuread_group_key = "caf_platform_contributors" + secret_permissions = ["Get"] + } {% endif %} -{% if config.platform_identity.azuread_identity_mode == 'logged_in_user' %} +{% if bootstrap.azure_landing_zones.identity.azuread_identity_mode == 'logged_in_user' %} logged_in_user = { # if the key is set to "logged_in_user" add the user running terraform in the keyvault policy # More examples in /examples/keyvault diff --git a/templates/platform/level0/launchpad/landingzone.tfvars.j2 b/templates/platform/level0/launchpad/landingzone.tfvars.j2 deleted file mode 100644 index 9fe64e7ca..000000000 --- a/templates/platform/level0/launchpad/landingzone.tfvars.j2 +++ /dev/null @@ -1,5 +0,0 @@ -landingzone = { - backend_type = "{{ caf_terraform.launchpad.backend_type | default("azurerm")}}" - level = "{{ config.tfstates.platform.launchpad.level }}" - key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" -} \ No newline at end of file diff --git a/templates/platform/level0/launchpad/readme.md b/templates/platform/level0/launchpad/readme.md index fb887b631..830a781b8 100644 --- a/templates/platform/level0/launchpad/readme.md +++ b/templates/platform/level0/launchpad/readme.md @@ -1,29 +1,31 @@ -# Launchpad - {{ config.caf_terraform.launchpad.caf_environment }} +# Launchpad - {{ bootstrap.caf_environment }} ## Pre-requisites This scenario requires the following privileges: -| Component | Privileges | -|--------------------|--------------------| -| Active Directory | None | -| Azure subscription | Subscription owner | +| Component | Privileges | +|--------------------|----------------------| +| Active Directory | Global Administrator | +| Azure subscription | Subscription owner | ## Deployment -{% if config.caf_terraform.billing_subscription_role_delegations is defined %} +{% if bootstrap.billing_subscription_role_delegations is defined %} ### Pre-requisite Elevate your credentials to the tenant root level to have enough privileges to create the management group hierarchy. ```bash -{% if config.caf_terraform.billing_subscription_role_delegations.enable %} -# Login to the subscription {{ config.caf_terraform.launchpad.subscription_name }} with the user {{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner }} +{% if bootstrap.billing_subscription_role_delegations.azuread_user_ea_account_owner is defined %} +# Login to the subscription {{ bootstrap.caf_launchpad.subscription_name }} with the user {{ bootstrap.billing_subscription_role_delegations.azuread_user_ea_account_owner }} {% else %} -# Login to the subscription {{ config.caf_terraform.launchpad.subscription_name }} with an account owner. +# Login to the subscription {{ bootstrap.caf_launchpad.subscription_name }} with an account owner. {% endif %} -rover login -t {{ config.platform_identity.tenant_name }} +rover login -t {{ bootstrap.azure_landing_zones.identity.tenant_name }} +{% if bootstrap.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' %} az rest --method post --url "/providers/Microsoft.Authorization/elevateAccess?api-version=2016-07-01" +{% endif %} ``` {% endif %} @@ -31,78 +33,71 @@ az rest --method post --url "/providers/Microsoft.Authorization/elevateAccess?ap ### Launchpad ```bash -{% if config.caf_terraform.billing_subscription_role_delegations is defined %} -{% if config.caf_terraform.billing_subscription_role_delegations.enable %} -# Login to the subscription {{ config.caf_terraform.launchpad.subscription_name }} with the user {{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner }} +{% if bootstrap.billing_subscription_role_delegations is defined %} +{% if bootstrap.billing_subscription_role_delegations.azuread_user_ea_account_owner is defined %} +# Login to the subscription {{ bootstrap.caf_launchpad.subscription_name }} with the user {{ bootstrap.billing_subscription_role_delegations.azuread_user_ea_account_owner }} {% else %} -# Login to the subscription {{ config.caf_terraform.launchpad.subscription_name }} with an account owner. +# Login to the subscription {{ bootstrap.caf_launchpad.subscription_name }} with an account owner. {% endif %} {% endif %} -rover login -t {{ config.platform_identity.tenant_name }} -s {{ config.caf_terraform.launchpad.subscription_id }} +rover login -t {{ bootstrap.azure_landing_zones.identity.tenant_name }} -s {{ bootstrap.caf_launchpad.subscription_id }} -cd /tf/caf/landingzones +cd {{ landingzones_folder }} git fetch origin -git checkout {{ config.gitops.caf_landingzone_branch }} +git checkout {{ bootstrap.caf_landingzone_branch }} +git pull rover \ -{% if ((config.platform_identity.azuread_identity_mode != "logged_in_user") and (credentials_tfstate_exists.rc == 0)) %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_level0.vault_uri }} \ +{% if bootstrap.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" and credentials_tfstate_exists.rc == 0 %} + --impersonate-sp-from-keyvault-url {{ keyvaults[tfstate_object.identity_aad_key].vault_uri }} \ {% endif %} - -lz /tf/caf/landingzones/caf_launchpad \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ config.tfstates.platform.launchpad.tfstate }} \ - -log-severity {{ config.gitops.rover_log_error }} \ + -lz {{ landingzones_folder }}/caf_launchpad \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ bootstrap.caf_launchpad.subscription_id }} \ + -target_subscription {{ bootstrap.caf_launchpad.subscription_id }} \ + -tfstate {{ tfstate_object.tfstate }} \ -launchpad \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -env {{ bootstrap.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.launchpad.tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ tfstate_object.tfstate }}.tfplan \ -a plan ``` -If the plan is not successfull you need to come back to the yaml contoso.caf.platform.yaml, fix the values, re-execute the rover ignite and then rover plan. +If the plan is not successfull you need to come back to the yaml ignite.yaml, fix the values, re-execute the rover ignite and then rover plan. ```bash # On success plan, execute rover \ -{% if ((config.platform_identity.azuread_identity_mode != "logged_in_user") and (credentials_tfstate_exists.rc == 0)) %} +{% if bootstrap.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" and credentials_tfstate_exists.rc == 0 %} --impersonate-sp-from-keyvault-url {{ keyvaults.cred_level0.vault_uri }} \ {% endif %} - -lz /tf/caf/landingzones/caf_launchpad \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ config.tfstates.platform.launchpad.tfstate }} \ - -log-severity {{ config.gitops.rover_log_error }} \ + -lz {{ landingzones_folder }}/caf_launchpad \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ bootstrap.caf_launchpad.subscription_id }} \ + -target_subscription {{ bootstrap.caf_launchpad.subscription_id }} \ + -tfstate {{ tfstate_object.tfstate }} \ -launchpad \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -env {{ bootstrap.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.launchpad.tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ tfstate_object.tfstate }}.tfplan \ -a apply ``` -```bash -# On success, re-execute the rover ignite - -rover ignite \ - --playbook /tf/caf/landingzones/templates/platform/ansible.yaml \ - -e base_templates_folder={{ base_templates_folder }} \ - -e resource_template_folder={{resource_template_folder}} \ - -e config_folder={{ config_folder }} - -``` - Execute a rover logout and rover login in order to make sure your azure sessions has the Azure groups membership updated. ```bash rover logout -rover login -t {{ config.platform_identity.tenant_name }} +rover login -t {{ bootstrap.azure_landing_zones.identity.tenant_name }} + +# On success, re-execute the rover ignite + +ansible-playbook {{public_templates_folder}}/ansible/ansible.yaml \ + --extra-vars "@{{platform_definition_folder}}/ignite.yaml" ``` @@ -110,8 +105,29 @@ rover login -t {{ config.platform_identity.tenant_name }} When you have successfully deployed the launchpad you can move to the next step. -{% if config.platform_identity.azuread_identity_mode == 'service_principal' %} +{% if bootstrap.azure_landing_zones.identity.azuread_identity_mode == 'service_principal' %} [Deploy the credentials landing zone](../credentials/readme.md) {% else %} [Deploy the management services](../../level1/management/readme.md) -{% endif %} \ No newline at end of file +{% endif %} + + +# To destroy the launchpad + +Destroying the launchpad is a specific opertion that requires the tfstate to be first downloaded in the rover and then run the terraform destroy command. Note the action to use is -a destroy + +```bash + +rover \ + -lz {{ landingzones_folder }}/caf_launchpad \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ bootstrap.caf_launchpad.subscription_id }} \ + -target_subscription {{ bootstrap.caf_launchpad.subscription_id }} \ + -tfstate {{ tfstate_object.tfstate }} \ + -launchpad \ + -env {{ bootstrap.caf_environment }} \ + -level {{ level }} \ + -p ${TF_DATA_DIR}/{{ tfstate_object.tfstate }}.tfplan \ + -a destroy + +``` \ No newline at end of file diff --git a/templates/platform/level0/launchpad/role_mappings.tfvars.j2 b/templates/platform/level0/launchpad/role_mappings.tfvars.j2 deleted file mode 100644 index 0eca43529..000000000 --- a/templates/platform/level0/launchpad/role_mappings.tfvars.j2 +++ /dev/null @@ -1,198 +0,0 @@ - -# -# Services supported: subscriptions, storage accounts and resource groups -# Can assign roles to: AD groups, AD object ID, AD applications, Managed identities -# - -role_mapping = { - built_in_role_mapping = { -{% if config.platform_core_setup %} - management_group = { - root = { - "User Access Administrator" = { -{% if config.platform_identity.azuread_identity_mode == 'logged_in_user' %} - logged_in = { - keys = ["user"] - } -{% endif %} -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - azuread_groups = { - keys = ["level0"] - } -{% endif %} - } - "Management Group Contributor" = { -{% if config.platform_identity.azuread_identity_mode == 'logged_in_user' %} - logged_in = { - keys = ["user"] - } -{% endif %} -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - azuread_groups = { - keys = ["eslz", "caf_platform_maintainers"] - } -{% endif %} - } - "Owner" = { -{% if config.platform_identity.azuread_identity_mode == 'logged_in_user' %} - logged_in = { - keys = ["user"] - } -{% endif %} -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - azuread_groups = { - keys = ["eslz", "caf_platform_maintainers"] - } -{% endif %} - } - } - } -{% endif %} -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - subscriptions = { - logged_in_subscription = { -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - "Owner" = { - azuread_groups = { - keys = ["level0", "caf_platform_maintainers", "subscription_creation_platform"] - } - } -{% endif %} -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - "Reader" = { - azuread_groups = { - keys = ["identity"] - } - } -{% endif %} - } - } -{% endif %} - -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - resource_groups = { - level0 = { - "Reader" = { - azuread_groups = { - keys = [ - "identity", - "subscription_creation_platform" - ] - } - } - } - level1 = { - "Reader" = { - azuread_groups = { - keys = [ - "identity", - "management", - "eslz", - "subscription_creation_platform" - ] - } - } - } - level2 = { - "Reader" = { - azuread_groups = { - keys = [ - "identity", - "connectivity", - "management", - "subscription_creation_landingzones" - ] - } - } - } - } -{% endif %} - - storage_accounts = { - level0 = { - "Storage Blob Data Contributor" = { - logged_in = { - keys = ["user"] - } -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - azuread_groups = { - keys = ["level0", "caf_platform_maintainers", "identity"] - } -{% endif %} - } -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - "Storage Blob Data Reader" = { - azuread_groups = { - keys = [ - "management", - "eslz", - "subscription_creation_platform" - ] - } - } -{% endif %} - } - - level1 = { - "Storage Blob Data Contributor" = { - logged_in = { - keys = ["user"] - } -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - azuread_groups = { - keys = [ - "caf_platform_maintainers", - "identity", - "management", - "eslz", - "subscription_creation_platform" - ] - } -{% endif %} - } -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - "Storage Blob Data Reader" = { - azuread_groups = { - keys = [ - "connectivity", -{% if config.platform_core_setup.enterprise_scale.enable_azure_subscription_vending_machine %} - "level0" -{% endif %} - ] - } - } -{% endif %} - } - - level2 = { - "Storage Blob Data Contributor" = { - logged_in = { - keys = ["user"] - } -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - azuread_groups = { - keys = [ - "identity", - "connectivity", - "management", - "caf_platform_maintainers", -{% if config.platform_core_setup.enterprise_scale.enable_azure_subscription_vending_machine %} - "level0" -{% endif %} - ] - } - } -{% endif %} - "Storage Blob Data Reader" = { - azuread_groups = { - keys = [ -{% if config.platform_core_setup.enterprise_scale.enable_azure_subscription_vending_machine %} - "subscription_creation_landingzones" -{% endif %} - ] - } - } - } - } - } -} diff --git a/templates/platform/level0/launchpad/service_principals.tfvars.j2 b/templates/platform/level0/launchpad/service_principals.tfvars.j2 deleted file mode 100644 index 75e0ef5d2..000000000 --- a/templates/platform/level0/launchpad/service_principals.tfvars.j2 +++ /dev/null @@ -1,44 +0,0 @@ -azuread_service_principals = { - # Manage the deployment of the level0 - level0 = { - azuread_application = { - key = "level0" - } - } - # Manage the deployment of Enterprise Scale - eslz = { - azuread_application = { - key = "eslz" - } - } - # Manage the deployment of the connectivity services - connectivity = { - azuread_application = { - key = "connectivity" - } - } - # Manage the deployment of the shared services - management = { - azuread_application = { - key = "management" - } - } - # Manage the deployment of the identity services - identity = { - azuread_application = { - key = "identity" - } - } - # Has delegation to create platform subscriptions - subscription_creation_platform = { - azuread_application = { - key = "subscription_creation_platform" - } - } - # Has delegation to create landingzone subscriptions - subscription_creation_landingzones = { - azuread_application = { - key = "subscription_creation_landingzones" - } - } -} \ No newline at end of file diff --git a/templates/platform/level0/launchpad/storage_accounts.tfvars.j2 b/templates/platform/level0/launchpad/storage_accounts.tfvars.j2 deleted file mode 100644 index 8aa17568c..000000000 --- a/templates/platform/level0/launchpad/storage_accounts.tfvars.j2 +++ /dev/null @@ -1,90 +0,0 @@ - -storage_accounts = { - level0 = { - name = "{{ resources.subscriptions[subscription_key].storage_accounts.level0.name }}" - resource_group_key = "{{ resources.subscriptions[subscription_key].storage_accounts.level0.resource_group_key }}" - account_kind = "BlobStorage" - account_tier = "Standard" - shared_access_key_enabled = false - account_replication_type = "{{ config.caf_terraform.launchpad.account_replication_type }}" - - tags = { - ## Those tags must never be changed after being set as they are used by the rover to locate the launchpad and the tfstates. - # Only adjust the environment value at creation time - caf_environment = "{{ config.caf_terraform.launchpad.caf_environment }}" - caf_launchpad = "launchpad" - caf_tfstate = "level0" - ## - } - - blob_properties = { - versioning_enabled = {{ config.caf_terraform.launchpad.blob_versioning_enabled | string | lower | default('true') }} - container_delete_retention_policy = {{ config.caf_terraform.launchpad.container_delete_retention_policy | default(7) }} - delete_retention_policy = {{ config.caf_terraform.launchpad.delete_retention_policy | default(7) }} - } - - containers = { - {{ config.tfstates.platform.launchpad.workspace | default('tfstate') }} = { - name = "{{ config.tfstates.platform.launchpad.workspace | default('tfstate') }}" - } - } - } - - level1 = { - name = "{{ resources.subscriptions[subscription_key].storage_accounts.level1.name }}" - resource_group_key = "{{ resources.subscriptions[subscription_key].storage_accounts.level1.resource_group_key }}" - account_kind = "BlobStorage" - account_tier = "Standard" - shared_access_key_enabled = false - account_replication_type = "{{ config.caf_terraform.launchpad.account_replication_type }}" - - tags = { - # Those tags must never be changed while set as they are used by the rover to locate the launchpad and the tfstates. - caf_environment = "{{ config.caf_terraform.launchpad.caf_environment }}" - caf_launchpad = "launchpad" - caf_tfstate = "level1" - } - - blob_properties = { - versioning_enabled = {{ config.caf_terraform.launchpad.blob_versioning_enabled | string | lower | default('true') }} - container_delete_retention_policy = {{ config.caf_terraform.launchpad.container_delete_retention_policy | default(7) }} - delete_retention_policy = {{ config.caf_terraform.launchpad.delete_retention_policy | default(7) }} - } - - containers = { - {{ config.tfstates.platform.launchpad.workspace | default('tfstate') }} = { - name = "{{ config.tfstates.platform.launchpad.workspace | default('tfstate') }}" - } - } - } - - level2 = { - name = "{{ resources.subscriptions[subscription_key].storage_accounts.level2.name }}" - resource_group_key = "{{ resources.subscriptions[subscription_key].storage_accounts.level2.resource_group_key }}" - account_kind = "BlobStorage" - account_tier = "Standard" - shared_access_key_enabled = false - account_replication_type = "{{ config.caf_terraform.launchpad.account_replication_type }}" - - tags = { - # Those tags must never be changed while set as they are used by the rover to locate the launchpad and the tfstates. - caf_environment = "{{ config.caf_terraform.launchpad.caf_environment }}" - caf_launchpad = "launchpad" - caf_tfstate = "level2" - } - - blob_properties = { - versioning_enabled = {{ config.caf_terraform.launchpad.blob_versioning_enabled | string | lower | default('true') }} - container_delete_retention_policy = {{ config.caf_terraform.launchpad.container_delete_retention_policy | default(7) }} - delete_retention_policy = {{ config.caf_terraform.launchpad.delete_retention_policy | default(7) }} - } - - containers = { - {{ config.tfstates.platform.launchpad.workspace | default('tfstate') }} = { - name = "{{ config.tfstates.platform.launchpad.workspace | default('tfstate') }}" - } - } - } - - -} \ No newline at end of file diff --git a/templates/platform/level1/alz/ansible.yaml b/templates/platform/level1/alz/ansible.yaml new file mode 100644 index 000000000..b3cc416c6 --- /dev/null +++ b/templates/platform/level1/alz/ansible.yaml @@ -0,0 +1,79 @@ +- name: "{{level }}-{{ tfstate}} - Set landingzone file_path" + set_fact: + mg: "{{ lookup('file', '{{ platform_definition_folder }}/alz/{{tfstate}}/archetype_config_overrides.caf.platform.yaml') | from_yaml }}" + mg_custom: "{{ lookup('file', '{{ platform_definition_folder }}/alz/{{tfstate}}/custom_landing_zones.caf.platform.yaml') | from_yaml }}" + level: "{{tfstate_object.level}}" + definition_source_folder: "{{platform_definition_folder}}/alz/{{ tfstate}}" + template_source_folder: "{{public_templates_folder}}/{{tfstate_object.template_lib_folder}}" + verbosity: 2 + +- debug: + msg: "{{destination_path}}" + +- name: "{{ level }}-{{ tfstate }} | Clean-up base directory" + shell: | + rm -rf "{{ destination_path }}" + when: + - bootstrap.management_groups[region][tfstate].clean_up_destination_folder + +- name: "{{ level }}-{{ tfstate }} | Creates directory structure" + shell: mkdir -p "{{ destination_path }}/{{ item.path }}" + with_filetree: "{{ definition_source_folder }}" + when: item.state == 'directory' + +- name: "{{ level }}-{{ tfstate }} | Tfvars" + ansible.builtin.template: + src: "{{ item }}" + dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" + force: yes + with_fileglob: + - "{{ template_source_folder }}/*.j2" + - "{{ template_source_folder }}/*.md" + +- name: "{{ level }}-{{ tfstate }} | Lib - archetypes - built-in" + ansible.builtin.template: + src: "{{ template_source_folder }}/lib/{{tfstate_object.alz_version}}/archetype_definitions/archetype_definition_template.json.j2" + dest: "{{ destination_path }}/lib/archetype_definitions/archetype_definition_{{ mg.archetype_definitions[item].archetype_id }}.json" + force: yes + loop: "{{ mg.archetype_definitions.keys() }}" + loop_control: + loop_var: item + +- name: "{{ level }}-{{ tfstate }} | Lib - archetypes - custom" + when: + - mg_custom.archetype_definitions is defined + ansible.builtin.template: + src: "{{ template_source_folder }}/lib/{{tfstate_object.alz_version}}/archetype_definitions/custom_landing_zone_template.json.j2" + dest: "{{ destination_path }}/lib/archetype_definitions/archetype_definition_{{ mg_custom.archetype_definitions[item].archetype_id }}.json" + force: yes + loop: "{{ mg_custom.archetype_definitions.keys() }}" + loop_control: + loop_var: item + +- name: "{{ level }}-{{ tfstate }} | archetypes" + ansible.builtin.template: + src: "{{ template_source_folder }}/lib/{{tfstate_object.alz_version}}/{{item}}" + dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" + force: yes + loop: + - archetype_config_overrides.tfvars.j2 + - custom_landing_zones.tfvars.j2 + +- name: "{{ level }}-{{ tfstate }} | Lib" + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ destination_path }}/{{ item.path }}" + force: yes + with_filetree: "{{ definition_source_folder }}" + when: + - item.state == 'file' and bootstrap.management_groups[region][tfstate].update_lib_folder + +- name: "{{ level }}-{{ tfstate }} | overrides" + when: + - mg_custom.archetype_definitions is defined + ansible.builtin.template: + src: "{{ item }}" + dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" + force: yes + with_fileglob: + - "{{ definition_source_folder }}/*.tfvars.j2" diff --git a/templates/platform/level1/alz/enterprise_scale.tfvars.j2 b/templates/platform/level1/alz/enterprise_scale.tfvars.j2 new file mode 100644 index 000000000..6f5844106 --- /dev/null +++ b/templates/platform/level1/alz/enterprise_scale.tfvars.j2 @@ -0,0 +1,11 @@ +# relative path to {{ landingzones_folder }}/caf_solution/add-ons/caf_alz +library_path = "{{ destination_base_path }}/{{tfstate_object.level}}/{{stage}}/{{tfstate}}/lib" +{% if bootstrap.management_groups[region][tfstate].root_parent_id is defined %} +root_parent_id = "{{ bootstrap.management_groups[region][tfstate].root_parent_id }}" +{% endif %} +root_id = "{{ bootstrap.management_groups[region][tfstate].management_group_prefix }}" +root_name = "{{ bootstrap.management_groups[region][tfstate].management_group_name }}" +deploy_core_landing_zones = {{ bootstrap.management_groups[region][tfstate].deploy_core_landing_zones | string | lower }} +{% if (bootstrap.enable_azure_subscription_vending_machine | default(false)) and bootstrap.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' %} +reconcile_vending_subscriptions = true +{% endif %} \ No newline at end of file diff --git a/templates/platform/level1/eslz/lib/v0.1.x/archetype_config_overrides.tfvars.j2 b/templates/platform/level1/alz/lib/v0.1.x/archetype_config_overrides.tfvars.j2 similarity index 76% rename from templates/platform/level1/eslz/lib/v0.1.x/archetype_config_overrides.tfvars.j2 rename to templates/platform/level1/alz/lib/v0.1.x/archetype_config_overrides.tfvars.j2 index c731806ec..dfb37b052 100644 --- a/templates/platform/level1/eslz/lib/v0.1.x/archetype_config_overrides.tfvars.j2 +++ b/templates/platform/level1/alz/lib/v0.1.x/archetype_config_overrides.tfvars.j2 @@ -6,34 +6,34 @@ archetype_config_overrides = { "Deny-Resource-Locations" = { "listOfAllowedLocations" = { value = [ - "{{ config.caf_terraform.launchpad.regions.region1.name }}", - "{{ config.caf_terraform.launchpad.regions.region2.name }}" + "{{ resources.caf_regions.region1.name }}", + "{{ resources.caf_regions.region2.name }}" ] } } "Deny-RSG-Locations" = { "listOfAllowedLocations" = { value = [ - "{{ config.caf_terraform.launchpad.regions.region1.name }}", - "{{ config.caf_terraform.launchpad.regions.region2.name }}" + "{{ resources.caf_regions.region1.name }}", + "{{ resources.caf_regions.region2.name }}" ] } } "Deploy-Resource-Diag" = { "logAnalytics" = { - lz_key = "{{ config.tfstates.platform.management.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.management.lz_key_name }}" output_key = "diagnostics" resource_type = "log_analytics" resource_key = "central_logs_region1" attribute_key = "id" } "profileName" = { - value = "eslz-diagnostic-log" + value = "alz-diagnostic-log" } } "Deploy-VM-Monitoring" = { "logAnalytics" = { - lz_key = "{{ config.tfstates.platform.management.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.management.lz_key_name }}" output_key = "diagnostics" resource_type = "log_analytics" resource_key = "central_logs_region1" @@ -42,7 +42,7 @@ archetype_config_overrides = { } "Deploy-VMSS-Monitoring" = { "logAnalytics" = { - lz_key = "{{ config.tfstates.platform.management.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.management.lz_key_name }}" output_key = "diagnostics" resource_type = "log_analytics" resource_key = "central_logs_region1" diff --git a/templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/README.md b/templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/README.md rename to templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/README.md diff --git a/templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_landingzone.json b/templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_landingzone.json similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_landingzone.json rename to templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_landingzone.json diff --git a/templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_landingzone_corp.json b/templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_landingzone_corp.json similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_landingzone_corp.json rename to templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_landingzone_corp.json diff --git a/templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_landingzone_online.json b/templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_landingzone_online.json similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_landingzone_online.json rename to templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_landingzone_online.json diff --git a/templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_platform.json b/templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_platform.json similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_platform.json rename to templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_platform.json diff --git a/templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_platform_connectivity.json b/templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_platform_connectivity.json similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_platform_connectivity.json rename to templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_platform_connectivity.json diff --git a/templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_platform_identity.json b/templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_platform_identity.json similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_platform_identity.json rename to templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_platform_identity.json diff --git a/templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_platform_management.json b/templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_platform_management.json similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_platform_management.json rename to templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_platform_management.json diff --git a/templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_root.json b/templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_root.json similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/archetype_definitions/archetype_definition_root.json rename to templates/platform/level1/alz/lib/v0.1.x/archetype_definitions/archetype_definition_root.json diff --git a/templates/platform/level1/eslz/lib/v0.1.x/custom_landing_zones.tfvars.j2 b/templates/platform/level1/alz/lib/v0.1.x/custom_landing_zones.tfvars.j2 similarity index 66% rename from templates/platform/level1/eslz/lib/v0.1.x/custom_landing_zones.tfvars.j2 rename to templates/platform/level1/alz/lib/v0.1.x/custom_landing_zones.tfvars.j2 index 75d3f2d03..d2ee49784 100644 --- a/templates/platform/level1/eslz/lib/v0.1.x/custom_landing_zones.tfvars.j2 +++ b/templates/platform/level1/alz/lib/v0.1.x/custom_landing_zones.tfvars.j2 @@ -1,7 +1,7 @@ custom_landing_zones = { - {{ config.eslz.root_id }}-corp = { + {{ resources.alz.root_id }}-corp = { display_name = "Corp" - parent_management_group_id = "{{ config.eslz.root_id }}-landing-zones" + parent_management_group_id = "{{ resources.alz.root_id }}-landing-zones" archetype_config = { archetype_id = "landingzone_corp" parameters = {} @@ -10,9 +10,9 @@ custom_landing_zones = { subscriptions = {} subscription_ids = [] } - {{ config.eslz.root_id }}-online = { + {{ resources.alz.root_id }}-online = { display_name = "Online" - parent_management_group_id = "{{ config.eslz.root_id }}-landing-zones" + parent_management_group_id = "{{ resources.alz.root_id }}-landing-zones" archetype_config = { archetype_id = "landingzone_online" parameters = {} diff --git a/templates/enterprise-scale/contoso/platform/eslz/lib/policy_assignments/README.md b/templates/platform/level1/alz/lib/v0.1.x/policy_assignments/README.md similarity index 100% rename from templates/enterprise-scale/contoso/platform/eslz/lib/policy_assignments/README.md rename to templates/platform/level1/alz/lib/v0.1.x/policy_assignments/README.md diff --git a/templates/platform/level1/eslz/lib/v0.1.x/policy_assignments/policy_assignment_pru_apply_security_benchmark.tmpl.json b/templates/platform/level1/alz/lib/v0.1.x/policy_assignments/policy_assignment_pru_apply_security_benchmark.tmpl.json similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/policy_assignments/policy_assignment_pru_apply_security_benchmark.tmpl.json rename to templates/platform/level1/alz/lib/v0.1.x/policy_assignments/policy_assignment_pru_apply_security_benchmark.tmpl.json diff --git a/templates/enterprise-scale/contoso/platform/eslz/lib/policy_definitions/README.md b/templates/platform/level1/alz/lib/v0.1.x/policy_definitions/README.md similarity index 100% rename from templates/enterprise-scale/contoso/platform/eslz/lib/policy_definitions/README.md rename to templates/platform/level1/alz/lib/v0.1.x/policy_definitions/README.md diff --git a/templates/enterprise-scale/contoso/platform/eslz/lib/policy_set_definitions/README.md b/templates/platform/level1/alz/lib/v0.1.x/policy_set_definitions/README.md similarity index 100% rename from templates/enterprise-scale/contoso/platform/eslz/lib/policy_set_definitions/README.md rename to templates/platform/level1/alz/lib/v0.1.x/policy_set_definitions/README.md diff --git a/templates/enterprise-scale/contoso/platform/eslz/lib/role_definitions/README.md b/templates/platform/level1/alz/lib/v0.1.x/role_definitions/README.md similarity index 100% rename from templates/enterprise-scale/contoso/platform/eslz/lib/role_definitions/README.md rename to templates/platform/level1/alz/lib/v0.1.x/role_definitions/README.md diff --git a/templates/platform/level1/eslz/lib/v0.3.3/archetype_config_overrides.old b/templates/platform/level1/alz/lib/v0.3.3/archetype_config_overrides.old similarity index 55% rename from templates/platform/level1/eslz/lib/v0.3.3/archetype_config_overrides.old rename to templates/platform/level1/alz/lib/v0.3.3/archetype_config_overrides.old index 1875a1bb2..59661f5b8 100644 --- a/templates/platform/level1/eslz/lib/v0.3.3/archetype_config_overrides.old +++ b/templates/platform/level1/alz/lib/v0.3.3/archetype_config_overrides.old @@ -6,8 +6,8 @@ archetype_config_overrides = { "Allowed-Locations" = { "listOfAllowedLocations" = { values = [ -{% for key in config.caf_terraform.launchpad.regions.keys() %} - "{{ config.caf_terraform.launchpad.regions[key].name }}", +{% for key in resources.caf_regions.keys() %} + "{{ resources.caf_regions[key].name }}", {% endfor %} ] } @@ -15,84 +15,84 @@ archetype_config_overrides = { "Deny-RSG-Locations" = { "listOfAllowedLocations" = { values = [ -{% for key in config.caf_terraform.launchpad.regions.keys() %} - "{{ config.caf_terraform.launchpad.regions[key].name }}", +{% for key in resources.caf_regions.keys() %} + "{{ resources.caf_regions[key].name }}", {% endfor %} ] } } "Deploy-Resource-Diag" = { "logAnalytics" = { - lz_key = "{{ config.tfstates.platform.management.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.management.lz_key_name }}" output_key = "diagnostics" resource_type = "log_analytics" - resource_key = "central_logs_{{config.caf_terraform.launchpad.regions[config.caf_terraform.launchpad.default_region_key].slug}}" + resource_key = "central_logs_{{resources.caf_regions[resources.default_region_key].slug}}" attribute_key = "id" } "profileName" = { - value = "eslz-diagnostic-log" + value = "alz-diagnostic-log" } } "Deploy-AzActivity-Log" = { "logAnalytics" = { - lz_key = "{{ config.tfstates.platform.management.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.management.lz_key_name }}" output_key = "diagnostics" resource_type = "log_analytics" - resource_key = "central_logs_{{config.caf_terraform.launchpad.regions[config.caf_terraform.launchpad.default_region_key].slug}}" + resource_key = "central_logs_{{resources.caf_regions[resources.default_region_key].slug}}" attribute_key = "id" } } -{% if "VM" in config.platform_management.enable_monitoring %} +{% if "VM" in resources.platform_management.enable_monitoring %} "Deploy-VM-Monitoring" = { "logAnalytics_1" = { - lz_key = "{{ config.tfstates.platform.management.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.management.lz_key_name }}" output_key = "diagnostics" resource_type = "log_analytics" - resource_key = "central_logs_{{config.caf_terraform.launchpad.regions[config.caf_terraform.launchpad.default_region_key].slug}}" + resource_key = "central_logs_{{resources.caf_regions[resources.default_region_key].slug}}" attribute_key = "id" } } {% endif %} -{% if "VMSS" in config.platform_management.enable_monitoring %} +{% if "VMSS" in resources.platform_management.enable_monitoring %} "Deploy-VMSS-Monitoring" = { "logAnalytics_1" = { - lz_key = "{{ config.tfstates.platform.management.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.management.lz_key_name }}" output_key = "diagnostics" resource_type = "log_analytics" - resource_key = "central_logs_{{config.caf_terraform.launchpad.regions[config.caf_terraform.launchpad.default_region_key].slug}}" + resource_key = "central_logs_{{resources.caf_regions[resources.default_region_key].slug}}" attribute_key = "id" } } {% endif %} -{% if "Arc" in config.platform_management.enable_monitoring %} +{% if "Arc" in resources.platform_management.enable_monitoring %} "Deploy-WS-Arc-Monitoring" = { "logAnalytics" = { - lz_key = "{{ config.tfstates.platform.management.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.management.lz_key_name }}" output_key = "diagnostics" resource_type = "log_analytics" - resource_key = "central_logs_{{config.caf_terraform.launchpad.regions[config.caf_terraform.launchpad.default_region_key].slug}}" + resource_key = "central_logs_{{resources.caf_regions[resources.default_region_key].slug}}" attribute_key = "id" } } "Deploy-LX-Arc-Monitoring" = { "logAnalytics" = { - lz_key = "{{ config.tfstates.platform.management.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.management.lz_key_name }}" output_key = "diagnostics" resource_type = "log_analytics" - resource_key = "central_logs_{{config.caf_terraform.launchpad.regions[config.caf_terraform.launchpad.default_region_key].slug}}" + resource_key = "central_logs_{{resources.caf_regions[resources.default_region_key].slug}}" attribute_key = "id" } } {% endif %} "Deploy-ASC-Defender" = { "emailSecurityContact" = { - value = "{{ config.notifications.security_center_email_contact }}" + value = "{{ resources.notifications.security_center_email_contact }}" } "logAnalytics" = { - lz_key = "{{ config.tfstates.platform.management.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.management.lz_key_name }}" output_key = "diagnostics" resource_type = "log_analytics" - resource_key = "central_logs_{{config.caf_terraform.launchpad.regions[config.caf_terraform.launchpad.default_region_key].slug}}" + resource_key = "central_logs_{{resources.caf_regions[resources.default_region_key].slug}}" attribute_key = "id" } {% for parameter_key in mg.archetype_definitions.root.policy_assignments["Deploy-ASC-Defender"].keys() %} @@ -109,10 +109,10 @@ archetype_config_overrides = { archetype_id = "landingzone" parameters = {} access_control = { -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' %} "Owner" = { "azuread_groups" = { - lz_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.launchpad.lz_key_name }}" attribute_key = "id" resource_keys = [ "subscription_creation_landingzones" @@ -133,20 +133,20 @@ archetype_config_overrides = { archetype_id = "platform_connectivity" parameters = {} access_control = { -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' %} "Owner" = { "azuread_groups" = { - lz_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.launchpad.lz_key_name }}" attribute_key = "id" resource_keys = [ "connectivity" ] } } -{% if config.platform_core_setup.enterprise_scale.enable_azure_subscription_vending_machine %} - "[{{ config.platform_core_setup.enterprise_scale.management_group_prefix | upper }}-CONNECTIVITY] CAF-network-vhub-peering" = { +{% if resources.azure_landing_zones.enterprise_scale.enable_azure_subscription_vending_machine %} + "[{{ resources.azure_landing_zones.enterprise_scale.management_group_prefix | upper }}-CONNECTIVITY] CAF-network-vhub-peering" = { "azuread_groups" = { - lz_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.launchpad.lz_key_name }}" attribute_key = "id" resource_keys = [ "subscription_creation_landingzones" @@ -162,10 +162,10 @@ archetype_config_overrides = { archetype_id = "platform_identity" parameters = {} access_control = { -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' %} "Owner" = { "azuread_groups" = { - lz_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.launchpad.lz_key_name }}" attribute_key = "id" resource_keys = [ "identity" @@ -180,10 +180,10 @@ archetype_config_overrides = { archetype_id = "platform_management" parameters = {} access_control = { -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' %} "Owner" = { "azuread_groups" = { - lz_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.launchpad.lz_key_name }}" attribute_key = "id" resource_keys = [ "management" diff --git a/templates/platform/level1/eslz/lib/v1.1.1/archetype_config_overrides.tfvars.j2 b/templates/platform/level1/alz/lib/v0.3.3/archetype_config_overrides.tfvars.j2 similarity index 91% rename from templates/platform/level1/eslz/lib/v1.1.1/archetype_config_overrides.tfvars.j2 rename to templates/platform/level1/alz/lib/v0.3.3/archetype_config_overrides.tfvars.j2 index e24a0bef6..ee59be455 100644 --- a/templates/platform/level1/eslz/lib/v1.1.1/archetype_config_overrides.tfvars.j2 +++ b/templates/platform/level1/alz/lib/v0.3.3/archetype_config_overrides.tfvars.j2 @@ -33,9 +33,9 @@ archetype_config_overrides = { {% else %} parameters = {} {% endif %} -{% if level.archetype_config.access_control is defined %} +{% if level.archetype_resources.access_control is defined %} access_control = { -{% for level_ac_key, level_ac in level.archetype_config.access_control.items() %} +{% for level_ac_key, level_ac in level.archetype_resources.access_control.items() %} "{{level_ac_key}}" = { {% for level_role_key, level_role in level_ac.items() %} "{{ level_role_key }}" = { diff --git a/templates/platform/level1/eslz/lib/v0.3.3/archetype_definitions/README.md b/templates/platform/level1/alz/lib/v0.3.3/archetype_definitions/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v0.3.3/archetype_definitions/README.md rename to templates/platform/level1/alz/lib/v0.3.3/archetype_definitions/README.md diff --git a/templates/platform/level1/eslz/lib/v0.3.3/archetype_definitions/archetype_definition_template.json.j2 b/templates/platform/level1/alz/lib/v0.3.3/archetype_definitions/archetype_definition_template.json.j2 similarity index 100% rename from templates/platform/level1/eslz/lib/v0.3.3/archetype_definitions/archetype_definition_template.json.j2 rename to templates/platform/level1/alz/lib/v0.3.3/archetype_definitions/archetype_definition_template.json.j2 diff --git a/templates/platform/level1/eslz/lib/v0.3.3/archetype_definitions/custom_landing_zone_template.json.j2 b/templates/platform/level1/alz/lib/v0.3.3/archetype_definitions/custom_landing_zone_template.json.j2 similarity index 100% rename from templates/platform/level1/eslz/lib/v0.3.3/archetype_definitions/custom_landing_zone_template.json.j2 rename to templates/platform/level1/alz/lib/v0.3.3/archetype_definitions/custom_landing_zone_template.json.j2 diff --git a/templates/platform/level1/eslz/lib/v1.1.1/custom_landing_zones.tfvars.j2 b/templates/platform/level1/alz/lib/v0.3.3/custom_landing_zones.tfvars.j2 similarity index 81% rename from templates/platform/level1/eslz/lib/v1.1.1/custom_landing_zones.tfvars.j2 rename to templates/platform/level1/alz/lib/v0.3.3/custom_landing_zones.tfvars.j2 index 4ebb58b6b..e2119656e 100644 --- a/templates/platform/level1/eslz/lib/v1.1.1/custom_landing_zones.tfvars.j2 +++ b/templates/platform/level1/alz/lib/v0.3.3/custom_landing_zones.tfvars.j2 @@ -1,8 +1,8 @@ custom_landing_zones = { {% for key, level in mg_custom.archetype_definitions.items() %} - {{ config.platform_core_setup.enterprise_scale.management_group_prefix }}-{{ key }} = { + {{ resources.azure_landing_zones.enterprise_scale.management_group_prefix }}-{{ key }} = { display_name = "{{ mg_custom.archetype_definitions[key].display_name }}" - parent_management_group_id = "{{ config.platform_core_setup.enterprise_scale.management_group_prefix }}-{{ mg_custom.archetype_definitions[key].parent_management_group_id }}" + parent_management_group_id = "{{ resources.azure_landing_zones.enterprise_scale.management_group_prefix }}-{{ mg_custom.archetype_definitions[key].parent_management_group_id }}" archetype_config = { archetype_id = "{{mg_custom.archetype_definitions[key].archetype_id }}" {% if mg_custom.archetype_definitions[key].policy_assignments is defined %} @@ -36,9 +36,9 @@ custom_landing_zones = { {% else %} parameters = {} {% endif %} -{% if mg_custom.archetype_definitions[key].archetype_config.access_control is defined %} +{% if mg_custom.archetype_definitions[key].archetype_resources.access_control is defined %} access_control = { -{% for level_ac_key, level_ac in mg_custom.archetype_definitions[key].archetype_config.access_control.items() %} +{% for level_ac_key, level_ac in mg_custom.archetype_definitions[key].archetype_resources.access_control.items() %} "{{level_ac_key}}" = { {% for level_role_key, level_role in level_ac.items() %} "{{ level_role_key }}" = { diff --git a/templates/platform/level1/eslz/lib/v0.1.x/policy_assignments/README.md b/templates/platform/level1/alz/lib/v0.3.3/policy_assignments/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/policy_assignments/README.md rename to templates/platform/level1/alz/lib/v0.3.3/policy_assignments/README.md diff --git a/templates/enterprise-scale/contoso/platform/eslz/lib/policy_assignments/policy_assignment_caf_aks_capability.json b/templates/platform/level1/alz/lib/v0.3.3/policy_assignments/policy_assignment_caf_aks_capability.json similarity index 100% rename from templates/enterprise-scale/contoso/platform/eslz/lib/policy_assignments/policy_assignment_caf_aks_capability.json rename to templates/platform/level1/alz/lib/v0.3.3/policy_assignments/policy_assignment_caf_aks_capability.json diff --git a/templates/enterprise-scale/contoso/platform/eslz/lib/policy_assignments/policy_assignment_es_allowed_locations.json b/templates/platform/level1/alz/lib/v0.3.3/policy_assignments/policy_assignment_es_allowed_locations.json similarity index 100% rename from templates/enterprise-scale/contoso/platform/eslz/lib/policy_assignments/policy_assignment_es_allowed_locations.json rename to templates/platform/level1/alz/lib/v0.3.3/policy_assignments/policy_assignment_es_allowed_locations.json diff --git a/templates/platform/level1/eslz/lib/v0.1.x/policy_definitions/README.md b/templates/platform/level1/alz/lib/v0.3.3/policy_definitions/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/policy_definitions/README.md rename to templates/platform/level1/alz/lib/v0.3.3/policy_definitions/README.md diff --git a/templates/platform/level1/eslz/lib/v0.1.x/policy_set_definitions/README.md b/templates/platform/level1/alz/lib/v0.3.3/policy_set_definitions/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/policy_set_definitions/README.md rename to templates/platform/level1/alz/lib/v0.3.3/policy_set_definitions/README.md diff --git a/templates/platform/level1/eslz/lib/v0.1.x/role_definitions/README.md b/templates/platform/level1/alz/lib/v0.3.3/role_definitions/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v0.1.x/role_definitions/README.md rename to templates/platform/level1/alz/lib/v0.3.3/role_definitions/README.md diff --git a/templates/platform/level1/eslz/lib/v0.3.3/role_definitions/role_definition_caf_vhub_peering.json b/templates/platform/level1/alz/lib/v0.3.3/role_definitions/role_definition_caf_vhub_peering.json similarity index 100% rename from templates/platform/level1/eslz/lib/v0.3.3/role_definitions/role_definition_caf_vhub_peering.json rename to templates/platform/level1/alz/lib/v0.3.3/role_definitions/role_definition_caf_vhub_peering.json diff --git a/templates/enterprise-scale/contoso/platform/eslz/archetype_config_overrides.caf.platform.yaml b/templates/platform/level1/alz/lib/v1.1.1/archetype_config_overrides.caf.platform.yaml similarity index 80% rename from templates/enterprise-scale/contoso/platform/eslz/archetype_config_overrides.caf.platform.yaml rename to templates/platform/level1/alz/lib/v1.1.1/archetype_config_overrides.caf.platform.yaml index c09590f41..3740933ce 100644 --- a/templates/enterprise-scale/contoso/platform/eslz/archetype_config_overrides.caf.platform.yaml +++ b/templates/platform/level1/alz/lib/v1.1.1/archetype_config_overrides.caf.platform.yaml @@ -4,12 +4,14 @@ archetype_definitions: policy_assignments: Allowed-Locations: listOfAllowedLocations: - - southeastasia # Use the lower-case region's name, short version with no space - - eastasia +{% for region in topology.resources_allowed_regions %} + - {{topology.caf_regions[region]}} +{% endfor %} Deny-RSG-Locations: listOfAllowedLocations: - - southeastasia - - eastasia +{% for region in topology.resource_groups_allowed_regions %} + - {{topology.caf_regions[region]}} +{% endfor %} # Set to Audit as Terraform cannot combine both in one operation yet. Deny-Subnet-Without-Nsg: effect: Audit @@ -37,17 +39,17 @@ archetype_definitions: sqlManagedInstanceAdvancedDataSecurityEmailsMonitoringEffect: Disabled sqlServerAdvancedDataSecurityEmailAdminsMonitoringEffect: Disabled sqlServerAdvancedDataSecurityMonitoringEffect: Disabled - systemUpdatesMonitoringEffect: Disabled + systemUpdatesMonitoringEffect: AuditIfNotExists useRbacRulesMonitoringEffect: Disabled vmssSystemUpdatesMonitoringEffect: Disabled windowsDefenderExploitGuardMonitoringEffect: Disabled Deploy-ASCDF-Config: - emailSecurityContact: + emailSecurityContact: {{topology.notifications.azure_defender.emailSecurityContact}} logAnalytics: lz_key: management output_key: diagnostics resource_type: log_analytics - resource_key: central_logs_sea + resource_key: region1 attribute_key: id enableAscForKubernetes: DeployIfNotExists enableAscForSql: DeployIfNotExists @@ -65,37 +67,37 @@ archetype_definitions: lz_key: management output_key: diagnostics resource_type: log_analytics - resource_key: central_logs_sea + resource_key: region1 attribute_key: id Deploy-LX-Arc-Monitoring: Deploy-Resource-Diag: - profileName: eslz-diagnostic-log + profileName: alz-diagnostic-log logAnalytics: lz_key: management output_key: diagnostics resource_type: log_analytics - resource_key: central_logs_sea + resource_key: region1 attribute_key: id Deploy-WS-Arc-Monitoring: logAnalytics: lz_key: management output_key: diagnostics resource_type: log_analytics - resource_key: central_logs_sea + resource_key: region1 attribute_key: id Deploy-VM-Monitoring: logAnalytics_1: lz_key: management output_key: diagnostics resource_type: log_analytics - resource_key: central_logs_sea + resource_key: region1 attribute_key: id Deploy-VMSS-Monitoring: logAnalytics_1: lz_key: management output_key: diagnostics resource_type: log_analytics - resource_key: central_logs_sea + resource_key: region1 attribute_key: id policy_definitions: Append-AppService-httpsonly: @@ -104,6 +106,7 @@ archetype_definitions: Append-Redis-disableNonSslPort: Append-Redis-sslEnforcement: Audit-MachineLearning-PrivateEndpointId: + CAF-Deploy-Nsg-FlowLogs: Deny-AA-child-resources: Deny-AppGW-Without-WAF: Deny-AppServiceApiApp-http: @@ -244,6 +247,7 @@ archetype_definitions: Deny-IP-Forwarding: Deny-Priv-Containers-AKS: Deny-Priv-Escalation-AKS: + Deny-Private-DNS-Zones: Deny-RDP-From-Internet: Deny-Storage-http: Deploy-AKS-Policy: @@ -252,6 +256,34 @@ archetype_definitions: Enable-DDoS-VNET: Enforce-AKS-HTTPS: Enforce-TLS-SSL: + CAF-Deploy-Nsg-FlowLogs: + effect: DeployIfNotExists + retention: 5 + storageAccountResourceId: + lz_key: management + output_key: objects + resource_type: storage_accounts + resource_key: nsgflogs + attribute_key: id + interval: 60 + flowAnalyticsEnabled: true + logAnalytics: + lz_key: management + output_key: diagnostics + resource_type: log_analytics + resource_key: region1 + attribute_key: id + Deny-Public-Endpoints: + ACRPublicIpDenyEffect: Audit + AFSPublicIpDenyEffect: Audit + AKSPublicIpDenyEffect: Audit + BatchPublicIpDenyEffect: Audit + CosmosPublicIpDenyEffect: Audit + KeyVaultPublicIpDenyEffect: Audit + MySQLFlexPublicIpDenyEffect: Audit + PostgreSQLFlexPublicIpDenyEffect: Audit + SqlServerPublicIpDenyEffect: Audit + StoragePublicIpDenyEffect: Audit archetype_config: access_control: Owner: @@ -274,14 +306,19 @@ archetype_definitions: attribute_key: id resource_keys: - connectivity - '[-CONNECTIVITY] CAF-network-vhub-peering': + # Make sure you replace with the Management Group ID in UPPER CASE + '[{{topology.caf_environment | upper}}-CONNECTIVITY] CAF-network-vhub-peering': azuread_groups: lz_key: launchpad attribute_key: id resource_keys: - subscription_creation_landingzones + - identity + - management management: archetype_id: platform_management + policy_assignments: + Deny-Private-DNS-Zones: archetype_config: access_control: Owner: @@ -295,6 +332,8 @@ archetype_definitions: policy_assignments: Deny-RDP-From-Internet: Deny-Public-IP: + Deny-Private-DNS-Zones: + Deny-IP-Forwarding: archetype_config: access_control: Owner: @@ -305,7 +344,31 @@ archetype_definitions: - identity decommissioned: archetype_id: platform_decommissioned + policy_assignments: + Deny-IP-Forwarding: + Deny-Private-DNS-Zones: platform: archetype_id: platform + policy_assignments: + CAF-Deploy-Nsg-FlowLogs: + effect: DeployIfNotExists + retention: 5 + storageAccountResourceId: + lz_key: management + output_key: objects + resource_type: storage_accounts + resource_key: nsgflogs + attribute_key: id + interval: 60 + flowAnalyticsEnabled: true + logAnalytics: + lz_key: management + output_key: diagnostics + resource_type: log_analytics + resource_key: region1 + attribute_key: id sandboxes: - archetype_id: platform_sandboxes \ No newline at end of file + archetype_id: platform_sandboxes + policy_assignments: + Deny-IP-Forwarding: + Deny-Private-DNS-Zones: \ No newline at end of file diff --git a/templates/platform/level1/eslz/lib/v0.3.3/archetype_config_overrides.tfvars.j2 b/templates/platform/level1/alz/lib/v1.1.1/archetype_config_overrides.tfvars.j2 similarity index 76% rename from templates/platform/level1/eslz/lib/v0.3.3/archetype_config_overrides.tfvars.j2 rename to templates/platform/level1/alz/lib/v1.1.1/archetype_config_overrides.tfvars.j2 index e24a0bef6..4ad74b76e 100644 --- a/templates/platform/level1/eslz/lib/v0.3.3/archetype_config_overrides.tfvars.j2 +++ b/templates/platform/level1/alz/lib/v1.1.1/archetype_config_overrides.tfvars.j2 @@ -2,7 +2,7 @@ archetype_config_overrides = { {% for key, level in mg.archetype_definitions.items() %} {{ key }} = { archetype_id = "{{mg.archetype_definitions[key].archetype_id }}" -{% if mg.archetype_definitions[key].policy_assignments is defined %} +{% if mg.archetype_definitions[key].policy_assignments is mapping %} parameters = { {% for pa_key, pa_value in mg.archetype_definitions[key].policy_assignments.items() %} {% if pa_value is mapping %} @@ -33,9 +33,10 @@ archetype_config_overrides = { {% else %} parameters = {} {% endif %} -{% if level.archetype_config.access_control is defined %} +{% if level.archetype_resources.access_control is mapping %} access_control = { -{% for level_ac_key, level_ac in level.archetype_config.access_control.items() %} +{% if resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} +{% for level_ac_key, level_ac in level.archetype_resources.access_control.items() %} "{{level_ac_key}}" = { {% for level_role_key, level_role in level_ac.items() %} "{{ level_role_key }}" = { @@ -46,6 +47,11 @@ archetype_config_overrides = { {% endfor %} } {% endfor %} +{% else %} + "Owner" = { + "principal_ids" = ["{{ resources.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] + } +{% endif %} } {% else %} access_control = {} diff --git a/templates/platform/level1/eslz/lib/v1.1.1/archetype_definitions/README.md b/templates/platform/level1/alz/lib/v1.1.1/archetype_definitions/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v1.1.1/archetype_definitions/README.md rename to templates/platform/level1/alz/lib/v1.1.1/archetype_definitions/README.md diff --git a/templates/platform/level1/eslz/lib/v1.1.1/archetype_definitions/archetype_definition_template.json.j2 b/templates/platform/level1/alz/lib/v1.1.1/archetype_definitions/archetype_definition_template.json.j2 similarity index 86% rename from templates/platform/level1/eslz/lib/v1.1.1/archetype_definitions/archetype_definition_template.json.j2 rename to templates/platform/level1/alz/lib/v1.1.1/archetype_definitions/archetype_definition_template.json.j2 index a489b4cdc..8eb4f14ea 100644 --- a/templates/platform/level1/eslz/lib/v1.1.1/archetype_definitions/archetype_definition_template.json.j2 +++ b/templates/platform/level1/alz/lib/v1.1.1/archetype_definitions/archetype_definition_template.json.j2 @@ -1,7 +1,7 @@ { "{{ mg.archetype_definitions[item].archetype_id }}": { "policy_assignments": [ -{% if mg.archetype_definitions[item].policy_assignments is defined %} +{% if mg.archetype_definitions[item].policy_assignments is mapping %} {% for key in mg.archetype_definitions[item].policy_assignments.keys() %} {% if loop.last %} "{{ key }}" @@ -10,7 +10,7 @@ {% endif %} {% endfor %} {% endif %} -{% if mg_custom.archetype_definitions[item].policy_assignments is defined %} +{% if mg_custom.archetype_definitions[item].policy_assignments is mapping %} {% for key in mg_custom.archetype_definitions[item].policy_assignments.keys() %} {% if loop.last %} "{{ key }}" @@ -21,7 +21,7 @@ {% endif %} ], "policy_definitions": [ -{% if mg.archetype_definitions[item].policy_definitions is defined %} +{% if mg.archetype_definitions[item].policy_definitions is mapping %} {% for key in mg.archetype_definitions[item].policy_definitions.keys() %} {% if loop.last %} "{{ key }}" @@ -30,7 +30,7 @@ {% endif %} {% endfor %} {% endif %} -{% if mg_custom.archetype_definitions[item].policy_definitions is defined %} +{% if mg_custom.archetype_definitions[item].policy_definitions is mapping %} {% for key in mg_custom.archetype_definitions[item].policy_definitions.keys() %} {% if loop.last %} "{{ key }}" @@ -41,7 +41,7 @@ {% endif %} ], "policy_set_definitions": [ -{% if mg.archetype_definitions[item].policy_set_definitions is defined %} +{% if mg.archetype_definitions[item].policy_set_definitions is mapping %} {% for key in mg.archetype_definitions[item].policy_set_definitions.keys() %} {% if loop.last %} "{{ key }}" @@ -50,7 +50,7 @@ {% endif %} {% endfor %} {% endif %} -{% if mg_custom.archetype_definitions[item].policy_set_definitions is defined %} +{% if mg_custom.archetype_definitions[item].policy_set_definitions is mapping %} {% for key in mg_custom.archetype_definitions[item].policy_set_definitions.keys() %} {% if loop.last %} "{{ key }}" @@ -61,7 +61,7 @@ {% endif %} ], "role_definitions": [ -{% if mg.archetype_definitions[item].role_definitions is defined %} +{% if mg.archetype_definitions[item].role_definitions is mapping %} {% for key in mg.archetype_definitions[item].role_definitions.keys() %} {% if loop.last %} "{{ key }}" @@ -70,7 +70,7 @@ {% endif %} {% endfor %} {% endif %} -{% if mg_custom.archetype_definitions[item].role_definitions is defined %} +{% if mg_custom.archetype_definitions[item].role_definitions is mapping %} {% for key in mg_custom.archetype_definitions[item].role_definitions.keys() %} {% if loop.last %} "{{ key }}" diff --git a/templates/platform/level1/eslz/lib/v1.1.1/archetype_definitions/custom_landing_zone_template.json.j2 b/templates/platform/level1/alz/lib/v1.1.1/archetype_definitions/custom_landing_zone_template.json.j2 similarity index 86% rename from templates/platform/level1/eslz/lib/v1.1.1/archetype_definitions/custom_landing_zone_template.json.j2 rename to templates/platform/level1/alz/lib/v1.1.1/archetype_definitions/custom_landing_zone_template.json.j2 index a795469dc..04df5040a 100644 --- a/templates/platform/level1/eslz/lib/v1.1.1/archetype_definitions/custom_landing_zone_template.json.j2 +++ b/templates/platform/level1/alz/lib/v1.1.1/archetype_definitions/custom_landing_zone_template.json.j2 @@ -1,7 +1,7 @@ { "{{ mg_custom.archetype_definitions[item].archetype_id }}": { "policy_assignments": [ -{% if mg.archetype_definitions[item].policy_assignments is defined %} +{% if mg.archetype_definitions[item].policy_assignments is mapping %} {% for key in mg.archetype_definitions[item].policy_assignments.keys() %} {% if loop.last %} "{{ key }}" @@ -10,7 +10,7 @@ {% endif %} {% endfor %} {% endif %} -{% if mg_custom.archetype_definitions[item].policy_assignments is defined %} +{% if mg_custom.archetype_definitions[item].policy_assignments is mapping %} {% for key in mg_custom.archetype_definitions[item].policy_assignments.keys() %} {% if loop.last %} "{{ key }}" @@ -21,7 +21,7 @@ {% endif %} ], "policy_definitions": [ -{% if mg.archetype_definitions[item].policy_definitions is defined %} +{% if mg.archetype_definitions[item].policy_definitions is mapping %} {% for key in mg.archetype_definitions[item].policy_definitions.keys() %} {% if loop.last %} "{{ key }}" @@ -30,7 +30,7 @@ {% endif %} {% endfor %} {% endif %} -{% if mg_custom.archetype_definitions[item].policy_definitions is defined %} +{% if mg_custom.archetype_definitions[item].policy_definitions is mapping %} {% for key in mg_custom.archetype_definitions[item].policy_definitions.keys() %} {% if loop.last %} "{{ key }}" @@ -41,7 +41,7 @@ {% endif %} ], "policy_set_definitions": [ -{% if mg.archetype_definitions[item].policy_set_definitions is defined %} +{% if mg.archetype_definitions[item].policy_set_definitions is mapping %} {% for key in mg.archetype_definitions[item].policy_set_definitions.keys() %} {% if loop.last %} "{{ key }}" @@ -50,7 +50,7 @@ {% endif %} {% endfor %} {% endif %} -{% if mg_custom.archetype_definitions[item].policy_set_definitions is defined %} +{% if mg_custom.archetype_definitions[item].policy_set_definitions is mapping %} {% for key in mg_custom.archetype_definitions[item].policy_set_definitions.keys() %} {% if loop.last %} "{{ key }}" @@ -61,7 +61,7 @@ {% endif %} ], "role_definitions": [ -{% if mg.archetype_definitions[item].role_definitions is defined %} +{% if mg.archetype_definitions[item].role_definitions is mapping %} {% for key in mg.archetype_definitions[item].role_definitions.keys() %} {% if loop.last %} "{{ key }}" @@ -70,7 +70,7 @@ {% endif %} {% endfor %} {% endif %} -{% if mg_custom.archetype_definitions[item].role_definitions is defined %} +{% if mg_custom.archetype_definitions[item].role_definitions is mapping %} {% for key in mg_custom.archetype_definitions[item].role_definitions.keys() %} {% if loop.last %} "{{ key }}" diff --git a/templates/enterprise-scale/contoso/platform/eslz/custom_landing_zones.caf.platform.yaml b/templates/platform/level1/alz/lib/v1.1.1/custom_landing_zones.caf.platform.yaml similarity index 79% rename from templates/enterprise-scale/contoso/platform/eslz/custom_landing_zones.caf.platform.yaml rename to templates/platform/level1/alz/lib/v1.1.1/custom_landing_zones.caf.platform.yaml index bdb6f5356..6ae8db0c4 100644 --- a/templates/enterprise-scale/contoso/platform/eslz/custom_landing_zones.caf.platform.yaml +++ b/templates/platform/level1/alz/lib/v1.1.1/custom_landing_zones.caf.platform.yaml @@ -3,19 +3,24 @@ archetype_definitions: display_name: Corp archetype_id: landingzone_corp parent_management_group_id: landing-zones + subscription_ids: online: display_name: Online archetype_id: landingzone_online parent_management_group_id: landing-zones + subscription_ids: corp-prod: display_name: Production archetype_id: landingzone_prod parent_management_group_id: corp + subscription_ids: corp-non-prod: display_name: Non Production archetype_id: landingzone_non_prod parent_management_group_id: corp + subscription_ids: online-web: display_name: Non Production archetype_id: landingzone_online_web - parent_management_group_id: online \ No newline at end of file + parent_management_group_id: online + subscription_ids: \ No newline at end of file diff --git a/templates/platform/level1/eslz/lib/v0.3.3/custom_landing_zones.tfvars.j2 b/templates/platform/level1/alz/lib/v1.1.1/custom_landing_zones.tfvars.j2 similarity index 57% rename from templates/platform/level1/eslz/lib/v0.3.3/custom_landing_zones.tfvars.j2 rename to templates/platform/level1/alz/lib/v1.1.1/custom_landing_zones.tfvars.j2 index 4ebb58b6b..570a7c7b0 100644 --- a/templates/platform/level1/eslz/lib/v0.3.3/custom_landing_zones.tfvars.j2 +++ b/templates/platform/level1/alz/lib/v1.1.1/custom_landing_zones.tfvars.j2 @@ -1,13 +1,13 @@ custom_landing_zones = { {% for key, level in mg_custom.archetype_definitions.items() %} - {{ config.platform_core_setup.enterprise_scale.management_group_prefix }}-{{ key }} = { - display_name = "{{ mg_custom.archetype_definitions[key].display_name }}" - parent_management_group_id = "{{ config.platform_core_setup.enterprise_scale.management_group_prefix }}-{{ mg_custom.archetype_definitions[key].parent_management_group_id }}" + {{ bootstrap.management_groups[region][tfstate].management_group_prefix }}-{{ key }} = { + display_name = "{{ level.display_name }}" + parent_management_group_id = "{{ bootstrap.management_groups[region][tfstate].management_group_prefix }}-{{ level.parent_management_group_id }}" archetype_config = { - archetype_id = "{{mg_custom.archetype_definitions[key].archetype_id }}" -{% if mg_custom.archetype_definitions[key].policy_assignments is defined %} + archetype_id = "{{ level.archetype_id }}" +{% if level.policy_assignments is defined %} parameters = { -{% for pa_key, pa_value in mg_custom.archetype_definitions[key].policy_assignments.items() %} +{% for pa_key, pa_value in level.policy_assignments.items() %} {% if pa_value is mapping %} "{{ pa_key }}" = { {% for attribute, attribute_value in pa_value.items() %} @@ -36,9 +36,10 @@ custom_landing_zones = { {% else %} parameters = {} {% endif %} -{% if mg_custom.archetype_definitions[key].archetype_config.access_control is defined %} +{% if level.archetype_resources.access_control is defined %} access_control = { -{% for level_ac_key, level_ac in mg_custom.archetype_definitions[key].archetype_config.access_control.items() %} +{% if resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} +{% for level_ac_key, level_ac in level.archetype_resources.access_control.items() %} "{{level_ac_key}}" = { {% for level_role_key, level_role in level_ac.items() %} "{{ level_role_key }}" = { @@ -49,13 +50,22 @@ custom_landing_zones = { {% endfor %} } {% endfor %} +{% else %} + "Owner" = { + "principal_ids" = ["{{ resources.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] + } +{% endif %} } {% else %} access_control = {} {% endif %} } subscriptions = {} +{% if level.subscription_ids is defined %} + subscription_ids = {{ level.subscription_ids | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% else %} subscription_ids = [] +{% endif %} } {% endfor %} diff --git a/templates/platform/level1/eslz/lib/v0.3.3/policy_assignments/README.md b/templates/platform/level1/alz/lib/v1.1.1/policy_assignments/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v0.3.3/policy_assignments/README.md rename to templates/platform/level1/alz/lib/v1.1.1/policy_assignments/README.md diff --git a/templates/platform/level1/eslz/lib/v0.3.3/policy_assignments/policy_assignment_caf_aks_capability.json b/templates/platform/level1/alz/lib/v1.1.1/policy_assignments/policy_assignment_caf_aks_capability.json similarity index 100% rename from templates/platform/level1/eslz/lib/v0.3.3/policy_assignments/policy_assignment_caf_aks_capability.json rename to templates/platform/level1/alz/lib/v1.1.1/policy_assignments/policy_assignment_caf_aks_capability.json diff --git a/templates/platform/level1/alz/lib/v1.1.1/policy_assignments/policy_assignment_caf_deploy_nsg_flowlogs.json b/templates/platform/level1/alz/lib/v1.1.1/policy_assignments/policy_assignment_caf_deploy_nsg_flowlogs.json new file mode 100644 index 000000000..575e6f450 --- /dev/null +++ b/templates/platform/level1/alz/lib/v1.1.1/policy_assignments/policy_assignment_caf_deploy_nsg_flowlogs.json @@ -0,0 +1,18 @@ +{ + "name": "CAF-Deploy-Nsg-FlowLogs", + "type": "Microsoft.Authorization/policyAssignments", + "apiVersion": "2019-09-01", + "properties": { + "description": "Deploy if not exists nsg flowlogs and traffic analytics on network security groups. Define also the retention days.", + "displayName": "CAF - Enable Nsg flowlogs and traffic analytics.", + "notScopes": [], + "parameters": {}, + "policyDefinitionId": "${root_scope_resource_id}/providers/Microsoft.Authorization/policyDefinitions/CAF-Deploy-Nsg-FlowLogs", + "scope": "${current_scope_resource_id}", + "enforcementMode": true + }, + "location": "${default_location}", + "identity": { + "type": "SystemAssigned" + } +} \ No newline at end of file diff --git a/templates/platform/level1/eslz/lib/v0.3.3/policy_assignments/policy_assignment_es_allowed_locations.json b/templates/platform/level1/alz/lib/v1.1.1/policy_assignments/policy_assignment_es_allowed_locations.json similarity index 100% rename from templates/platform/level1/eslz/lib/v0.3.3/policy_assignments/policy_assignment_es_allowed_locations.json rename to templates/platform/level1/alz/lib/v1.1.1/policy_assignments/policy_assignment_es_allowed_locations.json diff --git a/templates/platform/level1/eslz/lib/v0.3.3/policy_definitions/README.md b/templates/platform/level1/alz/lib/v1.1.1/policy_definitions/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v0.3.3/policy_definitions/README.md rename to templates/platform/level1/alz/lib/v1.1.1/policy_definitions/README.md diff --git a/templates/platform/level1/alz/lib/v1.1.1/policy_definitions/policy_definition_caf_deploy_nsg_flowlogs.json b/templates/platform/level1/alz/lib/v1.1.1/policy_definitions/policy_definition_caf_deploy_nsg_flowlogs.json new file mode 100644 index 000000000..daf0fa3df --- /dev/null +++ b/templates/platform/level1/alz/lib/v1.1.1/policy_definitions/policy_definition_caf_deploy_nsg_flowlogs.json @@ -0,0 +1,228 @@ +{ + "name": "CAF-Deploy-Nsg-FlowLogs", + "type": "Microsoft.Authorization/policyDefinitions", + "apiVersion": "2021-06-01", + "scope": null, + "properties": { + "policyType": "Custom", + "mode": "Indexed", + "displayName": "CAF - Enable Nsg flowlogs and traffic analytics.", + "parameters": { + "effect": { + "type": "String", + "metadata": { + "displayName": "Effect", + "description": "Enable or disable the execution of the policy" + }, + "allowedValues": [ + "DeployIfNotExists", + "Disabled" + ], + "defaultValue": "DeployIfNotExists" + }, + "flowAnalyticsEnabled": { + "type": "String", + "metadata": { + "displayName": "Enable Traffic Analytics", + "description": "Enable Traffic Analytics" + }, + "defaultValue": "true" + }, + "interval": { + "type": "String", + "metadata": { + "displayName": "Traffic Analytics processing interval mins (10/60)", + "description": "Traffic Analytics processing interval mins (10/60)" + }, + "defaultValue": "60" + }, + "retention": { + "type": "String", + "metadata": { + "displayName": "Retention days in storage account. If you want to retain data forever and do not want to apply any retention policy, set retention (days) to 0.", + "description": "Retention days in storage account. If you want to retain data forever and do not want to apply any retention policy, set retention (days) to 0." + }, + "defaultValue": "2" + }, + "logAnalytics": { + "type": "String", + "metadata": { + "displayName": "Resource ID of Log Analytics workspace", + "description": "Select Log Analytics workspace from dropdown list. If this workspace is outside of the scope of the assignment you must manually grant 'Log Analytics Contributor' permissions (or similar) to the policy assignment's principal ID.", + "strongType": "omsWorkspace" + }, + "defaultValue": "" + }, + "storageAccountResourceId": { + "type": "String", + "metadata": { + "displayName": "Storage Account Resource Id", + "description": "Storage Account Resource Id", + "strongType": "Microsoft.Storage/storageAccounts" + }, + "defaultValue": "" + } + }, + "policyRule": { + "if": { + "allOf": [ + { + "equals": "Microsoft.Network/networkSecurityGroups", + "field": "type" + } + ] + }, + "then": { + "details": { + "deployment": { + "properties": { + "mode": "Incremental", + "parameters": { + "flowAnalyticsEnabled": { + "value": "[bool(parameters('flowAnalyticsEnabled'))]" + }, + "interval": { + "value": "[int(parameters('interval'))]" + }, + "location": { + "value": "[field('location')]" + }, + "networkSecurityGroup": { + "value": "[field('id')]" + }, + "retention": { + "value": "[int(parameters('retention'))]" + }, + "storageAccountResourceId": { + "value": "[parameters('storageAccountResourceId')]" + }, + "logAnalytics": { + "value": "[parameters('logAnalytics')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "location": "[parameters('location')]", + "outputs": {}, + "parameters": { + "flowAnalyticsEnabled": { + "type": "bool" + }, + "interval": { + "type": "int" + }, + "location": { + "type": "String" + }, + "networkSecurityGroup": { + "type": "String" + }, + "retention": { + "type": "int" + }, + "storageAccountResourceId": { + "type": "String" + }, + "time": { + "defaultValue": "[utcNow()]", + "type": "String" + }, + "logAnalytics": { + "type": "String" + } + }, + "resources": [ + { + "apiVersion": "2019-10-01", + "name": "[take(concat('NetworkWatcherRG', '.', variables('securityGroupName')), 64)]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "apiVersion": "2020-05-01", + "name": "[concat('NetworkWatcher_', toLower(parameters('location')))]", + "location": "[parameters('location')]", + "properties": {}, + "resources": [ + { + "apiVersion": "2019-11-01", + "dependsOn": [ + "[concat('NetworkWatcher_', toLower(parameters('location')))]" + ], + "name": "[concat(variables('securityGroupName'), '-Network-flowlog')]", + "location": "[parameters('location')]", + "properties": { + "enabled": true, + "flowAnalyticsConfiguration": { + "networkWatcherFlowAnalyticsConfiguration": { + "enabled": "[bool(parameters('flowAnalyticsEnabled'))]", + "trafficAnalyticsInterval": "[parameters('interval')]", + "workspaceRegion": "[if(not(empty(parameters('logAnalytics'))), reference(parameters('logAnalytics'), '2020-03-01-preview', 'Full').location, json('null')) ]", + "workspaceResourceId": "[parameters('logAnalytics')]" + } + }, + "format": { + "type": "JSON", + "version": 2 + }, + "retentionPolicy": { + "days": "[parameters('retention')]", + "enabled": true + }, + "storageId": "[parameters('storageAccountResourceId')]", + "targetResourceId": "[parameters('networkSecurityGroup')]" + }, + "type": "flowLogs" + } + ], + "type": "Microsoft.Network/networkWatchers" + } + ] + } + }, + "resourceGroup": "NetworkWatcherRG", + "type": "Microsoft.Resources/deployments" + } + ], + "variables": { + "securityGroupName": "[split(parameters('networkSecurityGroup'), '/')[8]]" + } + } + } + }, + "existenceCondition": { + "allof": [ + { + "field": "Microsoft.Network/networkWatchers/flowLogs/enabled", + "equals": "true" + }, + { + "field": "Microsoft.Network/networkWatchers/flowLogs/flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled", + "equals": "[bool(parameters('flowAnalyticsEnabled'))]" + }, + { + "field": "Microsoft.Network/networkWatchers/flowLogs/flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.trafficAnalyticsInterval", + "equals": "[parameters('interval')]" + }, + { + "field": "Microsoft.Network/networkWatchers/flowLogs/retentionPolicy.days", + "equals": "[parameters('retention')]" + } + ] + }, + "resourceGroupName": "[if(empty(coalesce(field('Microsoft.Network/networkSecurityGroups/flowLogs'))), 'NetworkWatcherRG', split(first(field('Microsoft.Network/networkSecurityGroups/flowLogs[*].id')), '/')[4])]", + "name": "[if(empty(coalesce(field('Microsoft.Network/networkSecurityGroups/flowLogs[*].id'))), 'null/null', concat(split(first(field('Microsoft.Network/networkSecurityGroups/flowLogs[*].id')), '/')[8], '/', split(first(field('Microsoft.Network/networkSecurityGroups/flowLogs[*].id')), '/')[10]))]", + "roleDefinitionIds": [ + "/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7" + ], + "type": "Microsoft.Network/networkWatchers/flowLogs" + }, + "effect": "[parameters('effect')]" + } + } + } +} \ No newline at end of file diff --git a/templates/platform/level1/eslz/lib/v0.3.3/policy_set_definitions/README.md b/templates/platform/level1/alz/lib/v1.1.1/policy_set_definitions/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v0.3.3/policy_set_definitions/README.md rename to templates/platform/level1/alz/lib/v1.1.1/policy_set_definitions/README.md diff --git a/templates/platform/level1/eslz/lib/v0.3.3/role_definitions/README.md b/templates/platform/level1/alz/lib/v1.1.1/role_definitions/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v0.3.3/role_definitions/README.md rename to templates/platform/level1/alz/lib/v1.1.1/role_definitions/README.md diff --git a/templates/platform/level1/eslz/lib/v1.1.1/role_definitions/role_definition_caf_vhub_peering.json b/templates/platform/level1/alz/lib/v1.1.1/role_definitions/role_definition_caf_vhub_peering.json similarity index 100% rename from templates/platform/level1/eslz/lib/v1.1.1/role_definitions/role_definition_caf_vhub_peering.json rename to templates/platform/level1/alz/lib/v1.1.1/role_definitions/role_definition_caf_vhub_peering.json diff --git a/templates/platform/level1/alz/lib/v1.1.3/archetype_config_overrides.caf.platform.yaml b/templates/platform/level1/alz/lib/v1.1.3/archetype_config_overrides.caf.platform.yaml new file mode 100644 index 000000000..3740933ce --- /dev/null +++ b/templates/platform/level1/alz/lib/v1.1.3/archetype_config_overrides.caf.platform.yaml @@ -0,0 +1,374 @@ +archetype_definitions: + root: + archetype_id: root + policy_assignments: + Allowed-Locations: + listOfAllowedLocations: +{% for region in topology.resources_allowed_regions %} + - {{topology.caf_regions[region]}} +{% endfor %} + Deny-RSG-Locations: + listOfAllowedLocations: +{% for region in topology.resource_groups_allowed_regions %} + - {{topology.caf_regions[region]}} +{% endfor %} + # Set to Audit as Terraform cannot combine both in one operation yet. + Deny-Subnet-Without-Nsg: + effect: Audit + # Set to Audit as Terraform cannot combine both in one operation yet. + Deny-Subnet-Without-Udr: + effect: Audit + # More details on in the parameters in the Azure Policy definition (Azure Security Benchmark) 1f3afdf9-d0c9-4c3d-847f-89da613e70a8 + # Change the attributes values as they are not the same. Some are DeployIfNotExist, Some Disabled, Enabled... + Deploy-ASC-Monitoring: + aadAuthenticationInSqlServerMonitoringEffect: Disabled + diskEncryptionMonitoringEffect: Disabled + encryptionOfAutomationAccountMonitoringEffect: Disabled + identityDesignateLessThanOwnersMonitoringEffect: Disabled + identityDesignateMoreThanOneOwnerMonitoringEffect: Disabled + identityEnableMFAForWritePermissionsMonitoringEffect: Disabled + identityRemoveDeprecatedAccountMonitoringEffect: Disabled + identityRemoveDeprecatedAccountWithOwnerPermissionsMonitoringEffect: Disabled + identityRemoveExternalAccountWithOwnerPermissionsMonitoringEffect: Disabled + identityRemoveExternalAccountWithReadPermissionsMonitoringEffect: Disabled + identityRemoveExternalAccountWithWritePermissionsMonitoringEffect: Disabled + jitNetworkAccessMonitoringEffect: Disabled + networkSecurityGroupsOnSubnetsMonitoringEffect: Disabled + sqlDbEncryptionMonitoringEffect: Disabled + sqlManagedInstanceAdvancedDataSecurityEmailAdminsMonitoringEffect: Disabled + sqlManagedInstanceAdvancedDataSecurityEmailsMonitoringEffect: Disabled + sqlServerAdvancedDataSecurityEmailAdminsMonitoringEffect: Disabled + sqlServerAdvancedDataSecurityMonitoringEffect: Disabled + systemUpdatesMonitoringEffect: AuditIfNotExists + useRbacRulesMonitoringEffect: Disabled + vmssSystemUpdatesMonitoringEffect: Disabled + windowsDefenderExploitGuardMonitoringEffect: Disabled + Deploy-ASCDF-Config: + emailSecurityContact: {{topology.notifications.azure_defender.emailSecurityContact}} + logAnalytics: + lz_key: management + output_key: diagnostics + resource_type: log_analytics + resource_key: region1 + attribute_key: id + enableAscForKubernetes: DeployIfNotExists + enableAscForSql: DeployIfNotExists + enableAscForSqlOnVm: DeployIfNotExists + enableAscForDns: DeployIfNotExists + enableAscForArm: DeployIfNotExists + enableAscForOssDb: DeployIfNotExists + enableAscForAppServices: DeployIfNotExists + enableAscForRegistries: DeployIfNotExists + enableAscForKeyVault: DeployIfNotExists + enableAscForStorage: DeployIfNotExists + enableAscForServers: DeployIfNotExists + Deploy-AzActivity-Log: + logAnalytics: + lz_key: management + output_key: diagnostics + resource_type: log_analytics + resource_key: region1 + attribute_key: id + Deploy-LX-Arc-Monitoring: + Deploy-Resource-Diag: + profileName: alz-diagnostic-log + logAnalytics: + lz_key: management + output_key: diagnostics + resource_type: log_analytics + resource_key: region1 + attribute_key: id + Deploy-WS-Arc-Monitoring: + logAnalytics: + lz_key: management + output_key: diagnostics + resource_type: log_analytics + resource_key: region1 + attribute_key: id + Deploy-VM-Monitoring: + logAnalytics_1: + lz_key: management + output_key: diagnostics + resource_type: log_analytics + resource_key: region1 + attribute_key: id + Deploy-VMSS-Monitoring: + logAnalytics_1: + lz_key: management + output_key: diagnostics + resource_type: log_analytics + resource_key: region1 + attribute_key: id + policy_definitions: + Append-AppService-httpsonly: + Append-AppService-latestTLS: + Append-KV-SoftDelete: + Append-Redis-disableNonSslPort: + Append-Redis-sslEnforcement: + Audit-MachineLearning-PrivateEndpointId: + CAF-Deploy-Nsg-FlowLogs: + Deny-AA-child-resources: + Deny-AppGW-Without-WAF: + Deny-AppServiceApiApp-http: + Deny-AppServiceFunctionApp-http: + Deny-AppServiceWebApp-http: + Deny-Databricks-NoPublicIp: + Deny-Databricks-Sku: + Deny-Databricks-VirtualNetwork: + Deny-MachineLearning-Aks: + Deny-MachineLearning-Compute-SubnetId: + Deny-MachineLearning-Compute-VmSize: + Deny-MachineLearning-ComputeCluster-RemoteLoginPortPublicAccess: + Deny-MachineLearning-ComputeCluster-Scale: + Deny-MachineLearning-HbiWorkspace: + Deny-MachineLearning-PublicAccessWhenBehindVnet: + Deny-MachineLearning-PublicNetworkAccess: + Deny-MySql-http: + Deny-PostgreSql-http: + Deny-Private-DNS-Zones: + Deny-PublicEndpoint-MariaDB: + Deny-PublicIP: + Deny-RDP-From-Internet: + Deny-Redis-http: + Deny-Sql-minTLS: + Deny-SqlMi-minTLS: + Deny-Storage-minTLS: + Deny-Subnet-Without-Nsg: + Deny-Subnet-Without-Udr: + Deny-VNET-Peer-Cross-Sub: + Deny-VNet-Peering: + Deploy-ASC-SecurityContacts: + Deploy-Budget: + Deploy-Custom-Route-Table: + Deploy-DDoSProtection: + Deploy-Diagnostics-AA: + Deploy-Diagnostics-ACI: + Deploy-Diagnostics-ACR: + Deploy-Diagnostics-AnalysisService: + Deploy-Diagnostics-ApiForFHIR: + Deploy-Diagnostics-APIMgmt: + Deploy-Diagnostics-ApplicationGateway: + Deploy-Diagnostics-CDNEndpoints: + Deploy-Diagnostics-CognitiveServices: + Deploy-Diagnostics-CosmosDB: + Deploy-Diagnostics-Databricks: + Deploy-Diagnostics-DataExplorerCluster: + Deploy-Diagnostics-DataFactory: + Deploy-Diagnostics-DLAnalytics: + Deploy-Diagnostics-EventGridSub: + Deploy-Diagnostics-EventGridSystemTopic: + Deploy-Diagnostics-EventGridTopic: + Deploy-Diagnostics-ExpressRoute: + Deploy-Diagnostics-Firewall: + Deploy-Diagnostics-FrontDoor: + Deploy-Diagnostics-Function: + Deploy-Diagnostics-HDInsight: + Deploy-Diagnostics-iotHub: + Deploy-Diagnostics-LoadBalancer: + Deploy-Diagnostics-LogicAppsISE: + Deploy-Diagnostics-MariaDB: + Deploy-Diagnostics-MediaService: + Deploy-Diagnostics-MlWorkspace: + Deploy-Diagnostics-MySQL: + Deploy-Diagnostics-NetworkSecurityGroups: + Deploy-Diagnostics-NIC: + Deploy-Diagnostics-PostgreSQL: + Deploy-Diagnostics-PowerBIEmbedded: + Deploy-Diagnostics-RedisCache: + Deploy-Diagnostics-Relay: + Deploy-Diagnostics-SignalR: + Deploy-Diagnostics-SQLElasticPools: + Deploy-Diagnostics-SQLMI: + Deploy-Diagnostics-TimeSeriesInsights: + Deploy-Diagnostics-TrafficManager: + Deploy-Diagnostics-VirtualNetwork: + Deploy-Diagnostics-VM: + Deploy-Diagnostics-VMSS: + Deploy-Diagnostics-VNetGW: + Deploy-Diagnostics-WebServerFarm: + Deploy-Diagnostics-Website: + Deploy-Diagnostics-WVDAppGroup: + Deploy-Diagnostics-WVDHostPools: + Deploy-Diagnostics-WVDWorkspace: + Deploy-FirewallPolicy: + Deploy-MySQL-sslEnforcement: + Deploy-Nsg-FlowLogs-to-LA: + Deploy-Nsg-FlowLogs: + Deploy-PostgreSQL-sslEnforcement: + Deploy-Sql-AuditingSettings: + Deploy-SQL-minTLS: + Deploy-Sql-SecurityAlertPolicies: + Deploy-Sql-Tde: + Deploy-Sql-vulnerabilityAssessments: + Deploy-SqlMi-minTLS: + Deploy-Storage-sslEnforcement: + Deploy-Windows-DomainJoin: + policy_set_definitions: + Deny-PublicPaaSEndpoints: + Deploy-ASCDF-Config: + Deploy-Diagnostics-LogAnalytics: + Deploy-Sql-Security: + Enforce-Encryption-CMK: + Enforce-EncryptTransit: + remediation: + policy: + policy_set_definitions: + # policyDefinitionReferenceId = https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/blob/c7958266bd227e52dc1a3468e8c881633bc1b373/modules/archetypes/lib/policy_set_definitions/policy_set_definition_es_deploy_diagnostics_loganalytics.tmpl.json#L766 + # /providers/microsoft.management/managementgroups/contlle/providers/microsoft.authorization/policyassignments/deploy-resource-diag + Deploy-Diagnostics-LogAnalytics: + - ExpressRouteDeployDiagnosticLogDeployLogAnalytics + - FirewallDeployDiagnosticLogDeployLogAnalytics + - KeyVaultDeployDiagnosticLogDeployLogAnalytics + - LoadBalancerDeployDiagnosticLogDeployLogAnalytics + - NetworkNICDeployDiagnosticLogDeployLogAnalytics + - NetworkPublicIPNicDeployDiagnosticLogDeployLogAnalytics + - NetworkSecurityGroupsDeployDiagnosticLogDeployLogAnalytics + - RecoveryVaultDeployDiagnosticLogDeployLogAnalytics + - storageaccountdeploydiagnosticlogdeployloganalytics + - VirtualNetworkDeployDiagnosticLogDeployLogAnalytics + - VNetGWDeployDiagnosticLogDeployLogAnalytics + Deploy-ASCDF-Config: + - defenderForOssDb + - defenderForVM + - defenderForSqlServerVirtualMachines + - defenderForAppServices + - defenderForStorageAccounts + - defenderForKubernetesService + - defenderForContainerRegistry + - defenderForKeyVaults + - defenderForDns + - defenderForArm + - defenderForSqlPaas + - securityEmailContact + - ascExport + landing-zones: + archetype_id: landing-zones + policy_assignments: + Deny-IP-Forwarding: + Deny-Priv-Containers-AKS: + Deny-Priv-Escalation-AKS: + Deny-Private-DNS-Zones: + Deny-RDP-From-Internet: + Deny-Storage-http: + Deploy-AKS-Policy: + Deploy-SQL-DB-Auditing: + Deploy-SQL-Threat: + Enable-DDoS-VNET: + Enforce-AKS-HTTPS: + Enforce-TLS-SSL: + CAF-Deploy-Nsg-FlowLogs: + effect: DeployIfNotExists + retention: 5 + storageAccountResourceId: + lz_key: management + output_key: objects + resource_type: storage_accounts + resource_key: nsgflogs + attribute_key: id + interval: 60 + flowAnalyticsEnabled: true + logAnalytics: + lz_key: management + output_key: diagnostics + resource_type: log_analytics + resource_key: region1 + attribute_key: id + Deny-Public-Endpoints: + ACRPublicIpDenyEffect: Audit + AFSPublicIpDenyEffect: Audit + AKSPublicIpDenyEffect: Audit + BatchPublicIpDenyEffect: Audit + CosmosPublicIpDenyEffect: Audit + KeyVaultPublicIpDenyEffect: Audit + MySQLFlexPublicIpDenyEffect: Audit + PostgreSQLFlexPublicIpDenyEffect: Audit + SqlServerPublicIpDenyEffect: Audit + StoragePublicIpDenyEffect: Audit + archetype_config: + access_control: + Owner: + azuread_groups: + lz_key: launchpad + attribute_key: id + resource_keys: + - subscription_creation_landingzones + connectivity: + archetype_id: platform_connectivity + policy_assignments: + Enable-DDoS-VNET: + role_definitions: + CAF-network-vhub-peering: + archetype_config: + access_control: + Owner: + azuread_groups: + lz_key: launchpad + attribute_key: id + resource_keys: + - connectivity + # Make sure you replace with the Management Group ID in UPPER CASE + '[{{topology.caf_environment | upper}}-CONNECTIVITY] CAF-network-vhub-peering': + azuread_groups: + lz_key: launchpad + attribute_key: id + resource_keys: + - subscription_creation_landingzones + - identity + - management + management: + archetype_id: platform_management + policy_assignments: + Deny-Private-DNS-Zones: + archetype_config: + access_control: + Owner: + azuread_groups: + lz_key: launchpad + attribute_key: id + resource_keys: + - management + identity: + archetype_id: platform_identity + policy_assignments: + Deny-RDP-From-Internet: + Deny-Public-IP: + Deny-Private-DNS-Zones: + Deny-IP-Forwarding: + archetype_config: + access_control: + Owner: + azuread_groups: + lz_key: launchpad + attribute_key: id + resource_keys: + - identity + decommissioned: + archetype_id: platform_decommissioned + policy_assignments: + Deny-IP-Forwarding: + Deny-Private-DNS-Zones: + platform: + archetype_id: platform + policy_assignments: + CAF-Deploy-Nsg-FlowLogs: + effect: DeployIfNotExists + retention: 5 + storageAccountResourceId: + lz_key: management + output_key: objects + resource_type: storage_accounts + resource_key: nsgflogs + attribute_key: id + interval: 60 + flowAnalyticsEnabled: true + logAnalytics: + lz_key: management + output_key: diagnostics + resource_type: log_analytics + resource_key: region1 + attribute_key: id + sandboxes: + archetype_id: platform_sandboxes + policy_assignments: + Deny-IP-Forwarding: + Deny-Private-DNS-Zones: \ No newline at end of file diff --git a/templates/platform/level1/alz/lib/v1.1.3/archetype_config_overrides.tfvars.j2 b/templates/platform/level1/alz/lib/v1.1.3/archetype_config_overrides.tfvars.j2 new file mode 100644 index 000000000..4ad74b76e --- /dev/null +++ b/templates/platform/level1/alz/lib/v1.1.3/archetype_config_overrides.tfvars.j2 @@ -0,0 +1,62 @@ +archetype_config_overrides = { +{% for key, level in mg.archetype_definitions.items() %} + {{ key }} = { + archetype_id = "{{mg.archetype_definitions[key].archetype_id }}" +{% if mg.archetype_definitions[key].policy_assignments is mapping %} + parameters = { +{% for pa_key, pa_value in mg.archetype_definitions[key].policy_assignments.items() %} +{% if pa_value is mapping %} + "{{ pa_key }}" = { +{% for attribute, attribute_value in pa_value.items() %} + "{{attribute}}" = { +{% if attribute_value is string %} + value = "{{ attribute_value }}" +{% elif attribute_value is boolean %} + value = {{ attribute_value | string | lower }} +{% elif attribute_value is number %} + value = {{ attribute_value }} +{% else %} +{% if attribute_value is mapping %} +{% for caf_key, caf_value in attribute_value.items() %} + {{ caf_key }} = "{{ caf_value }}" +{% endfor %} +{% else %} + values = {{ attribute_value | replace('None','[]') | replace('\'','\"') }} +{% endif %} +{% endif %} + } +{% endfor %} + } +{% endif %} +{% endfor %} + } +{% else %} + parameters = {} +{% endif %} +{% if level.archetype_resources.access_control is mapping %} + access_control = { +{% if resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} +{% for level_ac_key, level_ac in level.archetype_resources.access_control.items() %} + "{{level_ac_key}}" = { +{% for level_role_key, level_role in level_ac.items() %} + "{{ level_role_key }}" = { + lz_key = "{{ level_role.lz_key }}" + attribute_key = "{{ level_role.attribute_key }}" + resource_keys = {{ level_role.resource_keys | replace('None','[]') | replace('\'','\"') }} + } +{% endfor %} + } +{% endfor %} +{% else %} + "Owner" = { + "principal_ids" = ["{{ resources.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] + } +{% endif %} + } +{% else %} + access_control = {} +{% endif %} + } + +{% endfor %} +} \ No newline at end of file diff --git a/templates/platform/level1/alz/lib/v1.1.3/archetype_definitions/README.md b/templates/platform/level1/alz/lib/v1.1.3/archetype_definitions/README.md new file mode 100644 index 000000000..519e9f330 --- /dev/null +++ b/templates/platform/level1/alz/lib/v1.1.3/archetype_definitions/README.md @@ -0,0 +1,11 @@ + +# Public documentation of the custom landingzones + +https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/wiki/%5BUser-Guide%5D-Archetype-Definitions + +https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/wiki/%5BExamples%5D-Deploy-Custom-Landing-Zone-Archetypes + +# List of the default archetypes + +https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/tree/main/modules/archetypes/lib/archetype_definitions + diff --git a/templates/platform/level1/alz/lib/v1.1.3/archetype_definitions/archetype_definition_template.json.j2 b/templates/platform/level1/alz/lib/v1.1.3/archetype_definitions/archetype_definition_template.json.j2 new file mode 100644 index 000000000..8eb4f14ea --- /dev/null +++ b/templates/platform/level1/alz/lib/v1.1.3/archetype_definitions/archetype_definition_template.json.j2 @@ -0,0 +1,90 @@ +{ + "{{ mg.archetype_definitions[item].archetype_id }}": { + "policy_assignments": [ +{% if mg.archetype_definitions[item].policy_assignments is mapping %} +{% for key in mg.archetype_definitions[item].policy_assignments.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} +{% if mg_custom.archetype_definitions[item].policy_assignments is mapping %} +{% for key in mg_custom.archetype_definitions[item].policy_assignments.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} + ], + "policy_definitions": [ +{% if mg.archetype_definitions[item].policy_definitions is mapping %} +{% for key in mg.archetype_definitions[item].policy_definitions.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} +{% if mg_custom.archetype_definitions[item].policy_definitions is mapping %} +{% for key in mg_custom.archetype_definitions[item].policy_definitions.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} + ], + "policy_set_definitions": [ +{% if mg.archetype_definitions[item].policy_set_definitions is mapping %} +{% for key in mg.archetype_definitions[item].policy_set_definitions.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} +{% if mg_custom.archetype_definitions[item].policy_set_definitions is mapping %} +{% for key in mg_custom.archetype_definitions[item].policy_set_definitions.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} + ], + "role_definitions": [ +{% if mg.archetype_definitions[item].role_definitions is mapping %} +{% for key in mg.archetype_definitions[item].role_definitions.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} +{% if mg_custom.archetype_definitions[item].role_definitions is mapping %} +{% for key in mg_custom.archetype_definitions[item].role_definitions.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} + ], + "archetype_config": { + "parameters": { + }, + "access_control": { + } + } + } +} diff --git a/templates/platform/level1/alz/lib/v1.1.3/archetype_definitions/custom_landing_zone_template.json.j2 b/templates/platform/level1/alz/lib/v1.1.3/archetype_definitions/custom_landing_zone_template.json.j2 new file mode 100644 index 000000000..04df5040a --- /dev/null +++ b/templates/platform/level1/alz/lib/v1.1.3/archetype_definitions/custom_landing_zone_template.json.j2 @@ -0,0 +1,90 @@ +{ + "{{ mg_custom.archetype_definitions[item].archetype_id }}": { + "policy_assignments": [ +{% if mg.archetype_definitions[item].policy_assignments is mapping %} +{% for key in mg.archetype_definitions[item].policy_assignments.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} +{% if mg_custom.archetype_definitions[item].policy_assignments is mapping %} +{% for key in mg_custom.archetype_definitions[item].policy_assignments.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} + ], + "policy_definitions": [ +{% if mg.archetype_definitions[item].policy_definitions is mapping %} +{% for key in mg.archetype_definitions[item].policy_definitions.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} +{% if mg_custom.archetype_definitions[item].policy_definitions is mapping %} +{% for key in mg_custom.archetype_definitions[item].policy_definitions.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} + ], + "policy_set_definitions": [ +{% if mg.archetype_definitions[item].policy_set_definitions is mapping %} +{% for key in mg.archetype_definitions[item].policy_set_definitions.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} +{% if mg_custom.archetype_definitions[item].policy_set_definitions is mapping %} +{% for key in mg_custom.archetype_definitions[item].policy_set_definitions.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} + ], + "role_definitions": [ +{% if mg.archetype_definitions[item].role_definitions is mapping %} +{% for key in mg.archetype_definitions[item].role_definitions.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} +{% if mg_custom.archetype_definitions[item].role_definitions is mapping %} +{% for key in mg_custom.archetype_definitions[item].role_definitions.keys() %} +{% if loop.last %} + "{{ key }}" +{% else %} + "{{ key }}", +{% endif %} +{% endfor %} +{% endif %} + ], + "archetype_config": { + "parameters": { + }, + "access_control": { + } + } + } +} diff --git a/templates/platform/level1/alz/lib/v1.1.3/custom_landing_zones.caf.platform.yaml b/templates/platform/level1/alz/lib/v1.1.3/custom_landing_zones.caf.platform.yaml new file mode 100644 index 000000000..6ae8db0c4 --- /dev/null +++ b/templates/platform/level1/alz/lib/v1.1.3/custom_landing_zones.caf.platform.yaml @@ -0,0 +1,26 @@ +archetype_definitions: + corp: + display_name: Corp + archetype_id: landingzone_corp + parent_management_group_id: landing-zones + subscription_ids: + online: + display_name: Online + archetype_id: landingzone_online + parent_management_group_id: landing-zones + subscription_ids: + corp-prod: + display_name: Production + archetype_id: landingzone_prod + parent_management_group_id: corp + subscription_ids: + corp-non-prod: + display_name: Non Production + archetype_id: landingzone_non_prod + parent_management_group_id: corp + subscription_ids: + online-web: + display_name: Non Production + archetype_id: landingzone_online_web + parent_management_group_id: online + subscription_ids: \ No newline at end of file diff --git a/templates/platform/level1/alz/lib/v1.1.3/custom_landing_zones.tfvars.j2 b/templates/platform/level1/alz/lib/v1.1.3/custom_landing_zones.tfvars.j2 new file mode 100644 index 000000000..570a7c7b0 --- /dev/null +++ b/templates/platform/level1/alz/lib/v1.1.3/custom_landing_zones.tfvars.j2 @@ -0,0 +1,72 @@ +custom_landing_zones = { +{% for key, level in mg_custom.archetype_definitions.items() %} + {{ bootstrap.management_groups[region][tfstate].management_group_prefix }}-{{ key }} = { + display_name = "{{ level.display_name }}" + parent_management_group_id = "{{ bootstrap.management_groups[region][tfstate].management_group_prefix }}-{{ level.parent_management_group_id }}" + archetype_config = { + archetype_id = "{{ level.archetype_id }}" +{% if level.policy_assignments is defined %} + parameters = { +{% for pa_key, pa_value in level.policy_assignments.items() %} +{% if pa_value is mapping %} + "{{ pa_key }}" = { +{% for attribute, attribute_value in pa_value.items() %} + "{{attribute}}" = { +{% if attribute_value is string %} + value = "{{ attribute_value }}" +{% elif attribute_value is boolean %} + value = {{ attribute_value | string | lower }} +{% elif attribute_value is number %} + value = {{ attribute_value }} +{% else %} +{% if attribute_value is mapping %} +{% for caf_key, caf_value in attribute_value.items() %} + {{ caf_key }} = "{{ caf_value }}" +{% endfor %} +{% else %} + values = {{ attribute_value | replace('None','[]') | replace('\'','\"') }} +{% endif %} +{% endif %} + } +{% endfor %} + } +{% endif %} +{% endfor %} + } +{% else %} + parameters = {} +{% endif %} +{% if level.archetype_resources.access_control is defined %} + access_control = { +{% if resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} +{% for level_ac_key, level_ac in level.archetype_resources.access_control.items() %} + "{{level_ac_key}}" = { +{% for level_role_key, level_role in level_ac.items() %} + "{{ level_role_key }}" = { + lz_key = "{{ level_role.lz_key }}" + attribute_key = "{{ level_role.attribute_key }}" + resource_keys = {{ level_role.resource_keys | replace('None','[]') | replace('\'','\"') }} + } +{% endfor %} + } +{% endfor %} +{% else %} + "Owner" = { + "principal_ids" = ["{{ resources.billing_subscription_role_delegations.azuread_user_ea_account_owner_object_id }}"] + } +{% endif %} + } +{% else %} + access_control = {} +{% endif %} + } + subscriptions = {} +{% if level.subscription_ids is defined %} + subscription_ids = {{ level.subscription_ids | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% else %} + subscription_ids = [] +{% endif %} + } + +{% endfor %} +} \ No newline at end of file diff --git a/templates/platform/level1/eslz/lib/v1.1.1/policy_assignments/README.md b/templates/platform/level1/alz/lib/v1.1.3/policy_assignments/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v1.1.1/policy_assignments/README.md rename to templates/platform/level1/alz/lib/v1.1.3/policy_assignments/README.md diff --git a/templates/platform/level1/eslz/lib/v1.1.1/policy_assignments/policy_assignment_caf_aks_capability.json b/templates/platform/level1/alz/lib/v1.1.3/policy_assignments/policy_assignment_caf_aks_capability.json similarity index 100% rename from templates/platform/level1/eslz/lib/v1.1.1/policy_assignments/policy_assignment_caf_aks_capability.json rename to templates/platform/level1/alz/lib/v1.1.3/policy_assignments/policy_assignment_caf_aks_capability.json diff --git a/templates/platform/level1/alz/lib/v1.1.3/policy_assignments/policy_assignment_caf_deploy_nsg_flowlogs.json b/templates/platform/level1/alz/lib/v1.1.3/policy_assignments/policy_assignment_caf_deploy_nsg_flowlogs.json new file mode 100644 index 000000000..575e6f450 --- /dev/null +++ b/templates/platform/level1/alz/lib/v1.1.3/policy_assignments/policy_assignment_caf_deploy_nsg_flowlogs.json @@ -0,0 +1,18 @@ +{ + "name": "CAF-Deploy-Nsg-FlowLogs", + "type": "Microsoft.Authorization/policyAssignments", + "apiVersion": "2019-09-01", + "properties": { + "description": "Deploy if not exists nsg flowlogs and traffic analytics on network security groups. Define also the retention days.", + "displayName": "CAF - Enable Nsg flowlogs and traffic analytics.", + "notScopes": [], + "parameters": {}, + "policyDefinitionId": "${root_scope_resource_id}/providers/Microsoft.Authorization/policyDefinitions/CAF-Deploy-Nsg-FlowLogs", + "scope": "${current_scope_resource_id}", + "enforcementMode": true + }, + "location": "${default_location}", + "identity": { + "type": "SystemAssigned" + } +} \ No newline at end of file diff --git a/templates/platform/level1/eslz/lib/v1.1.1/policy_assignments/policy_assignment_es_allowed_locations.json b/templates/platform/level1/alz/lib/v1.1.3/policy_assignments/policy_assignment_es_allowed_locations.json similarity index 100% rename from templates/platform/level1/eslz/lib/v1.1.1/policy_assignments/policy_assignment_es_allowed_locations.json rename to templates/platform/level1/alz/lib/v1.1.3/policy_assignments/policy_assignment_es_allowed_locations.json diff --git a/templates/platform/level1/eslz/lib/v1.1.1/policy_definitions/README.md b/templates/platform/level1/alz/lib/v1.1.3/policy_definitions/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v1.1.1/policy_definitions/README.md rename to templates/platform/level1/alz/lib/v1.1.3/policy_definitions/README.md diff --git a/templates/platform/level1/alz/lib/v1.1.3/policy_definitions/policy_definition_caf_deploy_nsg_flowlogs.json b/templates/platform/level1/alz/lib/v1.1.3/policy_definitions/policy_definition_caf_deploy_nsg_flowlogs.json new file mode 100644 index 000000000..daf0fa3df --- /dev/null +++ b/templates/platform/level1/alz/lib/v1.1.3/policy_definitions/policy_definition_caf_deploy_nsg_flowlogs.json @@ -0,0 +1,228 @@ +{ + "name": "CAF-Deploy-Nsg-FlowLogs", + "type": "Microsoft.Authorization/policyDefinitions", + "apiVersion": "2021-06-01", + "scope": null, + "properties": { + "policyType": "Custom", + "mode": "Indexed", + "displayName": "CAF - Enable Nsg flowlogs and traffic analytics.", + "parameters": { + "effect": { + "type": "String", + "metadata": { + "displayName": "Effect", + "description": "Enable or disable the execution of the policy" + }, + "allowedValues": [ + "DeployIfNotExists", + "Disabled" + ], + "defaultValue": "DeployIfNotExists" + }, + "flowAnalyticsEnabled": { + "type": "String", + "metadata": { + "displayName": "Enable Traffic Analytics", + "description": "Enable Traffic Analytics" + }, + "defaultValue": "true" + }, + "interval": { + "type": "String", + "metadata": { + "displayName": "Traffic Analytics processing interval mins (10/60)", + "description": "Traffic Analytics processing interval mins (10/60)" + }, + "defaultValue": "60" + }, + "retention": { + "type": "String", + "metadata": { + "displayName": "Retention days in storage account. If you want to retain data forever and do not want to apply any retention policy, set retention (days) to 0.", + "description": "Retention days in storage account. If you want to retain data forever and do not want to apply any retention policy, set retention (days) to 0." + }, + "defaultValue": "2" + }, + "logAnalytics": { + "type": "String", + "metadata": { + "displayName": "Resource ID of Log Analytics workspace", + "description": "Select Log Analytics workspace from dropdown list. If this workspace is outside of the scope of the assignment you must manually grant 'Log Analytics Contributor' permissions (or similar) to the policy assignment's principal ID.", + "strongType": "omsWorkspace" + }, + "defaultValue": "" + }, + "storageAccountResourceId": { + "type": "String", + "metadata": { + "displayName": "Storage Account Resource Id", + "description": "Storage Account Resource Id", + "strongType": "Microsoft.Storage/storageAccounts" + }, + "defaultValue": "" + } + }, + "policyRule": { + "if": { + "allOf": [ + { + "equals": "Microsoft.Network/networkSecurityGroups", + "field": "type" + } + ] + }, + "then": { + "details": { + "deployment": { + "properties": { + "mode": "Incremental", + "parameters": { + "flowAnalyticsEnabled": { + "value": "[bool(parameters('flowAnalyticsEnabled'))]" + }, + "interval": { + "value": "[int(parameters('interval'))]" + }, + "location": { + "value": "[field('location')]" + }, + "networkSecurityGroup": { + "value": "[field('id')]" + }, + "retention": { + "value": "[int(parameters('retention'))]" + }, + "storageAccountResourceId": { + "value": "[parameters('storageAccountResourceId')]" + }, + "logAnalytics": { + "value": "[parameters('logAnalytics')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "location": "[parameters('location')]", + "outputs": {}, + "parameters": { + "flowAnalyticsEnabled": { + "type": "bool" + }, + "interval": { + "type": "int" + }, + "location": { + "type": "String" + }, + "networkSecurityGroup": { + "type": "String" + }, + "retention": { + "type": "int" + }, + "storageAccountResourceId": { + "type": "String" + }, + "time": { + "defaultValue": "[utcNow()]", + "type": "String" + }, + "logAnalytics": { + "type": "String" + } + }, + "resources": [ + { + "apiVersion": "2019-10-01", + "name": "[take(concat('NetworkWatcherRG', '.', variables('securityGroupName')), 64)]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [ + { + "apiVersion": "2020-05-01", + "name": "[concat('NetworkWatcher_', toLower(parameters('location')))]", + "location": "[parameters('location')]", + "properties": {}, + "resources": [ + { + "apiVersion": "2019-11-01", + "dependsOn": [ + "[concat('NetworkWatcher_', toLower(parameters('location')))]" + ], + "name": "[concat(variables('securityGroupName'), '-Network-flowlog')]", + "location": "[parameters('location')]", + "properties": { + "enabled": true, + "flowAnalyticsConfiguration": { + "networkWatcherFlowAnalyticsConfiguration": { + "enabled": "[bool(parameters('flowAnalyticsEnabled'))]", + "trafficAnalyticsInterval": "[parameters('interval')]", + "workspaceRegion": "[if(not(empty(parameters('logAnalytics'))), reference(parameters('logAnalytics'), '2020-03-01-preview', 'Full').location, json('null')) ]", + "workspaceResourceId": "[parameters('logAnalytics')]" + } + }, + "format": { + "type": "JSON", + "version": 2 + }, + "retentionPolicy": { + "days": "[parameters('retention')]", + "enabled": true + }, + "storageId": "[parameters('storageAccountResourceId')]", + "targetResourceId": "[parameters('networkSecurityGroup')]" + }, + "type": "flowLogs" + } + ], + "type": "Microsoft.Network/networkWatchers" + } + ] + } + }, + "resourceGroup": "NetworkWatcherRG", + "type": "Microsoft.Resources/deployments" + } + ], + "variables": { + "securityGroupName": "[split(parameters('networkSecurityGroup'), '/')[8]]" + } + } + } + }, + "existenceCondition": { + "allof": [ + { + "field": "Microsoft.Network/networkWatchers/flowLogs/enabled", + "equals": "true" + }, + { + "field": "Microsoft.Network/networkWatchers/flowLogs/flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled", + "equals": "[bool(parameters('flowAnalyticsEnabled'))]" + }, + { + "field": "Microsoft.Network/networkWatchers/flowLogs/flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.trafficAnalyticsInterval", + "equals": "[parameters('interval')]" + }, + { + "field": "Microsoft.Network/networkWatchers/flowLogs/retentionPolicy.days", + "equals": "[parameters('retention')]" + } + ] + }, + "resourceGroupName": "[if(empty(coalesce(field('Microsoft.Network/networkSecurityGroups/flowLogs'))), 'NetworkWatcherRG', split(first(field('Microsoft.Network/networkSecurityGroups/flowLogs[*].id')), '/')[4])]", + "name": "[if(empty(coalesce(field('Microsoft.Network/networkSecurityGroups/flowLogs[*].id'))), 'null/null', concat(split(first(field('Microsoft.Network/networkSecurityGroups/flowLogs[*].id')), '/')[8], '/', split(first(field('Microsoft.Network/networkSecurityGroups/flowLogs[*].id')), '/')[10]))]", + "roleDefinitionIds": [ + "/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7" + ], + "type": "Microsoft.Network/networkWatchers/flowLogs" + }, + "effect": "[parameters('effect')]" + } + } + } +} \ No newline at end of file diff --git a/templates/platform/level1/eslz/lib/v1.1.1/policy_set_definitions/README.md b/templates/platform/level1/alz/lib/v1.1.3/policy_set_definitions/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v1.1.1/policy_set_definitions/README.md rename to templates/platform/level1/alz/lib/v1.1.3/policy_set_definitions/README.md diff --git a/templates/platform/level1/eslz/lib/v1.1.1/role_definitions/README.md b/templates/platform/level1/alz/lib/v1.1.3/role_definitions/README.md similarity index 100% rename from templates/platform/level1/eslz/lib/v1.1.1/role_definitions/README.md rename to templates/platform/level1/alz/lib/v1.1.3/role_definitions/README.md diff --git a/templates/enterprise-scale/contoso/platform/eslz/lib/role_definitions/role_definition_caf_vhub_peering.json b/templates/platform/level1/alz/lib/v1.1.3/role_definitions/role_definition_caf_vhub_peering.json similarity index 96% rename from templates/enterprise-scale/contoso/platform/eslz/lib/role_definitions/role_definition_caf_vhub_peering.json rename to templates/platform/level1/alz/lib/v1.1.3/role_definitions/role_definition_caf_vhub_peering.json index ef7060687..db51f3c40 100644 --- a/templates/enterprise-scale/contoso/platform/eslz/lib/role_definitions/role_definition_caf_vhub_peering.json +++ b/templates/platform/level1/alz/lib/v1.1.3/role_definitions/role_definition_caf_vhub_peering.json @@ -9,9 +9,9 @@ "permissions": [ { "actions": [ - "Microsoft.Network/virtualHubs/hubVirtualNetworkConnections/*", + "Microsoft.Resources/subscriptions/resourceGroups/read", "Microsoft.Network/virtualHubs/read", - "Microsoft.Resources/subscriptions/resourceGroups/read" + "Microsoft.Network/virtualHubs/hubVirtualNetworkConnections/*" ], "notActions": [ ], diff --git a/templates/platform/level1/alz/readme.md b/templates/platform/level1/alz/readme.md new file mode 100644 index 000000000..c1c1029a0 --- /dev/null +++ b/templates/platform/level1/alz/readme.md @@ -0,0 +1,39 @@ +# Enterprise scale + +## Deploy Enterprise Scale + +Note you need to adjust the branch to deploy Enterprise Scale to {{ resources.variables_azure_landing_zones.private_lib[tfstate_object.alz_version].caf_landingzone_branch }} + +```bash +az account clear +# login a with a user member of the caf-platform-maintainers group +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} + +cd {{ landingzones_folder }} +git fetch origin +git checkout {{ resources.variables_azure_landing_zones.private_lib[tfstate_object.alz_version].caf_landingzone_branch }} + +rover \ +{% if keyvaults is defined and resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} + --impersonate-sp-from-keyvault-url {{ keyvaults[tfstate_object.identity_aad_key].vault_uri }} \ +{% endif %} + -lz {{ landingzones_folder }}/caf_solution/add-ons/caf_eslz \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ + -tfstate {{ tfstate_object.tfstate }} \ + -env {{ resources.caf_environment }} \ + -level {{ tfstate_object.level }} \ + -p ${TF_DATA_DIR}/{{ tfstate_object.tfstate }}.tfplan \ + -a plan + +``` + +# Next steps + +[Deploy asvm](../../level2/asvm/readme.md) +{% if resources.deployments[stage].scale_out_domains[region].identity_level2 is defined %} +{% for key in resources.deployments[stage].scale_out_domains[region].identity_level2.keys() %} +[Deploy identity_level2 - {{key}}](../../{{resources['identity_level2_' + key].relative_destination_folder}}/readme.md) +{% endfor %} +{% endif %} +[Deploy Connectivity](../../level2/connectivity/virtual_wans/readme.md) diff --git a/templates/platform/level1/alz/subscription_id_overrides.tfvars.j2 b/templates/platform/level1/alz/subscription_id_overrides.tfvars.j2 new file mode 100644 index 000000000..46ac32559 --- /dev/null +++ b/templates/platform/level1/alz/subscription_id_overrides.tfvars.j2 @@ -0,0 +1,90 @@ +subscription_id_overrides = { +{% if resources.azure_landing_zones.enterprise_scale.subscription_id_overrides is defined %} +{% if resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.root is defined %} + root = {{ resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.root | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% else %} + root = [] +{% endif %} +{% endif %} +{% if resources.azure_landing_zones.enterprise_scale.subscription_id_overrides is defined %} +{% if resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.decommissioned is defined %} + decommissioned = {{ resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.decommissioned | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% else %} + decommissioned = [] +{% endif %} +{% if resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.sandboxes is defined %} + sandboxes = {{ resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.sandboxes | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% else %} + sandboxes = [] +{% endif %} +{% if resources.azure_landing_zones.enterprise_scale.subscription_id_overrides['landing-zones'] is defined %} + landing-zones = {{ resources.azure_landing_zones.enterprise_scale.subscription_id_overrides['landing-zones'] | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% else %} + landing-zones = [] +{% endif %} +{% if resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.platform is defined %} + platform = {{ resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.platform | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% else %} + platform = [] +{% endif %} +{% if resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.connectivity is defined %} + connectivity = {{ resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.connectivity | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% else %} + connectivity = [] +{% endif %} +{% if resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.management is defined %} + management = {{ resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.management | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% else %} + management = [] +{% endif %} +{% if resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.identity is defined %} + identity = {{ resources.azure_landing_zones.enterprise_scale.subscription_id_overrides.identity | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% else %} + identity = [] +{% endif %} +{% else %} +{% if resources.subscription_deployment_mode == 'single_reuse' %} + root = [ + "{{ resources.caf_launchpad.subscription_id }}" + ] +{% else %} + root = [] +{% endif %} + decommissioned = [] + sandboxes = [] + landing-zones = [] + platform = [] + connectivity = [] + management = [] + identity = [] +{% endif %} +} + +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' and resources.subscription_deployment_mode != 'single_reuse' %} +subscription_id_overrides_by_keys = { + connectivity = { + connectivity = { + lz_key = "{{ resources.tfstates.platform.platform_subscriptions.lz_key_name }}" + key = "connectivity" + } + } + management = { + launchpad = { + lz_key = "{{ resources.tfstates.platform.platform_subscriptions.lz_key_name }}" + key = "launchpad" + } + management = { + lz_key = "{{ resources.tfstates.platform.platform_subscriptions.lz_key_name }}" + key = "management" + } + } + identity = { + identity = { + lz_key = "{{ resources.tfstates.platform.platform_subscriptions.lz_key_name }}" + key = "identity" + } + } +} +{% else %} +subscription_id_overrides_by_keys = {} +{% endif %} \ No newline at end of file diff --git a/templates/platform/level1/eslz/ansible.yaml b/templates/platform/level1/eslz/ansible.yaml deleted file mode 100644 index 583a6ed3e..000000000 --- a/templates/platform/level1/eslz/ansible.yaml +++ /dev/null @@ -1,58 +0,0 @@ -- name: "{{ level }}-{{ base_folder }} | Clean-up base directory" - shell: | - rm -rf "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - when: - - config.platform_core_setup.enterprise_scale.enable - - config.platform_core_setup.enterprise_scale.clean_up_destination_folder - -- name: "{{ level }}-{{ base_folder }} | Creates directory structure" - shell: mkdir -p "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/lib/{{ item.path }}" - with_filetree: "{{ level }}/{{ base_folder }}/lib/{{ config.platform_core_setup.enterprise_scale.private_lib.version_to_deploy }}" - when: item.state == 'directory' - -- name: "{{ level }}-{{ base_folder }} | Tfvars" - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/*.j2" - - "{{ level }}/{{ base_folder }}/*.md" - -- name: "{{ level }}-{{ base_folder }} | Lib - archetypes - built-in" - ansible.builtin.template: - src: "{{ base_templates_folder }}/{{ level }}/eslz/lib/{{ config.platform_core_setup.enterprise_scale.private_lib.version_to_deploy }}/archetype_definitions/archetype_definition_template.json.j2" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/lib/archetype_definitions/archetype_definition_{{ mg.archetype_definitions[item].archetype_id }}.json" - force: yes - loop: "{{ mg.archetype_definitions.keys() }}" - loop_control: - loop_var: item - -- name: "{{ level }}-{{ base_folder }} | Lib - archetypes - custom" - when: - - mg_custom.archetype_definitions is defined - ansible.builtin.template: - src: "{{ base_templates_folder }}/{{ level }}/eslz/lib/{{ config.platform_core_setup.enterprise_scale.private_lib.version_to_deploy }}/archetype_definitions/custom_landing_zone_template.json.j2" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/lib/archetype_definitions/archetype_definition_{{ mg_custom.archetype_definitions[item].archetype_id }}.json" - force: yes - loop: "{{ mg_custom.archetype_definitions.keys() }}" - loop_control: - loop_var: item - -- name: "{{ level }}-{{ base_folder }} | Lib" - ansible.builtin.template: - src: "{{ item.src }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/lib/{{ item.path }}" - force: yes - with_filetree: "{{ config_folder }}/eslz/lib" - when: item.state == 'file' and config.platform_core_setup.enterprise_scale.update_lib_folder - -- name: "{{ level }}-{{ base_folder }} | overrides" - when: - - mg_custom.archetype_definitions is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/lib/{{ config.platform_core_setup.enterprise_scale.private_lib.version_to_deploy }}/*.tfvars.j2" diff --git a/templates/platform/level1/eslz/configuration.tfvars.j2 b/templates/platform/level1/eslz/configuration.tfvars.j2 deleted file mode 100644 index 87f255e2d..000000000 --- a/templates/platform/level1/eslz/configuration.tfvars.j2 +++ /dev/null @@ -1,28 +0,0 @@ -landingzone = { - backend_type = "{{ caf_terraform.launchpad.backend_type | default("azurerm")}}" - global_settings_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" - level = "level1" - key = "{{ config.tfstates.platform.eslz.lz_key_name }}" - tfstates = { - {{ config.tfstates.platform.launchpad.lz_key_name }} = { - level = "lower" - tfstate = "{{ config.tfstates.platform.launchpad.tfstate }}" - } - {{ config.tfstates.platform.management.lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.management.tfstate }}" - } -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - {{ config.tfstates.platform.platform_subscriptions.lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.platform_subscriptions.tfstate }}" - } -{% endif %} -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - {{ config.tfstates.platform.identity.lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.identity.tfstate }}" - } -{% endif %} - } -} diff --git a/templates/platform/level1/eslz/enterprise_scale.tfvars.j2 b/templates/platform/level1/eslz/enterprise_scale.tfvars.j2 deleted file mode 100644 index 4c56e4470..000000000 --- a/templates/platform/level1/eslz/enterprise_scale.tfvars.j2 +++ /dev/null @@ -1,7 +0,0 @@ -library_path = "../../../../{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/lib" -root_id = "{{ config.platform_core_setup.enterprise_scale.management_group_prefix }}" -root_name = "{{ config.platform_core_setup.enterprise_scale.management_group_name }}" -deploy_core_landing_zones = {{ config.platform_core_setup.enterprise_scale.deploy_core_landing_zones | string | lower }} -{% if (config.platform_core_setup.enterprise_scale.enable_azure_subscription_vending_machine | default(false)) and config.platform_identity.azuread_identity_mode != 'logged_in_user' %} -reconcile_vending_subscriptions = true -{% endif %} \ No newline at end of file diff --git a/templates/platform/level1/eslz/readme.md b/templates/platform/level1/eslz/readme.md deleted file mode 100644 index 96b22db83..000000000 --- a/templates/platform/level1/eslz/readme.md +++ /dev/null @@ -1,34 +0,0 @@ -# Enterprise scale - -## Deploy Enterprise Scale - -Note you need to adjust the branch to deploy Enterprise Scale to {{ config.platform_core_setup.enterprise_scale.private_lib[config.platform_core_setup.enterprise_scale.private_lib.version_to_deploy].caf_landingzone_branch }} - -```bash -az account clear -# login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} - -cd {{ destination_base }}/landingzones -git fetch origin -git checkout {{ config.platform_core_setup.enterprise_scale.private_lib[config.platform_core_setup.enterprise_scale.private_lib.version_to_deploy].caf_landingzone_branch }} - -rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_eslz.vault_uri }} \ -{% endif %} - -lz {{ destination_base }}/landingzones/caf_solution/add-ons/caf_eslz \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ config.tfstates.platform.eslz.tfstate }} \ - -log-severity ERROR \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.eslz.tfstate }}.tfplan \ - -a plan - -``` - -# Next steps - - [Deploy Connectivity](../../level2/connectivity/readme.md) diff --git a/templates/platform/level1/eslz/subscription_id_overrides.tfvars.j2 b/templates/platform/level1/eslz/subscription_id_overrides.tfvars.j2 deleted file mode 100644 index 7cfcc03e1..000000000 --- a/templates/platform/level1/eslz/subscription_id_overrides.tfvars.j2 +++ /dev/null @@ -1,45 +0,0 @@ -subscription_id_overrides = { -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} - root = [] -{% else %} - root = [ - "{{ config.caf_terraform.launchpad.subscription_id }}" - ] -{% endif %} - decommissioned = [] - sandboxes = [] - landing-zones = [] - platform = [] - connectivity = [] - management = [] - identity = [] -} - -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} -subscription_id_overrides_by_keys = { - connectivity = { - connectivity = { - lz_key = "{{ config.tfstates.platform.platform_subscriptions.lz_key_name }}" - key = "connectivity" - } - } - management = { - launchpad = { - lz_key = "{{ config.tfstates.platform.platform_subscriptions.lz_key_name }}" - key = "launchpad" - } - management = { - lz_key = "{{ config.tfstates.platform.platform_subscriptions.lz_key_name }}" - key = "management" - } - } - identity = { - identity = { - lz_key = "{{ config.tfstates.platform.platform_subscriptions.lz_key_name }}" - key = "identity" - } - } -} -{% else %} -subscription_id_overrides_by_keys = {} -{% endif %} \ No newline at end of file diff --git a/templates/platform/level1/identity/ansible.yaml b/templates/platform/level1/identity/ansible.yaml deleted file mode 100644 index f0068fb9a..000000000 --- a/templates/platform/level1/identity/ansible.yaml +++ /dev/null @@ -1,73 +0,0 @@ -- name: "[{{ level }}-{{ base_folder }}] Clean-up directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: absent - when: config.configuration_folders.platform.cleanup_destination | bool - -- name: "[{{ level }}-{{ base_folder }}] Creates directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: directory - -- name: "[{{ level }}-{{ base_folder }}] - Set variables" - set_fact: - destination_path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - -- name: "[{{ level }}-{{ base_folder }}] - Load variables" - include_vars: - name: resources - dir: "{{config_folder}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "identity.yaml|identity.caf.platform.yaml" - - -# -# resource_groups -# -- name: "[{{ level }}-{{ base_folder }}] - resources - resource_groups" - when: - - resources.subscriptions[subscription_key].resource_groups is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/resource_groups.tfvars.j2" - -# -# recovery_vaults -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - recovery_vaults" - when: - - resources.subscriptions[subscription_key].recovery_vaults is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/recovery_vaults.tfvars.j2" - -# -# service_health_alerts -# -- name: "[{{ level }}-{{ base_folder }}] - resources - service_health_alerts" - when: - - resources.subscriptions[subscription_key].service_health_alerts is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/servicehealth.tfvars.j2" - - -- name: "[{{ level }}-{{ base_folder }}] generate configuration files." - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/*.tfvars.j2" - - "{{ level }}/{{ base_folder }}/*.md" - diff --git a/templates/platform/level1/identity/landingzone.tfvars.j2 b/templates/platform/level1/identity/landingzone.tfvars.j2 deleted file mode 100644 index 48704bdde..000000000 --- a/templates/platform/level1/identity/landingzone.tfvars.j2 +++ /dev/null @@ -1,12 +0,0 @@ -landingzone = { - backend_type = "{{ caf_terraform.launchpad.backend_type | default("azurerm")}}" - global_settings_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" - level = "{{ config.tfstates.platform.identity.level }}" - key = "{{ config.tfstates.platform.identity.lz_key_name }}" - tfstates = { - {{ config.tfstates.platform.launchpad.lz_key_name }} = { - level = "lower" - tfstate = "{{ config.tfstates.platform.launchpad.tfstate }}" - } - } -} diff --git a/templates/platform/level1/identity/readme.md b/templates/platform/level1/identity/readme.md index d2a8ecee1..817fb8673 100644 --- a/templates/platform/level1/identity/readme.md +++ b/templates/platform/level1/identity/readme.md @@ -8,34 +8,31 @@ rover logout # login a with a user member of the caf-maintainers group {% if platform_subscriptions_details is defined %} -rover login -t {{ config.platform_identity.tenant_name }} -s {{ platform_subscriptions_details.identity.subscription_id }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -s {{ platform_subscriptions_details.identity.subscription_id }} {% elif subscriptions.platform_subscriptions.identity.subscription_id is defined %} -rover login -t {{ config.platform_identity.tenant_name }} -s {{ subscriptions.platform_subscriptions.identity.subscription_id }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -s {{ subscriptions.platform_subscriptions.identity.subscription_id }} {% else %} -rover login -t {{ config.platform_identity.tenant_name }} -s {{ config.caf_terraform.launchpad.subscription_id }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -s {{ resources.caf_launchpad.subscription_id }} {% endif %} rover \ -{% if platform_subscriptions_details.eslz is defined %} -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_identity.vault_uri }} \ +{% if keyvaults is defined and resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} + --impersonate-sp-from-keyvault-url {{ keyvaults[tfstate_object.identity_aad_key].vault_uri }} \ {% endif %} -{% endif %} - -lz /tf/caf/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ + -lz {{ landingzones_folder }}/caf_solution \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ {% if platform_subscriptions_details is defined %} -target_subscription {{ platform_subscriptions_details.identity.subscription_id }} \ {% elif subscriptions.platform_subscriptions.identity.subscription_id is defined %} -target_subscription {{ subscriptions.platform_subscriptions.identity.subscription_id }} \ {% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ {% endif %} - -tfstate {{ config.tfstates.platform.identity.tfstate }} \ - -log-severity {{ config.gitops.rover_log_error }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -tfstate {{ resources.tfstates.platform.identity.tfstate }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.identity.tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.identity.tfstate }}.tfplan \ -a plan ``` @@ -43,4 +40,6 @@ rover \ # Next steps - [Deploy Enterprise Scale](../../level1/eslz/readme.md) +{% for key in bootstrap.deployments[deployment_mode].alz.keys() %} +[Deploy Enterprise Scale - {{key}}](../../level1/alz/{{key}}/readme.md) +{% endfor %} diff --git a/templates/platform/level1/management/ansible.yaml b/templates/platform/level1/management/ansible.yaml deleted file mode 100644 index c61cf23d6..000000000 --- a/templates/platform/level1/management/ansible.yaml +++ /dev/null @@ -1,162 +0,0 @@ -- name: "[{{ level }}-{{ base_folder }}] Clean-up directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: absent - when: - - config.configuration_folders.platform.cleanup_destination | bool - -- name: "[{{ level }}-{{ base_folder }}] Creates directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: directory - - -- name: "[{{ level }}-{{ base_folder }}] - Set variables" - set_fact: - destination_path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - -- name: "[{{ level }}-{{ base_folder }}] - Load variables" - include_vars: - name: resources - dir: "{{config_folder}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "management.yaml|configuration.caf.platform.yaml" - -# -# automation_accounts -# -- name: "[{{ level }}-{{ base_folder }}] - resources - automation_accounts" - when: - - resources.subscriptions[subscription_key].automation_accounts is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/automation_accounts.tfvars.j2" - -# -# diagnostic_log_analytics -# -- name: "[{{ level }}-{{ base_folder }}] - resources - diagnostic_log_analytics" - when: - - resources.subscriptions[subscription_key].diagnostic_log_analytics is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/diagnostic_log_analytics.tfvars.j2" - -# -# diagnostic_storage_accounts -# -- name: "[{{ level }}-{{ base_folder }}] - resources - diagnostic_storage_accounts" - when: - - resources.subscriptions[subscription_key].diagnostic_storage_accounts is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/diagnostic_storage_accounts.tfvars.j2" - -# diagnostics_definition -# -- name: "[{{ level }}-{{ base_folder }}] - resources - diagnostics_definition" - when: - - resources.subscriptions[subscription_key].diagnostics_definition is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/diagnostics_definition.tfvars.j2" - -# diagnostics_destinations -# -- name: "[{{ level }}-{{ base_folder }}] - resources - diagnostics_destinations" - when: - - resources.subscriptions[subscription_key].diagnostics_destinations is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/diagnostics_destinations.tfvars.j2" - -# -# monitor_action_groups -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - monitor_action_groups" - when: - - resources.subscriptions[subscription_key].monitor_action_groups is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/monitor_action_groups.tfvars.j2" - -# -# recovery_vaults -# -- name: "[{{ level }}-{{ subscription_key }}] - resources - recovery_vaults" - when: - - resources.subscriptions[subscription_key].recovery_vaults is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/recovery_vaults.tfvars.j2" - -# -# resource_groups -# -- name: "[{{ level }}-{{ base_folder }}] - resources - resource_groups" - when: - - resources.subscriptions[subscription_key].resource_groups is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/resource_groups.tfvars.j2" - -# -# service_health_alerts -# -- name: "[{{ level }}-{{ base_folder }}] - resources - service_health_alerts" - when: - - resources.subscriptions[subscription_key].service_health_alerts is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/servicehealth.tfvars.j2" - -# -# Readme -# -- name: "[{{ level }}-{{ base_folder }}] - resources - *.md" - # when: always - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/*.md" - -# -# Legacy calls -# -- name: "[{{ level }}-{{ base_folder }}] - generate configuration files." - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/*.tfvars.j2" \ No newline at end of file diff --git a/templates/platform/level1/management/landingzone.tfvars.j2 b/templates/platform/level1/management/landingzone.tfvars.j2 deleted file mode 100644 index 367d6aaf8..000000000 --- a/templates/platform/level1/management/landingzone.tfvars.j2 +++ /dev/null @@ -1,12 +0,0 @@ -landingzone = { - backend_type = "{{ caf_terraform.launchpad.backend_type | default("azurerm")}}" - global_settings_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" - level = "{{ config.tfstates.platform.management.level }}" - key = "{{ config.tfstates.platform.management.lz_key_name }}" - tfstates = { - {{ config.tfstates.platform.launchpad.lz_key_name }} = { - level = "lower" - tfstate = "{{ config.tfstates.platform.launchpad.tfstate }}" - } - } -} diff --git a/templates/platform/level1/management/readme.md b/templates/platform/level1/management/readme.md index 130826048..ff43722b5 100644 --- a/templates/platform/level1/management/readme.md +++ b/templates/platform/level1/management/readme.md @@ -8,34 +8,31 @@ rover logout # login a with a user member of the caf-maintainers group {% if platform_subscriptions_details is defined %} -rover login -t {{ config.platform_identity.tenant_name }} -s {{ platform_subscriptions_details.management.subscription_id }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -s {{ platform_subscriptions_details.management.subscription_id }} {% elif subscriptions.platform_subscriptions.management.subscription_id is defined %} -rover login -t {{ config.platform_identity.tenant_name }} -s {{ subscriptions.platform_subscriptions.management.subscription_id }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -s {{ subscriptions.platform_subscriptions.management.subscription_id }} {% else %} -rover login -t {{ config.platform_identity.tenant_name }} -s {{ config.caf_terraform.launchpad.subscription_id }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -s {{ resources.caf_launchpad.subscription_id }} {% endif %} rover \ -{% if platform_subscriptions_details.eslz is defined %} -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_management.vault_uri }} \ +{% if resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" and keyvaults is defined %} + --impersonate-sp-from-keyvault-url {{ keyvaults[tfstate_object.identity_aad_key].vault_uri }} \ {% endif %} -{% endif %} - -lz /tf/caf/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ + -lz {{ landingzones_folder }}/caf_solution \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ {% if platform_subscriptions_details is defined %} -target_subscription {{ platform_subscriptions_details.management.subscription_id }} \ {% elif subscriptions.platform_subscriptions.management.subscription_id is defined %} -target_subscription {{ subscriptions.platform_subscriptions.management.subscription_id }} \ {% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ {% endif %} - -tfstate {{ config.tfstates.platform.management.tfstate }} \ - -log-severity {{ config.gitops.rover_log_error }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -tfstate {{ resources.tfstates.platform.management.tfstate }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.management.tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.management.tfstate }}.tfplan \ -a plan ``` @@ -45,8 +42,4 @@ rover \ When you have successfully deployed the management landing zone, you can move to the next step: -{% if config.platform_core_setup.enterprise_scale.enable %} - [Deploy Enterprise Scale](../../level1/eslz/readme.md) -{% else %} - [Deploy Connectivity](../../level2/connectivity/readme.md) -{% endif %} +[Deploy Identity](../../level1/identity/readme.md) diff --git a/templates/platform/level1/subscriptions/ansible.yaml b/templates/platform/level1/subscriptions/ansible.yaml deleted file mode 100644 index 4ac3f8907..000000000 --- a/templates/platform/level1/subscriptions/ansible.yaml +++ /dev/null @@ -1,88 +0,0 @@ -- name: "[{{ level }}-{{ base_folder }}] Clean-up directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: absent - when: config.configuration_folders.platform.cleanup_destination | bool - -- name: "[{{ level }}-{{ base_folder }}] Creates directory" - register: level1_subscriptions - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: directory - -- name: "[{{ level }}-{{ base_folder }}] generate configuration files." - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/*.tfvars.j2" - - "{{ level }}/{{ base_folder }}/*.md" - -# Create the subscriptions -- name: "[{{ level }}-{{ base_folder }}] Create subscriptions." - when: deploy_subscriptions | bool - shell: | - /tf/rover/rover.sh \ - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_subscription_creation_platform.vault_uri }} \ - -lz /tf/caf/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ config.tfstates.platform.platform_subscriptions.tfstate }} \ - -log-severity {{ config.gitops.rover_log_error }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -a apply - -- name: "[{{ level }}-{{ base_folder }}] Get latest cache folder" - set_fact: - job_cache_base_path: "/home/vscode/.terraform.cache" - -- name: "[{{ level }}-{{ base_folder }}] Get tfstate details" - register: subscription_tfstate_file_name - shell: | - az storage account list \ - --subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - --query "[?tags.caf_tfstate=='{{ config.tfstates.platform.platform_subscriptions.level }}' && tags.caf_environment=='{{ config.caf_terraform.launchpad.caf_environment }}'].{name:name}[0]" -o json | jq -r .name - -- debug: - msg: "{{ subscription_tfstate_file_name.stdout }}" - -- name: "[{{ level }}-{{ base_folder }}] Download tfstate details" - register: platform_subscriptions_tfstate_exists - ignore_errors: true - shell: | - az storage blob download \ - --name "{{ config.tfstates.platform.platform_subscriptions.tfstate }}" \ - --account-name "{{ subscription_tfstate_file_name.stdout }}" \ - --container-name "tfstate" \ - --auth-mode "login" \ - --file "{{ job_cache_base_path }}/{{ config.tfstates.platform.platform_subscriptions.tfstate }}" - -- name: "[{{ level }}-{{ base_folder }}] Get platform_subscriptions details" - shell: "cat {{ job_cache_base_path }}/{{ config.tfstates.platform.platform_subscriptions.tfstate }}" - register: platform_subscriptions - when: platform_subscriptions_tfstate_exists.rc == 0 - -- name: "[{{ level }}-{{ base_folder }}] Get platform_subscriptions json data" - when: platform_subscriptions_tfstate_exists.rc == 0 - set_fact: - platform_sub_jsondata: "{{ platform_subscriptions.stdout | from_json }}" - -- name: "[{{ level }}-{{ base_folder }}] Get subscriptions list" - when: platform_subscriptions_tfstate_exists.rc == 0 - set_fact: - platform_subscriptions_details: "{{ platform_sub_jsondata | json_query(path) }}" - vars: - path: 'outputs.objects.value.{{ config.tfstates.platform.platform_subscriptions.lz_key_name }}.subscriptions' - -- name: "[{{ level }}-{{ base_folder }}] cleanup" - when: platform_subscriptions_tfstate_exists.rc == 0 - file: - path: "{{ job_cache_base_path }}/{{ config.tfstates.platform.platform_subscriptions.tfstate }}" - state: absent - -- debug: - msg: "Platform subscriptions - {{ platform_subscriptions_details }}" - when: platform_subscriptions_tfstate_exists.rc == 0 diff --git a/templates/platform/level1/subscriptions/landingzone.tfvars.j2 b/templates/platform/level1/subscriptions/landingzone.tfvars.j2 deleted file mode 100644 index fae07cba7..000000000 --- a/templates/platform/level1/subscriptions/landingzone.tfvars.j2 +++ /dev/null @@ -1,12 +0,0 @@ -landingzone = { - backend_type = "azurerm" - global_settings_key = "{{ config.tfstates.platform.launchpad.lz_key_name }}" - level = "{{ config.tfstates.platform.platform_subscriptions.level }}" - key = "{{ config.tfstates.platform.platform_subscriptions.lz_key_name }}" - tfstates = { - {{ config.tfstates.platform.launchpad.lz_key_name }} = { - level = "lower" - tfstate = "{{ config.tfstates.platform.launchpad.tfstate }}" - } - } -} diff --git a/templates/platform/level1/subscriptions/readme.md b/templates/platform/level1/subscriptions/readme.md index dc36cd7b9..cdb27dc3d 100644 --- a/templates/platform/level1/subscriptions/readme.md +++ b/templates/platform/level1/subscriptions/readme.md @@ -4,23 +4,20 @@ Set-up the subscription delegations for platform and landingzone subscriptions ```bash # For manual bootstrap: -# Login to the subscription {{ config.caf_terraform.launchpad.subscription_name }} with the user {{ config.caf_terraform.billing_subscription_role_delegations.azuread_user_ea_account_owner }} -rover login -t {{ config.platform_identity.tenant_name }} -s {{ config.caf_terraform.launchpad.subscription_id }} +# Login to the subscription {{ resources.caf_launchpad.subscription_name }} with the user {{ resources.billing_subscription_role_delegations.azuread_user_ea_account_owner }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -s {{ resources.caf_launchpad.subscription_id }} rover \ -{% if platform_subscriptions_details.eslz is defined %} -{% if config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_subscription_creation_platform.vault_uri }} \ +{% if resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" and keyvaults is defined %} + --impersonate-sp-from-keyvault-url {{ keyvaults[tfstate_object.identity_aad_key].vault_uri }} \ {% endif %} -{% endif %} - -lz /tf/caf/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ config.tfstates.platform.platform_subscriptions.tfstate }} \ - -log-severity {{ config.gitops.rover_log_error }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.platform_subscriptions.tfstate }}.tfplan \ + -lz {{ landingzones_folder }}/caf_solution \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ + -tfstate {{ tfstate_object.tfstate }} \ + -env {{ resources.caf_environment }} \ + -level {{ tfstate_object.level }} \ + -p ${TF_DATA_DIR}/{{ tfstate_object.tfstate }}.tfplan \ -a plan ``` diff --git a/templates/platform/level1/subscriptions/subscriptions.tfvars.j2 b/templates/platform/level1/subscriptions/subscriptions.tfvars.j2 deleted file mode 100644 index b851adece..000000000 --- a/templates/platform/level1/subscriptions/subscriptions.tfvars.j2 +++ /dev/null @@ -1,38 +0,0 @@ -# -# Execute the following command to get the billing_account_name and management_group_id -# -# az rest --method get --uri https://management.azure.com/providers/Microsoft.Billing/billingaccounts/?api-version=2020-05-01 -# -# To retrieve the first billing account -# -# billing_account_name=$(az rest --method get --uri https://management.azure.com/providers/Microsoft.Billing/billingaccounts?api-version=2020-05-01 --query "value[?properties.agreementType=='EnterpriseAgreement'].{name:name}" -o tsv) -# -# enrollment_account_name=$(az rest --method get --uri https://management.azure.com/providers/Microsoft.Billing/billingaccounts?api-version=2020-05-01 --query "value[?properties.agreementType=='EnterpriseAgreement'].{name:properties.enrollmentAccounts[0].name}" -o tsv) -# - -subscriptions = { - - {{ config.tfstates.platform.launchpad.lz_key_name }} = { - name = "{{ config.caf_terraform.launchpad.subscription_name }}" - alias = "{{ config.platform_core_setup.enterprise_scale.management_group_prefix }}-launchpad" - subscription_id = "{{ config.caf_terraform.launchpad.subscription_id }}" - } -{% for key in subscriptions.platform_subscriptions.keys() %} - {{ key }} = { - name = "{{ subscriptions.platform_subscriptions[key].name }}" -{% if subscriptions.platform_subscriptions[key].alias is defined %} - alias = "{{ config.platform_core_setup.enterprise_scale.management_group_prefix }}-{{ subscriptions.platform_subscriptions[key].alias }}" -{% endif %} -{% if subscriptions.platform_subscriptions[key].billing_account_name is defined %} - billing_account_name = "{{ config.caf_terraform.billing_subscription_role_delegations.billing_account_name }}" - enrollment_account_name = "{{ config.caf_terraform.billing_subscription_role_delegations.enrollment_account_name }}" - workload = "{{ subscriptions.platform_subscriptions[key].workload | default('DevTest') }}" -{% else %} -{% if subscriptions.platform_subscriptions[key].subscription_id is defined %} - subscription_id = "{{ subscriptions.platform_subscriptions[key].subscription_id }}" -{% endif %} -{% endif %} - } -{% endfor %} - -} \ No newline at end of file diff --git a/templates/platform/level2/ansible_deployment.yaml b/templates/platform/level2/ansible_deployment.yaml deleted file mode 100644 index c9b3967f4..000000000 --- a/templates/platform/level2/ansible_deployment.yaml +++ /dev/null @@ -1,29 +0,0 @@ - -- name: "{{display_name}} Load variable for deployments {{deployment}} - {{resource_folder}}" - include_vars: - name: deployments - dir: "{{config_folder}}/deployments/{{deployment}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "{{ files_matching }}" - -- name: "{{display_name}} Load variable for resources {{deployment}} - {{resource_folder}}" - include_vars: - name: resources - dir: "{{config_folder}}/deployments/{{deployment}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "{{ files_matching }}" - -- name: "{{display_name}} - Content of resources - {{deployment}}" - debug: - msg: "{{resources}}" - -- name: "{{display_name}} - {{deployment}}" - include_tasks: "{{ level }}/ansible_resource_deployment.yaml" - when: - - config.tfstates.platform[resource_folder] is defined - - resources.deployments.keys is defined - loop: "{{ resources.deployments.keys() }}" - loop_control: - loop_var: subscription_key \ No newline at end of file diff --git a/templates/platform/level2/ansible_resource_deployment.yaml b/templates/platform/level2/ansible_resource_deployment.yaml deleted file mode 100644 index c12ab5523..000000000 --- a/templates/platform/level2/ansible_resource_deployment.yaml +++ /dev/null @@ -1,31 +0,0 @@ - -- name: "{{display_name}} - {{level}} - {{subscription_key}} - set destination paths" - set_fact: - destination_path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{resource_folder}}/{{ deployment }}" - -- name: "{{display_name}} - {{level}} - {{subscription_key}} - Clean-up directory - {{ destination_path }}" - file: - path: "{{ destination_path }}" - state: absent - when: config.configuration_folders.asvm.cleanup_destination | default(true) | bool - -- name: "{{display_name}} - {{level}} - {{subscription_key}} - Creates directory - {{ destination_path }}" - file: - path: "{{ destination_path }}" - state: directory - -- name: "{{display_name}} - {{level}} - {{subscription_key}} - {{ deployment }} - Tfvars" - include_tasks: "{{ level }}/ansible_resource_type.yaml" - loop: "{{ resources.subscriptions[subscription_key].keys() }}" - loop_control: - loop_var: resource_type - - -- name: "{{display_name}} - {{level}} - {{subscription_key}} - {{ deployment }} - Overrides" - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/{{resource_folder}}/*.j2" - - "{{ level }}/{{ base_folder }}/{{resource_folder}}/*.md" diff --git a/templates/platform/level2/ansible_resource_type.yaml b/templates/platform/level2/ansible_resource_type.yaml deleted file mode 100644 index 8269d046c..000000000 --- a/templates/platform/level2/ansible_resource_type.yaml +++ /dev/null @@ -1,7 +0,0 @@ -- name: "{{display_name}} - {{ level }} - {{subscription_key}} - {{ deployment }} - {{ resource_type }}" - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/{{resource_type}}.tfvars.j2" diff --git a/templates/platform/level2/asvm/ansible.yaml b/templates/platform/level2/asvm/ansible.yaml index 2135fd666..99739caac 100644 --- a/templates/platform/level2/asvm/ansible.yaml +++ b/templates/platform/level2/asvm/ansible.yaml @@ -1,92 +1,67 @@ -- name: "[{{ level }}-{{ base_folder }}] - Set variables" - set_fact: - destination_path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" -- name: "[{{ level }}-{{ base_folder }}] - Load variable for launchpad" - include_vars: - name: resources - dir: "{{config_folder}}" - depth: 1 - ignore_unknown_extensions: true - files_matching: "asvm.yaml" +- name: "[{{deployment_mode}}/{{stage}}] Get tfstate account name" + register: launchpad_storage_account + shell: | + az storage account list \ + --subscription {{ resources.caf_launchpad.subscription_id }} \ + --query "[?tags.caf_tfstate=='{{ resources.tfstates.platform.launchpad.level }}' && tags.caf_environment=='{{ resources.caf_environment }}'].{name:name}[0]" -o json | jq -r .name - debug: - msg: "{{resources}}" + msg: "{{launchpad_storage_account}}" + +- name: "[{{deployment_mode}}/{{stage}}] - Get launchpad tfstate details" + register: launchpad_tfstate_exists + ignore_errors: true + shell: | + az storage blob download \ + --name "{{ resources.tfstates.platform.launchpad.tfstate }}" \ + --account-name "{{ launchpad_storage_account.stdout | default('') }}" \ + --container-name "{{ resources.tfstates.platform.launchpad.workspace | default('tfstate') }}" \ + --auth-mode "login" \ + --file "~/.terraform.cache/launchpad/{{ resources.tfstates.platform.launchpad.tfstate }}" -- name: "[{{ level }}-{{ base_folder }}] Clean-up directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: absent - when: config.configuration_folders.platform.cleanup_destination | bool +- name: "[{{deployment_mode}}/{{stage}}] - Get subscription_creation_landingzones details" + when: + - launchpad_tfstate_exists.rc == 0 + - resources.enable_azure_subscription_vending_machine + shell: "cat ~/.terraform.cache/launchpad/{{ resources.tfstates.platform.launchpad.tfstate }}" + register: launchpad_tfstate -- name: "[{{ level }}-{{ base_folder }}] Creates directory" - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - state: directory +- name: "[{{deployment_mode}}/{{stage}}] - Get launchpad json data" + when: + - launchpad_tfstate_exists.rc == 0 + - resources.enable_azure_subscription_vending_machine + set_fact: + scljsondata: "{{ launchpad_tfstate.stdout | from_json }}" +- name: "[{{deployment_mode}}/{{stage}}] - set launchpad_azuread_groups" + when: + - launchpad_tfstate_exists.rc == 0 + - resources.enable_azure_subscription_vending_machine + set_fact: + launchpad_azuread_groups: "{{ scljsondata | json_query(path) }}" + vars: + path: 'outputs.objects.value.launchpad.azuread_groups' -- name: "[{{ level }}-{{ base_folder }}] Get level2 tfstate account name" + +- name: "[{{deployment_mode}}/{{stage}}] - Get level2 tfstate account name" register: level2_storage_account shell: | az storage account list \ - --subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - --query "[?tags.caf_tfstate=='{{ config.tfstates.platform.asvm.level }}' && tags.caf_environment=='{{ config.caf_terraform.launchpad.caf_environment }}'].{name:name}[0]" -o json | jq -r .name + --subscription {{ resources.caf_launchpad.subscription_id }} \ + --query "[?tags.caf_tfstate=='{{ resources.tfstates.platform.asvm.level }}' && tags.caf_environment=='{{ resources.caf_environment }}'].{name:name}[0]" -o json | jq -r .name - debug: msg: "{{level2_storage_account}}" + verbosity: 2 - -- name: "[{{ level }}-{{ base_folder }}] Get level2 tfstate account name" +- name: "[{{deployment_mode}}/{{stage}}] - Get level2 tfstate account name" register: level2_storage_rg shell: | az storage account list \ - --subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - --query "[?tags.caf_tfstate=='{{ config.tfstates.platform.asvm.level }}' && tags.caf_environment=='{{ config.caf_terraform.launchpad.caf_environment }}'].{resourceGroup:resourceGroup}[0]" -o json | jq -r .resourceGroup + --subscription {{ resources.caf_launchpad.subscription_id }} \ + --query "[?tags.caf_tfstate=='{{ resources.tfstates.platform.asvm.level }}' && tags.caf_environment=='{{ resources.caf_environment }}'].{resourceGroup:resourceGroup}[0]" -o json | jq -r .resourceGroup - debug: msg: "{{level2_storage_account}}" - - -# -# resource_groups -# -- name: "[{{ level }}-{{ base_folder }}] - resource_groups" - when: - - resources.subscriptions[subscription_key].resource_groups is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/resource_groups.tfvars.j2" - -# -# azuread_groups -# -- name: "[{{ level }}-{{ base_folder }}] - azuread_groups" - when: - - resources.subscriptions[subscription_key].azuread_groups is defined - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_path }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ resource_template_folder }}/azuread_groups.tfvars.j2" - -- name: "[{{ level }}-{{ base_folder }}] asvm" - ansible.builtin.template: - src: "{{ level }}/{{ base_folder }}/{{ item }}.tfvars.j2" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item }}.tfvars" - force: yes - loop: - - dynamic_secrets - - keyvaults - - landingzone - - role_mappings - - storage_accounts - -- name: "[{{ level }}-{{ base_folder }}] launchpad - readme" - ansible.builtin.template: - src: "{{ level }}/{{ base_folder }}/readme.md" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/readme.md" - force: yes \ No newline at end of file + verbosity: 2 diff --git a/templates/platform/level2/asvm/keyvaults.tfvars.j2 b/templates/platform/level2/asvm/keyvaults.tfvars.j2 index c73a72a5e..2feaae7a9 100644 --- a/templates/platform/level2/asvm/keyvaults.tfvars.j2 +++ b/templates/platform/level2/asvm/keyvaults.tfvars.j2 @@ -1,17 +1,16 @@ keyvaults = { level3 = { - name = "{{ resources.subscriptions[subscription_key].keyvaults.level3.name }}" - resource_group_key = "{{ resources.subscriptions[subscription_key].keyvaults.level3.resource_group_key }}" - sku_name = "{{ config.platform_core_setup.sku.keyvault}}" + name = "{{ resources[tfstate].resources[subscription_key].keyvaults.level3.name }}" + resource_group_key = "{{ resources[tfstate].resources[subscription_key].keyvaults.level3.resource_group_key }}" + sku_name = "{{ resources[tfstate].resources[subscription_key].keyvaults.level3.sku_name | default('standard') }}" tags = { - tfstate = "level3" - environment = "{{ config.caf_terraform.launchpad.caf_environment }}" caf_tfstate = "level3" - caf_environment = "{{ config.caf_terraform.launchpad.caf_environment }}" + caf_environment = "{{ resources.caf_environment }}" } creation_policies = { +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' and launchpad_azuread_groups is defined %} subscription_creation_landingzones = { object_id = "{{launchpad_azuread_groups.subscription_creation_landingzones.id}}" secret_permissions = ["Get"] @@ -20,13 +19,12 @@ keyvaults = { object_id = "{{launchpad_azuread_groups.level0.id}}" secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] } -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} caf_platform_maintainers = { object_id = "{{launchpad_azuread_groups.caf_platform_maintainers.id}}" secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] } {% endif %} -{% if config.platform_identity.azuread_identity_mode == 'logged_in_user' %} +{% if resources.azure_landing_zones.identity.azuread_identity_mode == 'logged_in_user' %} logged_in_user = { # if the key is set to "logged_in_user" add the user running terraform in the keyvault policy # More examples in /examples/keyvault @@ -38,21 +36,22 @@ keyvaults = { } level4 = { - name = "{{ resources.subscriptions[subscription_key].keyvaults.level4.name }}" - resource_group_key = "{{ resources.subscriptions[subscription_key].keyvaults.level4.resource_group_key }}" - sku_name = "{{ config.platform_core_setup.sku.keyvault}}" + name = "{{ resources[tfstate].resources[subscription_key].keyvaults.level4.name }}" + resource_group_key = "{{ resources[tfstate].resources[subscription_key].keyvaults.level4.resource_group_key }}" + sku_name = "{{ resources[tfstate].resources[subscription_key].keyvaults.level1.sku_name | default('standard') }}" tags = { - tfstate = "level4" - environment = "{{ config.caf_terraform.launchpad.caf_environment }}" caf_tfstate = "level4" - caf_environment = "{{ config.caf_terraform.launchpad.caf_environment }}" + caf_environment = "{{ resources.caf_environment }}" } creation_policies = { +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' %} +{% if launchpad_azuread_groups is defined %} subscription_creation_landingzones = { object_id = "{{launchpad_azuread_groups.subscription_creation_landingzones.id}}" secret_permissions = ["Get"] } +{% endif %} caf_ac_landingzone_maintainers_non_prod = { azuread_group_key = "caf_ac_landingzone_maintainers_non_prod" secret_permissions = ["Get"] @@ -61,17 +60,18 @@ keyvaults = { azuread_group_key = "caf_ac_landingzone_maintainers_prod" secret_permissions = ["Get"] } +{% if launchpad_azuread_groups is defined %} level0 = { object_id = "{{launchpad_azuread_groups.level0.id}}" secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] } -{% if config.platform_identity.azuread_identity_mode != 'logged_in_user' %} caf_platform_maintainers = { object_id = "{{launchpad_azuread_groups.caf_platform_maintainers.id}}" secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] } {% endif %} -{% if config.platform_identity.azuread_identity_mode == 'logged_in_user' %} +{% endif %} +{% if resources.azure_landing_zones.identity.azuread_identity_mode == 'logged_in_user' %} logged_in_user = { # if the key is set to "logged_in_user" add the user running terraform in the keyvault policy # More examples in /examples/keyvault diff --git a/templates/platform/level2/asvm/landingzone.tfvars.j2 b/templates/platform/level2/asvm/landingzone.tfvars.j2 deleted file mode 100644 index 9c5443ef7..000000000 --- a/templates/platform/level2/asvm/landingzone.tfvars.j2 +++ /dev/null @@ -1,12 +0,0 @@ -landingzone = { - backend_type = "{{ caf_terraform.asvm.backend_type | default("azurerm")}}" - global_settings_key = "{{ config.tfstates.platform.management.lz_key_name }}" - level = "{{ config.tfstates.platform.asvm.level }}" - key = "{{ config.tfstates.platform.asvm.lz_key_name }}" - tfstates = { - {{ config.tfstates.platform.management.lz_key_name }} = { - level = "lower" - tfstate = "{{ config.tfstates.platform.management.tfstate }}" - } - } -} \ No newline at end of file diff --git a/templates/platform/level2/asvm/readme.md b/templates/platform/level2/asvm/readme.md index 3e348beca..8935bcd28 100644 --- a/templates/platform/level2/asvm/readme.md +++ b/templates/platform/level2/asvm/readme.md @@ -2,24 +2,24 @@ ```bash # login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -cd {{ destination_base }}/landingzones +cd {{ landingzones_folder }} git fetch origin -git checkout {{ connectivity_express_routes.gitops.caf_landingzone_branch }} +git checkout {{ resources[deployment].gitops.caf_landingzone_branch }} rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_level0.vault_uri }} \ +{% if keyvaults is defined and resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} + --impersonate-sp-from-keyvault-url {{ keyvaults[tfstate_object.identity_aad_key].vault_uri }} \ {% endif %} - -lz {{ destination_base }}/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ - -tfstate {{ config.tfstates.platform.asvm.tfstate }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -lz {{ landingzones_folder }}/caf_solution \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ + -tfstate {{ resources.tfstates.platform.asvm.tfstate }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.asvm.tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.asvm.tfstate }}.tfplan \ -a plan ``` diff --git a/templates/platform/level2/asvm/role_mappings.tfvars.j2 b/templates/platform/level2/asvm/role_mappings.tfvars.j2 index 8691e97ca..ba81356c3 100644 --- a/templates/platform/level2/asvm/role_mappings.tfvars.j2 +++ b/templates/platform/level2/asvm/role_mappings.tfvars.j2 @@ -9,6 +9,7 @@ role_mapping = { resource_groups = { level3 = { "Reader" = { +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' and launchpad_azuread_groups is defined %} object_ids = { keys = [ "{{launchpad_azuread_groups.caf_platform_maintainers.id}}", // caf_platform_maintainers @@ -21,10 +22,16 @@ role_mapping = { "caf_ac_landingzone_maintainers_prod" ] } +{% else %} + logged_in = { + keys = [ "user" ] + } +{% endif %} } } level4 = { "Reader" = { +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' and launchpad_azuread_groups is defined %} object_ids = { keys = [ "{{launchpad_azuread_groups.caf_platform_maintainers.id}}", // caf_platform_maintainers @@ -37,6 +44,11 @@ role_mapping = { "caf_ac_landingzone_maintainers_prod" ] } +{% else %} + logged_in = { + keys = [ "user" ] + } +{% endif %} } } } @@ -44,13 +56,20 @@ role_mapping = { storage_accounts = { level3 = { "Storage Blob Data Contributor" = { +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' and launchpad_azuread_groups is defined %} object_ids = { keys = [ "{{launchpad_azuread_groups.caf_platform_maintainers.id}}", // caf_platform_maintainers "{{launchpad_azuread_groups.subscription_creation_landingzones.id}}" // subscription_creation_landingzones ] } +{% else %} + logged_in = { + keys = [ "user" ] + } +{% endif %} } +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' and launchpad_azuread_groups is defined %} "Owner" = { object_ids = { keys = [ @@ -58,17 +77,25 @@ role_mapping = { ] } } +{% endif %} } level4 = { "Storage Blob Data Contributor" = { +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' and launchpad_azuread_groups is defined %} object_ids = { keys = [ "{{launchpad_azuread_groups.caf_platform_maintainers.id}}", // caf_platform_maintainers "{{launchpad_azuread_groups.subscription_creation_landingzones.id}}" // subscription_creation_landingzones ] } +{% else %} + logged_in = { + keys = [ "user" ] + } +{% endif %} } +{% if resources.azure_landing_zones.identity.azuread_identity_mode != 'logged_in_user' and launchpad_azuread_groups is defined %} "Owner" = { object_ids = { keys = [ @@ -76,6 +103,7 @@ role_mapping = { ] } } +{% endif %} } } diff --git a/templates/platform/level2/asvm/storage_accounts.tfvars.j2 b/templates/platform/level2/asvm/storage_accounts.tfvars.j2 deleted file mode 100644 index 11b1bc99b..000000000 --- a/templates/platform/level2/asvm/storage_accounts.tfvars.j2 +++ /dev/null @@ -1,54 +0,0 @@ - -storage_accounts = { - level3 = { - name = "{{ resources.subscriptions[subscription_key].storage_accounts.level3.name }}" - resource_group_key = "{{ resources.subscriptions[subscription_key].storage_accounts.level3.resource_group_key }}" - account_kind = "BlobStorage" - account_tier = "Standard" - account_replication_type = "{{ config.caf_terraform.launchpad.account_replication_type }}" - tags = { - ## Those tags must never be changed after being set as they are used by the rover to locate the launchpad and the tfstates. - # Only adjust the environment value at creation time - tfstate = "level3" - environment = "{{ config.caf_terraform.launchpad.caf_environment }}" - launchpad = "launchpad" - caf_environment = "{{ config.caf_terraform.launchpad.caf_environment }}" - caf_launchpad = "launchpad" - caf_tfstate = "level3" - ## - } - blob_properties = { - versioning_enabled = {{ config.caf_terraform.launchpad.blob_versioning_enabled | string | lower | default('true') }} - container_delete_retention_policy = {{ config.caf_terraform.launchpad.container_delete_retention_policy | default(7) }} - delete_retention_policy = {{ config.caf_terraform.launchpad.delete_retention_policy | default(7) }} - } - containers = { - {{ config.tfstates.platform.asvm.workspace | default('tfstate') }} = { - name = "{{ config.tfstates.platform.asvm.workspace | default('tfstate') }}" - } - } - } - - level4 = { - name = "{{ resources.subscriptions[subscription_key].storage_accounts.level4.name }}" - resource_group_key = "{{ resources.subscriptions[subscription_key].storage_accounts.level4.resource_group_key }}" - account_kind = "BlobStorage" - account_tier = "Standard" - account_replication_type = "{{ config.caf_terraform.launchpad.account_replication_type }}" - tags = { - # Those tags must never be changed while set as they are used by the rover to locate the launchpad and the tfstates. - tfstate = "level4" - environment = "{{ config.caf_terraform.launchpad.caf_environment }}" - launchpad = "launchpad" - caf_environment = "{{ config.caf_terraform.launchpad.caf_environment }}" - caf_launchpad = "launchpad" - caf_tfstate = "level4" - } - blob_properties = { - versioning_enabled = {{ config.caf_terraform.launchpad.blob_versioning_enabled | string | lower | default('true') }} - container_delete_retention_policy = {{ config.caf_terraform.launchpad.container_delete_retention_policy | default(7) }} - delete_retention_policy = {{ config.caf_terraform.launchpad.delete_retention_policy | default(7) }} - } - } - -} \ No newline at end of file diff --git a/templates/platform/level2/connectivity/ansible.yaml b/templates/platform/level2/connectivity/ansible.yaml deleted file mode 100644 index 119700857..000000000 --- a/templates/platform/level2/connectivity/ansible.yaml +++ /dev/null @@ -1,86 +0,0 @@ -- name: Creates {{ base_folder }} directory structure - shell: mkdir -p "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - -# - name: "{{ base_folder }} - Readme" -# ansible.builtin.template: -# src: "{{ item }}" -# dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" -# force: yes -# with_fileglob: -# - "{{ level }}/{{ base_folder }}/*.md" - -- name: "{{ base_folder }} - Virtual WAN" - include_tasks: "{{ level }}/{{ base_folder }}/{{ folder_name }}/ansible.yaml" - loop: - - virtual_wan - loop_control: - loop_var: folder_name - -- name: Virtual Hubs - include_tasks: "{{ level }}/{{ base_folder }}/virtual_hub/ansible.yaml" - when: - - connectivity_virtual_hub.virtual_hubs is defined - loop: "{{ config.tfstates.platform.virtual_hubs.keys() }}" - loop_control: - loop_var: virtual_hub - -- name: VPN Sites - include_tasks: "{{ level }}/{{ base_folder }}/vpn_site/ansible.yaml" - when: - - connectivity_vpn_sites.vpn_sites is defined - loop: "{{ config.tfstates.platform.vpn_sites.keys() }}" - loop_control: - loop_var: site - -- name: Express Route Circuit - include_tasks: "{{ level }}/{{ base_folder }}/express_route_circuit/ansible.yaml" - when: - - connectivity_express_routes.express_route_circuits is defined - loop: "{{ config.tfstates.platform.express_route_circuits.keys() }}" - loop_control: - loop_var: circuit - -- name: Express Route Circuit Peerings - include_tasks: "{{ level }}/{{ base_folder }}/express_route_circuit_peering/ansible.yaml" - when: - - connectivity_express_routes.express_route_circuits is defined - - connectivity_express_route_peerings.express_route_circuit_peerings is defined - loop: "{{ config.tfstates.platform.express_route_circuit_peerings.keys() }}" - loop_control: - loop_var: circuit - -- name: Private DNS Zones - include_tasks: "{{ level }}/ansible_deployment.yaml" - when: - - config.tfstates.platform.private_dns is defined - loop: "{{ config.tfstates.platform.private_dns.keys() }}" - loop_control: - loop_var: deployment - vars: - files_matching: "connectivity_private_dns.yaml|connectivity_private_dns.caf.yaml" - resource_folder: private_dns - display_name: Private DNS Zones - -- name: Firewall Policies - include_tasks: "{{ level }}/ansible_deployment.yaml" - when: - - config.tfstates.platform.azurerm_firewall_policies is defined - loop: "{{ config.tfstates.platform.azurerm_firewall_policies.keys() }}" - loop_control: - loop_var: deployment - vars: - files_matching: "connectivity_firewall_policies.yaml|connectivity_firewall_policies.caf.yaml" - resource_folder: azurerm_firewall_policies - display_name: Firewall Policies - -- name: Azure Firewalls - include_tasks: "{{ level }}/ansible_deployment.yaml" - when: - - config.tfstates.platform.azurerm_firewalls is defined - loop: "{{ config.tfstates.platform.azurerm_firewalls.keys() }}" - loop_control: - loop_var: deployment - vars: - files_matching: "connectivity_firewalls.yaml|connectivity_firewalls.caf.yaml" - resource_folder: azurerm_firewalls - display_name: Azure Firewalls \ No newline at end of file diff --git a/templates/platform/level2/connectivity/azurerm_firewall_policies/landingzone.tfvars.j2 b/templates/platform/level2/connectivity/azurerm_firewall_policies/landingzone.tfvars.j2 deleted file mode 100644 index 6b633635b..000000000 --- a/templates/platform/level2/connectivity/azurerm_firewall_policies/landingzone.tfvars.j2 +++ /dev/null @@ -1,12 +0,0 @@ -landingzone = { - backend_type = "azurerm" - global_settings_key = "{{ config.tfstates.platform.management.lz_key_name }}" - level = "level2" - key = "{{ config.tfstates.platform.azurerm_firewall_policies[deployment].lz_key_name }}" - tfstates = { - {{ config.tfstates.platform.management.lz_key_name }} = { - level = "lower" - tfstate = "{{ config.tfstates.platform.management.tfstate }}" - } - } -} \ No newline at end of file diff --git a/templates/platform/level2/connectivity/azurerm_firewall_policies/readme.md b/templates/platform/level2/connectivity/azurerm_firewall_policies/readme.md index bf4d265a2..e9e3fa1c7 100644 --- a/templates/platform/level2/connectivity/azurerm_firewall_policies/readme.md +++ b/templates/platform/level2/connectivity/azurerm_firewall_policies/readme.md @@ -3,34 +3,34 @@ ## Select the correct branch for the landingzones code -Note you need to adjust the branch {{ resources.gitops.landingzones }} to deploy the connectivity services +Note you need to adjust the branch {{ resources.gitops.caf_landingzone_branch }} to deploy the connectivity services ## {{ environment }} ```bash # login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -cd {{ destination_base }}/landingzones +cd {{ landingzones_folder }} git fetch origin -git checkout {{ resources.gitops.landingzones }} +git checkout {{ resources.gitops.caf_landingzone_branch }} rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} +{% if keyvaults is defined and resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} --impersonate-sp-from-keyvault-url {{ keyvaults.cred_connectivity.vault_uri }} \ {% endif %} - -lz {{ destination_base }}/landingzones/caf_solution \ + -lz {{ landingzones_folder }}/caf_solution \ -var-folder {{ destination_path }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ {% if platform_subscriptions_details is defined %} -target_subscription {{ platform_subscriptions_details.connectivity.subscription_id }} \ {% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ {% endif %} - -tfstate {{ config.tfstates.platform.azurerm_firewall_policies[deployment].tfstate }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -tfstate {{ resources.tfstates.platform.azurerm_firewall_policies[deployment].tfstate }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.azurerm_firewall_policies[deployment].tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.azurerm_firewall_policies[deployment].tfstate }}.tfplan \ -a plan ``` diff --git a/templates/platform/level2/connectivity/azurerm_firewalls/landingzone.tfvars.j2 b/templates/platform/level2/connectivity/azurerm_firewalls/landingzone.tfvars.j2 deleted file mode 100644 index 6568d80d4..000000000 --- a/templates/platform/level2/connectivity/azurerm_firewalls/landingzone.tfvars.j2 +++ /dev/null @@ -1,18 +0,0 @@ -landingzone = { - backend_type = "azurerm" - global_settings_key = "{{ config.tfstates.platform.virtual_hubs[deployment].lz_key_name }}" - level = "{{ config.tfstates.platform.azurerm_firewalls[deployment].level }}" - key = "{{ config.tfstates.platform.azurerm_firewalls[deployment].lz_key_name }}" - tfstates = { - # Virtual Hub - {{ config.tfstates.platform.virtual_hubs[deployment].lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.virtual_hubs[deployment].tfstate }}" - } - # firewall policies - {{ config.tfstates.platform.azurerm_firewall_policies[deployment].lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.azurerm_firewall_policies[deployment].tfstate }}" - } - } -} diff --git a/templates/platform/level2/connectivity/azurerm_firewalls/readme.md b/templates/platform/level2/connectivity/azurerm_firewalls/readme.md index ebf4e3f3e..b53eda4ed 100644 --- a/templates/platform/level2/connectivity/azurerm_firewalls/readme.md +++ b/templates/platform/level2/connectivity/azurerm_firewalls/readme.md @@ -3,34 +3,34 @@ ## Select the correct branch for the landingzones code -Note you need to adjust the branch {{ resources.gitops.landingzones }} to deploy the connectivity services +Note you need to adjust the branch {{ resources.gitops.caf_landingzone_branch }} to deploy the connectivity services ## {{ environment }} ```bash # login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -cd {{ destination_base }}/landingzones +cd {{ landingzones_folder }} git fetch origin -git checkout {{ resources.gitops.landingzones }} +git checkout {{ resources.gitops.caf_landingzone_branch }} rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} +{% if keyvaults is defined and resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} --impersonate-sp-from-keyvault-url {{ keyvaults.cred_connectivity.vault_uri }} \ {% endif %} - -lz {{ destination_base }}/landingzones/caf_solution \ + -lz {{ landingzones_folder }}/caf_solution \ -var-folder {{ destination_path }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ {% if platform_subscriptions_details is defined %} -target_subscription {{ platform_subscriptions_details.connectivity.subscription_id }} \ {% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ {% endif %} - -tfstate {{ config.tfstates.platform.azurerm_firewalls[deployment].tfstate }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -tfstate {{ resources.tfstates.platform.azurerm_firewalls[deployment].tfstate }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.azurerm_firewalls[deployment].tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.azurerm_firewalls[deployment].tfstate }}.tfplan \ -a plan ``` diff --git a/templates/platform/level2/connectivity/express_route_circuit/ansible.yaml b/templates/platform/level2/connectivity/express_route_circuit/ansible.yaml index 10950aaed..86a234a4a 100644 --- a/templates/platform/level2/connectivity/express_route_circuit/ansible.yaml +++ b/templates/platform/level2/connectivity/express_route_circuit/ansible.yaml @@ -1,23 +1,23 @@ - name: Express_routes {{ circuit }} - Clean-up directory file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit/{{ circuit }}" + path: "{{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit/{{ circuit }}" state: absent when: - - config.configuration_folders.platform.cleanup_destination | bool + - resources.configuration_folders.platform.cleanup_destination | bool - name: Express_routes {{ circuit }} - Creates directory structure file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit/{{ circuit }}" + path: "{{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit/{{ circuit }}" state: directory - name: Express_routes {{ circuit }} - variables set_fact: - destination_path_resources: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit/{{ circuit }}" + destination_path_resources: "{{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit/{{ circuit }}" - name: Express_routes {{ circuit }} - readme ansible.builtin.template: src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit/{{ circuit }}/{{ item | basename | regex_replace('.j2$', '') }}" + dest: "{{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit/{{ circuit }}/{{ item | basename | regex_replace('.j2$', '') }}" force: yes with_fileglob: - "{{ level }}/{{ base_folder }}/express_route_circuit/*.md" diff --git a/templates/platform/level2/connectivity/express_route_circuit/landingzone.tfvars.j2 b/templates/platform/level2/connectivity/express_route_circuit/landingzone.tfvars.j2 index b5d785b79..aa9f0e93b 100644 --- a/templates/platform/level2/connectivity/express_route_circuit/landingzone.tfvars.j2 +++ b/templates/platform/level2/connectivity/express_route_circuit/landingzone.tfvars.j2 @@ -1,12 +1,12 @@ landingzone = { backend_type = "azurerm" - global_settings_key = "{{ config.tfstates.platform.management.lz_key_name }}" - level = "{{ config.tfstates.platform.express_route_circuits[circuit].level }}" - key = "{{ config.tfstates.platform.express_route_circuits[circuit].lz_key_name }}" + global_settings_key = "{{ resources.tfstates.platform.management.lz_key_name }}" + level = "{{ resources.tfstates.platform.express_route_circuits[circuit].level }}" + key = "{{ resources.tfstates.platform.express_route_circuits[circuit].lz_key_name }}" tfstates = { - {{ config.tfstates.platform.management.lz_key_name }} = { + {{ resources.tfstates.platform.management.lz_key_name }} = { level = "lower" - tfstate = "{{ config.tfstates.platform.management.tfstate }}" + tfstate = "{{ resources.tfstates.platform.management.tfstate }}" } } } diff --git a/templates/platform/level2/connectivity/express_route_circuit/readme.md b/templates/platform/level2/connectivity/express_route_circuit/readme.md index a8c1fd5cf..106ade681 100644 --- a/templates/platform/level2/connectivity/express_route_circuit/readme.md +++ b/templates/platform/level2/connectivity/express_route_circuit/readme.md @@ -9,28 +9,28 @@ Note you need to adjust the branch {{ connectivity_express_routes.gitops.caf_lan ```bash # login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -cd {{ destination_base }}/landingzones +cd {{ landingzones_folder }} git fetch origin git checkout {{ connectivity_express_routes.gitops.caf_landingzone_branch }} rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} +{% if keyvaults is defined and resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} --impersonate-sp-from-keyvault-url {{ keyvaults.cred_connectivity.vault_uri }} \ {% endif %} - -lz {{ destination_base }}/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit/{{ circuit }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ + -lz {{ landingzones_folder }}/caf_solution \ + -var-folder {{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit/{{ circuit }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ {% if platform_subscriptions_details is defined %} -target_subscription {{ platform_subscriptions_details.connectivity.subscription_id }} \ {% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ {% endif %} - -tfstate {{ config.tfstates.platform.express_route_circuits[circuit].tfstate }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -tfstate {{ resources.tfstates.platform.express_route_circuits[circuit].tfstate }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.express_route_circuits[circuit].tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.express_route_circuits[circuit].tfstate }}.tfplan \ -a plan ``` diff --git a/templates/platform/level2/connectivity/express_route_circuit_peering/ansible.yaml b/templates/platform/level2/connectivity/express_route_circuit_peering/ansible.yaml index faf21e149..108fc32f8 100644 --- a/templates/platform/level2/connectivity/express_route_circuit_peering/ansible.yaml +++ b/templates/platform/level2/connectivity/express_route_circuit_peering/ansible.yaml @@ -1,23 +1,23 @@ - name: "[{{ level }}-{{ circuit }}] - express route peering - Clean-up directory" file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit_peering/{{ circuit }}" + path: "{{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit_peering/{{ circuit }}" state: absent when: - - config.configuration_folders.platform.cleanup_destination | bool + - resources.configuration_folders.platform.cleanup_destination | bool - name: "[{{ level }}-{{ circuit }}] - express route peering - Creates directory structure" file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit_peering/{{ circuit }}" + path: "{{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit_peering/{{ circuit }}" state: directory - name: "[{{ level }}-{{ circuit }}] - express route peering - variables" set_fact: - destination_path_resources: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit_peering/{{ circuit }}" + destination_path_resources: "{{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit_peering/{{ circuit }}" - name: "[{{ level }}-{{ circuit }}] - express route peering - readme" ansible.builtin.template: src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit_peering/{{ circuit }}/{{ item | basename | regex_replace('.j2$', '') }}" + dest: "{{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit_peering/{{ circuit }}/{{ item | basename | regex_replace('.j2$', '') }}" force: yes with_fileglob: - "{{ level }}/{{ base_folder }}/express_route_circuit_peering/*.md" diff --git a/templates/platform/level2/connectivity/express_route_circuit_peering/landingzone.tfvars.j2 b/templates/platform/level2/connectivity/express_route_circuit_peering/landingzone.tfvars.j2 index a6e040839..e27df4155 100644 --- a/templates/platform/level2/connectivity/express_route_circuit_peering/landingzone.tfvars.j2 +++ b/templates/platform/level2/connectivity/express_route_circuit_peering/landingzone.tfvars.j2 @@ -1,12 +1,12 @@ landingzone = { backend_type = "azurerm" - global_settings_key = "{{ config.tfstates.platform.express_route_circuits[circuit].lz_key_name }}" - level = "{{ config.tfstates.platform.express_route_circuit_peerings[circuit].level }}" - key = "{{ config.tfstates.platform.express_route_circuit_peerings[circuit].lz_key_name }}" + global_settings_key = "{{ resources.tfstates.platform.express_route_circuits[circuit].lz_key_name }}" + level = "{{ resources.tfstates.platform.express_route_circuit_peerings[circuit].level }}" + key = "{{ resources.tfstates.platform.express_route_circuit_peerings[circuit].lz_key_name }}" tfstates = { - {{ config.tfstates.platform.express_route_circuits[circuit].lz_key_name }} = { + {{ resources.tfstates.platform.express_route_circuits[circuit].lz_key_name }} = { level = "current" - tfstate = "{{ config.tfstates.platform.express_route_circuits[circuit].tfstate }}" + tfstate = "{{ resources.tfstates.platform.express_route_circuits[circuit].tfstate }}" } } } diff --git a/templates/platform/level2/connectivity/express_route_circuit_peering/readme.md b/templates/platform/level2/connectivity/express_route_circuit_peering/readme.md index 0d661fa44..02d439b49 100644 --- a/templates/platform/level2/connectivity/express_route_circuit_peering/readme.md +++ b/templates/platform/level2/connectivity/express_route_circuit_peering/readme.md @@ -3,28 +3,28 @@ ```bash # login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -cd {{ destination_base }}/landingzones +cd {{ landingzones_folder }} git fetch origin git checkout {{ connectivity_express_routes.gitops.caf_landingzone_branch }} rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} +{% if keyvaults is defined and resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} --impersonate-sp-from-keyvault-url {{ keyvaults.cred_connectivity.vault_uri }} \ {% endif %} - -lz {{ destination_base }}/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit_peering/{{ circuit }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ + -lz {{ landingzones_folder }}/caf_solution \ + -var-folder {{ destination_base }}/{{ resources.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/express_route_circuit_peering/{{ circuit }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ {% if platform_subscriptions_details is defined %} -target_subscription {{ platform_subscriptions_details.connectivity.subscription_id }} \ {% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ {% endif %} - -tfstate {{ config.tfstates.platform.express_route_circuit_peerings[circuit].tfstate }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -tfstate {{ resources.tfstates.platform.express_route_circuit_peerings[circuit].tfstate }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.express_route_circuit_peerings[circuit].tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.express_route_circuit_peerings[circuit].tfstate }}.tfplan \ -a plan ``` diff --git a/templates/platform/level2/connectivity/private_dns/landingzone.tfvars.j2 b/templates/platform/level2/connectivity/private_dns/landingzone.tfvars.j2 deleted file mode 100644 index cf533e078..000000000 --- a/templates/platform/level2/connectivity/private_dns/landingzone.tfvars.j2 +++ /dev/null @@ -1,20 +0,0 @@ -landingzone = { - backend_type = "azurerm" - global_settings_key = "{{ config.tfstates.platform.virtual_wan.lz_key_name }}" - level = "{{ config.tfstates.platform.private_dns[deployment].level }}" - key = "{{ config.tfstates.platform.private_dns[deployment].lz_key_name }}" - tfstates = { -{% if config.tfstates.platform.azurerm_firewalls is defined %} - # Firewall - {{ config.tfstates.platform.azurerm_firewalls[deployment].lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.azurerm_firewalls[deployment].tfstate }}" - } -{% endif %} - # Identity Level2 - {{ config.tfstates.platform.identity_level2[deployment].lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.identity_level2[deployment].tfstate }}" - } - } -} diff --git a/templates/platform/level2/connectivity/private_dns/readme.md b/templates/platform/level2/connectivity/private_dns/readme.md index 4af38984f..4c1c69851 100644 --- a/templates/platform/level2/connectivity/private_dns/readme.md +++ b/templates/platform/level2/connectivity/private_dns/readme.md @@ -3,34 +3,34 @@ ## Select the correct branch for the landingzones code -Note you need to adjust the branch {{ resources.gitops.landingzones }} to deploy the connectivity services +Note you need to adjust the branch {{ resources.gitops.caf_landingzone_branch }} to deploy the connectivity services ## {{ environment }} ```bash # login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -cd {{ destination_base }}/landingzones +cd {{ landingzones_folder }} git fetch origin -git checkout {{ resources.gitops.landingzones }} +git checkout {{ resources.gitops.caf_landingzone_branch }} rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} +{% if keyvaults is defined and resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} --impersonate-sp-from-keyvault-url {{ keyvaults.cred_connectivity.vault_uri }} \ {% endif %} - -lz {{ destination_base }}/landingzones/caf_solution \ + -lz {{ landingzones_folder }}/caf_solution \ -var-folder {{ destination_path }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ {% if platform_subscriptions_details is defined %} -target_subscription {{ platform_subscriptions_details.connectivity.subscription_id }} \ {% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ {% endif %} - -tfstate {{ config.tfstates.platform.private_dns[deployment].tfstate }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -tfstate {{ resources.tfstates.platform.private_dns[deployment].tfstate }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.private_dns[deployment].tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.private_dns[deployment].tfstate }}.tfplan \ -a plan ``` diff --git a/templates/platform/level2/connectivity/readme.md b/templates/platform/level2/connectivity/readme.md deleted file mode 100644 index a74d2129b..000000000 --- a/templates/platform/level2/connectivity/readme.md +++ /dev/null @@ -1,151 +0,0 @@ - -# Connectivity -You have selected the vwan networking option to build your Enteprise Scale platform. The following instructions guides you through the steps to follow. - -## Select the correct branch for the landingzones code - -Note you need to adjust the branch {{ config.gitops.caf_landingzone_branch }} to deploy the connectivity services - -{% for folder_name in folders %} -## Virtual Wan - -```bash -# login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} - -cd {{ destination_base }}/landingzones -git fetch origin -git checkout {{ config.gitops.caf_landingzone_branch }} - -rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_connectivity.vault_uri }} \ -{% endif %} - -lz {{ destination_base }}/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ folder_name }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ -{% if platform_subscriptions_details is defined %} - -target_subscription {{ platform_subscriptions_details.connectivity.subscription_id }} \ -{% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ -{% endif %} - -tfstate {{ config.tfstates.platform.[folder_name].tfstate }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.[folder_name].tfstate }}.tfplan \ - -a plan - -``` -{% endfor %} - -## Virtual hubs - -{% for virtual_hub in tfstates.virtual_hubs.keys() %} -### {{ virtual_hub }} - -```bash -# login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} - -cd {{ destination_base }}/landingzones -git fetch origin -git checkout {{ config.gitops.caf_landingzone_branch }} - -rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_connectivity.vault_uri }} \ -{% endif %} - -lz {{ destination_base }}/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/virtual_hubs/{{ virtual_hub }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ -{% if platform_subscriptions_details is defined %} - -target_subscription {{ platform_subscriptions_details.connectivity.subscription_id }} \ -{% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ -{% endif %} - -tfstate {{ config.tfstates.platform.virtual_hubs[virtual_hub].tfstate }} \ - -log-severity ERROR \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.virtual_hubs[virtual_hub].tfstate }}.tfplan \ - -a plan - - -``` -{% endfor %} - -{% if connectivity_vpn_sites.vpn_sites is defined %} -## Virtual Hub VPN Sites - -{% for vpnsite in connectivity_vpn_sites.vpn_sites.keys() %} -### {{ vpnsite }} - -```bash -# login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} - -cd {{ destination_base }}/landingzones -git fetch origin -git checkout {{ config.gitops.caf_landingzone_branch }} - -rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_connectivity.vault_uri }} \ -{% endif %} - -lz {{ destination_base }}/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/vpn_sites/{{ vpnsite }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ -{% if platform_subscriptions_details is defined %} - -target_subscription {{ platform_subscriptions_details.connectivity.subscription_id }} \ -{% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ -{% endif %} - -tfstate {{ config.tfstates.platform.vpn_sites[vpnsite].tfstate }} \ - -log-severity ERROR \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.vpn_sites[vpnsite].tfstate }}.tfplan \ - -a plan - - -``` -{% endfor %} -{% endif %} - -{% if tfstates.firewall_policies is defined %} -## Firewall policies - -{% for firewall_policy in tfstates.firewall_policies.keys() %} -### {{ firewall_policy }} - -```bash -# login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} - -cd {{ destination_base }}/landingzones -git fetch origin -git checkout {{ config.gitops.caf_landingzone_branch }} - -rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_connectivity.vault_uri }} \ -{% endif %} - -lz {{ destination_base }}/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/firewall_policies/{{ firewall_policy }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ -{% if platform_subscriptions_details is defined %} - -target_subscription {{ platform_subscriptions_details.connectivity.subscription_id }} \ -{% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ -{% endif %} - -tfstate {{ config.tfstates.platform.firewall_policies[firewall_policy].tfstate }} \ - -log-severity ERROR \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.firewall_policies[firewall_policy].tfstate }}.tfplan \ - -a plan - - -``` -{% endfor %} -{% endif %} \ No newline at end of file diff --git a/templates/platform/level2/connectivity/virtual_hub/ansible.yaml b/templates/platform/level2/connectivity/virtual_hub/ansible.yaml deleted file mode 100644 index 1ac4b4ca5..000000000 --- a/templates/platform/level2/connectivity/virtual_hub/ansible.yaml +++ /dev/null @@ -1,20 +0,0 @@ -- name: Virtual_hubs {{ virtual_hub }} - Clean-up directory - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/virtual_hubs/{{ virtual_hub }}" - state: absent - when: - - config.configuration_folders.platform.cleanup_destination | bool - -- name: Virtual_hubs {{ virtual_hub }} - Creates directory structure - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/virtual_hubs/{{ virtual_hub }}" - state: directory - -- name: Virtual_hubs {{ virtual_hub }} - Tfvars - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/virtual_hubs/{{ virtual_hub }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/virtual_hub/*.j2" - - "{{ level }}/{{ base_folder }}/virtual_hub/*.md" diff --git a/templates/platform/level2/connectivity/virtual_hub/configuration.tfvars.j2 b/templates/platform/level2/connectivity/virtual_hub/configuration.tfvars.j2 deleted file mode 100644 index 6a7990e31..000000000 --- a/templates/platform/level2/connectivity/virtual_hub/configuration.tfvars.j2 +++ /dev/null @@ -1,31 +0,0 @@ -landingzone = { - backend_type = "azurerm" - global_settings_key = "{{ config.tfstates.platform.virtual_wan.lz_key_name }}" - level = "{{ config.tfstates.platform.virtual_hubs[virtual_hub].level }}" - key = "{{ config.tfstates.platform.virtual_hubs[virtual_hub].lz_key_name }}" - tfstates = { - # Virtual WAN - {{ config.tfstates.platform.virtual_wan.lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.virtual_wan.tfstate }}" - } -{% if connectivity_virtual_hub.virtual_hubs[virtual_hub].enable_er_connections and connectivity_virtual_hub.express_route_connections[virtual_hub] is defined %} - # Express Route Circuit - {{ config.tfstates.platform.express_route_circuits[connectivity_virtual_hub.express_route_connections[virtual_hub].express_route_circuit_authorization.tfstate_key].lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.express_route_circuits[connectivity_virtual_hub.express_route_connections[virtual_hub].express_route_circuit_authorization.tfstate_key].tfstate }}" - } -{% endif %} -{% if connectivity_virtual_hub.virtual_hubs[virtual_hub].enable_er_connections and connectivity_virtual_hub.express_route_connections[virtual_hub].circuit_peering is defined %} - # Express Route Circuit Peerings - {{ config.tfstates.platform.express_route_circuit_peerings[connectivity_virtual_hub.express_route_connections[virtual_hub].circuit_peering.tfstate_key].lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.express_route_circuit_peerings[connectivity_virtual_hub.express_route_connections[virtual_hub].circuit_peering.tfstate_key].tfstate }}" - } -{% endif %} - } -} - -custom_variables = { - virtual_hub_lz_key = "{{ config.tfstates.platform.virtual_hubs[virtual_hub].lz_key_name }}" -} \ No newline at end of file diff --git a/templates/platform/level2/connectivity/virtual_hub/virtual_hubs.tfvars.j2 b/templates/platform/level2/connectivity/virtual_hub/virtual_hubs.tfvars.j2 deleted file mode 100644 index 42a7db4c7..000000000 --- a/templates/platform/level2/connectivity/virtual_hub/virtual_hubs.tfvars.j2 +++ /dev/null @@ -1,82 +0,0 @@ -virtual_hubs = { - {{ virtual_hub }} = { - virtual_wan = { -{% if connectivity_virtual_hub.virtual_hubs[virtual_hub].virtual_wan.lz_key is defined %} - lz_key = "{{ config.tfstates.platform.virtual_wan.lz_key_name }}" -{% endif %} - key = "{{ connectivity_virtual_hub.virtual_hubs[virtual_hub].virtual_wan.key }}" - } - - resource_group = { -{% if connectivity_virtual_hub.virtual_hubs[virtual_hub].virtual_wan.lz_key is defined %} - lz_key = "{{ config.tfstates.platform.virtual_wan.lz_key_name }}" -{% endif %} - key = "{{ connectivity_virtual_hub.virtual_hubs[virtual_hub].virtual_wan.key }}" - } - - hub_name = "{{ connectivity_virtual_hub.virtual_hubs[virtual_hub].name }}" - region = "{{ connectivity_virtual_hub.virtual_hubs[virtual_hub].region_key }}" - hub_address_prefix = "{{ connectivity_virtual_hub.virtual_hubs[virtual_hub].hub_address_prefix }}" - deploy_firewall = false - deploy_p2s = false - p2s_config = {} -{% if connectivity_virtual_hub.virtual_hubs[virtual_hub].deploy_s2s %} - deploy_s2s = {{ connectivity_virtual_hub.virtual_hubs[virtual_hub].deploy_s2s | string | lower }} - s2s_config = { - name = "{{ connectivity_virtual_hub.virtual_hubs[virtual_hub].s2s_config.name }}" - scale_unit = {{ connectivity_virtual_hub.virtual_hubs[virtual_hub].s2s_config.scale_unit }} - } -{% else %} - deploy_s2s = false -{% endif %} -{% if connectivity_virtual_hub.virtual_hubs[virtual_hub].deploy_er %} - deploy_er = {{ connectivity_virtual_hub.virtual_hubs[virtual_hub].deploy_er | string | lower }} - er_config = { - name = "{{ connectivity_virtual_hub.virtual_hubs[virtual_hub].er_config.name }}" - scale_units = {{ connectivity_virtual_hub.virtual_hubs[virtual_hub].er_config.scale_units }} - } -{% else %} - deploy_er = false -{% endif %} - } -} - -{% if connectivity_virtual_hub.virtual_hubs[virtual_hub].enable_er_connections and connectivity_virtual_hub.express_route_connections is defined %} -express_route_connections = { - {{ virtual_hub }} = { - name = "{{ connectivity_virtual_hub.express_route_connections[virtual_hub].name }}" -{% if connectivity_virtual_hub.express_route_connections[virtual_hub].enable_internet_security is defined %} - enable_internet_security = {{ connectivity_virtual_hub.express_route_connections[virtual_hub].enable_internet_security | string | lower }} -{% endif %} -{% if connectivity_virtual_hub.virtual_hubs[virtual_hub].enable_er_connections %} - enable_er_connections = {{ connectivity_virtual_hub.virtual_hubs[virtual_hub].enable_er_connections | string | lower }} -{% endif %} -{% if connectivity_virtual_hub.express_route_connections[virtual_hub].routing_weight is defined %} - routing_weight = {{ connectivity_virtual_hub.express_route_connections[virtual_hub].routing_weight }} -{% endif %} - virtual_hub = { - key = "{{ connectivity_virtual_hub.express_route_connections[virtual_hub].virtual_hub.key }}" - } - circuit_peering = { - lz_key = "{{ config.tfstates.platform.express_route_circuit_peerings[connectivity_virtual_hub.express_route_connections[virtual_hub].circuit_peering.tfstate_key].lz_key_name }}" - key = "{{ connectivity_virtual_hub.express_route_connections[virtual_hub].circuit_peering.key }}" - } -{% if connectivity_virtual_hub.express_route_connections[virtual_hub].express_route_circuit_authorization is defined %} - express_route_circuit_authorization = { - lz_key = "{{ config.tfstates.platform.express_route_circuits[connectivity_virtual_hub.express_route_connections[virtual_hub].express_route_circuit_authorization.tfstate_key].lz_key_name }}" - key = "{{ connectivity_virtual_hub.express_route_connections[virtual_hub].express_route_circuit_authorization.key }}" - } -{% endif %} -{% if connectivity_virtual_hub.express_route_connections[virtual_hub].route_table is defined %} - route_table = { - key = "{{ connectivity_virtual_hub.express_route_connections[virtual_hub].route_table.key }}" - } -{% endif %} -{% if connectivity_virtual_hub.express_route_connections[virtual_hub].propagated_route_tables is defined %} - propagated_route_tables = { - key = "{{ connectivity_virtual_hub.express_route_connections[virtual_hub].propagated_route_tables.key }}" - } -{% endif %} - } -} -{% endif %} \ No newline at end of file diff --git a/templates/platform/level2/connectivity/virtual_hub/virtual_hubs_route_tables.tfvars.j2 b/templates/platform/level2/connectivity/virtual_hub/virtual_hubs_route_tables.tfvars.j2 deleted file mode 100644 index c1d31f8c5..000000000 --- a/templates/platform/level2/connectivity/virtual_hub/virtual_hubs_route_tables.tfvars.j2 +++ /dev/null @@ -1,35 +0,0 @@ -{% if connectivity_virtual_hub[virtual_hub].virtual_hub_route_tables is defined %} -virtual_hub_route_tables = { -{% for key, route_table in connectivity_virtual_hub[virtual_hub].virtual_hub_route_tables.items() %} - {{ key }} = { - name = "{{ route_table.name }}" - - virtual_hub = { - key = "{{ virtual_hub }}" - } - - # labels = ["label1"] - # routes = { - # egress_internet = { - # name = "egress-internet" - # destinations_type = "CIDR" - # destinations = ["0.0.0.0/0"] - - # # Either next_hop or next_hop_id can be used - # # - # # When using next_hop, the virtual_hub_connection must be deployed in a different landingzone. This cannot be tested in the standalone module. - # # Will be covered in the landingzone starter production configuration in future releases. - # # - # next_hop = { - # lz_key = "" # - # resource_type = "virtual_hub_connection" # Only supported value. - # resource_key = "egress-fw" - # } - # #to cather for external object - # #next_hop_id = "Azure_Resource_ID" - # } - # } - } -{% endfor %} -} -{% endif %} \ No newline at end of file diff --git a/templates/platform/level2/connectivity/virtual_hubs/readme.md b/templates/platform/level2/connectivity/virtual_hubs/readme.md new file mode 100644 index 000000000..02fa7f59c --- /dev/null +++ b/templates/platform/level2/connectivity/virtual_hubs/readme.md @@ -0,0 +1,36 @@ +# Virtual hubs + +## Select the correct branch for the landingzones code + +Note you need to adjust the branch {{ resources.gitops.caf_landingzone_branch }} to deploy the connectivity services + +## {{ deployment }} + +```bash +# login a with a user member of the caf-platform-maintainers group +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} + +cd {{ landingzones_folder }} +git fetch origin +git checkout {{ resources.gitops.caf_landingzone_branch }} + +rover \ +{% if keyvaults is defined and resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} + --impersonate-sp-from-keyvault-url {{ keyvaults.cred_connectivity.vault_uri }} \ +{% endif %} + -lz {{ landingzones_folder }}/caf_solution \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ +{% if platform_subscriptions_details is defined %} + -target_subscription {{ platform_subscriptions_details.connectivity.subscription_id }} \ +{% else %} + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ +{% endif %} + -tfstate {{ resources.tfstates.platform.virtual_hubs[deployment].tfstate }} \ + -log-severity ERROR \ + -env {{ resources.caf_environment }} \ + -level {{ level }} \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.virtual_hubs[deployment].tfstate }}.tfplan \ + -a plan + +``` diff --git a/templates/platform/level2/connectivity/virtual_wan/ansible.yaml b/templates/platform/level2/connectivity/virtual_wan/ansible.yaml deleted file mode 100644 index 9294e0ff0..000000000 --- a/templates/platform/level2/connectivity/virtual_wan/ansible.yaml +++ /dev/null @@ -1,20 +0,0 @@ -- name: ({{ folder_name }}) - Clean-up directory - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ folder_name }}" - state: absent - when: - - config.configuration_folders.platform.cleanup_destination | bool - -- name: ({{ folder_name }}) - Creates directory structure - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ folder_name }}" - state: directory - -- name: ({{ folder_name }}) - Tfvars - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ folder_name }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/{{ folder_name }}/*.j2" - - "{{ level }}/{{ base_folder }}/{{ folder_name }}/*.md" diff --git a/templates/platform/level2/connectivity/virtual_wan/configuration.tfvars.j2 b/templates/platform/level2/connectivity/virtual_wan/configuration.tfvars.j2 deleted file mode 100644 index d9a3f9cd5..000000000 --- a/templates/platform/level2/connectivity/virtual_wan/configuration.tfvars.j2 +++ /dev/null @@ -1,12 +0,0 @@ -landingzone = { - backend_type = "azurerm" - global_settings_key = "{{ config.tfstates.platform.management.lz_key_name }}" - level = "{{ config.tfstates.platform.virtual_wan.level }}" - key = "{{ config.tfstates.platform.virtual_wan.lz_key_name }}" - tfstates = { - {{ config.tfstates.platform.management.lz_key_name }} = { - level = "lower" - tfstate = "{{ config.tfstates.platform.management.tfstate }}" - } - } -} diff --git a/templates/platform/level2/connectivity/virtual_wan/readme.md b/templates/platform/level2/connectivity/virtual_wan/readme.md deleted file mode 100644 index c54911c52..000000000 --- a/templates/platform/level2/connectivity/virtual_wan/readme.md +++ /dev/null @@ -1,29 +0,0 @@ -# Virtual Wan - -```bash -# login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} - -cd {{ destination_base }}/landingzones -git fetch origin -git checkout {{ config.gitops.caf_landingzone_branch }} - -rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} - --impersonate-sp-from-keyvault-url {{ keyvaults.cred_connectivity.vault_uri }} \ -{% endif %} - -lz {{ destination_base }}/landingzones/caf_solution \ - -var-folder {{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/{{ folder_name }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ -{% if platform_subscriptions_details is defined %} - -target_subscription {{ platform_subscriptions_details.connectivity.subscription_id }} \ -{% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ -{% endif %} - -tfstate {{ config.tfstates.platform[folder_name].tfstate }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ - -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform[folder_name].tfstate }}.tfplan \ - -a plan - -``` diff --git a/templates/platform/level2/connectivity/virtual_wan/resource_groups.tfvars.j2 b/templates/platform/level2/connectivity/virtual_wan/resource_groups.tfvars.j2 deleted file mode 100644 index eae3fe158..000000000 --- a/templates/platform/level2/connectivity/virtual_wan/resource_groups.tfvars.j2 +++ /dev/null @@ -1,8 +0,0 @@ -resource_groups = { -{% for key, resource_group in connectivity_virtual_wan.resource_groups.items() %} - {{ key }} = { - name = "{{ resource_group.name }}" - region = "{{ resource_group.region_key | default(config.caf_terraform.launchpad.default_region_key) }}" - } -{% endfor %} -} \ No newline at end of file diff --git a/templates/platform/level2/connectivity/virtual_wans/readme.md b/templates/platform/level2/connectivity/virtual_wans/readme.md new file mode 100644 index 000000000..5cee956b8 --- /dev/null +++ b/templates/platform/level2/connectivity/virtual_wans/readme.md @@ -0,0 +1,29 @@ +# Virtual Wan + +```bash +# login a with a user member of the caf-platform-maintainers group +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} + +cd {{ landingzones_folder }} +git fetch origin +git checkout {{ resources.gitops.caf_landingzone_branch }} + +rover \ +{% if keyvaults is defined and resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} + --impersonate-sp-from-keyvault-url {{ keyvaults.cred_connectivity.vault_uri }} \ +{% endif %} + -lz {{ landingzones_folder }}/caf_solution \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ +{% if platform_subscriptions_details is defined %} + -target_subscription {{ platform_subscriptions_details.connectivity.subscription_id }} \ +{% else %} + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ +{% endif %} + -tfstate {{ resources.tfstates.platform.virtual_wans[deployment].tfstate }} \ + -env {{ resources.caf_environment }} \ + -level {{ level }} \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.virtual_wans[deployment].tfstate }}.tfplan \ + -a plan + +``` diff --git a/templates/platform/level2/connectivity/vpn_site/ansible.yaml b/templates/platform/level2/connectivity/vpn_site/ansible.yaml deleted file mode 100644 index 9d620b06b..000000000 --- a/templates/platform/level2/connectivity/vpn_site/ansible.yaml +++ /dev/null @@ -1,20 +0,0 @@ -- name: VPN Site {{ site }} - Clean-up directory - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/vpn_sites/{{ site }}" - state: absent - when: - - config.configuration_folders.platform.cleanup_destination | bool - -- name: VPN Site {{ site }} - Creates directory structure - file: - path: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/vpn_sites/{{ site }}" - state: directory - -- name: VPN Site {{ site }} - Tfvars - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}/vpn_sites/{{ site }}/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/vpn_site/*.j2" - - "{{ level }}/{{ base_folder }}/vpn_site/*.md" diff --git a/templates/platform/level2/connectivity/vpn_site/configuration.tfvars.j2 b/templates/platform/level2/connectivity/vpn_site/configuration.tfvars.j2 deleted file mode 100644 index 3870a6e90..000000000 --- a/templates/platform/level2/connectivity/vpn_site/configuration.tfvars.j2 +++ /dev/null @@ -1,16 +0,0 @@ -landingzone = { - backend_type = "azurerm" - global_settings_key = "{{ config.tfstates.platform.virtual_wan.lz_key_name }}" - level = "{{ config.tfstates.platform.vpn_sites[site].level }}" - key = "{{ config.tfstates.platform.vpn_sites[site].lz_key_name }}" - tfstates = { - {{ config.tfstates.platform.virtual_wan.lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.virtual_wan.tfstate }}" - } - {{ config.tfstates.platform.virtual_hubs[connectivity_vpn_gateway_connections.vpn_gateway_connections[site].vpn_site.key].lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.virtual_hubs[connectivity_vpn_gateway_connections.vpn_gateway_connections[site].vpn_site.key].tfstate }}" - } - } -} \ No newline at end of file diff --git a/templates/platform/level2/connectivity/vpn_site/vpn_sites.tfvars.j2 b/templates/platform/level2/connectivity/vpn_site/vpn_sites.tfvars.j2 deleted file mode 100644 index ee6a97350..000000000 --- a/templates/platform/level2/connectivity/vpn_site/vpn_sites.tfvars.j2 +++ /dev/null @@ -1,27 +0,0 @@ -vpn_sites = { - {{ site }} = { - name = "{{ connectivity_vpn_sites.vpn_sites[site].name }}" - resource_group = { - lz_key = "{{ connectivity_vpn_sites.vpn_sites[site].resource_group.lz_key }}" - key = "{{ connectivity_vpn_sites.vpn_sites[site].resource_group.key }}" - } - virtual_wan = { - lz_key = "{{ connectivity_vpn_sites.vpn_sites[site].virtual_wan.lz_key }}" - key = "{{ connectivity_vpn_sites.vpn_sites[site].virtual_wan.key }}" - } - device_vendor = "{{ connectivity_vpn_sites.vpn_sites[site].device_vendor }}" -{% if connectivity_vpn_sites.vpn_sites[site].address_cidrs is defined %} - address_cidrs = {{ connectivity_vpn_sites.vpn_sites[site].address_cidrs | replace('None','[]') | replace('\'','\"') }} -{% endif %} - links = { -{% for link_key, link in connectivity_vpn_sites.vpn_sites[site].links.items() %} - {{ link_key }} = { - name = "{{ link.name }}" - ip_address = "{{ link.ip_address }}" - provider_name = "{{ link.provider_name }}" - speed_in_mbps = "{{ link.speed_in_mbps }}" - } -{% endfor %} - } - } -} \ No newline at end of file diff --git a/templates/platform/level2/identity/adds/azure_monitor.tfvars b/templates/platform/level2/identity/adds/azure_monitor.tfvars deleted file mode 100644 index e69de29bb..000000000 diff --git a/templates/platform/level2/identity/adds/configuration.tfvars.j2 b/templates/platform/level2/identity/adds/configuration.tfvars.j2 deleted file mode 100644 index 7c369c753..000000000 --- a/templates/platform/level2/identity/adds/configuration.tfvars.j2 +++ /dev/null @@ -1,18 +0,0 @@ -landingzone = { - backend_type = "azurerm" - global_settings_key = "{{ config.tfstates.platform.management.lz_key_name }}" - level = "level2" - key = "{{ config.tfstates.platform.identity_adds.lz_key_name }}" - tfstates = { - {{ config.tfstates.platform.management.lz_key_name }} = { - level = "lower" - tfstate = "{{ config.tfstates.platform.management.tfstate }}" - } -{% for key, virtual_hub in tfstates.virtual_hubs.items() %} - {{ config.tfstates.platform.virtual_hubs[key].lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.virtual_hubs[key].tfstate }}" - } -{% endfor %} - } -} diff --git a/templates/platform/level2/identity/adds/cost_management.tfvars b/templates/platform/level2/identity/adds/cost_management.tfvars deleted file mode 100644 index e69de29bb..000000000 diff --git a/templates/platform/level2/identity/adds/demo.yaml b/templates/platform/level2/identity/adds/demo.yaml deleted file mode 100644 index c91a21597..000000000 --- a/templates/platform/level2/identity/adds/demo.yaml +++ /dev/null @@ -1,34 +0,0 @@ -- name: Identity - ADDS - Clean-up directory - file: - path: "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ level }}/{{ base_folder }}/adds" - state: absent - when: - - config.configuration_folders.cleanup_destination | bool - -- name: Identity - ADDS - Creates directory structure - file: - path: "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ level }}/{{ base_folder }}/adds" - state: directory - -- name: Identity - ADDS - Creates directory structure for diagnostics - file: - path: "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ level }}/{{ base_folder }}/adds/diagnostics" - state: directory - -- name: Identity - ADDS - tfvars - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ level }}/{{ base_folder }}/adds/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/*.j2" - - "{{ level }}/{{ base_folder }}/*.md" - -- name: Identity - ADDS - diagnostics - ansible.builtin.template: - src: "{{ item }}" - dest: "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ level }}/{{ base_folder }}/adds/diagnostics/{{ item | basename | regex_replace('.j2$', '') }}" - force: yes - with_fileglob: - - "{{ level }}/{{ base_folder }}/diagnostics/*.xml" - diff --git a/templates/platform/level2/identity/adds/domain_controllers.tfvars.j2 b/templates/platform/level2/identity/adds/domain_controllers.tfvars.j2 deleted file mode 100644 index 2f3b079e0..000000000 --- a/templates/platform/level2/identity/adds/domain_controllers.tfvars.j2 +++ /dev/null @@ -1,102 +0,0 @@ -# Availability set for domain controllers -availability_sets = { - avset1 = { - name = "avset-dc" - region = "region1" - resource_group_key = "contoso_identity_adds" - # Depends on the region, update and fault domain count availability varies. - platform_update_domain_count = 2 - platform_fault_domain_count = 2 - # By default availability set is configured as managed. Below can be used to change it to unmanged. - # managed = false - } -} - -# Virtual machines -virtual_machines = { -{% for key, vm in identity.virtual_machines.items() %} - # Configuration to deploy a bastion host linux virtual machine - {{ key }} = { - resource_group_key = "{{ vm.resource_group_key}}" - provision_vm_agent = true - boot_diagnostics_storage_account_key = "bootdiag_region1" - - os_type = "windows" - - # the auto-generated ssh key in keyvault secret. Secret name being {VM name}-ssh-public and {VM name}-ssh-private - keyvault_key = "dc01" - - # Define the number of networking cards to attach the virtual machine - networking_interfaces = { - nic0 = { - # Value of the keys from networking.tfvars - vnet_key = "identity_adds" - subnet_key = "ActiveDirectory" - name = "{{ vm.name }}" - enable_ip_forwarding = false - - diagnostic_profiles = { - operations = { - definition_key = "network_interface_card" - destination_type = "storage" - destination_key = "all_regions" - } - } - } - } - - virtual_machine_settings = { - windows = { - name = "{{ vm.name }}" - size = "{{ vm.size }}" - admin_username = "adminuser" - availability_set_key = "avset1" - - # Value of the nic keys to attach the VM. The first one in the list is the default nic - network_interface_keys = ["nic0"] - - os_disk = { - name = "{{ vm.name }}-os" - caching = "ReadWrite" - storage_account_type = "Standard_LRS" - } - - source_image_reference = { - publisher = "MicrosoftWindowsServer" - offer = "WindowsServer" - sku = "2019-Datacenter" - version = "latest" - } - - } - } - - virtual_machine_extensions = { - microsoft_enterprise_cloud_monitoring = { - diagnostic_log_analytics_key = "central_logs_region1" - } - - microsoft_azure_diagnostics = { - # Requires at least one diagnostics storage account - diagnostics_storage_account_keys = ["bootdiag_region1"] - - # Relative path to the configuration folder or full path - xml_diagnostics_file = "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ level }}/{{ base_folder }}/adds/diagnostics/wadcfg.xml" - } - } - } -{% endfor %} -} - -diagnostic_storage_accounts = { - # Stores boot diagnostic for region1 - bootdiag_region1 = { - name = "boot-dc-re1" - resource_group_key = "contoso_identity_adds" - account_kind = "StorageV2" - account_tier = "Standard" - account_replication_type = "LRS" - access_tier = "Cool" - } -} - diff --git a/templates/platform/level2/identity/adds/keyvaults.tfvars.j2 b/templates/platform/level2/identity/adds/keyvaults.tfvars.j2 deleted file mode 100644 index 6c5053f05..000000000 --- a/templates/platform/level2/identity/adds/keyvaults.tfvars.j2 +++ /dev/null @@ -1,31 +0,0 @@ -keyvaults = { - dc01 = { - name = "dc01-secrets" - resource_group_key = "contoso_identity_adds" - sku_name = "{{ config.platform_core_setup.sku.keyvault }}" - - creation_policies = { - logged_in_user = { - certificate_permissions = ["Get", "List", "Update", "Create", "Import", "Delete", "Purge", "Recover"] - secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] - } - logged_in_app = { - certificate_permissions = ["Get", "List", "Update", "Create", "Import", "Delete", "Purge", "Recover"] - secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] - } - } - - diagnostic_profiles = { - operations = { - definition_key = "default_all" - destination_type = "log_analytics" - destination_key = "central_logs" - } - siem = { - definition_key = "siem_all" - destination_type = "storage" - destination_key = "all_regions" - } - } - } -} diff --git a/templates/platform/level2/identity/adds/network_security_groups.tfvars.j2 b/templates/platform/level2/identity/adds/network_security_groups.tfvars.j2 deleted file mode 100644 index 72740f61a..000000000 --- a/templates/platform/level2/identity/adds/network_security_groups.tfvars.j2 +++ /dev/null @@ -1,481 +0,0 @@ -# -# Definition of the networking security groups -# -network_security_group_definition = { - # This entry is applied to all subnets with no NSG defined - empty_nsg = { - flow_logs = { - version = 2 - enabled = true - storage_account = { - storage_account_destination = "all_regions" - retention = { - enabled = true - days = 30 - } - } - traffic_analytics = { - enabled = true - log_analytics_workspace_destination = "central_logs" - interval_in_minutes = "10" - } - } - diagnostic_profiles = { - nsg = { - definition_key = "network_security_group" - destination_type = "storage" - destination_key = "all_regions" - } - operations = { - name = "operations" - definition_key = "network_security_group" - destination_type = "log_analytics" - destination_key = "central_logs" - } - } - nsg = [] - } - - azure_bastion_nsg = { - flow_logs = { - version = 2 - enabled = true - storage_account = { - storage_account_destination = "all_regions" - retention = { - enabled = true - days = 30 - } - } - traffic_analytics = { - enabled = false - log_analytics_workspace_destination = "central_logs" - interval_in_minutes = "10" - } - } - - diagnostic_profiles = { - nsg = { - definition_key = "network_security_group" - destination_type = "storage" - destination_key = "all_regions" - } - operations = { - name = "operations" - definition_key = "network_security_group" - destination_type = "log_analytics" - destination_key = "central_logs" - } - } - - nsg = [ - { - name = "bastion-in-allow", - priority = "100" - direction = "Inbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "443" - source_address_prefix = "*" - destination_address_prefix = "*" - }, - { - name = "bastion-control-in-allow-443", - priority = "120" - direction = "Inbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "135" - source_address_prefix = "GatewayManager" - destination_address_prefix = "*" - }, - { - name = "Kerberos-password-change", - priority = "121" - direction = "Inbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "4443" - source_address_prefix = "GatewayManager" - destination_address_prefix = "*" - }, - { - name = "bastion-vnet-out-allow-22", - priority = "103" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "22" - source_address_prefix = "*" - destination_address_prefix = "VirtualNetwork" - }, - { - name = "bastion-vnet-out-allow-3389", - priority = "101" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "3389" - source_address_prefix = "*" - destination_address_prefix = "VirtualNetwork" - }, - { - name = "bastion-azure-out-allow", - priority = "120" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "443" - source_address_prefix = "*" - destination_address_prefix = "AzureCloud" - } - ] - } - - application_gateway = { - - diagnostic_profiles = { - nsg = { - definition_key = "network_security_group" - destination_type = "storage" - destination_key = "all_regions" - } - operations = { - name = "operations" - definition_key = "network_security_group" - destination_type = "log_analytics" - destination_key = "central_logs" - } - } - - flow_logs = { - version = 2 - enabled = true - storage_account = { - storage_account_destination = "all_regions" - retention = { - enabled = true - days = 30 - } - } - traffic_analytics = { - enabled = true - log_analytics_workspace_destination = "central_logs" - interval_in_minutes = "10" - } - } - - nsg = [ - { - name = "Inbound-HTTP", - priority = "120" - direction = "Inbound" - access = "Allow" - protocol = "*" - source_port_range = "*" - destination_port_range = "80-82" - source_address_prefix = "*" - destination_address_prefix = "*" - }, - { - name = "Inbound-HTTPs", - priority = "130" - direction = "Inbound" - access = "Allow" - protocol = "*" - source_port_range = "*" - destination_port_range = "443" - source_address_prefix = "*" - destination_address_prefix = "*" - }, - { - name = "Inbound-AGW", - priority = "140" - direction = "Inbound" - access = "Allow" - protocol = "*" - source_port_range = "*" - destination_port_range = "65200-65535" - source_address_prefix = "*" - destination_address_prefix = "*" - }, - ] - } - - api_management = { - - diagnostic_profiles = { - nsg = { - definition_key = "network_security_group" - destination_type = "storage" - destination_key = "all_regions" - } - operations = { - name = "operations" - definition_key = "network_security_group" - destination_type = "log_analytics" - destination_key = "central_logs" - } - } - flow_logs = { - version = 2 - enabled = true - storage_account = { - storage_account_destination = "all_regions" - retention = { - enabled = true - days = 30 - } - } - traffic_analytics = { - enabled = true - log_analytics_workspace_destination = "central_logs" - interval_in_minutes = "10" - } - } - - nsg = [ - { - name = "Inbound-APIM", - priority = "100" - direction = "Inbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "3443" - source_address_prefix = "ApiManagement" - destination_address_prefix = "VirtualNetwork" - }, - { - name = "Inbound-Redis", - priority = "110" - direction = "Inbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "6381-6383" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "VirtualNetwork" - }, - { - name = "Inbound-LoadBalancer", - priority = "120" - direction = "Inbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "*" - source_address_prefix = "AzureLoadBalancer" - destination_address_prefix = "VirtualNetwork" - }, - { - name = "Outbound-StorageHttp", - priority = "100" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "80" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "Storage" - }, - { - name = "Outbound-StorageHttps", - priority = "110" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "443" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "Storage" - }, - { - name = "Outbound-AADHttp", - priority = "120" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "80" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "AzureActiveDirectory" - }, - { - name = "Outbound-AADHttps", - priority = "130" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "443" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "AzureActiveDirectory" - }, - { - name = "Outbound-SQL", - priority = "140" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "1433" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "SQL" - }, - { - name = "Outbound-EventHub", - priority = "150" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "5671-5672" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "EventHub" - }, - { - name = "Outbound-EventHubHttps", - priority = "160" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "443" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "EventHub" - }, - { - name = "Outbound-FileShareGit", - priority = "170" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "445" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "Storage" - }, - { - name = "Outbound-Health", - priority = "180" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "1886" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "INTERNET" - }, - { - name = "Outbound-Monitor", - priority = "190" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "443" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "AzureMonitor" - }, - { - name = "Outbound-MoSMTP1itor", - priority = "200" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "25" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "INTERNET" - }, - { - name = "Outbound-SMTP2", - priority = "210" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "587" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "INTERNET" - }, - { - name = "Outbound-SMTP3", - priority = "220" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "25028" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "INTERNET" - }, - { - name = "Outbound-Redis", - priority = "230" - direction = "Outbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "6381-6383" - source_address_prefix = "VirtualNetwork" - destination_address_prefix = "VirtualNetwork" - }, - ] - } - - jumpbox = { - flow_logs = { - version = 2 - enabled = true - storage_account = { - storage_account_destination = "all_regions" - retention = { - enabled = true - days = 30 - } - } - traffic_analytics = { - enabled = true - log_analytics_workspace_destination = "central_logs" - interval_in_minutes = "10" - } - } - - diagnostic_profiles = { - nsg = { - definition_key = "network_security_group" - destination_type = "storage" - destination_key = "all_regions" - } - operations = { - name = "operations" - definition_key = "network_security_group" - destination_type = "log_analytics" - destination_key = "central_logs" - } - } - - nsg = [ - { - name = "ssh-inbound-22", - priority = "200" - direction = "Inbound" - access = "Allow" - protocol = "tcp" - source_port_range = "*" - destination_port_range = "22" - source_address_prefix = "*" - destination_address_prefix = "VirtualNetwork" - }, - ] - } - -} diff --git a/templates/platform/level2/identity/adds/readme.md b/templates/platform/level2/identity/adds/readme.md deleted file mode 100644 index be20632b9..000000000 --- a/templates/platform/level2/identity/adds/readme.md +++ /dev/null @@ -1,26 +0,0 @@ - -### Identity - Active Directory Domain Controllers (ADDS) - -Deploy 2 domain controllers in the primary region - -```bash -# login a with a user member of the caf-maintainers group -rover login -t {{ config.tenant_name }} - -cd {{ destination_base_path }}landingzones -git fetch origin -git checkout {{ config.caf_landingzone_branch }} - -export ARM_USE_AZUREAD=true -caf_env="{{ config.caf_terraform.launchpad.caf_environment }}" - -rover \ - -lz {{ destination_base_path }}landingzones/caf_solution \ - -var-folder {{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ level }}/{{ tfstates["identity_adds"].base_config_path }}/adds \ - -tfstate {{ tfstates["identity_adds"].tfstate }} \ - -log-severity ERROR \ - -env ${caf_env} \ - -level {{ level }} \ - -a plan - -``` diff --git a/templates/platform/level2/identity/adds/resource_groups.tfvars.j2 b/templates/platform/level2/identity/adds/resource_groups.tfvars.j2 deleted file mode 100644 index 7d66f7c3f..000000000 --- a/templates/platform/level2/identity/adds/resource_groups.tfvars.j2 +++ /dev/null @@ -1,8 +0,0 @@ -resource_groups = { -{% for key, resource_group in identity.resource_groups.items() %} - {{ key }} = { - name = "{{ resource_group.name }}" - region = "{{ resource_group.region_key }}" - } -{% endfor %} -} \ No newline at end of file diff --git a/templates/platform/level2/identity/adds/site_recovery.tfvars b/templates/platform/level2/identity/adds/site_recovery.tfvars deleted file mode 100644 index e69de29bb..000000000 diff --git a/templates/platform/level2/identity/adds/virtual_hub_connections.tfvars.j2 b/templates/platform/level2/identity/adds/virtual_hub_connections.tfvars.j2 deleted file mode 100644 index 5117df94c..000000000 --- a/templates/platform/level2/identity/adds/virtual_hub_connections.tfvars.j2 +++ /dev/null @@ -1,32 +0,0 @@ -virtual_hub_connections = { -{% for virtual_network_key, virtual_network in identity.virtual_networks.items() %} -{% for vhub_conn_key, vhub_connection in virtual_network.virtual_hub_connection.items() %} - {{ vhub_conn_key }} = { - name = "{{ vhub_connection.name }}" - virtual_hub = { - lz_key = "{{ config.tfstates.platform.virtual_hubs[vhub_connection.virtual_hub.lz_key_name].lz_key_name }}" - key = "{{ vhub_connection.virtual_hub.key }}" - } - vnet = { - vnet_key = "{{ virtual_network_key }}" - } - routing = { -{% for rt_key, route_table in vhub_connection.routing.items() %} - {{ rt_key }} = { - virtual_hub_route_table_key = "{{ route_table.route_table.key }}" - lz_key = "{{ config.tfstates.platform.virtual_hubs[route_table.route_table.lz_key_name].lz_key_name }}" - - propagated_route_table = { -{% if route_table.propagated_route_table.virtual_hub_route_table_keys is defined %} - lz_key = "{{ config.tfstates.platform.virtual_hubs[route_table.propagated_route_table.lz_key_name].lz_key_name }}" - virtual_hub_route_table_keys = {{ route_table.propagated_route_table.virtual_hub_route_table_keys | replace('None','[]') | replace('\'','\"') }} -{% endif %} - labels = {{ route_table.propagated_route_table.labels | replace('None','[]') | replace('\'','\"') }} - } - } -{% endfor %} - } - } -{% endfor %} -{% endfor %} -} \ No newline at end of file diff --git a/templates/platform/level2/identity/adds/virtual_networks.tfvars.j2 b/templates/platform/level2/identity/adds/virtual_networks.tfvars.j2 deleted file mode 100644 index c1080e5a3..000000000 --- a/templates/platform/level2/identity/adds/virtual_networks.tfvars.j2 +++ /dev/null @@ -1,41 +0,0 @@ -vnets = { -{% for key, vnet in identity.virtual_networks.items() %} - {{ key }} = { - resource_group_key = "{{vnet.resource_group_key}}" - vnet = { - name = "{{ vnet.name }}" - address_space = {{ vnet.address_space | replace('None','[]') | replace('\'','\"') }} - } - subnets = { -{% if vnet.subnets is defined %} -{% for subnet_key, subnet in vnet.subnets.items() %} - {{ subnet_key }} = { - name = "{{subnet.name}}" - cidr = {{ vnet.subnets[subnet_key].cidr | replace('None','[]') | replace('\'','\"') }} - nsg_key = "empty_nsg" - } -{% endfor %} -{% endif %} - } -{% if vnet.specialsubnets is defined %} - specialsubnets = { -{% for subnet_key, subnet in vnet.specialsubnets.items() %} - {{ subnet_key }} = { - name = "{{subnet.name}}" - cidr = {{ vnet.specialsubnets[subnet_key].cidr | replace('None','[]') | replace('\'','\"') }} - } -{% endfor %} - } -{% endif %} - - # you can setup up to 5 keys - vnet diganostic - diagnostic_profiles = { - vnet = { - definition_key = "networking_all" - destination_type = "log_analytics" - destination_key = "central_logs" - } - } - } -{% endfor %} -} \ No newline at end of file diff --git a/templates/platform/level2/identity/ansible.yaml b/templates/platform/level2/identity/ansible.yaml deleted file mode 100644 index 2fdc64f6e..000000000 --- a/templates/platform/level2/identity/ansible.yaml +++ /dev/null @@ -1,26 +0,0 @@ -- name: Creates {{ base_folder }} directory structure - shell: mkdir -p "{{ destination_base }}/{{ config.configuration_folders.platform.destination_relative_path }}/{{ level }}/{{ base_folder }}" - -- name: Azure Identity level2 - include_tasks: "{{ level }}/ansible_deployment.yaml" - when: - - config.tfstates.platform.identity_level2 is defined - loop: "{{ config.tfstates.platform.identity_level2.keys() }}" - loop_control: - loop_var: deployment - vars: - files_matching: "identity_level2.yaml|identity_level2.caf.yaml" - resource_folder: identity_level2 - display_name: Azure Identity level2 - -- name: Azure Active Directory Domain Services (AADDS) - include_tasks: "{{ level }}/ansible_deployment.yaml" - when: - - config.tfstates.platform.identity_level2_aadds is defined - loop: "{{ config.tfstates.platform.identity_level2_aadds.keys() }}" - loop_control: - loop_var: deployment - vars: - files_matching: "identity_level2_aadds.yaml|identity_level2_aadds.caf.yaml" - resource_folder: identity_level2_aadds - display_name: Azure Active Directory Domain Services (AADDS) diff --git a/templates/platform/level2/identity/identity_level2/landingzone.tfvars.j2 b/templates/platform/level2/identity/identity_level2/landingzone.tfvars.j2 deleted file mode 100644 index f14f87604..000000000 --- a/templates/platform/level2/identity/identity_level2/landingzone.tfvars.j2 +++ /dev/null @@ -1,12 +0,0 @@ -landingzone = { - backend_type = "azurerm" - global_settings_key = "{{ config.tfstates.platform.management.lz_key_name }}" - level = "{{ config.tfstates.platform.identity_level2[deployment].level }}" - key = "{{ config.tfstates.platform.identity_level2[deployment].lz_key_name }}" - tfstates = { - {{ config.tfstates.platform.management.lz_key_name }} = { - level = "lower" - tfstate = "{{ config.tfstates.platform.management.tfstate }}" - } - } -} diff --git a/templates/platform/level2/identity/identity_level2/readme.md b/templates/platform/level2/identity/identity_level2/readme.md index 5bef01ac9..ce718d42d 100644 --- a/templates/platform/level2/identity/identity_level2/readme.md +++ b/templates/platform/level2/identity/identity_level2/readme.md @@ -7,21 +7,21 @@ Deploy the identity services rover logout # login a with a user member of the caf-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} rover \ -{% if config.platform_identity.azuread_identity_mode != "logged_in_user" %} +{% if resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} --impersonate-sp-from-keyvault-url {{ keyvaults.cred_identity.vault_uri }} \ {% endif %} - -lz /tf/caf/landingzones/caf_solution \ + -lz {{ landingzones_folder }}/caf_solution \ -var-folder {{ destination_path }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ -target_subscription {{ platform_subscriptions_details.identity.subscription_id }} \ - -tfstate {{ config.tfstates.platform.identity_level2[deployment].tfstate }} \ - -log-severity {{ config.gitops.rover_log_error }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -tfstate {{ resources.tfstates.platform.identity_level2[deployment].tfstate }} \ + -log-severity {{ resources.gitops.rover_log_error }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.identity_level2[deployment].tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.identity_level2[deployment].tfstate }}.tfplan \ -a plan ``` @@ -29,4 +29,4 @@ rover \ # Next steps - [Deploy Enterprise Scale](../../level1/eslz/readme.md) + [Deploy Enterprise Scale](../../level1/alz/readme.md) diff --git a/templates/platform/level2/identity/identity_level2_aadds/landingzone.tfvars.j2 b/templates/platform/level2/identity/identity_level2_aadds/landingzone.tfvars.j2 deleted file mode 100644 index 45333d9e4..000000000 --- a/templates/platform/level2/identity/identity_level2_aadds/landingzone.tfvars.j2 +++ /dev/null @@ -1,17 +0,0 @@ -landingzone = { - backend_type = "azurerm" - global_settings_key = "{{ config.tfstates.platform.management.lz_key_name }}" - level = "{{ config.tfstates.platform.identity_level2_aadds[deployment].level }}" - key = "{{ config.tfstates.platform.identity_level2_aadds[deployment].lz_key_name }}" - tfstates = { - # Virtual Hub - {{ config.tfstates.platform.virtual_hubs[deployment].lz_key_name }} = { - level = "current" - tfstate = "{{ config.tfstates.platform.virtual_hubs[deployment].tfstate }}" - } - {{ config.tfstates.platform.management.lz_key_name }} = { - level = "lower" - tfstate = "{{ config.tfstates.platform.management.tfstate }}" - } - } -} diff --git a/templates/platform/level2/identity/identity_level2_aadds/readme.md b/templates/platform/level2/identity/identity_level2_aadds/readme.md index 9106bea3c..d0d09bad1 100644 --- a/templates/platform/level2/identity/identity_level2_aadds/readme.md +++ b/templates/platform/level2/identity/identity_level2_aadds/readme.md @@ -3,34 +3,34 @@ ## Select the correct branch for the landingzones code -Note you need to adjust the branch {{ resources.gitops.landingzones }} to deploy the AADDS services +Note you need to adjust the branch {{ resources.gitops.caf_landingzone_branch }} to deploy the AADDS services ## {{ environment }} ```bash # login a with a user member of the caf-platform-maintainers group -rover login -t {{ config.platform_identity.tenant_name }} +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} -cd {{ destination_base }}/landingzones +cd {{ landingzones_folder }} git fetch origin -git checkout {{ resources.gitops.landingzones }} +git checkout {{ resources.gitops.caf_landingzone_branch }} rover \ -{% if keyvaults is defined and config.platform_identity.azuread_identity_mode != "logged_in_user" %} +{% if keyvaults is defined and resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} --impersonate-sp-from-keyvault-url {{ keyvaults.cred_identity.vault_uri }} \ {% endif %} - -lz {{ destination_base }}/landingzones/caf_solution \ + -lz {{ landingzones_folder }}/caf_solution \ -var-folder {{ destination_path }} \ - -tfstate_subscription_id {{ config.caf_terraform.launchpad.subscription_id }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ {% if platform_subscriptions_details is defined %} -target_subscription {{ platform_subscriptions_details.identity.subscription_id }} \ {% else %} - -target_subscription {{ config.caf_terraform.launchpad.subscription_id }} \ + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ {% endif %} - -tfstate {{ config.tfstates.platform.identity_level2_aadds[deployment].tfstate }} \ - -env {{ config.caf_terraform.launchpad.caf_environment }} \ + -tfstate {{ resources.tfstates.platform.identity_level2_aadds[deployment].tfstate }} \ + -env {{ resources.caf_environment }} \ -level {{ level }} \ - -p ${TF_DATA_DIR}/{{ config.tfstates.platform.identity_level2_aadds[deployment].tfstate }}.tfplan \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.identity_level2_aadds[deployment].tfstate }}.tfplan \ -a plan ``` diff --git a/templates/platform/level2/identity/adds/diagnostics/wadcfg.xml b/templates/platform/level2/identity/identity_level2_adds/diagnostics/wadcfg.xml similarity index 100% rename from templates/platform/level2/identity/adds/diagnostics/wadcfg.xml rename to templates/platform/level2/identity/identity_level2_adds/diagnostics/wadcfg.xml diff --git a/templates/platform/level2/identity/identity_level2_adds/readme.md b/templates/platform/level2/identity/identity_level2_adds/readme.md new file mode 100644 index 000000000..7112493b0 --- /dev/null +++ b/templates/platform/level2/identity/identity_level2_adds/readme.md @@ -0,0 +1,32 @@ + +### Identity - Active Directory Domain Controllers (ADDS) + +Deploy 2 domain controllers in the primary region + +```bash +# login a with a user member of the caf-maintainers group +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} + +cd {{ landingzones_folder }} +git fetch origin +git checkout {{ resources.gitops.caf_landingzone_branch }} + +rover \ +{% if keyvaults is defined and resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" %} + --impersonate-sp-from-keyvault-url {{ keyvaults.cred_identity.vault_uri }} \ +{% endif %} + -lz {{ landingzones_folder }}/caf_solution \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ +{% if platform_subscriptions_details is defined %} + -target_subscription {{ platform_subscriptions_details.identity.subscription_id }} \ +{% else %} + -target_subscription {{ resources.caf_launchpad.subscription_id }} \ +{% endif %} + -tfstate {{ resources.tfstates.platform.identity_level2_adds[deployment].tfstate }} \ + -env {{ resources.caf_environment }} \ + -level {{ level }} \ + -p ${TF_DATA_DIR}/{{ resources.tfstates.platform.identity_level2_adds[deployment].tfstate }}.tfplan \ + -a plan + +``` diff --git a/templates/platform/level3/ansible.yaml b/templates/platform/level3/ansible.yaml new file mode 100644 index 000000000..33f6ac533 --- /dev/null +++ b/templates/platform/level3/ansible.yaml @@ -0,0 +1,87 @@ + +- name: "[{{ level }}-asvm] Get asvm keyvault credentials name" + register: keyvault_scl + shell: | + az keyvault list \ + --subscription {{ resources.caf_launchpad.subscription_id }} \ + --query "[?tags.caf_identity_aad_key=='cred_subscription_creation_landingzones' && tags.caf_environment=='{{ resources.caf_environment }}'].{name:name}[0]" -o json | jq -r --arg http "https://" --arg suffix ".vault.azure.net/" '$http + (.name) + $suffix' + +- debug: + msg: "{{keyvault_scl.stdout}}" + +# +# Get landingzones subscriptions +# + +- name: "[{{ level }}-asvm] - get keyvault credentials" + register: keyvault_scl + shell: | + az keyvault list \ + --query "[?tags.caf_identity_aad_key=='cred_subscription_creation_landingzones'].{name:name}[0]" | \ + jq -r --arg http "https://" --arg suffix ".vault.azure.net/" '$http + (.name) + $suffix' + +- name: "[{{ level }}-asvm] - storage_containers - launchpad level3" + register: storage_account_level3 + shell: | + az storage account list \ + --subscription {{ resources.caf_launchpad.subscription_id }} \ + --query "[?tags.caf_tfstate=='level3' && tags.caf_environment=='{{ resources.caf_environment }}'].{name:name, resource_group:resourceGroup}[0]" -o json | jq -r + +- name: "[{{ level }}-asvm] - storage_containers - launchpad level4" + register: storage_account_level4 + shell: | + az storage account list \ + --subscription {{ resources.caf_launchpad.subscription_id }} \ + --query "[?tags.caf_tfstate=='level4' && tags.caf_environment=='{{ resources.caf_environment }}'].{name:name, resource_group:resourceGroup}[0]" -o json | jq -r + +- debug: + msg: + - "{{storage_account_level3.stdout}}" + - "{{storage_account_level4.stdout}}" + +- name: "[{{ level }}-asvm] Get credentials tfstate details" + register: landingzones_subscriptions + ignore_errors: true + shell: | + az storage blob download \ + --name "{{ resources.tfstates[lz_type][tfstate_resource].tfstate }}" \ + --account-name "{{ storage_account_level3.stdout|from_json|json_query('name') }}" \ + --container-name "{{ resources.tfstates[lz_type][tfstate_resource].workspace | default('tfstate') }}" \ + --auth-mode "login" \ + --file "~/.terraform.cache/launchpad/{{ resources.tfstates[lz_type][tfstate_resource].tfstate }}" + +- debug: + msg: "{{landingzones_subscriptions}}" + verbosity: 1 + +- name: "[{{ level }}-asvm] Get subscription_creation_landingzones details" + when: + - landingzones_subscriptions.rc == 0 + shell: "cat ~/.terraform.cache/launchpad/{{ resources.tfstates[lz_type][tfstate_resource].tfstate }}" + register: landingzones_tfstate + +- debug: + msg: "{{landingzones_tfstate.stdout | from_json }}" + verbosity: 1 + when: + - landingzones_subscriptions.rc == 0 + +- name: "[{{ level }}-asvm] Get landingzone json data" + when: + - landingzones_subscriptions.rc == 0 + set_fact: + scljsondata: "{{ landingzones_tfstate.stdout | from_json }}" + +- name: "[{{ level }}-asvm] Get landingzone subscription ids" + when: + - landingzones_subscriptions.rc == 0 + set_fact: + asvm_subscriptions_details: "{{ scljsondata | json_query(path) }}" + vars: + path: 'outputs.objects.value.{{resources.tfstates[lz_type][tfstate_resource].lz_key_name}}.subscriptions' + +- debug: + msg: "{{asvm_subscriptions_details}}" + verbosity: 1 + when: + - landingzones_subscriptions.rc == 0 \ No newline at end of file diff --git a/templates/platform/level3/readme.md b/templates/platform/level3/readme.md new file mode 100644 index 000000000..e368cf716 --- /dev/null +++ b/templates/platform/level3/readme.md @@ -0,0 +1,30 @@ + +```bash +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} + +unset ARM_SKIP_PROVIDER_REGISTRATION + +cd {{landingzones_folder}} +git pull +git checkout {{ resources.gitops.caf_landingzone_branch }} + +rover \ +{% if resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" and keyvault_scl is defined %} + --impersonate-sp-from-keyvault-url {{ keyvault_scl.stdout }} \ +{% endif %} + -lz {{landingzones_folder}}/caf_solution \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ +{% if asvm_subscriptions_details[subscription_key].subscription_id is defined %} + -target_subscription {{ asvm_subscriptions_details[subscription_key].subscription_id }} \ +{% endif %} + -tfstate {{ tfstate_object.tfstate }} \ + --workspace {{ tfstate_object.workspace }} \ + -env {{ resources.caf_environment }} \ + -level {{ level }} \ + -p ${TF_DATA_DIR}/{{ tfstate_object.tfstate }}.tfplan \ + -a plan + +rover logout + +``` diff --git a/templates/platform/level3/subscriptions/readme.md b/templates/platform/level3/subscriptions/readme.md new file mode 100644 index 000000000..3eb493d31 --- /dev/null +++ b/templates/platform/level3/subscriptions/readme.md @@ -0,0 +1,28 @@ + +### Create storage containers for the landingzone + +```bash +rover login -t {{ resources.azure_landing_zones.identity.tenant_name }} + +cd {{landingzones_folder}} +git pull +git checkout {{ resources[deployment].gitops.caf_landingzone_branch }} + +rover \ +{% if resources.azure_landing_zones.identity.azuread_identity_mode != "logged_in_user" and keyvault_scl is defined %} + --impersonate-sp-from-keyvault-url {{ keyvault_scl.stdout }} \ +{% endif %} + -lz {{landingzones_folder}}/caf_solution \ + -var-folder {{ destination_path }} \ + -tfstate_subscription_id {{ resources.caf_launchpad.subscription_id }} \ + -target_subscription {{resources.caf_launchpad.subscription_id }} \ + -tfstate {{ tfstate_object.tfstate }} \ + --workspace {{ tfstate_object.workspace | default('tfstate') }} \ + -env {{ resources.caf_environment }} \ + -level {{ level }} \ + -p ${TF_DATA_DIR}/{{ tfstate_object.tfstate }}.tfplan \ + -a plan + +rover logout + +``` diff --git a/templates/platform/level3/subscriptions/storage_containers.tfvars.j2 b/templates/platform/level3/subscriptions/storage_containers.tfvars.j2 new file mode 100644 index 000000000..6d06023b9 --- /dev/null +++ b/templates/platform/level3/subscriptions/storage_containers.tfvars.j2 @@ -0,0 +1,16 @@ +storage_containers = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].subscriptions.items() %} + {{key }}_level3 = { + name = "{{ resources.tfstates[lz_type][key].workspace }}" + storage_account = { + name = "{{storage_account_level3.stdout|from_json|json_query('name')}}" + } + } + {{key }}_level4 = { + name = "{{ resources.tfstates[lz_type][key].workspace }}" + storage_account = { + name = "{{storage_account_level4.stdout|from_json|json_query('name')}}" + } + } +{% endfor %} +} \ No newline at end of file diff --git a/templates/platform/pipelines/README.md b/templates/platform/pipelines/README.md index 453154a6a..6773e82c4 100644 --- a/templates/platform/pipelines/README.md +++ b/templates/platform/pipelines/README.md @@ -22,7 +22,7 @@ ansible-playbook e2e.yaml \ ## Prerequisites ```bash -branch={{ config.eslz.private_lib[config.eslz.private_lib.version_to_deploy].caf_landingzone_branch }} +branch={{ resources.alz.private_lib[resources.alz.private_lib.version_to_deploy].caf_landingzone_branch }} cd {{ destination_base_path }} git clone --branch ${branch} https://github.com/Azure/caf-terraform-landingzones.git landingzones diff --git a/templates/platform/pipelines/demo.yaml b/templates/platform/pipelines/demo.yaml index 6830023e0..49dae435c 100644 --- a/templates/platform/pipelines/demo.yaml +++ b/templates/platform/pipelines/demo.yaml @@ -1,18 +1,18 @@ - name: Clean-up directory file: - path: "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ base_folder }}" + path: "{{ destination_base_path }}{{ resources.configuration_folders.destination_relative_path }}/{{ base_folder }}" state: absent - when: config.configuration_folders.cleanup_destination | bool + when: resources.configuration_folders.cleanup_destination | bool - name: Creates directory file: - path: "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ base_folder }}" + path: "{{ destination_base_path }}{{ resources.configuration_folders.destination_relative_path }}/{{ base_folder }}" state: directory - name: Symphony ansible.builtin.template: src: "{{ item }}" - dest: "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" + dest: "{{ destination_base_path }}{{ resources.configuration_folders.destination_relative_path }}/{{ base_folder }}/{{ item | basename | regex_replace('.j2$', '') }}" force: yes with_fileglob: - "{{ base_folder }}/symphony*.yaml" @@ -20,7 +20,7 @@ - name: Next steps ansible.builtin.template: src: "{{ item }}" - dest: "{{ destination_base_path }}{{ config.configuration_folders.destination_relative_path }}/{{ item | basename | regex_replace('.j2$', '') }}" + dest: "{{ destination_base_path }}{{ resources.configuration_folders.destination_relative_path }}/{{ item | basename | regex_replace('.j2$', '') }}" force: yes with_fileglob: - "{{ base_folder }}/README.md" diff --git a/templates/platform/pipelines/symphony_e2e.yaml b/templates/platform/pipelines/symphony_e2e.yaml index 0d86c0d6c..f3774b388 100644 --- a/templates/platform/pipelines/symphony_e2e.yaml +++ b/templates/platform/pipelines/symphony_e2e.yaml @@ -2,7 +2,7 @@ environment: {{ model }} repositories: - name: landingzones uri: https://github.com/Azure/caf-terraform-landingzones.git - branch: {{ config.caf_landingzone_branch }} + branch: {{ resources.caf_landingzone_branch }} # All paths are relative levels: @@ -11,8 +11,8 @@ levels: stacks: - stack: launchpad landingZonePath: landingzones/caf_launchpad - configurationPath: "{{ config.configuration_folders.destination_relative_path }}/{{ config.tfstates.platform.launchpad.level }}/{{ config.tfstates.platform.launchpad.base_config_path }}" - tfState: {{ config.tfstates.platform.launchpad.tfstate }} + configurationPath: "{{ resources.configuration_folders.destination_relative_path }}/{{ resources.tfstates.platform.launchpad.level }}/{{ resources.tfstates.platform.launchpad.base_config_path }}" + tfState: {{ resources.tfstates.platform.launchpad.tfstate }} repository: landingzones launchpad: true @@ -21,21 +21,21 @@ levels: stacks: - stack: management landingZonePath: landingzones/caf_solution - configurationPath: "{{ config.configuration_folders.destination_relative_path }}/{{ config.tfstates.platform.management.level }}/{{ config.tfstates.platform.management.base_config_path }}" - tfState: {{ config.tfstates.platform.management.tfstate }} + configurationPath: "{{ resources.configuration_folders.destination_relative_path }}/{{ resources.tfstates.platform.management.level }}/{{ resources.tfstates.platform.management.base_config_path }}" + tfState: {{ resources.tfstates.platform.management.tfstate }} repository: landingzones - - stack: eslz - landingZonePath: landingzones/caf_solution/add-ons/caf_eslz - configurationPath: "{{ config.configuration_folders.destination_relative_path }}/{{ config.tfstates.platform.eslz.level }}/{{ config.tfstates.platform.eslz.base_config_path }}" - tfState: {{ config.tfstates.platform.eslz.tfstate }} + - stack: alz + landingZonePath: landingzones/caf_solution/add-ons/caf_alz + configurationPath: "{{ resources.configuration_folders.destination_relative_path }}/{{ resources.tfstates.platform.alz.level }}/{{ resources.tfstates.platform.alz.base_config_path }}" + tfState: {{ resources.tfstates.platform.alz.tfstate }} repository: landingzones - branch: "{{ config.eslz.private_lib[config.eslz.private_lib.version_to_deploy].caf_landingzone_branch }}" + branch: "{{ resources.alz.private_lib[resources.alz.private_lib.version_to_deploy].caf_landingzone_branch }}" - level: level2 type: platform stacks: - stack: connectivity_virtual_wan landingZonePath: landingzones/caf_solution - configurationPath: "{{ config.configuration_folders.destination_relative_path }}/{{ config.tfstates.platform.management.level }}/{{ config.tfstates.platform.management.base_config_path }}" - tfState: {{ config.tfstates.platform.management.tfstate }} + configurationPath: "{{ resources.configuration_folders.destination_relative_path }}/{{ resources.tfstates.platform.management.level }}/{{ resources.tfstates.platform.management.base_config_path }}" + tfState: {{ resources.tfstates.platform.management.tfstate }} repository: landingzones \ No newline at end of file diff --git a/templates/platform/readme.md b/templates/platform/readme.md index d3b1ed5d3..b745d1cd6 100644 --- a/templates/platform/readme.md +++ b/templates/platform/readme.md @@ -1,19 +1,18 @@ # Generate the terraform configuration files -To execute this step you need to login with one of the CAF maintainers accounts: -{% for maintainer in config.platform_identity.caf_platform_maintainers %} - - {{ maintainer }} -{% endfor %} +## Deploy into a single subscription -```bash -rover login -t {{ config.platform_identity.tenant_name }} +``` +ansible-playbook /tf/caf/landingzones/templates/ansible/walk-through-single.yaml \ + -e topology_file=/tf/caf/landingzones/templates/platform/single_subscription.yaml \ + -e config_folder_platform_templates=/tf/caf/landingzones/templates/platform \ + -e platform_service_folder=/tf/caf/landingzones/templates/platform/services \ + -e public_templates_folder=/tf/caf/landingzones/templates \ + -e resource_template_folder=/tf/caf/landingzones/templates/resources \ + -e landingzones_folder=/tf/caf/landingzones \ + -e platform_configuration_folder=/tf/caf/configuration \ + -e platform_definition_folder=/tf/caf/platform/definition -rover ignite \ - --playbook /tf/caf/landingzones/templates/platform/ansible.yaml \ - -e base_templates_folder={{ base_templates_folder }} \ - -e resource_template_folder={{resource_template_folder}} \ - -e config_folder={{ config_folder }} - ``` +``` -Get started with the [launchpad](./platform/level0/launchpad) \ No newline at end of file diff --git a/templates/platform/services/README.md b/templates/platform/services/README.md new file mode 100644 index 000000000..5c99b1c20 --- /dev/null +++ b/templates/platform/services/README.md @@ -0,0 +1,58 @@ +# Cloud Adoption Framework landing zones for Terraform - Ignite the Azure Platform and landing zones + + +:rocket: START HERE: [Follow the onboarding guide from](https://aztfmod.github.io/documentation/docs/enterprise-scale/landingzones/platform/org-setup) + + +For further executions or command, you can refer to the following sections + +## Commands + +### Rover ignite the platform + +Rover ignite will process the YAML files and start building the configuration structure of the TFVARS. + +Please note that during the creation of the platform landingones you will have to run rover ignite multiple times as some deployments are required to be completed before you can perform the next steps. + +The best course of actions is to follow the readme files generated within each landing zones, as rover ignite creates the tfvars and also the documentation. + +Once you are ready to ingite, just run: + +```bash +rover login -t {{tenant_name.stdout}} -s {{subscription_id.stdout}} + +ansible-playbook {{public_templates_folder}}/ansible/ansible.yaml \ + --extra-vars "@{{platform_definition_folder}}/ignite.yaml" + +``` + +### Next step + +Once the rover ignite command has been executed, go to your configuration folder when the platform launchpad configuration has been created. + +Get started with the [launchpad]({{destination_path}}/{{topologies.launchpad.relative_destination_folder}}) + + + +## References + +Whenever needed, or under a profesional supervision you can use the following commands + +### Clone the landingzone project (Terraform base code) + +```bash +git clone https://github.com/Azure/caf-terraform-landingzones.git {{landingzones_folder}} +cd {{landingzones_folder}} && git pull +git checkout {{topology.caf_landingzone_branch}} + +``` + +### Regenerate the definition folder + +For your reference, if you need to re-generate the YAML definition files later, you can run the following command: + +```bash +ansible-playbook {{public_templates_folder}}/ansible/walk-through-single.yaml \ + --extra-vars "@{{platform_definition_folder}}/ignite.yaml" + +``` \ No newline at end of file diff --git a/templates/platform/services/alz.yaml b/templates/platform/services/alz.yaml new file mode 100644 index 000000000..def573cb5 --- /dev/null +++ b/templates/platform/services/alz.yaml @@ -0,0 +1,35 @@ +alz_{{item}}: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level1/alz/{{item}} + + + tfstate: + lz_key_name: alz_{{item}} + tfstate: alz_{{item}}.tfstate + level: level1 + identity_aad_key: cred_alz + config_file: alz_{{item}}.yaml + template_lib_folder: platform/level1/alz + sub_template_folder: platform/level1/alz + alz_version: {{topology.management_groups[region][item].version_to_deploy | default('v1.1.3')}} + yaml: platform/level1/alz/ansible.yaml + # Do not rename the item_key_name + tfstate_key_name: alz_{{item}} + + deployments: + landingzone: + global_settings_key: + platform: + launchpad: + remote_tfstates: + platform: + launchpad: + identity: + management: + subscriptions: + + # Keep the following to allow rover ignite to process the deployment. + resources: + launchpad: \ No newline at end of file diff --git a/templates/platform/services/asvm.yaml b/templates/platform/services/asvm.yaml new file mode 100644 index 000000000..d451f1817 --- /dev/null +++ b/templates/platform/services/asvm.yaml @@ -0,0 +1,98 @@ +asvm: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level2/asvm + + tfstate: + lz_key_name: asvm + tfstate: asvm_subscription_vending_machine.tfstate + level: level2 + config_file: asvm.yaml + identity_aad_key: cred_level0 + sub_template_folder: platform/level2/asvm + yaml: platform/level2/asvm/ansible.yaml + # Do not rename the tfstate_key_name + tfstate_key_name: asvm + + deployments: + landingzone: + global_settings_key: + platform: + management: + remote_tfstates: + platform: + management: + + resources: + launchpad: + resource_groups: + level3: + name: caf-level3 + tags: + level: level3 + level4: + name: caf-level4 + tags: + level: level4 + + storage_accounts: + level3: + name: l3 + resource_group_key: level3 + account_kind: BlobStorage + account_tier: Standard + shared_access_key_enabled: false + account_replication_type: GRS + blob_properties: + versioning_enabled: true + last_access_time_enabled: true + container_delete_retention_policy: + days: 7 + delete_retention_policy: + days: 7 + containers: + tfstate: + name: tfstate + tags: + ## Those tags must never be changed after being set as they are used by the rover to locate the launchpad and the tfstates. + # Only adjust the environment value at creation time + caf_environment: {{topology.caf_environment}} + caf_launchpad: launchpad + caf_tfstate: level3 + level4: + name: l4 + resource_group_key: level4 + account_kind: BlobStorage + account_tier: Standard + shared_access_key_enabled: false + account_replication_type: GRS + blob_properties: + versioning_enabled: true + last_access_time_enabled: true + container_delete_retention_policy: + days: 7 + delete_retention_policy: + days: 7 + tags: + ## Those tags must never be changed after being set as they are used by the rover to locate the launchpad and the tfstates. + # Only adjust the environment value at creation time + caf_environment: {{topology.caf_environment}} + caf_launchpad: launchpad + caf_tfstate: level4 + + keyvaults: + level3: + name: l3 + resource_group_key: level3 + level4: + name: l4 + resource_group_key: level4 + + + azuread_groups: + caf_ac_landingzone_maintainers_non_prod: + name: caf_ac_landingzone_maintainers_non_prod + + caf_ac_landingzone_maintainers_prod: + name: caf_ac_landingzone_maintainers_prod diff --git a/templates/enterprise-scale/contoso/platform/connectivity_express_route_peerings.yaml b/templates/platform/services/connectivity_express_route_peerings.yaml similarity index 100% rename from templates/enterprise-scale/contoso/platform/connectivity_express_route_peerings.yaml rename to templates/platform/services/connectivity_express_route_peerings.yaml diff --git a/templates/platform/services/connectivity_express_routes.yaml b/templates/platform/services/connectivity_express_routes.yaml new file mode 100644 index 000000000..d99aed61a --- /dev/null +++ b/templates/platform/services/connectivity_express_routes.yaml @@ -0,0 +1,22 @@ +gitops: + caf_landingzone_branch: 2203.0 + +express_route_circuits: + {{env}}: + name: er-1-{{env}} + resource_group_key: {{env}} + service_provider_name: XL Axiata + peering_location: Jakarta + tier: Standard + family: MeteredData + bandwidth_in_mbps: 50 + +express_route_circuit_authorizations: + vhub-prod: + name: er-auth-vhub-{{env}} + resource_group_key: {{env}} + + +resource_groups: + name: connectivity-express-route-{{env}} + region_key: region1 diff --git a/templates/platform/services/connectivity_firewall_policies.yaml b/templates/platform/services/connectivity_firewall_policies.yaml new file mode 100644 index 000000000..32c6172b7 --- /dev/null +++ b/templates/platform/services/connectivity_firewall_policies.yaml @@ -0,0 +1,40 @@ +azurerm_firewall_policies_{{env}}: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level2/connectivity/azurerm_firewall_policies/{{env}} + + tfstate: + lz_key_name: connectivity_firewall_policies_{{env}} + tfstate: connectivity_firewall_policies_{{env}}.tfstate + level: level2 + config_file: azurerm_firewall_policies.yaml + identity_aad_key: cred_connectivity + # Do not rename the tfstate_key_name + tfstate_key_name: azurerm_firewall_policies + + deployments: + landingzone: + global_settings_key: + platform: + virtual_wans: prod + remote_tfstates: + platform: + virtual_wans: prod + + + resources: + connectivity: + resource_groups: + firewall_policies: + name: connectivity-{{env}}-firewall-policies + region_key: region1 + + azurerm_firewall_policies: + secure_root: + name: "secure-root-policy-{{env}}" + region_key: region1 + resource_group: + key: firewall_policies + threat_intelligence_mode: "Alert" + diff --git a/templates/platform/services/connectivity_private_dns.yaml b/templates/platform/services/connectivity_private_dns.yaml new file mode 100644 index 000000000..27e739666 --- /dev/null +++ b/templates/platform/services/connectivity_private_dns.yaml @@ -0,0 +1,84 @@ +private_dns_{{env}}: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level2/connectivity/private_dns/{{env}} + + tfstate: + lz_key_name: connectivity_private_dns_{{env}} + tfstate: connectivity_private_dns_{{env}}.tfstate + level: level2 + config_file: private_dns.yaml + identity_aad_key: cred_connectivity + # Do not rename the tfstate_key_name + tfstate_key_name: private_dns + + deployments: + landingzone: + global_settings_key: + platform: + private_dns_firewalls: {{env}} + remote_tfstates: + platform: + private_dns_firewalls: {{env}} + identity_level2: {{env}} + + resources: + connectivity: + role_mapping: + custom_role_mapping: + resource_groups: + dns_connectivity_{{env}}: + landgingzone_extended: + azuread_groups: + lz_key: identity_level2_{{env}} + keys: + - caf_{{env}}_landingzones_dns_contributors + built_in_role_mapping: + resource_groups: + dns_connectivity_{{env}}: + Private DNS Zone Contributor: + azuread_groups: + lz_key: identity_level2_{{env}} + keys: + - caf_{{env}}_landingzones_dns_contributors + + custom_role_definitions: + landgingzone_extended: + name: landingzone-networking-private-dns-extended + useprefix: true + description: "({{env}}) Provides additional permissions for the level4 principal to perform activies on the level2 private dns zones for private links." + permissions: + actions: + - Microsoft.Network/privateDnsZones/join/action + - Microsoft.Network/privateEndpoints/privateDnsZoneGroups/read + - Microsoft.Network/privateEndpoints/privateDnsZoneGroups/write + + resource_groups: + dns_connectivity_{{env}}: + name: dns-connectivity-{{env}} + + private_dns: +{% for key in variables.variables_private_dns_zones.zones.keys() %} + {{key}}: + name: {{key}} + resource_group_key: dns_connectivity_{{env}} + vnet_links: + fw_{{env}}_01: + name: fw-{{env}}-01 + vnet_key: vnet + lz_key: connectivity_private_dns_firewalls_{{env}} +{% endfor %} +{% for region in topology.resources_allowed_regions %} +{% for z_key in variables.variables_private_dns_zones.regional_zones %} + {{z_key | replace('region', region)}}: + name: {{z_key | replace('region', region)}} + resource_group_key: dns_connectivity_{{env}} + vnet_links: + fw_{{env}}_01: + name: fw-{{env}}-01 + vnet_key: vnet + lz_key: connectivity_private_dns_firewalls_{{env}} +{% endfor %} +{% endfor %} + \ No newline at end of file diff --git a/templates/platform/services/connectivity_private_dns_firewalls.yaml b/templates/platform/services/connectivity_private_dns_firewalls.yaml new file mode 100644 index 000000000..ef28f11fb --- /dev/null +++ b/templates/platform/services/connectivity_private_dns_firewalls.yaml @@ -0,0 +1,93 @@ +private_dns_firewalls_{{env}}: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level2/connectivity/private_dns_firewalls/{{env}} + + tfstate: + lz_key_name: connectivity_private_dns_firewalls_{{env}} + tfstate: connectivity_private_dns_firewalls_{{env}}.tfstate + level: level2 + config_file: connectivity_private_dns_firewalls.yaml + identity_aad_key: cred_connectivity + # Do not rename the tfstate_key_name + tfstate_key_name: private_dns_firewalls + + deployments: + landingzone: + global_settings_key: + platform: + virtual_hubs: {{env}} + remote_tfstates: + platform: + virtual_hubs: {{env}} + azurerm_firewall_policies: {{env}} + + + resources: + connectivity: + resource_groups: + firewall: + name: connectivity-{{env}}-firewall + region_key: region1 + + + virtual_networks: + vnet: + name: vnet-connectivity-{{env}}-fw-plinks + resource_group_key: firewall + region_key: region1 + address_space: + {{variables.variables_cidr[deployment_mode][service]['region1'][env].address_prefixes}} + specialsubnets: + AzureFirewallSubnet: + name: AzureFirewallSubnet + cidr: + {{variables.variables_cidr[deployment_mode][service]['region1'][env].address_prefixes}} + + public_ip_addresses: + fw_pip1: + name: pip-{{env}}-fw-01 + resource_group_key: firewall + sku: Standard + allocation_method: Static + ip_version: IPv4 + idle_timeout_in_minutes: 4 + + azurerm_firewalls: + fw_{{env}}_dns: + name: fw-{{env}}-dns-01 + resource_group_key: firewall + vnet_key: vnet + sku_tier: Standard + firewall_policy: + key: private_links + zones: + - 1 + - 2 + - 3 + public_ips: + ip1: + name: pip1 + public_ip_key: fw_pip1 + vnet_key: vnet + subnet_key: AzureFirewallSubnet + + azurerm_firewall_policies: + private_links: + name: "private-links-{{env}}" + region_key: region1 + resource_group: + key: firewall + dns: + proxy_enabled: true + threat_intelligence_mode: "Alert" + + virtual_hub_connections: + vnet_to_hub: + name: vnet-connectivity-{{env}}-fw-plinks-TO-vhub-{{env}} + virtual_hub: + lz_key: connectivity_virtual_hubs_{{env}} + key: {{env}} + vnet: + vnet_key: vnet \ No newline at end of file diff --git a/templates/platform/services/connectivity_secure_firewalls.yaml b/templates/platform/services/connectivity_secure_firewalls.yaml new file mode 100644 index 000000000..07658a20c --- /dev/null +++ b/templates/platform/services/connectivity_secure_firewalls.yaml @@ -0,0 +1,50 @@ +secure_firewalls_{{env}}: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level2/connectivity/secure_firewalls/{{env}} + + tfstate: + lz_key_name: connectivity_secure_firewalls_{{env}} + tfstate: connectivity_secure_firewalls_{{env}}.tfstate + level: level2 + config_file: connectivity_secure_firewalls.yaml + identity_aad_key: cred_connectivity + # Do not rename the tfstate_key_name + tfstate_key_name: secure_firewalls + + deployments: + landingzone: + global_settings_key: + platform: + virtual_hubs: {{env}} + remote_tfstates: + platform: + virtual_hubs: {{env}} + azurerm_firewall_policies: {{env}} + + + resources: + connectivity: + resource_groups: + firewall: + name: connectivity-{{env}}-secure-firewall + region_key: region1 + azurerm_firewalls: + fw_secure_{{env}}: + name: fw-secure-{{env}} + resource_group_key: firewall + sku_name: AZFW_Hub + sku_tier: Standard + virtual_hub: + {{env}}: + lz_key: connectivity_virtual_hubs_{{env}} + virtual_hub_key: {{env}} + public_ip_count: 1 + firewall_policy: + key: secure_root + lz_key: connectivity_firewall_policies_{{env}} + zones: + - 1 + - 2 + - 3 \ No newline at end of file diff --git a/templates/platform/services/connectivity_virtual_hubs.yaml b/templates/platform/services/connectivity_virtual_hubs.yaml new file mode 100644 index 000000000..9e213e25b --- /dev/null +++ b/templates/platform/services/connectivity_virtual_hubs.yaml @@ -0,0 +1,64 @@ +virtual_hubs_{{env}}: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level2/connectivity/virtual_hubs/{{env}} + + tfstate: + lz_key_name: connectivity_virtual_hubs_{{env}} + tfstate: connectivity_virtual_hubs_{{env}}.tfstate + workspace: tfstate + level: level2 + config_file: virtual_hubs.yaml + identity_aad_key: cred_connectivity + # Do not rename the tfstate_key_name + tfstate_key_name: virtual_hubs + + deployments: + landingzone: + global_settings_key: + platform: + virtual_wans: prod + remote_tfstates: + platform: + virtual_wans: prod + custom_variables: + virtual_hub_lz_key: connectivity_virtual_hubs_{{env}} + # ddos_protection_plan_id: + + resources: + connectivity: + virtual_hubs: + {{env}}: + name: {{env | replace('_', '-')}} + virtual_wan: + lz_key: connectivity_virtual_wans_prod + key: global_wan + region_key: region1 + hub_address_prefix: {{variables.variables_cidr[deployment_mode][service]['region1'][env].address_prefix}} + deploy_s2s: false + s2s_config: + name: {{env}} + scale_unit: 1 + deploy_er: false + er_config: + name: {{env}} + scale_units: 1 + deploy_p2s: false + p2s_config: + name: {{env}} + scale_units: 1 + + express_route_connections: + {{env}}: + enable_er_connections: false + name: er-1-{{env}} + virtual_hub: + key: {{env}} + circuit_peering: + tfstate_key: {{env}} + key: private_peering + express_route_circuit_authorization: + tfstate_key: {{env}} + key: vhub-{{env}} + diff --git a/templates/platform/services/connectivity_virtual_hubs_route_tables.yaml b/templates/platform/services/connectivity_virtual_hubs_route_tables.yaml new file mode 100644 index 000000000..842bdb6cc --- /dev/null +++ b/templates/platform/services/connectivity_virtual_hubs_route_tables.yaml @@ -0,0 +1,45 @@ +virtual_hubs_route_tables_{{env}}: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level2/connectivity/virtual_hubs_route_tables/{{env}} + + tfstate: + lz_key_name: virtual_hubs_route_tables_{{env}} + tfstate: connectivity_virtual_hubs_route_tables_{{env}}.tfstate + workspace: tfstate + level: level2 + config_file: virtual_hubs_route_tables.yaml + identity_aad_key: cred_connectivity + # Do not rename the tfstate_key_name + tfstate_key_name: virtual_hubs_route_tables + + deployments: + landingzone: + global_settings_key: + platform: + virtual_hubs: {{env}} + remote_tfstates: + platform: + virtual_hubs: {{env}} + secure_firewalls: {{env}} + private_dns_firewalls: {{env}} + + resources: + connectivity: + virtual_hub_route_tables: + egress_internet: + name: egress-internet + virtual_hub: + lz_key: connectivity_virtual_hubs_{{env}} + key: {{env}} + routes: + egress_internet: + name: egress-internet + destinations_type: CIDR + destinations: + - 0.0.0.0/0 + next_hop: + lz_key: connectivity_secure_firewalls_{{env}} + resource_type: azurerm_firewalls + key: fw_secure_{{env}} diff --git a/templates/platform/services/connectivity_virtual_wans.yaml b/templates/platform/services/connectivity_virtual_wans.yaml new file mode 100644 index 000000000..dda25ab55 --- /dev/null +++ b/templates/platform/services/connectivity_virtual_wans.yaml @@ -0,0 +1,37 @@ +virtual_wans_{{env}}: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level2/connectivity/virtual_wans + + tfstate: + lz_key_name: connectivity_virtual_wans_{{env}} + tfstate: connectivity_virtual_wans_{{env}}.tfstate + level: level2 + config_file: virtual_wans.yaml + identity_aad_key: cred_connectivity + # Do not rename the tfstate_key_name + tfstate_key_name: virtual_wans + + deployments: + landingzone: + global_settings_key: + platform: + management: + remote_tfstates: + platform: + management: + + resources: + connectivity: + virtual_wans: + global_wan: + name: vwan + resource_group_key: global_wan + region_key: region1 + + resource_groups: + global_wan: + name: connectivity-global-wan + region_key: region1 + diff --git a/templates/enterprise-scale/contoso/platform/connectivity_vpn_gateway_connections.yaml b/templates/platform/services/connectivity_vpn_gateway_connections.yaml similarity index 50% rename from templates/enterprise-scale/contoso/platform/connectivity_vpn_gateway_connections.yaml rename to templates/platform/services/connectivity_vpn_gateway_connections.yaml index c8eeeee61..d1b46ade7 100644 --- a/templates/enterprise-scale/contoso/platform/connectivity_vpn_gateway_connections.yaml +++ b/templates/platform/services/connectivity_vpn_gateway_connections.yaml @@ -25,29 +25,4 @@ vpn_gateway_connections: pfs_group: None sa_data_size_kb: 102400000 sa_lifetime_sec: 3600 - non_prod: - name: production - internet_security_enabled: true - vpn_site: - key: non_prod - virtual_hub: - lz_key: connectivity_virtual_hub_non_prod - key: non_prod - vpn_links: - non_prod: - name: non_prod - shared_key: - bgp_enabled: false - bandwidth_mbps: 100 - link_index: 0 - protocol: IKEv2 - ipsec_policies: - policy1: - dh_group: DHGroup24 - ike_encryption_algorithm: AES256 - ike_integrity_algorithm: SHA256 - encryption_algorithm: AES256 - integrity_algorithm: SHA256 - pfs_group: None - sa_data_size_kb: 102400000 - sa_lifetime_sec: 3600 + diff --git a/templates/enterprise-scale/contoso/platform/connectivity_vpn_sites.yaml b/templates/platform/services/connectivity_vpn_sites.yaml similarity index 100% rename from templates/enterprise-scale/contoso/platform/connectivity_vpn_sites.yaml rename to templates/platform/services/connectivity_vpn_sites.yaml diff --git a/templates/platform/services/identity.yaml b/templates/platform/services/identity.yaml new file mode 100644 index 000000000..08a4c97a6 --- /dev/null +++ b/templates/platform/services/identity.yaml @@ -0,0 +1,65 @@ +identity: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level1/identity + + tfstate: + lz_key_name: identity + tfstate: identity.tfstate + level: level1 + identity_aad_key: cred_identity + config_file: identity.yaml + sub_template_folder: platform/level1/identity + # Do not rename the tfstate_key_name + tfstate_key_name: identity + + deployments: + landingzone: + global_settings_key: + platform: + launchpad: + remote_tfstates: + platform: + launchpad: + + resources: + identity: + resource_groups: + management: + name: management + alerts: + name: alerts + + service_health_alerts: + enable_service_health_alerts: true + name: alerts + shortname: HealthAlerts + resource_group_key: alerts + action_group_name: actiongrp + email_alert_settings: + support1: + name: email_alert_support1 + email_address: {{topology.notifications.service_health_alerts}} + use_common_alert_schema: false + + recovery_vaults: + asr: + name: asr + resource_group_key: management + soft_delete_enabled: true + backup_policies: + {{topology.backup_policies | to_nice_yaml(width=80, indent=2) | indent(12)}} + +# Bring here you existing active directory security groups. +# Those are the groups you will inject to RBAC in the Enterprise Scale deployment. +# Note Terraform will create a new Azure AD group and add the existing as a member + + # azuread_groups: + # network_ops_team: + # name: netops + # members: + # # Set the list of the existing groups + # objects_ids: + # - existing_azure_ad_group_object_id + diff --git a/templates/platform/services/identity_level2.yaml b/templates/platform/services/identity_level2.yaml new file mode 100644 index 000000000..70b036ce7 --- /dev/null +++ b/templates/platform/services/identity_level2.yaml @@ -0,0 +1,30 @@ +identity_level2_{{env}}: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level2/identity/{{env}} + + tfstate: + lz_key_name: identity_level2_{{env}} + tfstate: identity_level2_{{env}}.tfstate + level: level2 + config_file: identity_level2.yaml + identity_aad_key: cred_identity + # Do not rename the tfstate_key_name + tfstate_key_name: identity_level2 + + + deployments: + landingzone: + global_settings_key: + platform: + identity: + remote_tfstates: + platform: + identity: + + resources: + identity: + azuread_groups: + caf_{{env}}_landingzones_dns_contributors: + name: caf ac {{env}} landingzones dns contributors \ No newline at end of file diff --git a/templates/platform/services/identity_level2_aadds.yaml b/templates/platform/services/identity_level2_aadds.yaml new file mode 100644 index 000000000..e39413ba1 --- /dev/null +++ b/templates/platform/services/identity_level2_aadds.yaml @@ -0,0 +1,178 @@ +identity_level2_aadds_{{env}}: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level2/identity/aadds + + tfstate: + lz_key_name: connectivity_virtual_wans_{{env}} + tfstate: connectivity_virtual_wans_{{env}}.tfstate + level: level2 + config_file: virtual_wans.yaml + identity_aad_key: cred_connectivity + # Do not rename the tfstate_key_name + tfstate_key_name: virtual_wans + + deployments: + landingzone: + global_settings_key: + platform: + virtual_hubs: {{env}} + remote_tfstates: + platform: + management: + virtual_hubs: {{env}} + identity_level2: {{env}} + + resources: + identity: + resource_groups: + rg: + name: identity-{{env}}-aadds + region_key: region1 + + + virtual_networks: + vnet: + name: vnet-identity-{{env}}-aadds + resource_group_key: rg + region_key: region1 + address_space: + - 10.10.100.0/27 + dns_servers: + - 10.10.100.4 + - 10.10.100.5 + subnets: + aadds: + name: snet-aadds + cidr: + - 10.10.100.0/28 + nsg_key: aadds_re1 + management: + name: snet-aadds-management + cidr: + - 10.10.100.16/28 + + virtual_hub_connections: + vnet_to_hub: + name: vnet-identity-{{env}}-aadds-TO-vhub-{{env}} + virtual_hub: + lz_key: connectivity_virtual_hub_{{env}} + key: {{env}} + vnet: + vnet_key: vnet + + active_directory_domain_service: + aadds: + name: aadds + region: region1 + resource_group: + key: rg + domain_name: aadds-contoso.net + sku: Standard + filtered_sync_enabled: false + initial_replica_set: + region: region1 + subnet: + vnet_key: vnet + key: aadds + notifications: + additional_recipients: + - notifyA@example.net + - notifyB@example.net + notify_dc_admins: true + notify_global_admins: false + security: + ntlm_v1_enabled: false + sync_kerberos_passwords: true + sync_ntlm_passwords: false + sync_on_prem_passwords: true + tls_v1_enabled: false + + azuread_groups: + aad_dc_administrators: + name: AAD DC Administrators + prevent_duplicate_name: true + + network_security_group_definition: + aadds_re1: + version: 1 + resource_group_key: rg + region: region1 + name: nsg-aadds-re1 + nsg: + Inbound: + 400: + name: Debugging for support. + access: Allow + protocol: tcp + source_port_range: "*" + destination_port_range: "3389" + source_address_prefix: CorpNetSaw + destination_address_prefix: "*" + 401: + name: Powershell remoting. + access: Allow + protocol: tcp + source_port_range: "*" + destination_port_range: "5986" + source_address_prefix: AzureActiveDirectoryDomainServices + destination_address_prefix: "*" + Outbound: + 400: + name: Communication with the Azure AD Domain Services management service. + access: Allow + protocol: tcp + source_port_range: "*" + destination_port_range: "443" + source_address_prefix: "*" + destination_address_prefix: "AzureActiveDirectoryDomainServices" + 401: + name: Monitoring of the virtual machines. + access: Allow + protocol: tcp + source_port_range: "*" + destination_port_range: "443" + source_address_prefix: "*" + destination_address_prefix: "AzureMonitor" + 402: + name: Communication with Azure Storage. + access: Allow + protocol: tcp + source_port_range: "*" + destination_port_range: "443" + source_address_prefix: "*" + destination_address_prefix: "Storage" + 403: + name: Communication with Azure Active Directory. + access: Allow + protocol: tcp + source_port_range: "*" + destination_port_range: "443" + source_address_prefix: "*" + destination_address_prefix: "AzureActiveDirectory" + 404: + name: Communication with Windows Update. + access: Allow + protocol: tcp + source_port_range: "*" + destination_port_range: "443" + source_address_prefix: "*" + destination_address_prefix: "AzureUpdateDelivery" + 405: + name: Download of patches from Windows Update. + access: Allow + protocol: tcp + source_port_range: "*" + destination_port_range: "443" + source_address_prefix: "*" + destination_address_prefix: "AzureFrontDoor.FirstParty" + 406: + name: Automated management of security patches. + access: Allow + protocol: tcp + source_port_range: "*" + destination_port_range: "443" + source_address_prefix: "*" + destination_address_prefix: "GuestAndHybridManagement" + diff --git a/templates/platform/services/identity_level2_adds.yaml b/templates/platform/services/identity_level2_adds.yaml new file mode 100644 index 000000000..4db290b64 --- /dev/null +++ b/templates/platform/services/identity_level2_adds.yaml @@ -0,0 +1,404 @@ +identity_level2_adds_{{env}}: + gitops: + landingzones: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level2/identity/adds/{{env}} + + deployments: + landingzone: + global_settings_key: + platform: + virtual_hubs: {{env}} + remote_tfstates: + platform: + management: + virtual_hubs: {{env}} + identity: + + tfstate: + lz_key_name: identity_level2_adds_{{env}} + tfstate: identity_level2_adds_{{env}}.tfstate + level: level2 + config_file: identity_level2_adds.yaml + identity_aad_key: cred_identity + # Do not rename the tfstate_key_name + tfstate_key_name: identity_level2_adds + + resources: + identity: + resource_groups: + rg: + name: identity-{{env}}-adds + region_key: region1 + + virtual_networks: + vnet: + name: identity-{{env}}-adds + resource_group_key: rg + region_key: region1 + address_space: + - 10.10.100.0/27 + dns_servers: + - 10.10.100.4 + - 10.10.100.5 + subnets: + adds: + name: snet-adds + cidr: + - 10.10.100.0/28 + nsg_key: adds_re1 + management: + name: snet-adds-management + cidr: + - 10.10.100.16/28 + + keyvaults: + adds_credentials: + name: addskv + resource_group_key: rg + sku_name: premium + purge_protection_enabled: false + creation_policies: + logged_in_user: + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + + dynamic_keyvault_secrets: + adds_credentials: + vmadmin-username: + secret_name: vmadmin-username + value: vmadmin + vmadmin-password: + secret_name: vmadmin-password + value: Very@Str5ngP!44w0rdToChaNge# + + virtual_machines: + adds1: + resource_group: + key: rg + region: region1 + os_type: windows + keyvault_key: adds_credentials + backup: + vault_key: asr + policy_key: default + lz_key: identity + + virtual_machine_settings: + windows: + computer_name: adds1 + name: adds1 + admin_password_key: vmadmin-password + admin_username_key: vmadmin-username + network_interface_keys: + - nic0 + provision_vm_agent: true + size: Standard_F2 + zone: 1 + os_disk: + name: adds1-os + caching: ReadWrite + storage_account_type: Standard_LRS + disk_size_gb: 128 + # identity: + # type: SystemAssigned, UserAssigned + # managed_identity_keys: + # - id1 + # remote: + # lz_key_name1: + # managed_identity_keys: + # - id2 + # - id3 + # lz_key_name2: + # managed_identity_keys: + # - id4 + # - id5 + + # custom_image_id: + + source_image_reference: + publisher: MicrosoftWindowsServer + offer: WindowsServer + sku: 2019-Datacenter + version: latest + + data_disks: + lun1: + name: adds1-data1 + lun: "1" + caching: None + storage_account_type: Standard_LRS + create_option: Empty + disk_size_gb: 10 + zones: + - "1" + + networking_interfaces: + nic0: + name: 0 + vnet_key: vnet + subnet_key: adds + enable_ip_forwarding: false + internal_dns_name_label: adds1-nic0 + private_ip_address_allocation: Static + private_ip_address: 10.10.100.4 + primary: true + tags: + adds: "ok" + dns_servers: + # - Set on-prem dns + - 10.10.100.5 + network_security_group: + key: adds_re1 + # ip_configurations: + # conf2: + # name: 0-conf + # vnet_key: vnet + # subnet_key: management + # enable_ip_forwarding: false + # private_ip_address_allocation: Static + # private_ip_address: 10.10.100.20 + + adds2: + resource_group: + key: rg + region: region1 + os_type: windows + keyvault_key: adds_credentials + backup: + vault_key: asr + policy_key: default + lz_key: identity_level2 + + virtual_machine_settings: + windows: + computer_name: adds2 + name: adds2 + admin_password_key: vmadmin-password + admin_username_key: vmadmin-username + network_interface_keys: + - nic0 + provision_vm_agent: true + size: Standard_F2 + zone: 2 + os_disk: + name: adds2-os + caching: ReadWrite + storage_account_type: Standard_LRS + disk_size_gb: 128 + # identity: + # type: SystemAssigned, UserAssigned + # managed_identity_keys: + # - id1 + # remote: + # lz_key_name1: + # managed_identity_keys: + # - id2 + # - id3 + # lz_key_name2: + # managed_identity_keys: + # - id4 + # - id5 + + + source_image_reference: + publisher: MicrosoftWindowsServer + offer: WindowsServer + sku: 2019-Datacenter + version: latest + + data_disks: + lun1: + name: adds2-data1 + lun: "1" + storage_account_type: Standard_LRS + create_option: Empty + disk_size_gb: 10 + zones: + - "2" + + networking_interfaces: + nic0: + name: 0 + vnet_key: vnet + subnet_key: adds + enable_ip_forwarding: false + internal_dns_name_label: adds2-nic0 + private_ip_address_allocation: Static + private_ip_address: 10.10.100.5 + primary: true + tags: + adds: "ok" + dns_servers: + # - Set on-prem ADDS dns + - 10.10.100.4 + network_security_group: + key: adds_re1 + # ip_configurations: + # conf2: + # name: 0-conf + # vnet_key: vnet + # subnet_key: management + # enable_ip_forwarding: false + # private_ip_address_allocation: Static + # private_ip_address: 10.10.100.21 + + virtual_hub_connections: + vnet_to_hub: + name: vnet-identity-prod-adds-TO-vhub-prod + virtual_hub: + lz_key: connectivity_virtual_hub_prod + key: prod + vnet: + vnet_key: vnet + + network_security_group_definition: + adds_re1: + version: 1 + resource_group_key: rg + region: region1 + name: nsg-adds-re1 + # Reference - https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/config-firewall-for-ad-domains-and-trusts + # following is for Windows Server 2008 and later + nsg: + Inbound: + 400: + name: W32Time. + access: Allow + protocol: udp + source_address_prefix: "VirtualNetwork" + # source_address_prefixes: + # - on-prem CIDR for ADDS + source_port_range: "49152-65535" + destination_port_range: "123" + destination_address_prefix: "*" + 401: + name: RPC Endpoint Mapper. + access: Allow + protocol: tcp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "135" + destination_address_prefix: "*" + 402: + name: Kerberos password change tcp. + access: Allow + protocol: tcp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "464" + destination_address_prefix: "*" + 403: + name: Kerberos password change udp. + access: Allow + protocol: udp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "464" + destination_address_prefix: "*" + 404: + name: RPC for LSA, SAM, NetLogon. + access: Allow + protocol: tcp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "49152-65535" + destination_address_prefix: "*" + 405: + name: LDAP-tcp. + access: Allow + protocol: tcp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "389" + destination_address_prefix: "*" + 406: + name: LDAP-udp. + access: Allow + protocol: udp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "389" + destination_address_prefix: "*" + 407: + name: LDAP SSL. + access: Allow + protocol: tcp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "636" + destination_address_prefix: "*" + 408: + name: LDAP GC. + access: Allow + protocol: tcp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "3268" + destination_address_prefix: "*" + 409: + name: LDAP GC SSL. + access: Allow + protocol: tcp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "3269" + destination_address_prefix: "*" + 410: + name: DNS tcp. + access: Allow + protocol: tcp + source_address_prefix: "VirtualNetwork" + source_port_ranges: + - "53" + - "49152-65535" + destination_port_range: "53" + destination_address_prefix: "*" + 411: + name: DNS udp. + access: Allow + protocol: udp + source_address_prefix: "VirtualNetwork" + source_port_ranges: + - "53" + - "49152-65535" + destination_port_range: "53" + destination_address_prefix: "*" + 412: + name: Kerberos tcp. + access: Allow + protocol: tcp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "88" + destination_address_prefix: "*" + 413: + name: Kerberos udp. + access: Allow + protocol: udp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "88" + destination_address_prefix: "*" + 414: + name: SMB. + access: Allow + protocol: tcp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "445" + destination_address_prefix: "*" + # Adjust the following based on your RPC custom ports configuration + 415: + name: FRS RPC. + access: Allow + protocol: tcp + source_address_prefix: "VirtualNetwork" + source_port_range: "49152-65535" + destination_port_range: "49152-65535" + destination_address_prefix: "*" \ No newline at end of file diff --git a/templates/platform/services/launchpad_azuread_sp_single_subscription.yaml b/templates/platform/services/launchpad_azuread_sp_single_subscription.yaml new file mode 100644 index 000000000..46b2a0bd4 --- /dev/null +++ b/templates/platform/services/launchpad_azuread_sp_single_subscription.yaml @@ -0,0 +1,519 @@ +launchpad: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level0/launchpad + + tfstate: + lz_key_name: launchpad + tfstate: caf_launchpad.tfstate + workspace: tfstate + level: level0 + identity_aad_key: cred_level0 + config_file: launchpad.yaml + sub_template_folder: platform/level0/launchpad + yaml: platform/level0/launchpad/ansible.yaml + # Do not rename the tfstate_key_name + tfstate_key_name: launchpad + + deployments: + landingzone: + + resources: + launchpad: + resource_groups: + level0: + name: caf-level0 + level1: + name: caf-level1 + level2: + name: caf-level2 + + storage_accounts: + level0: + name: l0 + resource_group_key: level0 + account_kind: BlobStorage + account_tier: Standard + shared_access_key_enabled: false + account_replication_type: GRS + blob_properties: + versioning_enabled: true + last_access_time_enabled: true + container_delete_retention_policy: + days: 7 + delete_retention_policy: + days: 7 + containers: + tfstate: + name: tfstate + tags: + ## Those tags must never be changed after being set as they are used by the rover to locate the launchpad and the tfstates. + # Only adjust the environment value at creation time + caf_environment: {{topology.caf_environment}} + caf_launchpad: launchpad + caf_tfstate: level0 + level1: + name: l1 + resource_group_key: level1 + account_kind: BlobStorage + account_tier: Standard + shared_access_key_enabled: false + account_replication_type: GRS + blob_properties: + versioning_enabled: true + last_access_time_enabled: true + container_delete_retention_policy: + days: 7 + delete_retention_policy: + days: 7 + containers: + tfstate: + name: tfstate + tags: + ## Those tags must never be changed after being set as they are used by the rover to locate the launchpad and the tfstates. + # Only adjust the environment value at creation time + caf_environment: {{topology.caf_environment}} + caf_launchpad: launchpad + caf_tfstate: level1 + level2: + name: l2 + resource_group_key: level2 + account_kind: BlobStorage + account_tier: Standard + shared_access_key_enabled: false + account_replication_type: GRS + blob_properties: + versioning_enabled: true + last_access_time_enabled: true + container_delete_retention_policy: + days: 7 + delete_retention_policy: + days: 7 + containers: + tfstate: + name: tfstate + tags: + ## Those tags must never be changed after being set as they are used by the rover to locate the launchpad and the tfstates. + # Only adjust the environment value at creation time + caf_environment: {{topology.caf_environment}} + caf_launchpad: launchpad + caf_tfstate: level2 + + role_mapping: + built_in_role_mapping: + management_group: + # if you are using a root_parent_id, replace the following root by the root_parent_id value + root: + User Access Administrator: + azuread_groups: + keys: + - level0 + Management Group Contributor: + azuread_groups: + keys: + - alz + - caf_platform_maintainers + Owner: + azuread_groups: + keys: + - alz + - caf_platform_maintainers + - connectivity # only when deploying in single subscription + - identity # only when deploying in single subscription + - management # only when deploying in single subscription + - subscription_creation_landingzones # # only when deploying in single subscription + Reader: + azuread_groups: + keys: + - caf_platform_contributors + subscriptions: + logged_in_subscription: + Owner: + azuread_groups: + keys: + - level0 + - subscription_creation_platform + - caf_platform_maintainers + Reader: + azuread_groups: + keys: + - identity + resource_groups: + level0: + Reader: + azuread_groups: + keys: + - identity + - subscription_creation_platform + - caf_platform_contributors + level1: + Reader: + azuread_groups: + keys: + - identity + - management + - alz + - subscription_creation_platform + - caf_platform_contributors + level2: + Reader: + azuread_groups: + keys: + - identity + - management + - connectivity + - subscription_creation_platform + - caf_platform_contributors + + storage_accounts: + level0: + Storage Blob Data Contributor: + azuread_groups: + keys: + - level0 + - identity + - caf_platform_maintainers + Storage Blob Data Reader: + azuread_groups: + keys: + - management + - alz + - subscription_creation_platform + - caf_platform_contributors + level1: + Storage Blob Data Contributor: + azuread_groups: + keys: + - caf_platform_maintainers + - identity + - management + - alz + - subscription_creation_platform + Storage Blob Data Reader: + azuread_groups: + keys: + - connectivity + - caf_platform_contributors + - level0 + level2: + Storage Blob Data Contributor: + azuread_groups: + keys: + - identity + - connectivity + - management + - caf_platform_maintainers + - level0 + Storage Blob Data Reader: + azuread_groups: + keys: + - subscription_creation_landingzones + - caf_platform_contributors + + keyvaults: + level0: + name: l0 + sku_name: premium + resource_group_key: level0 + level1: + name: l1 + sku_name: premium + resource_group_key: level1 + level2: + name: l2 + sku_name: premium + resource_group_key: level2 + + keyvault_access_policies: + level0: + sp_level0: + azuread_group_key: level0 + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + identity: + azuread_group_key: identity + secret_permissions: + - Get + level1: + sp_level0: + azuread_group_key: level0 + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + identity: + azuread_group_key: identity + secret_permissions: + - Get + management: + azuread_group_key: management + secret_permissions: + - Get + alz: + azuread_group_key: alz + secret_permissions: + - Get + subscription_creation_platform: + azuread_group_key: subscription_creation_platform + secret_permissions: + - Get + level2: + sp_level0: + azuread_group_key: level0 + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + identity: + azuread_group_key: identity + secret_permissions: + - Get + management: + azuread_group_key: management + secret_permissions: + - Get + connectivity: + azuread_group_key: connectivity + secret_permissions: + - Get + subscription_creation_platform: + azuread_group_key: subscription_creation_platform + secret_permissions: + - Get + + azuread_applications: + level0: + application_name: sp-caf-level0 + identity: + application_name: sp-caf-identity + management: + application_name: sp-caf-management + alz: + application_name: sp-caf-alz + connectivity: + application_name: sp-caf-connectivity + subscription_creation_platform: + application_name: sp-caf-subscription_creation_platform + subscription_creation_landingzones: + application_name: sp-caf-subscription_creation_landingzones + + azuread_service_principals: + # Manage the deployment of the level0 + level0: + azuread_application: + key: level0 + # Manage the deployment of Enterprise Scale + alz: + azuread_application: + key: alz + # Manage the deployment of the connectivity services + connectivity: + azuread_application: + key: connectivity + # Manage the deployment of the shared services + management: + azuread_application: + key: management + # Manage the deployment of the identity services + identity: + azuread_application: + key: identity + # Has delegation to create platform subscriptions + subscription_creation_platform: + azuread_application: + key: subscription_creation_platform + # Has delegation to create landingzone subscriptions + subscription_creation_landingzones: + azuread_application: + key: subscription_creation_landingzones + + azuread_api_permissions: + level0: + microsoft_graph: + resource_app_id: 00000003-0000-0000-c000-000000000000 + resource_access: + AppRoleAssignment_ReadWrite_All: + id: 06b708a9-e830-4db3-a914-8e69da51d44f + type: Role + DelegatedPermissionGrant_ReadWrite_All: + id: 8e8e4742-1d95-4f68-9d56-6ee75648c72a + type: Role + Application_ReadWrite_OwnedBy: + id: 18a4783c-866b-4cc7-a460-3d5e5662c884 + type: Role + identity: + active_directory_graph: + resource_app_id: 00000002-0000-0000-c000-000000000000 + resource_access: + Application_ReadWrite_OwnedBy: + id: 824c81eb-e3f8-4ee6-8f6d-de7f50d565b7 + type: Role + Directory_ReadWrite_All: + id: 78c8a3c8-a07e-4b9e-af1b-b5ccab50a175 + type: Role + microsoft_graph: + resource_app_id: 00000003-0000-0000-c000-000000000000 + resource_access: + AppRoleAssignment_ReadWrite_All: + id: 06b708a9-e830-4db3-a914-8e69da51d44f + type: Role + DelegatedPermissionGrant_ReadWrite_All: + id: 8e8e4742-1d95-4f68-9d56-6ee75648c72a + type: Role + GroupReadWriteAll: + id: 62a82d76-70ea-41e2-9197-370581804d09 + type: Role + RoleManagement_ReadWrite_Directory: + id: 9e3f62cf-ca93-4989-b6ce-bf83c28f9fe8 + type: Role + + azuread_roles: + azuread_service_principals: + level0: + roles: + - Privileged Role Administrator + - Application Administrator + - Groups Administrator + identity: + roles: + - User Administrator + - Application Administrator + - Groups Administrator + subscription_creation_landingzones: + roles: + - Application Administrator + - Groups Administrator + + dynamic_keyvault_secrets: + level0: + subscription_id: + output_key: client_config + attribute_key: subscription_id + secret_name: subscription-id + tenant_id: + output_key: client_config + attribute_key: tenant_id + secret_name: tenant-id + level1: + lower_stg: + output_key: storage_accounts + resource_key: level0 + attribute_key: name + secret_name: lower-storage-account-name + lower_rg: + output_key: resource_groups + resource_key: level0 + attribute_key: name + secret_name: lower-resource-group-name + subscription_id: + output_key: client_config + attribute_key: subscription_id + secret_name: subscription-id + tenant_id: + output_key: client_config + attribute_key: tenant_id + secret_name: tenant-id + level2: + lower_stg: + output_key: storage_accounts + resource_key: level1 + attribute_key: name + secret_name: lower-storage-account-name + lower_rg: + output_key: resource_groups + resource_key: level1 + attribute_key: name + secret_name: lower-resource-group-name + subscription_id: + output_key: client_config + attribute_key: subscription_id + secret_name: subscription-id + tenant_id: + output_key: client_config + attribute_key: tenant_id + secret_name: tenant-id + + azuread_groups: + caf_platform_maintainers: + name: caf-platform-maintainers + description: High privileged group to run all CAF deployments from vscode. Can be used to bootstrap or troubleshoot deployments. + prevent_duplicate_name: true + owners: + - {{topology.ea_owner_object_id}} + caf_platform_contributors: + name: caf-platform-contributors + description: Can only execute terraform plans for level1 and level2. They can test platform improvements and propose PR. + prevent_duplicate_name: true + owners: + - {{topology.ea_owner_object_id}} + level0: + name: caf-level0 + prevent_duplicate_name: true + owners: + - {{topology.ea_owner_object_id}} + members: + azuread_service_principal_keys: + - level0 + alz: + name: caf-alz + prevent_duplicate_name: true + owners: + - {{topology.ea_owner_object_id}} + members: + azuread_service_principal_keys: + - alz + identity: + name: caf-identity + prevent_duplicate_name: true + owners: + - {{topology.ea_owner_object_id}} + members: + azuread_service_principal_keys: + - identity + management: + name: caf-management + prevent_duplicate_name: true + owners: + - {{topology.ea_owner_object_id}} + members: + azuread_service_principal_keys: + - management + connectivity: + name: caf-connectivity + prevent_duplicate_name: true + owners: + - {{topology.ea_owner_object_id}} + members: + azuread_service_principal_keys: + - connectivity + subscription_creation_platform: + name: caf-subscription_creation_platform + prevent_duplicate_name: true + owners: + - {{topology.ea_owner_object_id}} + members: + azuread_service_principal_keys: + - subscription_creation_platform + subscription_creation_landingzones: + name: caf-subscription_creation_landingzones + prevent_duplicate_name: true + owners: + - {{topology.ea_owner_object_id}} + members: + azuread_service_principal_keys: + - subscription_creation_landingzones + # object_ids: + # - + diff --git a/templates/platform/services/launchpad_credentials_azuread_sp.yaml b/templates/platform/services/launchpad_credentials_azuread_sp.yaml new file mode 100644 index 000000000..16c596780 --- /dev/null +++ b/templates/platform/services/launchpad_credentials_azuread_sp.yaml @@ -0,0 +1,467 @@ +launchpad_credentials: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level0/credentials + + tfstate: + lz_key_name: launchpad_credentials + tfstate: launchpad_credentials.tfstate + level: level0 + identity_aad_key: cred_identity + config_file: credentials.yaml + sub_template_folder: platform/level0/credentials + # Do not rename the tfstate_key_name + tfstate_key_name: launchpad_credentials + + deployments: + landingzone: + global_settings_key: + platform: + launchpad: + remote_tfstates: + platform: + launchpad: + + + resources: + launchpad_credentials: + resource_groups: + sp_credentials: + name: credentials + + keyvaults: + cred_ea_account_owner: + name: eaowner + resource_group_key: sp_credentials + purge_protection_enabled: false + tags: + caf_environment: {{topology.caf_environment}} + caf_identity_aad_key: cred_ea_account_owner + creation_policies: + caf_platform_maintainers: + lz_key: launchpad + azuread_group_key: caf_platform_maintainers + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + identity_azuread_group: + lz_key: launchpad + azuread_group_key: identity + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + cred_level0: + name: idl0 + resource_group_key: sp_credentials + purge_protection_enabled: false + tags: + caf_environment: {{topology.caf_environment}} + caf_identity_aad_key: cred_level0 + creation_policies: + caf_platform_maintainers: + lz_key: launchpad + azuread_group_key: caf_platform_maintainers + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + identity_azuread_group: + lz_key: launchpad + azuread_group_key: identity + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + level0: + lz_key: launchpad + azuread_group_key: level0 + secret_permissions: + - Get + cred_identity: + name: id + resource_group_key: sp_credentials + purge_protection_enabled: false + tags: + caf_environment: {{topology.caf_environment}} + caf_identity_aad_key: cred_identity + creation_policies: + caf_platform_maintainers: + lz_key: launchpad + azuread_group_key: caf_platform_maintainers + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + identity_azuread_group: + lz_key: launchpad + azuread_group_key: identity + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + cred_management: + name: mg + resource_group_key: sp_credentials + purge_protection_enabled: false + tags: + caf_environment: {{topology.caf_environment}} + caf_identity_aad_key: cred_management + creation_policies: + caf_platform_maintainers: + lz_key: launchpad + azuread_group_key: caf_platform_maintainers + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + identity_azuread_group: + lz_key: launchpad + azuread_group_key: identity + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + management_azuread_group: + lz_key: launchpad + azuread_group_key: management + secret_permissions: + - Get + cred_alz: + name: es + resource_group_key: sp_credentials + purge_protection_enabled: false + tags: + caf_environment: {{topology.caf_environment}} + caf_identity_aad_key: cred_alz + creation_policies: + caf_platform_maintainers: + lz_key: launchpad + azuread_group_key: caf_platform_maintainers + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + identity_azuread_group: + lz_key: launchpad + azuread_group_key: identity + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + alz_azuread_group: + lz_key: launchpad + azuread_group_key: alz + secret_permissions: + - Get + cred_connectivity: + name: co + resource_group_key: sp_credentials + purge_protection_enabled: false + tags: + caf_environment: {{topology.caf_environment}} + caf_identity_aad_key: cred_connectivity + creation_policies: + caf_platform_maintainers: + lz_key: launchpad + azuread_group_key: caf_platform_maintainers + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + identity_azuread_group: + lz_key: launchpad + azuread_group_key: identity + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + connectivity_azuread_group: + lz_key: launchpad + azuread_group_key: connectivity + secret_permissions: + - Get + cred_subscription_creation_platform: + name: scp + resource_group_key: sp_credentials + purge_protection_enabled: false + tags: + caf_environment: {{topology.caf_environment}} + caf_identity_aad_key: cred_subscription_creation_platform + creation_policies: + caf_platform_maintainers: + lz_key: launchpad + azuread_group_key: caf_platform_maintainers + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + identity_azuread_group: + lz_key: launchpad + azuread_group_key: identity + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + subscription_creation_platform_azuread_group: + lz_key: launchpad + azuread_group_key: subscription_creation_platform + secret_permissions: + - Get + cred_subscription_creation_landingzones: + name: scl + resource_group_key: sp_credentials + purge_protection_enabled: false + tags: + caf_environment: {{topology.caf_environment}} + caf_identity_aad_key: cred_subscription_creation_landingzones + creation_policies: + caf_platform_maintainers: + lz_key: launchpad + azuread_group_key: caf_platform_maintainers + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + identity_azuread_group: + lz_key: launchpad + azuread_group_key: identity + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + subscription_creation_platform_azuread_group: + lz_key: launchpad + azuread_group_key: subscription_creation_landingzones + secret_permissions: + - Get + cred_gitops: + name: gitops + resource_group_key: sp_credentials + purge_protection_enabled: false + tags: + caf_environment: {{topology.caf_environment}} + caf_identity_aad_key: cred_gitops + creation_policies: + caf_platform_maintainers: + lz_key: launchpad + azuread_group_key: caf_platform_maintainers + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + identity_azuread_group: + lz_key: launchpad + azuread_group_key: identity + secret_permissions: + - Set + - Get + - List + - Delete + - Purge + - Recover + + keyvault_access_policies: + cred_ea_account_owner: + gitops: + azuread_service_principal_key: gitops + secret_permissions: + - Get + cred_level0: + gitops: + azuread_service_principal_key: gitops + secret_permissions: + - Get + cred_identity: + gitops: + azuread_service_principal_key: gitops + secret_permissions: + - Get + cred_management: + gitops: + azuread_service_principal_key: gitops + secret_permissions: + - Get + cred_alz: + gitops: + azuread_service_principal_key: gitops + secret_permissions: + - Get + cred_connectivity: + gitops: + azuread_service_principal_key: gitops + secret_permissions: + - Get + cred_subscription_creation_platform: + gitops: + azuread_service_principal_key: gitops + secret_permissions: + - Get + cred_subscription_creation_landingzones: + gitops: + azuread_service_principal_key: gitops + secret_permissions: + - Get + cred_gitops: + gitops: + azuread_service_principal_key: gitops + secret_permissions: + - Get + + azuread_applications: + gitops: + application_name: app-azure-platform-credentials-for-gitops + + azuread_service_principals: + gitops: + azuread_application: + key: gitops + + azuread_credentials: + gitops: + type: password + azuread_credential_policy_key: gitops + azuread_application: + key: gitops + keyvaults: + cred_gitops: + secret_prefix: sp + level0: + type: password + azuread_credential_policy_key: default_policy + azuread_application: + lz_key: launchpad + key: level0 + keyvaults: + cred_level0: + secret_prefix: sp + identity: + type: password + azuread_credential_policy_key: default_policy + azuread_application: + lz_key: launchpad + key: identity + keyvaults: + cred_identity: + secret_prefix: sp + management: + type: password + azuread_credential_policy_key: default_policy + azuread_application: + lz_key: launchpad + key: management + keyvaults: + cred_management: + secret_prefix: sp + alz: + type: password + azuread_credential_policy_key: default_policy + azuread_application: + lz_key: launchpad + key: alz + keyvaults: + cred_alz: + secret_prefix: sp + connectivity: + type: password + azuread_credential_policy_key: default_policy + azuread_application: + lz_key: launchpad + key: connectivity + keyvaults: + cred_connectivity: + secret_prefix: sp + subscription_creation_platform: + type: password + azuread_credential_policy_key: default_policy + azuread_application: + lz_key: launchpad + key: subscription_creation_platform + keyvaults: + cred_subscription_creation_platform: + secret_prefix: sp + subscription_creation_landingzones: + type: password + azuread_credential_policy_key: default_policy + azuread_application: + lz_key: launchpad + key: subscription_creation_landingzones + keyvaults: + cred_subscription_creation_landingzones: + secret_prefix: sp + + azuread_credential_policies: + gitops: + length: 250 + special: false + upper: true + number: true + expire_in_days: 360 + rotation_key0: + days: 181 + rotation_key1: + days: 300 + default_policy: + length: 250 + special: false + upper: true + number: true + expire_in_days: 65 + rotation_key0: + days: 33 + rotation_key1: + days: 58 + diff --git a/templates/platform/services/management.yaml b/templates/platform/services/management.yaml new file mode 100644 index 000000000..4dad1440e --- /dev/null +++ b/templates/platform/services/management.yaml @@ -0,0 +1,113 @@ +management: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level1/management + + tfstate: + lz_key_name: management + tfstate: management.tfstate + level: level1 + identity_aad_key: cred_management + config_file: management.yaml + sub_template_folder: platform/level1/management + # Do not rename the tfstate_key_name + tfstate_key_name: management + + deployments: + landingzone: + global_settings_key: + platform: + launchpad: + remote_tfstates: + platform: + launchpad: + + resources: + management: + resource_groups: + management: + name: management + alerts: + name: alerts + + storage_accounts: + nsgflogs: + name: nsglogs + resource_group_key: management + account_kind: BlobStorage + account_tier: Standard + shared_access_key_enabled: false + account_replication_type: LRS + + diagnostic_log_analytics: + # if you change this key you also need to change it in the alz deployment + # alz/archetype_config_overrides.caf.platform.yaml + # alz/custom_landing_zones.caf.platform.yaml + region1: + name: logre1 + resource_group_key: management + + solutions_maps: + NetworkMonitoring: + publisher: Microsoft + product: OMSGallery/NetworkMonitoring + ADAssessment: + publisher: Microsoft + product: OMSGallery/ADAssessment + ADReplication: + publisher: Microsoft + product: OMSGallery/ADReplication + AgentHealthAssessment: + publisher: Microsoft + product: OMSGallery/AgentHealthAssessment + DnsAnalytics: + publisher: Microsoft + product: OMSGallery/DnsAnalytics + ContainerInsights: + publisher: Microsoft + product: OMSGallery/ContainerInsights + KeyVaultAnalytics: + publisher: Microsoft + product: OMSGallery/KeyVaultAnalytics + + monitor_action_groups: + networking_operations: + action_group_name: Networking Operations + resource_group_key: alerts + shortname: netops + arm_role_alert: + contributors: + name: Monitoring Contributor + role_name: Monitoring Contributor + use_common_alert_schema: false + email_receiver: + noc: + name: email_alert_support1 + email_address: {{topology.notifications.monitor_action_groups.networking_operations}} + use_common_alert_schema: false + + service_health_alerts: + enable_service_health_alerts: true + name: alerts + shortname: HealthAlerts + resource_group_key: alerts + action_group_name: actiongrp + email_alert_settings: + support1: + name: email_alert_support1 + email_address: {{topology.notifications.service_health_alerts}} + use_common_alert_schema: false + + automation_accounts: + account1: + name: automationAccount1 + resource_group_key: management + + recovery_vaults: + asr: + name: asr + resource_group_key: management + soft_delete_enabled: true + backup_policies: + {{topology.backup_policies | to_nice_yaml(width=80, indent=2) | indent(12)}} diff --git a/templates/platform/services/subscriptions.yaml b/templates/platform/services/subscriptions.yaml new file mode 100644 index 000000000..289130852 --- /dev/null +++ b/templates/platform/services/subscriptions.yaml @@ -0,0 +1,32 @@ +subscriptions: + gitops: + caf_landingzone_branch: {{topology.caf_landingzone_branch}} + + relative_destination_folder: level1/subscriptions + + tfstate: + lz_key_name: subscriptions + tfstate: platform_subscriptions.tfstate + level: level1 + identity_aad_key: cred_subscription_creation_platform + config_file: subscriptions.yaml + sub_template_folder: platform/level1/subscriptions + # Do not rename the tfstate_key_name + tfstate_key_name: subscriptions + + resources: + landingzone: + + subscriptions: + launchpad: + subscriptions: +{% for key, value in topology.subscriptions.items() %} + {{key}}: +{% for l_key, l_value in value.items() %} +{% if l_key == 'create_alias' %} + {{l_key}}: {{l_value | lower }} +{% else %} + {{l_key}}: {{l_value}} +{% endif %} +{% endfor %} +{% endfor %} diff --git a/templates/platform/services/tfstates.yaml b/templates/platform/services/tfstates.yaml new file mode 100644 index 000000000..204ec3dcf --- /dev/null +++ b/templates/platform/services/tfstates.yaml @@ -0,0 +1,35 @@ +tfstates: + {{deployment_mode}}: +{% for a_key, value in topology.deployments[deployment_mode].root.items() %} +{% for key in value.keys() %} + {{topologies[key].tfstate.tfstate_key_name}}: +{% for l_key, l_value in topologies[key].tfstate.items() %} + {{l_key}}: {{l_value}} +{% endfor %} + +{% endfor %} +{% endfor %} + +{% for a_key, value in topology.deployments[deployment_mode].alz.items() %} +{% for key in value.keys() %} + {{topologies['alz_' + key].tfstate.tfstate_key_name}}: +{% for l_key, l_value in topologies['alz_' + key].tfstate.items() %} + {{l_key}}: {{l_value}} +{% endfor %} + +{% endfor %} +{% endfor %} + + +{% for a_key, a_value in topology.deployments[deployment_mode].scale_out_domains.items() %} +{% for key, value in a_value.items() %} + {{key}}: +{% for b_key in value.keys() %} + {{b_key}}: +{% for l_key, l_value in topologies[key + '_' + b_key].tfstate.items() %} + {{l_key}}: {{l_value}} +{% endfor %} +{% endfor %} + +{% endfor %} +{% endfor %} \ No newline at end of file diff --git a/templates/platform/single_subscription.yaml b/templates/platform/single_subscription.yaml new file mode 100644 index 000000000..4d6697e86 --- /dev/null +++ b/templates/platform/single_subscription.yaml @@ -0,0 +1,249 @@ +customer_name: {{customer_name}} +caf_environment: {{caf_environment}} +default_email_address: {{default_email_address}} +alz_mg_prefix: {{alz_mg_prefix}} +alz_mg_name: {{alz_mg_name}} +azure_regions: {{azure_regions}} +prefix: {{prefix}} + +# folder parameters +topology_file: {{platform_definition_folder}}/ignite.yaml +landingzones_folder: {{landingzones_folder}} +public_templates_folder: {{public_templates_folder}} +platform_configuration_folder: {{platform_configuration_folder}} +platform_definition_folder: {{platform_definition_folder}} +platform_template_folder: {{platform_template_folder}} + +deployment_mode: {{deployment_mode}} + +caf_landingzone_branch: 2203.0 + +caf_regions: +{% for region, location in regions.items() %} + {{region}}: {{location}} +{% endfor %} + +# Use the lower-case region's name, short version with no space +resources_allowed_regions: +{% for region in regions.keys() %} + - {{region}} +{% endfor %} + +resource_groups_allowed_regions: +{% for region in regions.keys() %} + - {{region}} +{% endfor %} + +default_region_key: {{default_region_key}} + +naming_convention: + # When set to false use the CAF provider to generate names aligned to CAF guidance + # true: use the name as defined in the configuration files. You may have to iterate multiple times to prevent conflicts with Azure unique names with servides like storage account, keyvault or log analytics workspace. + passthrough: false + inherit_tags: false + # set: define the prefix to add to all resource names + # unset: if passthrough is set to false, generate a random prefix + prefix: {{prefix}} + # if passthrough is set to false, add random suffix to name, up to the random_lenght value. + random_length: 3 + +caf_launchpad: + # Subscription_id to deploy the launchpad. Note 1 existing manual subscription is required to deploy the launhchapd. + subscription_id: {{subscription_id.stdout}} + subscription_name: {{subscription_name.stdout}} + tenant_id: {{tenant_id.stdout}} + global_tags_propagated: yes + tags: + caf_deployment_mode: demo_single_subscription + + +azuread_user_ea_account_owner: {{upn.stdout}} +ea_owner_object_id: {{object_id.stdout}} + +azuread_identity_mode: service_principal +enable_azuread_groups: True +enable_azuread_applications: True + +enable_azure_subscription_vending_machine: {{topology.enable_azure_subscription_vending_machine | default(bootstrap.enable_azure_subscription_vending_machine)}} + +management_groups: +{% for region, a_value in topology.deployments.platform.alz.items() %} + {{region}}: +{% for key in a_value.keys() %} + {{key}}: + management_group_prefix: "{{ topology.management_groups[region][key].management_group_prefix | default(alz_mg_prefix)}}" + management_group_name: "{{ topology.management_groups[region][key].management_group_name | default(alz_mg_name)}}" + deploy_core_landing_zones: {{topology.management_groups[region][key].deploy_core_landing_zones | default(True)}} + clean_up_destination_folder: {{topology.management_groups[region][key].clean_up_destination_folder | default(True)}} + update_lib_folder: {{topology.management_groups[region][key].update_lib_folder | default(True)}} + version_to_deploy: "{{topology.management_groups[region][key].version_to_deploy | default('v1.1.3')}}" +{% if topology.management_groups[region][key].root_parent_id is defined %} + root_parent_id: "{{topology.management_groups[region][key].root_parent_id}}" +{% endif %} +{% endfor %} +{% endfor %} + +subscription_deployment_mode: single_reuse + +billing_subscription_role_delegations: + # true: enable this deployment. The remaining attributes are required. + # false: disable this deployment. + # azuread_user_ea_account_owner: set the upn of the user doing the manual deployment of the platform + # azuread_user_ea_account_owner_object_id: if that user is already loged-in to an azure cli session you can get the object_id by running: + # az ad signed-in-user show --query objectId -o tsv + # The remaining attributes are ignored: [billing_account_name, enrollment_account_name] + enable: false + # Azure Active Directory User (UPN) that is Account Owner in the EA portal + # if enable=false, set the upn of the user doing the manual deployment + azuread_user_ea_account_owner: {{topology.azuread_user_ea_account_owner | default(upn.stdout)}} + # see comments above to get the object_id + # + # Also set this GUID to the owner of the launchpad azuread_groups + # + azuread_user_ea_account_owner_object_id: {{topology.ea_owner_object_id | default(object_id.stdout)}} + # Only set the following two attributes when enable=true + billing_account_name: + enrollment_account_name: + +subscriptions: + launchpad: # Do not rename the key + name: {{subscription_name.stdout}} + create_alias: false + subscription_id: {{subscription_id.stdout}} + identity: # Do not rename the key + name: {{subscription_name.stdout}} + create_alias: false + subscription_id: {{subscription_id.stdout}} + connectivity: # Do not rename the key + name: {{subscription_name.stdout}} + create_alias: false + subscription_id: {{subscription_id.stdout}} + management: # Do not rename the key + name: {{subscription_name.stdout}} + create_alias: false + subscription_id: {{subscription_id.stdout}} + +deployments: + platform: + root: + {{default_region_key}}: + launchpad: launchpad_azuread_sp_single_subscription.yaml + launchpad_credentials: launchpad_credentials_azuread_sp.yaml + subscriptions: subscriptions.yaml + identity: identity.yaml + management: management.yaml + asvm: asvm.yaml + alz: + {{default_region_key}}: + {{alz_mg_prefix}}: alz.yaml + scale_out_domains: + {{default_region_key}}: + identity_level2: + prod: identity_level2.yaml + non_prod: identity_level2.yaml + virtual_wans: + prod: connectivity_virtual_wans.yaml + virtual_hubs: + prod: connectivity_virtual_hubs.yaml + non_prod: connectivity_virtual_hubs.yaml + virtual_hubs_route_tables: + prod: connectivity_virtual_hubs_route_tables.yaml + non_prod: connectivity_virtual_hubs_route_tables.yaml + azurerm_firewall_policies: + prod: connectivity_firewall_policies.yaml + non_prod: connectivity_firewall_policies.yaml + secure_firewalls: + prod: connectivity_secure_firewalls.yaml + non_prod: connectivity_secure_firewalls.yaml + private_dns_firewalls: + prod: connectivity_private_dns_firewalls.yaml + non_prod: connectivity_private_dns_firewalls.yaml + private_dns: + prod: connectivity_private_dns.yaml + non_prod: connectivity_private_dns.yaml + +# +# Advanced settings +# + +notifications: + monitor_action_groups: + networking_operations: {{default_email_address}} + service_health_alerts: {{default_email_address}} + azure_defender: + emailSecurityContact: {{default_email_address}} + + +backup_policies: + vms: + default: + name: vm-default-policy + # Default to UTC + # possible values - https://jackstromberg.com/2017/01/list-of-time-zones-consumed-by-azure/ + timezone: SE Asia Standard Time + backup: + frequency: Daily + time: "23:00" + retention_daily: + count: 7 + retention_weekly: + count: 2 + weekdays: + - Sunday + retention_monthly: + count: 2 + weeks: + - First + weekdays: + - Sunday + retention_yearly: + count: 1 + weeks: + - First + months: + - January + weekdays: + - Sunday + +azure_landing_zones: + identity: + # Set the Azure Active Directory tenant name (primary domain name) + # has to be the default domain name (custom dns name or tenantname.onmicrosoft.com) + # check the AAD property + tenant_name: {{tenant_name.stdout}} + # only service_principal supported with rover ignite at the moment + azuread_identity_mode: {{topology.azuread_identity_mode}} + enable_azuread_groups: {{topology.enable_azuread_groups}} + enable_azuread_applications: {{topology.enable_azuread_applications}} + # UPNs you want to add in the caf_platform_maintainers Azure AD group + # Can use user or guest accounts + # Those users will have full permissions on platform. + # Once setup, you can remove them from here or add them from + # Check in Azure AD the User Principal Name attribute value. Note there is a special convention for guest accounts. + caf_platform_maintainers: + user_principal_names: + # - + caf_platform_contributors: + user_principal_names: + # - + backup_policy: + vms: default + + management: + backup_policy: + vms: default + + connectivity: + networking_topology: + deployment_option: virtual_wan + backup_policy: + vms: default + +# cleanup_destination - recommended to clean and recreated a clean state from template. +configuration_folders: + platform: + # true: force the destination folder to be deleted and re-created before the files are created. + # false: create the target folder structure if it does not exist. On sub-sequent executions, the folder structure is reused as is. + cleanup_destination: true + + diff --git a/templates/platform/template_topology.yaml b/templates/platform/template_topology.yaml new file mode 100644 index 000000000..75361fe04 --- /dev/null +++ b/templates/platform/template_topology.yaml @@ -0,0 +1,59 @@ +bootstrap: + azuread_identity_mode: service_principal + enable_azuread_groups: True + enable_azuread_applications: True + + enable_azure_subscription_vending_machine: True + + management_groups: + region1: + es: + management_group_prefix: "es" + management_group_name: "Contoso" + deploy_core_landing_zones: True + clean_up_destination_folder: True + update_lib_folder: True + version_to_deploy: "v1.1.1" + + subscription_deployment_mode: single_reuse + + caf_landingzone_branch: 2203.0 + + deployments: + platform: + root: + region1: + launchpad: launchpad_azuread_sp_single_subscription.yaml + launchpad_credentials: launchpad_credentials_azuread_sp.yaml + subscriptions: subscriptions.yaml + identity: identity.yaml + management: management.yaml + asvm: asvm.yaml + alz: + region1: + es: alz.yaml + scale_out_domains: + region1: + identity_level2: + prod: identity_level2.yaml + non_prod: identity_level2.yaml + virtual_wans: + prod: connectivity_virtual_wans.yaml + virtual_hubs: + prod: connectivity_virtual_hubs.yaml + non_prod: connectivity_virtual_hubs.yaml + virtual_hubs_route_tables: + prod: connectivity_virtual_hubs_route_tables.yaml + non_prod: connectivity_virtual_hubs_route_tables.yaml + azurerm_firewall_policies: + prod: connectivity_firewall_policies.yaml + non_prod: connectivity_firewall_policies.yaml + secure_firewalls: + prod: connectivity_secure_firewalls.yaml + non_prod: connectivity_secure_firewalls.yaml + private_dns_firewalls: + prod: connectivity_private_dns_firewalls.yaml + non_prod: connectivity_private_dns_firewalls.yaml + private_dns: + prod: connectivity_private_dns.yaml + non_prod: connectivity_private_dns.yaml diff --git a/templates/readme.md b/templates/readme.md index aabe8006c..c6a224d5f 100644 --- a/templates/readme.md +++ b/templates/readme.md @@ -4,3 +4,6 @@ Rover Ignite allows you to create a coherent stack of configuration files for CA It integrates all levels in a consistent and interactive way. In some configuration, the output of an execution is needed to continue, you might have to run multiple times the rover ignite command in order to generate the full configuration files. +You have now created the configuration files and are ready to proceed with the deployment. + +[Go to](./level0/readme.md) \ No newline at end of file diff --git a/templates/resources/active_directory_domain_service.tfvars.j2 b/templates/resources/active_directory_domain_service.tfvars.j2 index 44091996f..fbb8d44a0 100644 --- a/templates/resources/active_directory_domain_service.tfvars.j2 +++ b/templates/resources/active_directory_domain_service.tfvars.j2 @@ -1,5 +1,5 @@ active_directory_domain_service = { -{% for key, value in resources.subscriptions[subscription_key].active_directory_domain_service.items() %} +{% for key, value in resources[tfstate_resource].resources[subscription_key].active_directory_domain_service.items() %} {{ key }} = { name = "{{ value.name }}" region = "{{ value.region }}" diff --git a/templates/resources/active_directory_domain_service_replica_set.tfvars.j2 b/templates/resources/active_directory_domain_service_replica_set.tfvars.j2 index 70ea38c19..b58a2952d 100644 --- a/templates/resources/active_directory_domain_service_replica_set.tfvars.j2 +++ b/templates/resources/active_directory_domain_service_replica_set.tfvars.j2 @@ -1,5 +1,5 @@ active_directory_domain_service_replica_set = { -{% for key, value in resources.subscriptions[subscription_key].active_directory_domain_service_replica_set.items() %} +{% for key, value in resources[tfstate_resource].resources[subscription_key].active_directory_domain_service_replica_set.items() %} {{ key }} = { region = "{{ value.region }}" active_directory_domain_service = { diff --git a/templates/resources/automation_accounts.tfvars.j2 b/templates/resources/automation_accounts.tfvars.j2 index b80313ce5..3c3fd5824 100644 --- a/templates/resources/automation_accounts.tfvars.j2 +++ b/templates/resources/automation_accounts.tfvars.j2 @@ -1,5 +1,5 @@ automations = { -{% for key, automation in resources.subscriptions[subscription_key].automation_accounts.items() %} +{% for key, automation in resources[tfstate_resource].resources[subscription_key].automation_accounts.items() %} {{ key }} = { name = "{{ automation.name }}" sku = "{{ automation.sku | default('Basic') }}" diff --git a/templates/resources/azuread_api_permissions.tfvars.j2 b/templates/resources/azuread_api_permissions.tfvars.j2 new file mode 100644 index 000000000..348cf32a6 --- /dev/null +++ b/templates/resources/azuread_api_permissions.tfvars.j2 @@ -0,0 +1,32 @@ +azuread_api_permissions = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].azuread_api_permissions.items() %} + {{ key }} = { +{% if value.microsoft_graph is defined %} + microsoft_graph = { + resource_app_id = "{{ value.microsoft_graph.resource_app_id }}" + resource_access = { +{% for r_key, r_value in value.microsoft_graph.resource_access.items() %} + {{r_key}} = { + id = "{{ r_value.id }}" + type = "{{ r_value.type }}" + } +{% endfor%} + } + } +{% endif %} +{% if value.active_directory_graph is defined %} + active_directory_graph = { + resource_app_id = "{{ value.active_directory_graph.resource_app_id }}" + resource_access = { +{% for r_key, r_value in value.active_directory_graph.resource_access.items() %} + {{r_key}} = { + id = "{{ r_value.id }}" + type = "{{ r_value.type }}" + } +{% endfor%} + } + } +{% endif %} + } +{% endfor %} +} diff --git a/templates/resources/azuread_applications.tfvars.j2 b/templates/resources/azuread_applications.tfvars.j2 index b3dee9f39..5138b99dd 100644 --- a/templates/resources/azuread_applications.tfvars.j2 +++ b/templates/resources/azuread_applications.tfvars.j2 @@ -1,5 +1,5 @@ azuread_applications = { -{% for key, app in resources.subscriptions[subscription_key].azuread_applications.items() %} +{% for key, app in resources[tfstate_resource].resources[subscription_key].azuread_applications.items() %} {{ key }} = { application_name = "{{ app.application_name }}" } diff --git a/templates/resources/azuread_credential_policies.tfvars.j2 b/templates/resources/azuread_credential_policies.tfvars.j2 index d2c3a2874..e16107501 100644 --- a/templates/resources/azuread_credential_policies.tfvars.j2 +++ b/templates/resources/azuread_credential_policies.tfvars.j2 @@ -1,5 +1,5 @@ azuread_credential_policies = { -{% for key, value in resources.subscriptions[subscription_key].azuread_credential_policies.items() %} +{% for key, value in resources[tfstate_resource].resources[subscription_key].azuread_credential_policies.items() %} {{ key }} = { # Length of the password length = {{ value.length }} diff --git a/templates/resources/azuread_credentials.tfvars.j2 b/templates/resources/azuread_credentials.tfvars.j2 index 5dcb81e4c..7f1e9d690 100644 --- a/templates/resources/azuread_credentials.tfvars.j2 +++ b/templates/resources/azuread_credentials.tfvars.j2 @@ -1,5 +1,5 @@ azuread_credentials = { -{% for key, cred in resources.subscriptions[subscription_key].azuread_credentials.items() %} +{% for key, cred in resources[tfstate_resource].resources[subscription_key].azuread_credentials.items() %} {{ key }} = { type = "{{ cred.type | default('password') }}" azuread_credential_policy_key = "{{ cred.azuread_credential_policy_key }}" diff --git a/templates/resources/azuread_groups.tfvars.j2 b/templates/resources/azuread_groups.tfvars.j2 index ee523c96a..0b33712cc 100644 --- a/templates/resources/azuread_groups.tfvars.j2 +++ b/templates/resources/azuread_groups.tfvars.j2 @@ -1,5 +1,5 @@ azuread_groups = { -{% for key, ad_group in resources.subscriptions[subscription_key].azuread_groups.items() %} +{% for key, ad_group in resources[tfstate_resource].resources[subscription_key].azuread_groups.items() %} {{ key }} = { name = "{{ ad_group.name }}" {% if ad_group.description is defined %} @@ -14,24 +14,20 @@ azuread_groups = { group_names = {{ ad_group.members.group_names | replace('None','[]') | replace('\'','\"') }} {% endif %} {% if ad_group.members.object_ids is defined %} - object_ids = {{ ad_group.members.object_ids | replace('None','[]') | replace('\'','\"') }} + object_ids = {{ ad_group.members.object_ids | string | replace('None','[]') | replace('\'','\"') }} {% endif %} {% if ad_group.members.group_keys is defined %} group_keys = {{ ad_group.members.group_keys | replace('None','[]') | replace('\'','\"') }} {% endif %} -{% if ad_group.members.service_principal_keys is defined %} - service_principal_keys = {{ ad_group.members.service_principal_keys | replace('None','[]') | replace('\'','\"') }} +{% if ad_group.members.azuread_service_principal_keys is defined %} + azuread_service_principal_keys = {{ ad_group.members.azuread_service_principal_keys | replace('None','[]') | replace('\'','\"') }} {% endif %} } {% endif %} {% if ad_group.owners is defined %} - owners = { -{% if ad_group.owners.user_principal_names is defined %} - user_principal_names = {{ ad_group.owners.user_principal_names | replace('None','[]') | replace('\'','\"') }} + owners = {{ ad_group.owners| string | replace('None','[]') | replace('\'','\"') }} {% endif %} - } -{% endif %} - prevent_duplicate_name = {{ ad_group.owners.prevent_duplicate_name | default(false) | string | lower }} + prevent_duplicate_name = {{ ad_group.owners.prevent_duplicate_name | default(true) | string | lower }} } {% endfor %} } diff --git a/templates/resources/azuread_groups_membership.tfvars.j2 b/templates/resources/azuread_groups_membership.tfvars.j2 index faf15682b..cebf2e2a1 100644 --- a/templates/resources/azuread_groups_membership.tfvars.j2 +++ b/templates/resources/azuread_groups_membership.tfvars.j2 @@ -1,5 +1,5 @@ azuread_groups_membership = { -{% for key, value in resources.subscriptions[subscription_key].azuread_groups_membership.items() %} +{% for key, value in resources[tfstate_resource].resources[subscription_key].azuread_groups_membership.items() %} {{ key }} = { {% for l1_key , l1_value in value.items() %} {{l1_key}} = { diff --git a/templates/resources/azuread_roles.tfvars.j2 b/templates/resources/azuread_roles.tfvars.j2 new file mode 100644 index 000000000..6ace90376 --- /dev/null +++ b/templates/resources/azuread_roles.tfvars.j2 @@ -0,0 +1,15 @@ +# +# Available roles: +# az rest --method Get --uri https://graph.microsoft.com/v1.0/directoryRoleTemplates -o json | jq -r .value[].displayName +# +azuread_roles = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].azuread_roles.items() %} + {{ key }} = { +{% for l_key, l_value in value.items() %} + {{l_key}} = { + roles = {{ l_value.roles | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} + } +{% endfor %} + } +{% endfor %} +} \ No newline at end of file diff --git a/templates/resources/azuread_service_principals.tfvars.j2 b/templates/resources/azuread_service_principals.tfvars.j2 index 7503333e3..ffbc4fdf6 100644 --- a/templates/resources/azuread_service_principals.tfvars.j2 +++ b/templates/resources/azuread_service_principals.tfvars.j2 @@ -1,6 +1,6 @@ azuread_service_principals = { -{% for key, sp in resources.subscriptions[subscription_key].azuread_service_principals.items() %} +{% for key, sp in resources[tfstate_resource].resources[subscription_key].azuread_service_principals.items() %} {{ key }} = { azuread_application = { key = "{{ sp.azuread_application.key }}" diff --git a/templates/resources/azurerm_firewall_policies.tfvars.j2 b/templates/resources/azurerm_firewall_policies.tfvars.j2 index 1b787593a..f50514b50 100644 --- a/templates/resources/azurerm_firewall_policies.tfvars.j2 +++ b/templates/resources/azurerm_firewall_policies.tfvars.j2 @@ -1,5 +1,5 @@ azurerm_firewall_policies = { -{% for key, value in resources.subscriptions[subscription_key].azurerm_firewall_policies.items() %} +{% for key, value in resources[tfstate_resource].resources[subscription_key].azurerm_firewall_policies.items() %} {{ key }} = { name = "{{ value.name }}" {% if value.region_key is defined %} @@ -11,14 +11,14 @@ azurerm_firewall_policies = { resource_group = { key = "{{ value.resource_group.key }}" {% if value.resource_group.lz_key is defined %} - lz_key = "{{ config.tfstates.platform.azurerm_firewall_policies[value.resource_group.lz_key].lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.azurerm_firewall_policies[value.resource_group.lz_key].lz_key_name }}" {% endif %} } {% if value.base_policy is defined %} base_policy = { key = "{{ value.base_policy.key }}" {% if value.resource_group.lz_key is defined %} - lz_key = "{{ config.tfstates.platform.azurerm_firewall_policies[value.resource_group.lz_key].lz_key_name }}" + lz_key = "{{ resources.tfstates.platform.azurerm_firewall_policies[value.resource_group.lz_key].lz_key_name }}" {% endif %} } {% endif %} diff --git a/templates/resources/azurerm_firewalls.tfvars.j2 b/templates/resources/azurerm_firewalls.tfvars.j2 index 5711738f7..bc524b83d 100644 --- a/templates/resources/azurerm_firewalls.tfvars.j2 +++ b/templates/resources/azurerm_firewalls.tfvars.j2 @@ -1,9 +1,11 @@ azurerm_firewalls = { -{% for key, value in resources.subscriptions[subscription_key].azurerm_firewalls.items() %} +{% for key, value in resources[tfstate_resource].resources[subscription_key].azurerm_firewalls.items() %} {{ key }} = { name = "{{ value.name }}" resource_group_key = "{{ value.resource_group_key }}" +{% if value.vnet_key is defined %} vnet_key = "{{ value.vnet_key }}" +{% endif %} {% if value.sku_tier is defined %} sku_tier = "{{ value.sku_tier }}" {% endif %} @@ -55,46 +57,43 @@ azurerm_firewalls = { {% if value.management_ip_configuration.subnet_id is defined %} subnet_id = "{{ value.management_ip_configuration.subnet_id }}" {% else %} - vnet_key = "{{ value.management_ip_configuration.vnet_key }}" - subnet_key = "{{ value.management_ip_configuration.subnet_key }}" + vnet_key = "{{ value.management_ip_configuration.vnet_key }}" + subnet_key = "{{ value.management_ip_configuration.subnet_key }}" {% if value.management_ip_configuration.lz_key is defined %} - lz_key = "{{ value.management_ip_configuration.lz_key }}" + lz_key = "{{ value.management_ip_configuration.lz_key }}" {% endif %} {% endif %} } {% endif %} -{% if value.virtual_hub_id is defined %} +{% if value.virtual_hub is defined %} virtual_hub = { -{% if value.virtual_hub.virtual_hub_id is defined %} - virtual_hub_id = "{{ value.virtual_hub_id }}" -{% elif value.virtual_hub is defined %} - virtual_wan_key = " {{ value.virtual_hub.virtual_wan_key }}" - virtual_hub_key = " {{ value.virtual_hub.virtual_hub_key }}" -{% if value.virtual_hub.lz_key is defined %} - lz_key = "{{ value.virtual_hub.lz_key }}" -{% endif %} - virtual_wan_key = " {{ value.virtual_hub.virtual_wan_key }}" +{% for vh_key, vh_value in value.virtual_hub.items() %} + {{vh_key}} = { +{% if vh_value.lz_key is defined %} + lz_key = "{{vh_value.lz_key}}" {% endif %} - public_ip_count = " {{ value.virtual_hub.public_ip_count }}" + virtual_hub_key = "{{vh_value.virtual_hub_key}}" + } +{% endfor %} } {% endif %} {% if value.public_ips is defined %} public_ips = { {% for p_key, p_value in value.public_ips.items() %} {{ p_key }} = { - name = "{{ p_value.name }}" + name = "{{ p_value.name }}" {% if p_value.public_ip_id is defined %} - public_ip_id = "{{ p_value.public_ip_id }}" + public_ip_id = "{{ p_value.public_ip_id }}" {% else %} - public_ip_key = "{{ p_value.public_ip_key }}" + public_ip_key = "{{ p_value.public_ip_key }}" {% endif %} {% if p_value.subnet_id is defined %} - subnet_id = "{{ p_value.subnet_id }}" + subnet_id = "{{ p_value.subnet_id }}" {% else %} - vnet_key = "{{ p_value.vnet_key }}" - subnet_key = "{{ p_value.subnet_key }}" + vnet_key = "{{ p_value.vnet_key }}" + subnet_key = "{{ p_value.subnet_key }}" {% if p_value.lz_key is defined %} - lz_key = "{{ p_value.lz_key }}" + lz_key = "{{ p_value.lz_key }}" {% endif %} {% endif %} } diff --git a/templates/resources/container_groups.tfvars.j2 b/templates/resources/container_groups.tfvars.j2 new file mode 100644 index 000000000..460b122f8 --- /dev/null +++ b/templates/resources/container_groups.tfvars.j2 @@ -0,0 +1,205 @@ +container_groups = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].container_groups.items() %} + {{ key }} = { + name = "{{ value.name }}" +{% if value.region is defined %} + region = "{{ value.region }}" +{% endif %} +{% if value.resource_group_key is defined %} + resource_group_key = "{{ value.resource_group_key }}" +{% endif %} +{% if value.resource_group is defined %} + resource_group = { +{% if value.resource_group.lz_key is defined %} + lz_key = "{{ value.resource_group.lz_key }}" +{% endif %} + key = "{{ value.resource_group.key }}" + } +{% endif %} + ip_address_type = "{{ value.ip_address_type | default('Private') }}" + os_type = "{{ value.os_type | default('Linux') }}" + restart_policy = "{{ value.restart_policy | default('Never') }}" +{% if value.network_profile is defined %} + network_profile = { +{% if value.network_profile.lz_key is defined %} + lz_key = "{{ value.network_profile.lz_key }}" +{% endif %} +{% if value.network_profile.key is defined %} + key = "{{ value.network_profile.key }}" +{% endif %} + } +{% endif %} +{% for c_key, c_value in value.containers.items() %} + containers = { + {{ c_key }} = { +{% if c_value.count is defined %} + count = "{{ c_value.count }}" +{% endif %} + name = "{{ c_value.name }}" + image = "{{ c_value.image }}" + cpu = "{{ c_value.cpu }}" + memory = "{{ c_value.memory }}" +{% if c_value.commands is defined %} + commands = "{{ c_value.commands }}" +{% endif %} +{% if c_value.gpu is defined %} + gpu = { + count = c_value.gpu.count + sku = c_value.gpu.sku + } +{% endif %} +{% if c_value.ports is defined %} + ports = { +{% for p_key, p_value in c_value.ports.items() %} + {{p_key}} = { + port = "{{p_value.port}}" +{% if p_value.protocol is defined %} + protocol = "{{p_value.protocol}}" +{% endif %} + } +{% endfor %} + } +{% endif %} +{% if c_value.readiness_probe is defined %} + readiness_probe = { +{% if c_value.readiness_probe.exec is defined %} + exec = "{{ c_value.readiness_probe.exec }}" +{% endif %} +{% if c_value.readiness_probe.initial_delay_seconds is defined %} + initial_delay_seconds = {{ c_value.readiness_probe.initial_delay_seconds }} +{% endif %} +{% if c_value.readiness_probe.period_seconds is defined %} + period_seconds = {{ c_value.readiness_probe.period_seconds }} +{% endif %} +{% if c_value.readiness_probe.failure_threshold is defined %} + failure_threshold = {{ c_value.readiness_probe.failure_threshold }} +{% endif %} +{% if c_value.readiness_probe.success_threshold is defined %} + success_threshold = {{ c_value.readiness_probe.success_threshold }} +{% endif %} +{% if c_value.readiness_probe.timeout_seconds is defined %} + timeout_seconds = {{ c_value.readiness_probe.timeout_seconds }} +{% endif %} + } +{% endif %} +{% if c_value.liveness_probe is defined %} + liveness_probe = { +{% if c_value.liveness_probe.exec is defined %} + exec = "{{ c_value.liveness_probe.exec }}" +{% endif %} +{% if c_value.liveness_probe.initial_delay_seconds is defined %} + initial_delay_seconds = {{ c_value.liveness_probe.initial_delay_seconds }} +{% endif %} +{% if c_value.liveness_probe.period_seconds is defined %} + period_seconds = {{ c_value.liveness_probe.period_seconds }} +{% endif %} +{% if c_value.liveness_probe.failure_threshold is defined %} + failure_threshold = {{ c_value.liveness_probe.failure_threshold }} +{% endif %} +{% if c_value.liveness_probe.success_threshold is defined %} + success_threshold = {{ c_value.liveness_probe.success_threshold }} +{% endif %} +{% if c_value.liveness_probe.timeout_seconds is defined %} + timeout_seconds = {{ c_value.liveness_probe.timeout_seconds }} +{% endif %} +{% if c_value.liveness_probe.http_get is defined %} + http_get = { +{% if c_value.liveness_probe.http_get.path is defined %} + path = "{{c_value.liveness_probe.http_get.path}}" +{% endif %} +{% if c_value.liveness_probe.http_get.port is defined %} + port = "{{c_value.liveness_probe.http_get.port}}" +{% endif %} +{% if c_value.liveness_probe.http_get.scheme is defined %} + scheme = "{{c_value.liveness_probe.http_get.paschemeth}}" +{% endif %} + } +{% endif %} + } +{% endif %} +{% if c_value.volume is defined %} + volume = { + name = "{{c_value.volume.name}}" + mount_path = "{{c_value.volume.mount_path}}" + read_only = {{c_value.volume.read_only | lower | default(false)}} + empty_dir = {{c_value.volume.empty_dir | lower | default(false)}} +{% if c_value.volume.storage_account_name is defined %} + storage_account_name = {{ c_value.volume.storage_account_name }} +{% endif %} +{% if c_value.volume.storage_account_key is defined %} + storage_account_key = {{ c_value.volume.storage_account_key }} +{% endif %} +{% if c_value.volume.share_name is defined %} + share_name = {{ c_value.volume.share_name }} +{% endif %} +{% if c_value.volume.secret is defined %} + secret = {{ c_value.volume.secret }} +{% endif %} +{% if c_value.volume.git_repo is defined %} + git_repo = { + url = "{{c_value.volume.git_repo.git_repo}}" +{% if c_value.volume.git_repo.directory is defined %} + directory = "{{c_value.volume.git_repo.directory}}" +{% endif %} +{% if c_value.volume.git_repo.revision is defined %} + revision = "{{c_value.volume.git_repo.revision}}" +{% endif %} + } +{% endif %} + } +{% endif %} +{% if c_value.environment_variables is defined %} + environment_variables = { +{% for ev_key, ev_value in c_value.environment_variables.items() %} + {{ev_key}} = "{{ev_value}}" +{% endfor %} + } +{% endif %} +{% if c_value.secure_environment_variables is defined %} + secure_environment_variables = { +{% for sev_key, sev_value in c_value.secure_environment_variables.items() %} + {{sev_key}} = "{{sev_value}}" +{% endfor %} + } +{% endif %} +{% if c_value.environment_variables_from_resources is defined %} + environment_variables_from_resources = { +{% for evr_key, evr_value in c_value.environment_variables_from_resources.items() %} + {{evr_key}} = { + lz_key = "{{evr_value.lz_key}}" + output_key = "{{evr_value.output_key}}" + resource_key = "{{evr_value.resource_key}}" + attribute_key = "{{evr_value.attribute_key}}" + } +{% endfor %} + } +{% endif %} + } + } +{% endfor%} +{% if value.identity is defined %} + identity = { + type = "{{ value.identity.type }}" +{% if value.identity.managed_identity_keys is defined %} + managed_identity_keys = {{ value.identity.managed_identity_keys | replace('None','[]') | replace('\'','\"') }} +{% endif %} +{% if value.identity.remote is defined %} + remote = { +{% for msi_key, msi_value in value.identity.remote.items() %} + {{ msi_key }} = { + managed_identity_keys = {{ msi_value.managed_identity_keys | replace('None','[]') | replace('\'','\"') }} + } +{% endfor %} + } +{% endif %} + } +{% endif %} +{% if value.dns_config is defined %} + dns_config = { + nameservers = {{ value.dns_resources.nameservers | replace('None','[]') | replace('\'','\"') }} + search_domains = {{ value.dns_resources.search_domains | replace('None','[]') | replace('\'','\"') }} + } +{% endif %} + } +{% endfor %} +} \ No newline at end of file diff --git a/templates/resources/custom_role_definitions.tfvars.j2 b/templates/resources/custom_role_definitions.tfvars.j2 index 0cbfac619..d1e1bcc51 100644 --- a/templates/resources/custom_role_definitions.tfvars.j2 +++ b/templates/resources/custom_role_definitions.tfvars.j2 @@ -1,5 +1,5 @@ custom_role_definitions = { -{% for key, value in resources.subscriptions[subscription_key].custom_role_definitions.items() %} +{% for key, value in resources[tfstate_resource].resources[subscription_key].custom_role_definitions.items() %} {{ key }} = { name = "{{ value.name }}" {% if value.useprefix is defined %} @@ -11,7 +11,7 @@ custom_role_definitions = { {% if value.permissions is defined %} permissions = { {% for p_key, permission in value.permissions.items() %} - {{ p_key }} = {{ permission | sort | replace('None','[]') | replace('\'','\"') | replace(',', ',\n') }} + {{ p_key }} = {{ permission | sort | replace('None','[]') | replace('\'','\"') | replace(',', ',\n') | replace('[', '[\n') | replace(']', '\n]') }} {% endfor %} } {% endif %} diff --git a/templates/resources/ddos_services.tfvars.j2 b/templates/resources/ddos_services.tfvars.j2 new file mode 100644 index 000000000..7e7b608b3 --- /dev/null +++ b/templates/resources/ddos_services.tfvars.j2 @@ -0,0 +1,20 @@ +ddos_services = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].ddos_services.items() %} + "{{key}}" = { + resource_group_key = "{{ value.resource_group_key }}" + name = "{{ value.name }}" +{% if value.region_key is defined %} + region = "{{ value.region_key}}" +{% elif value.region is defined %} + region = "{{ value.region}}" +{% endif %} +{% if value.tags is defined %} + tags = { +{% for tag_key, tag_value in value.tags.items() %} + {{ tag_key }} = "{{ tag_value }}" +{% endfor %} + } +{% endif %} + } +{% endfor %} +} diff --git a/templates/resources/diagnostic_log_analytics.tfvars.j2 b/templates/resources/diagnostic_log_analytics.tfvars.j2 index 9fd8fe2a2..aa208500b 100644 --- a/templates/resources/diagnostic_log_analytics.tfvars.j2 +++ b/templates/resources/diagnostic_log_analytics.tfvars.j2 @@ -3,16 +3,29 @@ # diagnostic_log_analytics = { -{% for key, dla in resources.subscriptions[subscription_key].diagnostic_log_analytics.items() %} +{% for key, dla in resources[tfstate_resource].resources[subscription_key].diagnostic_log_analytics.items() %} {{ key }} = { - region = "{{ dla.region | default(config.caf_terraform.launchpad.default_region_key)}}" + region = "{{ dla.region | default(resources.default_region_key)}}" name = "{{ dla.name }}" resource_group_key = "{{ dla.resource_group_key }}" +{% if dla.sku is defined %} + sku = "{{ dla.sku }}" +{% endif %} +{% if dla.retention_in_days is defined %} + retention_in_days = {{ dla.retention_in_days }} +{% endif %} +{% if dla.tags is defined %} + tags = { +{% for tag_key, tag_value in dla.tags.items() %} + {{ tag_key }} = "{{ tag_value }}" +{% endfor %} + } +{% endif %} -{% if resources.subscriptions[subscription_key].diagnostic_log_analytics[key].diagnostic_profiles is defined %} +{% if dla.diagnostic_profiles is defined %} # you can setup up to 5 key diagnostic_profiles = { -{% for dp_key, dp_value in resources.subscriptions[subscription_key].diagnostic_log_analytics[key].diagnostic_profiles.items() %} +{% for dp_key, dp_value in dla.diagnostic_profiles.items() %} {{ dp_key }} = { definition_key = "{{ dp_value.definition_key }}" destination_type = "{{ dp_value.destination_type }}" @@ -21,12 +34,15 @@ diagnostic_log_analytics = { {% endfor %} } {% endif %} -{% if resources.subscriptions[subscription_key].diagnostic_log_analytics[key].solutions is defined %} - solutions = { -{% for sol_key, sol_value in resources.subscriptions[subscription_key].diagnostic_log_analytics[key].solutions.items() %} +{% if dla.solutions_maps is defined %} + solutions_maps = { +{% for sol_key, sol_value in dla.solutions_maps.items() %} {{ sol_key }} = { "publisher" = "{{ sol_value.publisher }}" "product" = "{{ sol_value.product }}" +{% if sol_value.promotion_code is defined %} + promotion_code = "{{ sol_value.promotion_code }}" +{% endif %} } {% endfor %} diff --git a/templates/resources/diagnostic_storage_accounts.tfvars.j2 b/templates/resources/diagnostic_storage_accounts.tfvars.j2 index d3dda9027..3916d115e 100644 --- a/templates/resources/diagnostic_storage_accounts.tfvars.j2 +++ b/templates/resources/diagnostic_storage_accounts.tfvars.j2 @@ -2,40 +2,40 @@ # Storage accounts, log analytics, event hubs diagnostic_storage_accounts = { -{% for key in config.caf_terraform.launchpad.regions.keys() %} +{% for key in resources.caf_regions.keys() %} # Stores diagnostic logging for {{key}} - diaglogs_{{config.caf_terraform.launchpad.regions[key].slug}} = { - name = "diaglogs{{ config.caf_terraform.launchpad.regions[key].slug }}" + diaglogs_{{resources.caf_regions[key].slug}} = { + name = "diaglogs{{ resources.caf_regions[key].slug }}" region = "{{key}}" - resource_group_key = "{{ resources.subscriptions[subscription_key].diagnostic_storage_accounts.diagnostics.resource_group_key }}" - account_kind = "{{ resources.subscriptions[subscription_key].diagnostic_storage_accounts.diagnostics.account_kind }}" - account_tier = "{{ resources.subscriptions[subscription_key].diagnostic_storage_accounts.diagnostics.account_tier }}" - account_replication_type = "{{ config.caf_terraform.launchpad.account_replication_type }}" - access_tier = "{{ resources.subscriptions[subscription_key].diagnostic_storage_accounts.diagnostics.access_tier }}" + resource_group_key = "{{ resources[tfstate_resource].resources[subscription_key].diagnostic_storage_accounts.diagnostics.resource_group_key }}" + account_kind = "{{ resources[tfstate_resource].resources[subscription_key].diagnostic_storage_accounts.diagnostics.account_kind }}" + account_tier = "{{ resources[tfstate_resource].resources[subscription_key].diagnostic_storage_accounts.diagnostics.account_tier }}" + account_replication_type = "{{ resources.launchpad.account_replication_type }}" + access_tier = "{{ resources[tfstate_resource].resources[subscription_key].diagnostic_storage_accounts.diagnostics.access_tier }}" } {% endfor %} -{% for key in config.caf_terraform.launchpad.regions.keys() %} +{% for key in resources.caf_regions.keys() %} # Stores security logs for siem for {{key}} - diagsiem_{{config.caf_terraform.launchpad.regions[key].slug}} = { - name = "siem{{ config.caf_terraform.launchpad.regions[key].slug }}" + diagsiem_{{resources.caf_regions[key].slug}} = { + name = "siem{{ resources.caf_regions[key].slug }}" region = "{{key}}" - resource_group_key = "{{ resources.subscriptions[subscription_key].diagnostic_storage_accounts.siem.resource_group_key }}" - account_kind = "{{ resources.subscriptions[subscription_key].diagnostic_storage_accounts.siem.account_kind }}" - account_tier = "{{ resources.subscriptions[subscription_key].diagnostic_storage_accounts.siem.account_tier }}" - account_replication_type = "{{ config.caf_terraform.launchpad.account_replication_type }}" - access_tier = "{{ resources.subscriptions[subscription_key].diagnostic_storage_accounts.siem.access_tier }}" + resource_group_key = "{{ resources[tfstate_resource].resources[subscription_key].diagnostic_storage_accounts.siem.resource_group_key }}" + account_kind = "{{ resources[tfstate_resource].resources[subscription_key].diagnostic_storage_accounts.siem.account_kind }}" + account_tier = "{{ resources[tfstate_resource].resources[subscription_key].diagnostic_storage_accounts.siem.account_tier }}" + account_replication_type = "{{ resources.launchpad.account_replication_type }}" + access_tier = "{{ resources[tfstate_resource].resources[subscription_key].diagnostic_storage_accounts.siem.access_tier }}" } {% endfor %} -{% for key in config.caf_terraform.launchpad.regions.keys() %} +{% for key in resources.caf_regions.keys() %} # Stores boot diagnostic for {{key}} - bootdiag_{{config.caf_terraform.launchpad.regions[key].slug}} = { - name = "boot{{ config.caf_terraform.launchpad.regions[key].slug }}" + bootdiag_{{resources.caf_regions[key].slug}} = { + name = "boot{{ resources.caf_regions[key].slug }}" region = "{{key}}" - resource_group_key = "{{ resources.subscriptions[subscription_key].diagnostic_storage_accounts.bootdiagnostics.resource_group_key }}" - account_kind = "{{ resources.subscriptions[subscription_key].diagnostic_storage_accounts.bootdiagnostics.account_kind }}" - account_tier = "{{ resources.subscriptions[subscription_key].diagnostic_storage_accounts.bootdiagnostics.account_tier }}" - account_replication_type = "{{ config.caf_terraform.launchpad.account_replication_type }}" - access_tier = "{{ resources.subscriptions[subscription_key].diagnostic_storage_accounts.bootdiagnostics.access_tier }}" + resource_group_key = "{{ resources[tfstate_resource].resources[subscription_key].diagnostic_storage_accounts.bootdiagnostics.resource_group_key }}" + account_kind = "{{ resources[tfstate_resource].resources[subscription_key].diagnostic_storage_accounts.bootdiagnostics.account_kind }}" + account_tier = "{{ resources[tfstate_resource].resources[subscription_key].diagnostic_storage_accounts.bootdiagnostics.account_tier }}" + account_replication_type = "{{ resources.launchpad.account_replication_type }}" + access_tier = "{{ resources[tfstate_resource].resources[subscription_key].diagnostic_storage_accounts.bootdiagnostics.access_tier }}" } {% endfor %} } \ No newline at end of file diff --git a/templates/resources/diagnostics_destinations.tfvars.j2 b/templates/resources/diagnostics_destinations.tfvars.j2 index 55f8acce2..cbf8abdb5 100644 --- a/templates/resources/diagnostics_destinations.tfvars.j2 +++ b/templates/resources/diagnostics_destinations.tfvars.j2 @@ -7,9 +7,9 @@ diagnostics_destinations = { # in the region of the deployment storage = { all_regions = { -{% for key in config.caf_terraform.launchpad.regions.keys() %} - "{{ config.caf_terraform.launchpad.regions[key].name }}" = { - storage_account_key = "diagsiem_{{config.caf_terraform.launchpad.regions[config.caf_terraform.launchpad.default_region_key].slug}}" +{% for key in resources.caf_regions.keys() %} + "{{ resources.caf_regions[key].name }}" = { + storage_account_key = "diagsiem_{{resources.caf_regions[resources.default_region_key].slug}}" } {% endfor %} } @@ -17,14 +17,14 @@ diagnostics_destinations = { log_analytics = { central_logs = { - log_analytics_key = "central_logs_{{config.caf_terraform.launchpad.regions[config.caf_terraform.launchpad.default_region_key].slug}}" + log_analytics_key = "central_logs_{{resources.caf_regions[resources.default_region_key].slug}}" log_analytics_destination_type = "Dedicated" } } event_hub_namespaces = { central_logs = { - event_hub_namespace_key = "central_logs_{{config.caf_terraform.launchpad.regions[config.caf_terraform.launchpad.default_region_key].slug}}" + event_hub_namespace_key = "central_logs_{{resources.caf_regions[resources.default_region_key].slug}}" } } } diff --git a/templates/resources/dynamic_keyvault_secrets.tfvars.j2 b/templates/resources/dynamic_keyvault_secrets.tfvars.j2 new file mode 100644 index 000000000..edccb1955 --- /dev/null +++ b/templates/resources/dynamic_keyvault_secrets.tfvars.j2 @@ -0,0 +1,13 @@ +dynamic_keyvault_secrets = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].dynamic_keyvault_secrets.items() %} + {{ key }} = { +{% for l1_key, l1_value in value.items() %} + {{l1_key}} = { +{% for l2_key, l2_value in l1_value.items() %} + {{l2_key}} = "{{l2_value}}" +{% endfor%} + } +{% endfor%} + } +{% endfor %} +} \ No newline at end of file diff --git a/templates/resources/express_route_connections.tfvars.j2 b/templates/resources/express_route_connections.tfvars.j2 new file mode 100644 index 000000000..7ca3b4574 --- /dev/null +++ b/templates/resources/express_route_connections.tfvars.j2 @@ -0,0 +1,83 @@ +express_route_connections = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].express_route_connections.items() %} +{% if value.enable_er_connections %} + {{ key }} = { + name = "{{ value.name }}" +{% if value.enable_internet_security is defined %} + enable_internet_security = {{ value.enable_internet_security | string | lower }} +{% endif %} +{% if value.routing_weight is defined %} + routing_weight = {{ value.routing_weight }} +{% endif %} +{% if value.express_route_gateway_id is defined %} + express_route_gateway_id = "{{ value.express_route_gateway_id }}" +{% endif %} + virtual_hub = { +{% if value.virtual_hub.key is defined %} + key = "{{ value.virtual_hub.key }}" +{% endif %} +{% if value.virtual_hub.lz_key is defined %} + lz_key = "{{ value.virtual_hub.lz_key }}" +{% endif %} +{% if value.virtual_hub.id is defined %} + id = "{{ value.virtual_hub.id }}" +{% endif %} + } +{% if value.express_route_circuit_peering_id is defined %} + express_route_circuit_peering_id = "{{ value.express_route_circuit_peering_id }}" +{% endif %} + circuit_peering = { +{% if value.circuit_peering.lz_key is defined %} + lz_key = "{{ value.circuit_peering.lz_key }}" +{% endif %} + key = "{{ value.circuit_peering.key }}" + } +{% if value.express_route_circuit_authorization is defined %} + express_route_circuit_authorization = { +{% if value.express_route_circuit_authorization.lz_key is defined %} + lz_key = "{{ value.express_route_circuit_authorization.lz_key }}" +{% endif %} + key = "{{ value.express_route_circuit_authorization.key }}" + } +{% endif %} +{% if value.routing is defined %} + routing = { +{% if value.routing.propagated_route_table is defined %} + propagated_route_table = { +{% if value.routing.propagated_route_table.labels is defined %} + labels = {{ value.routing.propagated_route_table.labels | replace('None','[]') | replace('\'','\"') }} +{% endif %} + } +{% endif %} + } +{% endif %} +{% if value.route_table is defined %} + route_table = { +{% if value.route_table.key is defined %} + key = "{{ value.route_table.key }}" +{% endif %} +{% if value.route_table.lz_key is defined %} + lz_key = "{{ value.route_table.lz_key }}" +{% endif %} +{% if value.route_table.id is defined %} + id = "{{ value.route_table.id }}" +{% endif %} + } +{% endif %} +{% if value.propagated_route_tables is defined %} + propagated_route_tables = { +{% if value.propagated_route_tables.lz_key is defined %} + lz_key = "{{ value.propagated_route_tables.lz_key }}" +{% endif %} +{% if value.propagated_route_tables.keys is defined %} + keys = {{ value.propagated_route_tables.keys | replace('None','[]') | replace('\'','\"') }} +{% endif %} +{% if value.propagated_route_tables.ids is defined %} + ids = {{ value.propagated_route_tables.ids | replace('None','[]') | replace('\'','\"') }} +{% endif %} + } +{% endif %} + } +{% endif %} +{% endfor %} +} \ No newline at end of file diff --git a/templates/resources/global_settings.tfvars.j2 b/templates/resources/global_settings.tfvars.j2 index 03b0894c4..c7774c050 100644 --- a/templates/resources/global_settings.tfvars.j2 +++ b/templates/resources/global_settings.tfvars.j2 @@ -1,21 +1,21 @@ -{% if resources.subscriptions[subscription_key].global_settings is defined %} +{% if resources[tfstate_resource].resources[subscription_key].global_settings is defined %} global_settings = { - passthrough = {{ resources.subscriptions[subscription_key].global_settings.passthrough | string | lower }} - prefix = "{{ resources.subscriptions[subscription_key].global_settings.prefix }}" - use_slug = {{ resources.subscriptions[subscription_key].global_settings.use_slug | string | lower }} - inherit_tags = {{ resources.subscriptions[subscription_key].global_settings.inherit_tags | string | lower }} - random_length = {{ resources.subscriptions[subscription_key].global_settings.random_length }} -{% if resources.subscriptions[subscription_key].global_settings.tags is defined %} + passthrough = {{ resources[tfstate_resource].resources[subscription_key].global_settings.passthrough | string | lower }} + prefix = "{{ resources[tfstate_resource].resources[subscription_key].global_settings.prefix }}" + use_slug = {{ resources[tfstate_resource].resources[subscription_key].global_settings.use_slug | string | lower }} + inherit_tags = {{ resources[tfstate_resource].resources[subscription_key].global_settings.inherit_tags | string | lower }} + random_length = {{ resources[tfstate_resource].resources[subscription_key].global_settings.random_length }} +{% if resources[tfstate_resource].resources[subscription_key].global_settings.tags is defined %} tags = { -{% for tag, value in resources.subscriptions[subscription_key].global_settings.tags.items() %} +{% for tag, value in resources[tfstate_resource].resources[subscription_key].global_settings.tags.items() %} "{{ tag }}" = "{{value}}" {% endfor %} } {% endif %} - default_region = "{{ resources.subscriptions[subscription_key].global_settings.default_region_key }}" + default_region = "{{ resources[tfstate_resource].resources[subscription_key].global_settings.default_region_key }}" regions = { -{% for key in resources.subscriptions[subscription_key].global_settings.regions.keys() %} - {{ key }} = "{{ resources.subscriptions[subscription_key].global_settings.regions[key].name }}" +{% for key in resources[tfstate_resource].resources[subscription_key].global_settings.regions.keys() %} + {{ key }} = "{{ resources[tfstate_resource].resources[subscription_key].global_settings.regions[key].name }}" {% endfor %} } } diff --git a/templates/resources/keyvault_access_policies.tfvars.j2 b/templates/resources/keyvault_access_policies.tfvars.j2 index c1626040e..e81fadd16 100644 --- a/templates/resources/keyvault_access_policies.tfvars.j2 +++ b/templates/resources/keyvault_access_policies.tfvars.j2 @@ -1,5 +1,5 @@ keyvault_access_policies = { - {% for key, policy in resources.subscriptions[subscription_key].keyvault_access_policies.items() %} + {% for key, policy in resources[tfstate_resource].resources[subscription_key].keyvault_access_policies.items() %} {{ key }} = { {% for s_key, s_policy in policy.items() %} {{ s_key }} = { diff --git a/templates/resources/keyvaults.tfvars.j2 b/templates/resources/keyvaults.tfvars.j2 index 7eb353ee2..79f0561ec 100644 --- a/templates/resources/keyvaults.tfvars.j2 +++ b/templates/resources/keyvaults.tfvars.j2 @@ -1,9 +1,9 @@ keyvaults = { -{% for key, keyvault in resources.subscriptions[subscription_key].keyvaults.items() %} +{% for key, keyvault in resources[tfstate_resource].resources[subscription_key].keyvaults.items() %} {{ key }} = { - name = "{{ resources.subscriptions[subscription_key].keyvaults[key].name }}" - resource_group_key = "{{ resources.subscriptions[subscription_key].keyvaults[key].resource_group_key }}" - sku_name = "{{ resources.subscriptions[subscription_key].keyvaults[key].sku_name | default('standard')}}" + name = "{{ resources[tfstate_resource].resources[subscription_key].keyvaults[key].name }}" + resource_group_key = "{{ resources[tfstate_resource].resources[subscription_key].keyvaults[key].resource_group_key }}" + sku_name = "{{ resources[tfstate_resource].resources[subscription_key].keyvaults[key].sku_name | default('standard')}}" {% if keyvault.enabled_for_deployment is defined %} enabled_for_deployment = "{{ keyvault.enabled_for_deployment | string | lower }}" {% endif %} @@ -22,10 +22,16 @@ keyvaults = { {% if keyvault.soft_delete_retention_days is defined %} soft_delete_retention_days = {{ keyvault.soft_delete_retention_days }} {% endif %} - +{% if keyvault.tags is defined %} + tags = { +{% for tag_key, tag_value in keyvault.tags.items() %} + {{ tag_key }} = "{{ tag_value }}" +{% endfor %} + } +{% endif %} creation_policies = { -{% if config.platform_identity is defined %} -{% if config.platform_identity.azuread_identity_mode == 'logged_in_user' %} +{% if resources.platform_identity is defined %} +{% if resources.azure_landing_zones.identity.azuread_identity_mode == 'logged_in_user' %} logged_in_user = { secret_permissions = ["Set", "Get", "List", "Delete", "Purge", "Recover"] } diff --git a/templates/resources/landingzone.tfvars.j2 b/templates/resources/landingzone.tfvars.j2 index 67c882584..5ba1525f1 100644 --- a/templates/resources/landingzone.tfvars.j2 +++ b/templates/resources/landingzone.tfvars.j2 @@ -1,46 +1,51 @@ landingzone = { - backend_type = "{{ config.caf_terraform.launchpad.backend_type | default("azurerm") }}" - level = "{{ config.tfstates['asvm'][subscription_key].level }}" -{% if deployments.deployments[subscription_key][deployment].landingzone.key.asvm is defined %} -{% for l_key, l_value in deployments.deployments[subscription_key][deployment].landingzone.key.asvm.items() %} - key = "{{ config.tfstates['asvm'][l_key][l_value].lz_key_name}}" -{% endfor %} -{% endif %} -{% if deployments.deployments[subscription_key][deployment].landingzone.global_settings_key.platform is defined %} -{% if deployments.deployments[subscription_key][deployment].landingzone.global_settings_key.platform.virtual_hubs is defined %} - global_settings_key = "{{ config.tfstates['platform'].virtual_hubs[deployments.deployments[subscription_key][deployment].landingzone.global_settings_key.platform.virtual_hubs].lz_key_name }}" -{% elif deployments.deployments[subscription_key][deployment].landingzone.global_settings_key.platform.asvm is defined %} - global_settings_key = "{{ config.tfstates['platform'].asvm.lz_key_name }}" -{% endif %} + backend_type = "{{ tfstate_object.backend_type | default("azurerm") }}" + level = "{{ tfstate_object.level }}" + key = "{{ tfstate_object.lz_key_name }}" +{% if resources[tfstate_resource].deployments.landingzone.global_settings_key.platform is defined %} +{% if resources[tfstate_resource].deployments.landingzone.global_settings_key.platform.values() | first %} + global_settings_key = "{{ resources.tfstates['platform'][resources[tfstate_resource].deployments.landingzone.global_settings_key.platform.keys() | first][resources[tfstate_resource].deployments.landingzone.global_settings_key.platform.values() | first].lz_key_name }}" {% else %} -{% for m_key, m_value in deployments.deployments[subscription_key][deployment].landingzone.global_settings_key.asvm.items() %} - global_settings_key = "{{ config.tfstates['asvm'][m_key][m_value].lz_key_name }}" -{% endfor %} + global_settings_key = "{{ resources.tfstates['platform'][resources[tfstate_resource].deployments.landingzone.global_settings_key.platform.keys() | first].lz_key_name }}" +{% endif %} +{% elif resources[tfstate_resource].deployments.landingzone.global_settings_key.asvm is defined %} + global_settings_key = "{{ resources.tfstates['asvm'][resources[tfstate_resource].deployments.landingzone.global_settings_key.asvm.keys() | first].lz_key_name }}" {% endif %} - -{% if deployments.deployments[subscription_key][deployment].landingzone.remote_tfstates is defined %} +{% if resources[tfstate_resource].deployments.landingzone.remote_tfstates is defined %} tfstates = { -{% if deployments.deployments[subscription_key][deployment].landingzone.remote_tfstates.asvm is defined %} -{% for a_key, a_value in deployments.deployments[subscription_key][deployment].landingzone.remote_tfstates.asvm.items() %} - {{ config.tfstates['asvm'][a_key][a_value].lz_key_name }} = { - tfstate = "{{ config.tfstates['asvm'][a_key][a_value].tfstate }}" - workspace = "{{ config.tfstates['asvm'][a_key].workspace }}" +{% if resources[tfstate_resource].deployments.landingzone.remote_tfstates.asvm is defined %} +{% if resources[tfstate_resource].deployments.landingzone.remote_tfstates.asvm.values() | first %} +{% for a_key, a_value in resources[tfstate_resource].deployments.landingzone.remote_tfstates.asvm.items() %} + {{ resources.tfstates['asvm'][a_key][a_value].lz_key_name }} = { + tfstate = "{{ resources.tfstates['asvm'][a_key][a_value].tfstate }}" + workspace = "{{ resources.tfstates['asvm'][a_key].workspace }}" } {% endfor %} +{% else %} + {{ resources.tfstates['asvm'][resources[tfstate_resource].deployments.landingzone.remote_tfstates.asvm.keys() | first].lz_key_name }} = { + tfstate = "{{ resources.tfstates['asvm'][resources[tfstate_resource].deployments.landingzone.remote_tfstates.asvm.keys() | first].tfstate }}" + workspace = "{{ resources.tfstates['asvm'][resources[tfstate_resource].deployments.landingzone.remote_tfstates.asvm.keys() | first].workspace | default('tfstate')}}" + } {% endif %} -{% if deployments.deployments[subscription_key][deployment].landingzone.remote_tfstates.platform is defined %} -{% for p_key in deployments.deployments[subscription_key][deployment].landingzone.remote_tfstates.platform.keys() %} -{% if config.tfstates['platform'][p_key][deployments.deployments[subscription_key][deployment].landingzone.remote_tfstates.platform[p_key]] is defined %} - {{ config.tfstates['platform'][p_key][deployments.deployments[subscription_key][deployment].landingzone.remote_tfstates.platform[p_key]].lz_key_name }} = { - tfstate = "{{ config.tfstates['platform'][p_key][deployments.deployments[subscription_key][deployment].landingzone.remote_tfstates.platform[p_key]].tfstate }}" +{% endif %} +{% if resources[tfstate_resource].deployments.landingzone.remote_tfstates.platform is defined %} +{% for p_key in resources[tfstate_resource].deployments.landingzone.remote_tfstates.platform.keys() %} +{% if resources.tfstates['platform'][p_key][resources[tfstate_resource].deployments.landingzone.remote_tfstates.platform[p_key]] is defined %} + {{ resources.tfstates['platform'][p_key][resources[tfstate_resource].deployments.landingzone.remote_tfstates.platform[p_key]].lz_key_name }} = { + {% set remote_tfstate = resources.tfstates['platform'][p_key][resources[tfstate_resource].deployments.landingzone.remote_tfstates.platform[p_key]] %} + tfstate = "{{ remote_tfstate.tfstate }}" + workspace = "{{ remote_tfstate.workspace | default('tfstate') }}" +{% if remote_tfstate.level != level %} level = "lower" - workspace = "{{ config.tfstates['platform'][p_key][deployments.deployments[subscription_key][deployment].landingzone.remote_tfstates.platform[p_key]].workspace | default('tfstate') }}" +{% endif %} } {% else %} - {{ config.tfstates['platform'][p_key].lz_key_name }} = { - tfstate = "{{ config.tfstates['platform'][p_key].tfstate }}" + {{ resources.tfstates['platform'][p_key].lz_key_name }} = { + tfstate = "{{ resources.tfstates['platform'][p_key].tfstate }}" + workspace = "{{ resources.tfstates['platform'][p_key].workspace | default('tfstate') }}" +{% if resources.tfstates['platform'][p_key].level != level %} level = "lower" - workspace = "{{ config.tfstates['platform'][p_key].workspace | default('tfstate') }}" +{% endif %} } {% endif %} {% endfor %} @@ -48,3 +53,10 @@ landingzone = { } {% endif %} } +{% if resources[tfstate_resource].deployments.custom_variables is defined %} +custom_variables = { +{% for cv_key, cv_value in resources[tfstate_resource].deployments.custom_variables.items() %} + {{cv_key}} = "{{cv_value}}" +{% endfor %} +} +{% endif %} \ No newline at end of file diff --git a/templates/resources/managed_identities.tfvars.j2 b/templates/resources/managed_identities.tfvars.j2 index d7c483b16..4618d6f6e 100644 --- a/templates/resources/managed_identities.tfvars.j2 +++ b/templates/resources/managed_identities.tfvars.j2 @@ -1,5 +1,5 @@ managed_identities = { -{% for key, value in resources.subscriptions[subscription_key].managed_identities.items() %} +{% for key, value in resources[tfstate_resource].resources[subscription_key].managed_identities.items() %} {{ key }} = { name = "{{ value.name }}" resource_group_key = "{{ value.resource_group_key }}" diff --git a/templates/resources/monitor_action_groups.tfvars.j2 b/templates/resources/monitor_action_groups.tfvars.j2 index 83601f60a..40f5479f0 100644 --- a/templates/resources/monitor_action_groups.tfvars.j2 +++ b/templates/resources/monitor_action_groups.tfvars.j2 @@ -1,5 +1,5 @@ monitor_action_groups = { -{% for key, mag in resources.subscriptions[subscription_key].monitor_action_groups.items() %} +{% for key, mag in resources[tfstate_resource].resources[subscription_key].monitor_action_groups.items() %} {{ key }} = { action_group_name = "{{ mag.action_group_name }}" shortname = "{{ mag.shortname }}" diff --git a/templates/resources/network_profiles.tfvars.j2 b/templates/resources/network_profiles.tfvars.j2 new file mode 100644 index 000000000..d1792ee28 --- /dev/null +++ b/templates/resources/network_profiles.tfvars.j2 @@ -0,0 +1,38 @@ +network_profiles = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].network_profiles.items() %} + {{ key }} = { + name = "{{ value.name }}" + resource_group = { +{% if value.resource_group.lz_key is defined %} + lz_key = "{{ value.resource_group.lz_key }}" +{% endif %} + key = "{{ value.resource_group.key }}" + } + container_network_interface = { + name = "{{ value.container_network_interface.name }}" + ip_configurations = { +{% for ip_key, ip_value in value.container_network_interface.ip_configurations.items() %} + {{ip_key}} = { + name = "{{ ip_value.name }}" +{% if ip_value.subnet_id is defined %} + subnet_id = "{{ ip_value.subnet_id }}" +{% endif %} +{% if ip_value.lz_key is defined %} + subnetlz_key_id = "{{ ip_value.lz_key }}" +{% endif %} +{% if ip_value.vnet_key is defined %} + vnet_key = "{{ ip_value.vnet_key }}" +{% endif %} +{% if ip_value.subnet_key is defined %} + subnet_key = "{{ ip_value.subnet_key }}" +{% endif %} +{% if ip_value.virtual_subnet_key is defined %} + virtual_subnet_key = "{{ ip_value.virtual_subnet_key }}" +{% endif %} + } +{% endfor %} + } + } + } +{% endfor %} +} \ No newline at end of file diff --git a/templates/resources/network_security_group_definition.tfvars.j2 b/templates/resources/network_security_group_definition.tfvars.j2 index 90cf1d185..e5949d1de 100644 --- a/templates/resources/network_security_group_definition.tfvars.j2 +++ b/templates/resources/network_security_group_definition.tfvars.j2 @@ -1,5 +1,5 @@ network_security_group_definition = { -{% for key, value in resources.subscriptions[subscription_key].network_security_group_definition.items() %} +{% for key, value in resources[tfstate_resource].resources[subscription_key].network_security_group_definition.items() %} {{ key }} = { version = {{ value.version }} resource_group_key = "{{ value.resource_group_key }}" diff --git a/templates/resources/private_dns.tfvars.j2 b/templates/resources/private_dns.tfvars.j2 index aeba296a4..cbc93b2d7 100644 --- a/templates/resources/private_dns.tfvars.j2 +++ b/templates/resources/private_dns.tfvars.j2 @@ -1,5 +1,5 @@ private_dns = { -{% for key, value in resources.subscriptions[subscription_key].private_dns.items() %} +{% for key, value in resources[tfstate_resource].resources[subscription_key].private_dns.items() %} "{{ key }}" = { name = "{{ value.name }}" resource_group_key = "{{ value.resource_group_key }}" diff --git a/templates/resources/public_ip_addresses.tfvars.j2 b/templates/resources/public_ip_addresses.tfvars.j2 index 03e218019..aee729c64 100644 --- a/templates/resources/public_ip_addresses.tfvars.j2 +++ b/templates/resources/public_ip_addresses.tfvars.j2 @@ -1,5 +1,5 @@ public_ip_addresses = { -{% for key, value in resources.subscriptions[subscription_key].public_ip_addresses.items() %} +{% for key, value in resources[tfstate_resource].resources[subscription_key].public_ip_addresses.items() %} {{ key }} = { name = "{{ value.name }}" resource_group_key = "{{ value.resource_group_key }}" diff --git a/templates/resources/recovery_vaults.tfvars.j2 b/templates/resources/recovery_vaults.tfvars.j2 index 6da1e957b..0d53d2e53 100644 --- a/templates/resources/recovery_vaults.tfvars.j2 +++ b/templates/resources/recovery_vaults.tfvars.j2 @@ -1,10 +1,10 @@ recovery_vaults = { -{% for key, asr in resources.subscriptions[subscription_key].recovery_vaults.items() %} +{% for key, asr in resources[tfstate_resource].resources[subscription_key].recovery_vaults.items() %} {{ key }} = { name = "{{ asr.name }}" resource_group_key = "{{ asr.resource_group_key }}" - region = "{{ asr.region | default(config.caf_terraform.launchpad.default_region_key) }}" + region = "{{ asr.region | default(resources.default_region_key) }}" soft_delete_enabled = {{ asr.soft_delete_enabled | default(true) | string | lower }} {% if asr.backup_policies is defined %} backup_policies = { diff --git a/templates/resources/resource_groups.tfvars.j2 b/templates/resources/resource_groups.tfvars.j2 index 939de697a..700fc9c8f 100644 --- a/templates/resources/resource_groups.tfvars.j2 +++ b/templates/resources/resource_groups.tfvars.j2 @@ -1,8 +1,8 @@ resource_groups = { -{% for key, resource_group in resources.subscriptions[subscription_key].resource_groups.items() %} +{% for key, resource_group in resources[tfstate_resource].resources[subscription_key].resource_groups.items() %} {{ key }} = { name = "{{ resource_group.name }}" - region = "{{ resource_group.region_key | default(config.caf_terraform.launchpad.default_region_key) }}" + region = "{{ resource_group.region_key | default(resources.default_region_key) }}" {% if resource_group.tags is defined %} tags = { {% for tag_key, tag_value in resource_group.tags.items() %} diff --git a/templates/resources/role_mapping.tfvars.j2 b/templates/resources/role_mapping.tfvars.j2 index 79827a28b..0b21b8458 100644 --- a/templates/resources/role_mapping.tfvars.j2 +++ b/templates/resources/role_mapping.tfvars.j2 @@ -1,5 +1,5 @@ role_mapping = { -{% for top_key, mappings in resources.subscriptions[subscription_key].role_mapping.items() %} +{% for top_key, mappings in resources[tfstate_resource].resources[subscription_key].role_mapping.items() %} {{ top_key }} = { {% for key, role_mappings in mappings.items() %} {{ key }} = { diff --git a/templates/resources/servicehealth.tfvars.j2 b/templates/resources/servicehealth.tfvars.j2 index f2ae44920..763189d5d 100644 --- a/templates/resources/servicehealth.tfvars.j2 +++ b/templates/resources/servicehealth.tfvars.j2 @@ -1,14 +1,14 @@ monitoring = { -{% if resources.subscriptions[subscription_key].service_health_alerts is defined %} +{% if resources[tfstate_resource].resources[subscription_key].service_health_alerts is defined %} service_health_alerts = { - enable_service_health_alerts = {{resources.subscriptions[subscription_key].service_health_alerts.enable_service_health_alerts | lower | default(true)}} - name = "{{resources.subscriptions[subscription_key].service_health_alerts.name}}" - action_group_name = "{{resources.subscriptions[subscription_key].service_health_alerts.action_group_name}}" - shortname = "{{resources.subscriptions[subscription_key].service_health_alerts.shortname}}" - resource_group_key = "{{resources.subscriptions[subscription_key].service_health_alerts.resource_group_key}}" -{% if resources.subscriptions[subscription_key].service_health_alerts.email_alert_settings is defined %} + enable_service_health_alerts = {{resources[tfstate_resource].resources[subscription_key].service_health_alerts.enable_service_health_alerts | lower | default(true)}} + name = "{{resources[tfstate_resource].resources[subscription_key].service_health_alerts.name}}" + action_group_name = "{{resources[tfstate_resource].resources[subscription_key].service_health_alerts.action_group_name}}" + shortname = "{{resources[tfstate_resource].resources[subscription_key].service_health_alerts.shortname}}" + resource_group_key = "{{resources[tfstate_resource].resources[subscription_key].service_health_alerts.resource_group_key}}" +{% if resources[tfstate_resource].resources[subscription_key].service_health_alerts.email_alert_settings is defined %} email_alert_settings = { -{% for key, sha in resources.subscriptions[subscription_key].service_health_alerts.email_alert_settings.items() %} +{% for key, sha in resources[tfstate_resource].resources[subscription_key].service_health_alerts.email_alert_settings.items() %} {{ key }} = { name = "{{ sha.name }}" email_address = "{{ sha.email_address }}" diff --git a/templates/resources/storage_accounts.tfvars.j2 b/templates/resources/storage_accounts.tfvars.j2 new file mode 100644 index 000000000..827293ac6 --- /dev/null +++ b/templates/resources/storage_accounts.tfvars.j2 @@ -0,0 +1,171 @@ +storage_accounts = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].storage_accounts.items() %} + {{ key }} = { + name = "{{ value.name }}" + resource_group_key = "{{ value.resource_group_key }}" + account_kind = "{{ value.account_kind | default('BlobStorage') }}" + account_tier = "{{ value.account_tier | default('Standard') }}" +{% if value.shared_access_key_enabled is defined %} + shared_access_key_enabled = {{ value.shared_access_key_enabled | lower | default('false') }} +{% endif %} + account_replication_type = "{{ value.account_replication_type }}" +{% if value.access_tier is defined %} + access_tier = "{{ value.access_tier }}" +{% endif %} +{% if value.min_tls_version is defined %} + min_tls_version = "{{ value.min_tls_version }}" +{% endif %} +{% if value.allow_blob_public_access is defined %} + allow_blob_public_access = {{ value.allow_blob_public_access | lower }} +{% endif %} +{% if value.is_hns_enabled is defined %} + is_hns_enabled = {{ value.is_hns_enabled | lower }} +{% endif %} +{% if value.nfsv3_enabled is defined %} + nfsv3_enabled = {{ value.nfsv3_enabled | lower }} +{% endif %} +{% if value.large_file_share_enabled is defined %} + large_file_share_enabled = {{ value.large_file_share_enabled | lower }} +{% endif %} +{% if value.enable_system_msi is defined %} + enable_system_msi = {{ value.enable_system_msi | lower }} +{% endif %} +{% if value.blob_properties is defined %} + blob_properties = { +{% if value.blob_properties.versioning_enabled is defined %} + versioning_enabled = {{ value.blob_properties.versioning_enabled | lower }} +{% endif %} +{% if value.blob_properties.change_feed_enabled is defined %} + change_feed_enabled = {{ value.blob_properties.change_feed_enabled | lower }} +{% endif %} +{% if value.blob_properties.last_access_time_enabled is defined %} + last_access_time_enabled = {{ value.blob_properties.last_access_time_enabled | lower }} +{% endif %} +{% if value.blob_properties.default_service_version is defined %} + default_service_version = "{{ value.blob_properties.default_service_version }}" +{% endif %} +{% if value.blob_properties.container_delete_retention_policy is defined %} + container_delete_retention_policy = { + days = {{ value.blob_properties.container_delete_retention_policy.days }} + } +{% endif %} +{% if value.blob_properties.delete_retention_policy is defined %} + delete_retention_policy = { + days = {{ value.blob_properties.delete_retention_policy.days }} + } +{% endif %} + } +{% endif %} +{% if value.network is defined %} + network = { +{% if value.network.default_action is defined %} + default_action = "{{ value.network.default_action }}" +{% endif %} +{% if value.network.bypass is defined %} + bypass = {{ value.network.bypass | replace('None','[]') | replace('\'','\"') }} +{% endif %} +{% if value.network.ip_rules is defined %} + ip_rules = {{ value.network.ip_rules | replace('None','[]') | replace('\'','\"') }} +{% endif %} +{% if value.network.subnets is defined %} + subnets = { +{% for s_key, s_value in value.network.subnets.items() %} + {{ s_key }} = { +{% if s_value.remote_subnet_id is defined %} + remote_subnet_id = "{{ s_value.remote_subnet_id }}" +{% else %} +{% if s_value.lz_key is defined %} + lz_key = "{{ s_value.lz_key }}" +{% endif %} + vnet_key = "{{ s_value.vnet_key }}" + subnet_key = "{{ s_value.subnet_key }}" +{% endif %} + } +{% endfor %} + } +{% endif %} + } +{% endif %} + + +{% if value.management_policies is defined %} + management_policies = { +{% for mp_key, mp_value in value.management_policies.items() %} + {{ mp_key }} = { + enabled = {{mp_value.enabled | default(True) | lower}} + name = "{{mp_value.name}}" + filters = { +{% for mpf_key, mpf_value in mp_value.filters.items() %} + {{mpf_key}} = { +{% if mpf_value.prefix_match is defined %} + prefix_match = {{ mpf_value.prefix_match | replace('None','[]') | replace('\'','\"') }} +{% endif %} +{% if mpf_value.blob_types is defined %} + blob_types = {{ mpf_value.blob_types | replace('None','[]') | replace('\'','\"') }} +{% endif %} +{% if mpf_value.match_blob_index_tag is defined %} + match_blob_index_tag = { + {{ mpf_value.match_blob_index_tag.0.keys() }} = { + name = "{{ mpf_value.match_blob_index_tag.0.name }}" + operation = "{{ mpf_value.match_blob_index_tag.0.operation }}" + value = "{{ mpf_value.match_blob_index_tag.0.value }}" + } + } +{% endif %} + } +{% endfor %} + } + actions = { + base_blob = { +{% for aa_key, aa_value in mp_value.actions.base_blob.items() %} + {{ aa_key }} = { +{% for ab_key, ab_value in aa_value.items() %} + {{ ab_key }} = {{ ab_value }} +{% endfor %} + } +{% endfor %} + } + snapshot = { +{% for aa_key, aa_value in mp_value.actions.snapshot.items() %} + {{ aa_key }} = { +{% for ab_key, ab_value in aa_value.items() %} + {{ ab_key }} = {{ ab_value }} +{% endfor %} + } +{% endfor %} + } + version = { +{% for aa_key, aa_value in mp_value.actions.version.items() %} + {{ aa_key }} = { +{% for ab_key, ab_value in aa_value.items() %} + {{ ab_key }} = {{ ab_value }} +{% endfor %} + } +{% endfor %} + } + } + } +{% endfor %} + } +{% endif %} + +{% if value.containers is defined %} + containers = { +{% for c_key, c_value in value.containers.items() %} + {{ c_key }} = { + name = "{{ c_value.name }}" + } +{% endfor %} + } +{% endif %} +{% if value.tags is defined %} + tags = { +{% for tag_key, tag_value in value.tags.items() %} + {{ tag_key }} = "{{ tag_value }}" +{% endfor %} + } +{% endif %} + } + +{% endfor %} +} \ No newline at end of file diff --git a/templates/resources/subscriptions.tfvars.j2 b/templates/resources/subscriptions.tfvars.j2 index f11c58513..0bbac20da 100644 --- a/templates/resources/subscriptions.tfvars.j2 +++ b/templates/resources/subscriptions.tfvars.j2 @@ -1,22 +1,18 @@ +# +# Execute the following command to get the billing_account_name and management_group_id +# +# az rest --method get --uri https://management.azure.com/providers/Microsoft.Billing/billingaccounts/?api-version=2020-05-01 +# +# To retrieve the first billing account +# +# billing_account_name=$(az rest --method get --uri https://management.azure.com/providers/Microsoft.Billing/billingaccounts?api-version=2020-05-01 --query "value[?properties.agreementType=='EnterpriseAgreement'].{name:name}" -o tsv) +# +# enrollment_account_name=$(az rest --method get --uri https://management.azure.com/providers/Microsoft.Billing/billingaccounts?api-version=2020-05-01 --query "value[?properties.agreementType=='EnterpriseAgreement'].{name:properties.enrollmentAccounts[0].name}" -o tsv) +# + subscriptions = { -{% for key, value in resources.subscriptions[subscription_key].items() %} - {{ key }} = { - name = "{{ value.name }}" - billing_account_name = "{{ config.caf_terraform.billing_subscription_role_delegations.billing_account_name }}" - enrollment_account_name = "{{ config.caf_terraform.billing_subscription_role_delegations.enrollment_account_name }}" -{% if value.management_group_suffix is defined %} - management_group_id = "{{ config.platform_core_setup.enterprise_scale.management_group_prefix }}-{{ value.management_group_suffix }}" -{% else %} - management_group_id = "{{ value.management_group_id }}" -{% endif %} - workload = "{{ value.workload | default('Production') }}" -{% if value.tags is defined %} - tags = { -{% for tag_key in value.tags %} - {{ tag_key }} = "{{ value.tags[tag_key] }}" -{% endfor %} - } -{% endif %} - } -{% endfor %} +{% for key, value in resources[tfstate_resource].resources[subscription_key].subscriptions.items() %} +{% include 'subscriptions_tpl.j2' %} +{% endfor %} + } \ No newline at end of file diff --git a/templates/resources/subscriptions_tpl.j2 b/templates/resources/subscriptions_tpl.j2 new file mode 100644 index 000000000..3c9d4351a --- /dev/null +++ b/templates/resources/subscriptions_tpl.j2 @@ -0,0 +1,26 @@ + +{{ key }} = { + name = "{{ value.name }}" +{% if value.create_alias is defined %} + create_alias = {{ value.create_alias | lower}} +{% endif %} +{% if value.subscription_id is not defined %} + billing_account_name = "{{ resources.caf_terraform.billing_subscription_role_delegations.billing_account_name }}" + enrollment_account_name = "{{ resources.caf_terraform.billing_subscription_role_delegations.enrollment_account_name }}" +{% if value.management_group_suffix is defined %} + management_group_id = "{{ resources.azure_landing_zones.enterprise_scale.management_group_prefix }}-{{ value.management_group_suffix }}" +{% else %} + management_group_id = "{{ value.management_group_id }}" +{% endif %} + workload = "{{ value.workload | default('Production') }}" +{% if value.tags is defined %} + tags = { +{% for tag_key in value.tags %} + {{ tag_key }} = "{{ value.tags[tag_key] }}" +{% endfor %} + } +{% endif %} +{% else %} + subscription_id = "{{value.subscription_id}}" +{% endif %} +} diff --git a/templates/resources/virtual_hub_connections.tfvars.j2 b/templates/resources/virtual_hub_connections.tfvars.j2 index b279dc554..997bb2915 100644 --- a/templates/resources/virtual_hub_connections.tfvars.j2 +++ b/templates/resources/virtual_hub_connections.tfvars.j2 @@ -1,5 +1,5 @@ virtual_hub_connections = { -{% for key, vhc in resources.subscriptions[subscription_key].virtual_hub_connections.items() %} +{% for key, vhc in resources[tfstate_resource].resources[subscription_key].virtual_hub_connections.items() %} {{ key }} = { name = "{{ vhc.name }}" virtual_hub = { diff --git a/templates/resources/virtual_hub_route_tables.tfvars.j2 b/templates/resources/virtual_hub_route_tables.tfvars.j2 new file mode 100644 index 000000000..b287670ca --- /dev/null +++ b/templates/resources/virtual_hub_route_tables.tfvars.j2 @@ -0,0 +1,37 @@ +virtual_hub_route_tables = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].virtual_hub_route_tables.items() %} + {{ key }} = { + name = "{{ value.name }}" + virtual_hub = { +{% if value.virtual_hub.id is defined %} + id = "{{value.virtual_hub.id}}" +{% else %} +{% for k, v in value.virtual_hub.items() %} + {{k}} = "{{v}}" +{% endfor %} +{% endif %} + } +{% if value.labels is defined %} + labels = {{value.labels | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% endif %} +{% if value.routes is defined %} + routes = { +{% for k, v in value.routes.items() %} + {{k}} = { + name = "{{v.name}}" + destinations_type = "{{v.destinations_type}}" + destinations = {{v.destinations | replace('None','[]') | replace('[', '[\n') | replace(']', '\n]') | replace(',', ',\n') | replace('\'','\"') }} +{% if v.next_hop is defined %} + next_hop = { +{% for l, w in v.next_hop.items() %} + {{l}} = "{{w}}" +{% endfor %} + } +{% endif %} + } +{% endfor %} + } +{% endif %} + } +{% endfor %} +} \ No newline at end of file diff --git a/templates/resources/virtual_hubs.tfvars.j2 b/templates/resources/virtual_hubs.tfvars.j2 new file mode 100644 index 000000000..a6efb9510 --- /dev/null +++ b/templates/resources/virtual_hubs.tfvars.j2 @@ -0,0 +1,121 @@ +virtual_hubs = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].virtual_hubs.items() %} + {{ key }} = { + virtual_wan = { +{% if value.virtual_wan.lz_key is defined %} + lz_key = "{{ value.virtual_wan.lz_key }}" +{% endif %} + key = "{{ value.virtual_wan.key }}" + } + resource_group = { +{% if value.virtual_wan.lz_key is defined %} + lz_key = "{{ value.virtual_wan.lz_key }}" +{% endif %} + key = "{{ value.virtual_wan.key }}" + } + hub_name = "{{ value.name }}" +{% if value.region_key is defined %} + region = "{{ value.region_key }}" +{% endif %} + hub_address_prefix = "{{ value.hub_address_prefix }}" +{% if value.routes is defined %} + routes = { +{% for rt_key, rt_value in value.routes.items() %} + {{rt_key}} = { + address_prefixes = {{ rt_value.address_prefixes | replace('None','[]') | replace('\'','\"') }} + next_hop_ip_address = "{{ rt_value.next_hop_ip_address }}" + } +{% endfor %} + } +{% endif %} + deploy_p2s = {{ value.deploy_p2s | default(false) | lower }} +{% if value.p2s_config is defined %} + p2s_config = { + name = "{{ value.p2s_config.name }}" + scale_unit = "{{ value.p2s_config.scale_unit | default(1) }}" +{% if value.p2s_config.connection_configuration is defined %} + connection_configuration = { + name = "{{ value.p2s_config.connection_configuration.name }}" +{% if value.p2s_config.connection_configuration.vpn_client_address_pool is defined %} + vpn_client_address_pool = { +{% for cap_key, cap_value in value.p2s_config.connection_configuration.vpn_client_address_pool.items() %} + {{cap_key}} = { + address_prefixes = {{cap_value | replace('None','[]') | replace('\'','\"') }} + } +{% endfor %} + } +{% endif %} + } +{% endif %} +{% if value.deploy_p2s.server_config is defined %} + server_config = { + vpn_authentication_types = "{{ value.deploy_p2s.server_resources.vpn_authentication_types }}" + client_root_certificate = { + name = "{{ value.deploy_p2s.server_resources.client_root_certificate.name }}" + public_cert_data = "{{ value.deploy_p2s.server_resources.client_root_certificate.public_cert_data }}" + } + } +{% endif %} + } +{% else %} + p2s_config = {} +{% endif %} + deploy_s2s = {{ value.deploy_s2s | string | lower | default(false) }} + s2s_config = { +{% if value.s2s_resources.name is defined %} + name = "{{ value.s2s_resources.name }}" +{% endif %} +{% if value.s2s_resources.scale_unit is defined %} + scale_unit = {{ value.s2s_resources.scale_unit }} +{% endif %} +{% if value.s2s_resources.routing_preference is defined %} + routing_preference = "{{ value.s2s_resources.routing_preference | default('Microsoft Network') }}" +{% endif %} +{% if value.deploy_s2s.bgp_settings is defined %} + bgp_settings = { + asn = "{{ value.deploy_s2s.bgp_settings.asn }}" + peer_weight = {{ value.deploy_s2s.bgp_settings.peer_weight }} +{% if value.deploy_s2s.bgp_settings.instance_0_bgp_peering_address is defined %} + instance_0_bgp_peering_address = { + custom_ips = {{ value.deploy_s2s.bgp_settings.instance_0_bgp_peering_address.custom_ips | replace('None','[]') | replace('\'','\"') }} + } +{% endif %} +{% if value.deploy_s2s.bgp_settings.instance_1_bgp_peering_address is defined %} + instance_1_bgp_peering_address = { + custom_ips = {{ value.deploy_s2s.bgp_settings.instance_1_bgp_peering_address.custom_ips | replace('None','[]') | replace('\'','\"') }} + } +{% endif %} + } +{% endif %} + } + deploy_er = {{ value.deploy_er | string | lower | default(false) }} +{% if value.er_resources is defined %} + er_config = { + name = "{{ value.er_resources.name }}" + scale_units = {{ value.er_resources.scale_units }} + } +{% endif %} +{% if value.security_partner_provider is defined %} + security_partner_provider = { +{% for spp_key, spp_value in value.security_partner_provider.items() %} + {{spp_key}} = { + name = "{{ spp_value.name }}" + security_provider_name = "{{ spp_value.security_provider_name }}" + } +{% endfor %} + } +{% endif %} +{% if value.bgp_connection is defined %} + bgp_connection = { +{% for bgp_key, bgp_value in value.bgp_connection.items() %} + {{bgp_key}} = { + name = "{{ bgp_value.name }}" + peer_asn = "{{ bgp_value.peer_asn }}" + peer_ip = "{{ bgp_value.peer_ip }}" + } +{% endfor %} + } +{% endif %} + } +{% endfor %} +} diff --git a/templates/resources/virtual_machines.tfvars.j2 b/templates/resources/virtual_machines.tfvars.j2 new file mode 100644 index 000000000..5177141d9 --- /dev/null +++ b/templates/resources/virtual_machines.tfvars.j2 @@ -0,0 +1,358 @@ +virtual_machines = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].virtual_machines.items() %} + {{ key }} = { + resource_group = { +{% if value.resource_group.lz_key is defined %} + lz_key = "{{ value.resource_group.lz_key }}" +{% endif %} + key = "{{ value.resource_group.key }}" + } +{% if value.region is defined %} + region = "{{ value.region }}" +{% endif %} +{% if value.os_type is defined %} + os_type = "{{ value.os_type }}" +{% endif %} +{% if value.lz_key is defined %} + // lz_key name of the keyvault key holding the user_name and password when using admin_username_key and admin_password_key + lz_key = "{{ value.lz_key }}" +{% endif %} +{% if value.keyvault_key is defined %} + // keyvault key holding the user_name and password when using admin_username_key and admin_password_key + keyvault_key = "{{ value.keyvault_key }}" +{% endif %} +{% if value.public_key_pem_file is defined %} + public_key_pem_file = "{{ value.public_key_pem_file }}" +{% endif %} +{% if value.backup is defined %} + backup = { +{% if value.backup.backup_vault_rg is defined %} + backup_vault_rg = "{{ value.backup.backup_vault_rg }}" +{% endif %} +{% if value.backup.backup_vault_id is defined %} + backup_vault_id = "{{ value.backup.backup_vault_id }}" +{% endif %} +{% if value.backup.backup_policy_id is defined %} + backup_policy_id = "{{ value.backup.backup_policy_id }}" +{% endif %} +{% if value.backup.vault_key is defined %} + vault_key = "{{ value.backup.vault_key }}" +{% endif %} +{% if value.backup.policy_key is defined %} + policy_key = "{{ value.backup.policy_key }}" +{% endif %} +{% if value.backup.lz_key is defined %} + lz_key = "{{ value.backup.lz_key }}" +{% endif %} + } +{% endif %} +{% if value.tags is defined %} + tags = { +{% for tag_key, tag_value in value.tags.items() %} + {{ tag_key }} = "{{ tag_value }}" +{% endfor %} + } +{% endif %} + + virtual_machine_settings = { +{% for os_key, os_value in value.virtual_machine_settings.items() %} + {{ os_key }} = { +{% if os_value.name is defined %} + name = "{{ os_value.name }}" +{% endif %} +{% if os_value.computer_name is defined %} + computer_name = "{{ os_value.computer_name }}" +{% endif %} +{% if os_value.admin_username_key is defined %} + admin_username_key = "{{ os_value.admin_username_key }}" +{% endif %} +{% if os_value.admin_password_key is defined %} + admin_password_key = "{{ os_value.admin_password_key }}" +{% endif %} +{% if os_value.allow_extension_operations is defined %} + allow_extension_operations = "{{ os_value.allow_extension_operations }}" +{% endif %} +{% if os_value.availability_set_key is defined %} + availability_set_key = "{{ os_value.availability_set_key }}" +{% endif %} +{% if os_value.enable_automatic_updates is defined %} + enable_automatic_updates = "{{ os_value.enable_automatic_updates }}" +{% endif %} +{% if os_value.eviction_policy is defined %} + eviction_policy = "{{ os_value.eviction_policy }}" +{% endif %} +{% if os_value.license_type is defined %} + license_type = "{{ os_value.license_type }}" +{% endif %} +{% if os_value.max_bid_price is defined %} + max_bid_price = "{{ os_value.max_bid_price }}" +{% endif %} +{% if os_value.network_interface_keys is defined %} + network_interface_keys = {{ os_value.network_interface_keys | replace('None','[]') | replace('\'','\"') }} +{% endif %} +{% if os_value.priority is defined %} + priority = "{{ os_value.priority }}" +{% endif %} +{% if os_value.provision_vm_agent is defined %} + provision_vm_agent = {{ os_value.provision_vm_agent | lower }} +{% endif %} +{% if os_value.proximity_placement_group_key is defined %} + proximity_placement_group_key = "{{ os_value.proximity_placement_group_key }}" +{% endif %} +{% if os_value.size is defined %} + size = "{{ os_value.size }}" +{% endif %} +{% if os_value.timezone is defined %} + timezone = "{{ os_value.timezone }}" +{% endif %} +{% if os_value.zone is defined %} + zone = "{{ os_value.zone }}" +{% endif %} + os_disk = { + name = "{{ os_value.os_disk.name }}" + caching = "{{ os_value.os_disk.caching }}" +{% if os_value.os_disk.disk_size_gb is defined %} + disk_size_gb = "{{ os_value.os_disk.disk_size_gb }}" +{% endif %} +{% if os_value.os_disk.storage_account_type is defined %} + storage_account_type = "{{ os_value.os_disk.storage_account_type }}" +{% endif %} +{% if os_value.os_disk.write_accelerator_enabled is defined %} + write_accelerator_enabled = {{ os_value.os_disk.write_accelerator_enabled | lower }} +{% endif %} +{% if os_value.os_disk.disk_encryption_set_key is defined %} + disk_encryption_set_key = "{{ os_value.os_disk.disk_encryption_set_key }}" +{% endif %} +{% if os_value.os_disk.lz_key is defined %} + lz_key = "{{ os_value.os_disk.lz_key }}" +{% endif %} +{% if os_value.os_disk.diff_disk_settings is defined %} + diff_disk_settings = { + option = os_value.os_disk.diff_disk_settings.option + } +{% endif %} + } +{% if os_value.custom_data is defined %} + custom_data = "{{ os_value.custom_data }}" +{% endif %} +{% if os_value.dedicated_host is defined %} + diff_disk_settings = { +{% if os_value.dedicated_host.id is defined %} + id = "{{ os_value.dedicated_host.id }}" +{% else %} + key = "{{ os_value.dedicated_host.key }}" +{% if os_value.dedicated_host.lz_key is defined %} + lz_key = "{{ os_value.dedicated_host.lz_key }}" +{% endif %} +{% endif %} + } +{% endif %} +{% if os_value.source_image_reference is defined %} + source_image_reference = { +{% if os_value.source_image_reference.publisher is defined %} + publisher = "{{ os_value.source_image_reference.publisher }}" +{% endif %} +{% if os_value.source_image_reference.offer is defined %} + offer = "{{ os_value.source_image_reference.offer }}" +{% endif %} +{% if os_value.source_image_reference.sku is defined %} + sku = "{{ os_value.source_image_reference.sku }}" +{% endif %} +{% if os_value.source_image_reference.version is defined %} + version = "{{ os_value.source_image_reference.version }}" +{% endif %} + } +{% endif %} +{% if os_value.plan is defined %} + plan = { + name = "{{ os_value.plan.name }}" + product = "{{ os_value.plan.product }}" + publisher = "{{ os_value.plan.publisher }}" + } +{% endif %} +{% if os_value.custom_image_id is defined %} + custom_image_id = "{{ os_value.custom_image_id }}" +{% else %} +{% if os_value.custom_image_key is defined %} + custom_image_key = "{{ os_value.custom_image_key }}" +{% endif %} +{% endif %} +{% if os_value.additional_capabilities is defined %} + additional_capabilities = { + ultra_ssd_enabled = {{ os_value.additional_capabilities.ultra_ssd_enabled | lower }} + } +{% endif %} +{% if os_value.additional_unattend_content is defined %} + additional_unattend_content = { + content = "{{ os_value.additional_capabilities.content }}" + setting = "{{ os_value.additional_capabilities.setting }}" + } +{% endif %} +{% if os_value.identity is defined %} + identity = { + type = "{{ os_value.identity.type }}" +{% if os_value.identity.managed_identity_keys is defined %} + managed_identity_keys = {{ os_value.identity.managed_identity_keys | replace('None','[]') | replace('\'','\"') }} +{% endif %} +{% if os_value.identity.remote is defined %} + remote = { +{% for msi_key, msi_value in os_value.identity.remote.items() %} + {{ msi_key }} = { + managed_identity_keys = {{ msi_value.managed_identity_keys | replace('None','[]') | replace('\'','\"') }} + } +{% endfor %} + } +{% endif %} + } +{% endif %} + } +{% endfor %} + } +{% if value.data_disks is defined %} + data_disks = { +{% for disk_key, disk_value in value.data_disks.items() %} + {{ disk_key }} = { + name = "{{ disk_value.name }}" + lun = {{ disk_value.lun }} + storage_account_type = "{{ disk_value.storage_account_type }}" + create_option = "{{ disk_value.create_option }}" +{% if disk_value.write_accelerator_enabled is defined %} + write_accelerator_enabled = {{ disk_value.write_accelerator_enabled | lower }} +{% endif %} +{% if disk_value.caching is defined %} + caching = "{{ disk_value.caching }}" +{% endif %} +{% if disk_value.disk_size_gb is defined %} + disk_size_gb = "{{ disk_value.disk_size_gb }}" +{% endif %} +{% if disk_value.disk_iops_read_write is defined %} + disk_iops_read_write = "{{ disk_value.disk_iops_read_write }}" +{% endif %} +{% if disk_value.disk_mbps_read_write is defined %} + disk_mbps_read_write = "{{ disk_value.disk_mbps_read_write }}" +{% endif %} +{% if disk_value.disk_encryption_set_key is defined %} + disk_encryption_set_key = "{{ disk_value.disk_encryption_set_key }}" +{% endif %} +{% if disk_value.zones is defined %} + zones = {{ disk_value.zones | map('string') | replace('None','[]') | replace('\'','\"') }} +{% endif %} +{% if disk_value.tags is defined %} + tags = { +{% for tag_key, tag_value in nic_value.tags.items() %} + {{ tag_key }} = "{{ tag_value }}" +{% endfor %} + } +{% endif %} + } +{% endfor %} + } +{% endif %} + networking_interfaces = { +{% for nic_key, nic_value in value.networking_interfaces.items() %} + {{ nic_key }} = { + name = "{{ nic_value.name }}" +{% if nic_value.dns_servers is defined %} + dns_servers = {{ nic_value.dns_servers | replace('None','[]') | replace('\'','\"') }} +{% endif %} +{% if nic_value.enable_ip_forwarding is defined %} + enable_ip_forwarding = {{ nic_value.enable_ip_forwarding | lower }} +{% endif %} +{% if nic_value.enable_accelerated_networking is defined %} + enable_accelerated_networking = {{ nic_value.enable_accelerated_networking | lower }} +{% endif %} +{% if nic_value.internal_dns_name_label is defined %} + internal_dns_name_label = "{{ nic_value.internal_dns_name_label }}" +{% endif %} +{% if nic_value.tags is defined %} + tags = { +{% for tag_key, tag_value in nic_value.tags.items() %} + {{ tag_key }} = "{{ tag_value }}" +{% endfor %} + } +{% endif %} +{% if nic_value.subnet_id is defined %} + subnet_id = "{{ nic_value.subnet_id }}" +{% endif %} +{% if nic_value.lz_key is defined %} + lz_key = "{{ nic_value.lz_key }}" +{% endif %} +{% if nic_value.vnet_key is defined %} + vnet_key = "{{ nic_value.vnet_key }}" +{% endif %} +{% if nic_value.subnet_key is defined %} + subnet_key = "{{ nic_value.subnet_key }}" +{% endif %} +{% if nic_value.private_ip_address_allocation is defined %} + private_ip_address_allocation = "{{ nic_value.private_ip_address_allocation }}" +{% endif %} +{% if nic_value.private_ip_address_version is defined %} + private_ip_address_version = "{{ nic_value.private_ip_address_version }}" +{% endif %} +{% if nic_value.private_ip_address is defined %} + private_ip_address = "{{ nic_value.private_ip_address }}" +{% endif %} +{% if nic_value.primary is defined %} + primary = {{ nic_value.primary | lower }} +{% endif %} +{% if nic_value.public_ip_address_id is defined %} + public_ip_address_id = "{{ nic_value.public_ip_address_id }}" +{% endif %} +{% if nic_value.public_ip_address_key is defined %} + public_ip_address_key = "{{ nic_value.public_ip_address_key }}" +{% endif %} +{% if nic_value.ip_configurations is defined %} + ip_configurations = { +{% for ipc_key, ipc_value in nic_value.ip_configurations.items() %} + {{ ipc_key }} = { + name = "{{ ipc_value.name }}" +{% if ipc_value.subnet_id is defined %} + subnet_id = "{{ ipc_value.subnet_id }}" +{% endif %} +{% if ipc_value.lz_key is defined %} + lz_key = "{{ ipc_value.lz_key }}" +{% endif %} +{% if ipc_value.vnet_key is defined %} + vnet_key = "{{ ipc_value.vnet_key }}" +{% endif %} +{% if ipc_value.subnet_key is defined %} + subnet_key = "{{ ipc_value.subnet_key }}" +{% endif %} +{% if ipc_value.private_ip_address_allocation is defined %} + private_ip_address_allocation = "{{ ipc_value.private_ip_address_allocation }}" +{% endif %} +{% if ipc_value.private_ip_address_version is defined %} + private_ip_address_version = "{{ ipc_value.private_ip_address_version }}" +{% endif %} +{% if ipc_value.private_ip_address is defined %} + private_ip_address = "{{ ipc_value.private_ip_address }}" +{% endif %} +{% if ipc_value.primary is defined %} + primary = {{ ipc_value.primary | lower }} +{% endif %} +{% if ipc_value.public_ip_address_id is defined %} + public_ip_address_id = "{{ ipc_value.public_ip_address_id }}" +{% endif %} +{% if ipc_value.public_ip_address_key is defined %} + public_ip_address_key = "{{ ipc_value.public_ip_address_key }}" +{% endif %} + } +{% endfor %} + } +{% endif %} +{% if nic_value.network_security_group is defined %} + network_security_group = { +{% if nic_value.network_security_group.lz_key is defined %} + lz_key = "{{ nic_value.network_security_group.lz_key }}" +{% endif %} +{% if nic_value.network_security_group.key is defined %} + key = "{{ nic_value.network_security_group.key }}" +{% endif %} + } +{% endif %} + } +{% endfor %} + } + } +{% endfor %} +} \ No newline at end of file diff --git a/templates/resources/virtual_networks.tfvars.j2 b/templates/resources/virtual_networks.tfvars.j2 index 7a12ad5f0..5eee716cb 100644 --- a/templates/resources/virtual_networks.tfvars.j2 +++ b/templates/resources/virtual_networks.tfvars.j2 @@ -1,5 +1,5 @@ vnets = { -{% for key, vnet in resources.subscriptions[subscription_key].virtual_networks.items() %} +{% for key, vnet in resources[tfstate_resource].resources[subscription_key].virtual_networks.items() %} {{ key }} = { resource_group_key = "{{vnet.resource_group_key}}" vnet = { diff --git a/templates/platform/level2/connectivity/virtual_wan/virtual_wan.tfvars.j2 b/templates/resources/virtual_wans.tfvars.j2 similarity index 66% rename from templates/platform/level2/connectivity/virtual_wan/virtual_wan.tfvars.j2 rename to templates/resources/virtual_wans.tfvars.j2 index 128c9e9ad..606048e53 100644 --- a/templates/platform/level2/connectivity/virtual_wan/virtual_wan.tfvars.j2 +++ b/templates/resources/virtual_wans.tfvars.j2 @@ -1,5 +1,5 @@ virtual_wans = { -{% for key, vwan in connectivity_virtual_wan.virtual_wans.items() %} +{% for key, vwan in resources[tfstate_resource].resources[subscription_key].virtual_wans.items() %} "{{key}}" = { resource_group_key = "{{ vwan.resource_group_key }}" name = "{{ vwan.name }}" diff --git a/templates/platform/level2/connectivity/vpn_site/vpn_gateways_connections.tfvars.j2 b/templates/resources/vpn_gateway_connections.tfvars.j2 similarity index 60% rename from templates/platform/level2/connectivity/vpn_site/vpn_gateways_connections.tfvars.j2 rename to templates/resources/vpn_gateway_connections.tfvars.j2 index 0720ce648..c7e0d8c44 100644 --- a/templates/platform/level2/connectivity/vpn_site/vpn_gateways_connections.tfvars.j2 +++ b/templates/resources/vpn_gateway_connections.tfvars.j2 @@ -1,17 +1,18 @@ vpn_gateway_connections = { - {{ site }} = { - name = "{{ connectivity_vpn_gateway_connections.vpn_gateway_connections[site].name }}" - internet_security_enabled = {{ connectivity_vpn_gateway_connections.vpn_gateway_connections[site].internet_security_enabled | default(true) | string | lower }} // propagate to default route table +{% for key, value in resources[tfstate_resource].resources[subscription_key].vpn_gateway_connections.items() %} + {{ key }} = { + name = "{{ value.name }}" + internet_security_enabled = {{ value.internet_security_enabled | default(true) | string | lower }} // propagate to default route table vpn_site = { - key = "{{ connectivity_vpn_gateway_connections.vpn_gateway_connections[site].vpn_site.key }}" + key = "{{ value.vpn_site.key }}" } virtual_hub = { - lz_key = "{{ connectivity_vpn_gateway_connections.vpn_gateway_connections[site].virtual_hub.lz_key }}" - key = "{{ connectivity_vpn_gateway_connections.vpn_gateway_connections[site].virtual_hub.key }}" + lz_key = "{{ value.virtual_hub.lz_key }}" + key = "{{ value.virtual_hub.key }}" } vpn_links = { -{% for link_key, link in connectivity_vpn_gateway_connections.vpn_gateway_connections[site].vpn_links.items() %} +{% for link_key, link in value.vpn_links.items() %} {{ link_key }} = { name = "{{ link.name }}" shared_key = "{{ link.shared_key }}" @@ -37,4 +38,5 @@ vpn_gateway_connections = { {% endfor %} } } +{% endfor %} } \ No newline at end of file diff --git a/templates/resources/vpn_sites.tfvars.j2 b/templates/resources/vpn_sites.tfvars.j2 new file mode 100644 index 000000000..c13da8d02 --- /dev/null +++ b/templates/resources/vpn_sites.tfvars.j2 @@ -0,0 +1,38 @@ +vpn_sites = { +{% for key, value in resources[tfstate_resource].resources[subscription_key].vpn_sites.items() %} + {{ key }} = { + name = "{{ value.name }}" + resource_group = { + lz_key = "{{ value.resource_group.lz_key }}" + key = "{{ value.resource_group.key }}" + } + virtual_wan = { + lz_key = "{{ value.virtual_wan.lz_key }}" + key = "{{ value.virtual_wan.key }}" + } + device_vendor = "{{ value.device_vendor }}" + } +{% if value.address_cidrs is defined %} + address_cidrs = {{ value.address_cidrs | replace('None','[]') | replace('\'','\"') }} +{% endif %} + links = { +{% for link_key, link in value.links.items() %} + {{ link_key }} = { + name = "{{ link.name }}" + ip_address = "{{ link.ip_address }}" + provider_name = "{{ link.provider_name }}" + speed_in_mbps = "{{ link.speed_in_mbps }}" +{% if link.fqdn is defined %} + fqdn = "{{ ink.fqdn }}" +{% endif %} +{% if link.bgp is defined %} + bgp = { + asn = "{{ link.bgp.asn }}" + peering_address = "{{ link.bgp.peering_address }}" + } +{% endif %} + } +{% endfor %} + } +{% endfor %} +} \ No newline at end of file diff --git a/templates/variables/_variables_azure_landing_zones.yaml b/templates/variables/_variables_azure_landing_zones.yaml new file mode 100644 index 000000000..ac4b231c4 --- /dev/null +++ b/templates/variables/_variables_azure_landing_zones.yaml @@ -0,0 +1,6 @@ +variables_azure_landing_zones: + private_lib: + v1.1.3: + caf_landingzone_branch: 2203.0 + v1.1.1: + caf_landingzone_branch: 2201.0 \ No newline at end of file diff --git a/templates/variables/_variables_networking_cidr.yaml b/templates/variables/_variables_networking_cidr.yaml new file mode 100644 index 000000000..148260cb6 --- /dev/null +++ b/templates/variables/_variables_networking_cidr.yaml @@ -0,0 +1,85 @@ +variables_cidr: + platform: + # + # launchpad landingzone + # + launchpad: + region1: + prod: + address_prefixes: + - 10.101.10.0/24 + subnets: + available_cidr: + - 10.101.10.32/28 + - 10.101.10.128/26 + gitops_agents: + - 10.101.10.0/27 + jumpbox: + - 10.101.10.48/28 + bastion: + - 10.101.10.64/26 + private_endpoints: + - 10.101.10.192/26 + region2: + prod: + address_prefixes: + - 10.102.10.0/24 + subnets: + available_cidr: + - 10.102.10.32/28 + - 10.102.10.128/26 + gitops_agents: + - 10.102.10.0/27 + jumpbox: + - 10.102.10.48/28 + bastion: + - 10.102.10.64/26 + private_endpoints: + - 10.102.10.192/26 + + # + # connectivity landingzone + # + virtual_hubs: + region1: + prod: + address_prefix: 10.101.51.0/24 + non_prod: + address_prefix: 10.101.52.0/24 + region2: + prod: + address_prefix: 10.102.51.0/24 + non_prod: + address_prefix: 10.102.52.0/24 + + + # + # private_dns_firewalls landingzone + # + private_dns_firewalls: + region1: + prod: + address_prefixes: + - 10.101.61.0/24 + subnets: + AzureFirewallSubnet: + - 10.101.61.0/26 + non_prod: + address_prefixes: + - 10.101.62.0/24 + subnets: + AzureFirewallSubnet: + - 10.101.62.0/26 + region2: + prod: + address_prefixes: + - 10.102.61.0/24 + subnets: + AzureFirewallSubnet: + - 10.101.62.0/26 + non_prod: + address_prefixes: + - 10.102.62.0/24 + subnets: + AzureFirewallSubnet: + - 10.101.62.0/26 diff --git a/templates/variables/_variables_private_dns_zones.yaml b/templates/variables/_variables_private_dns_zones.yaml new file mode 100644 index 000000000..3e5a36964 --- /dev/null +++ b/templates/variables/_variables_private_dns_zones.yaml @@ -0,0 +1,57 @@ +variables_private_dns_zones: + zones: + privatelink.adf.azure.com: + privatelink.afs.azure.net: + privatelink.agentsvc.azure-automation.net: + privatelink.api.azureml.ms: + privatelink.azconfig.io: + privatelink.azure-automation.net: + privatelink.azure-devices.net: + privatelink.azurecr.io: + privatelink.azurehdinsight.net: + privatelink.azuresynapse.net: + privatelink.azurewebsites.net: + privatelink.blob.core.windows.net: + privatelink.cassandra.cosmos.azure.com: + privatelink.cognitiveservices.azure.com: + privatelink.database.windows.net: + privatelink.datafactory.azure.net: + privatelink.dev.azuresynapse.net: + privatelink.dfs.core.windows.net: + privatelink.digitaltwins.azure.net: + privatelink.documents.azure.com: + privatelink.eventgrid.azure.net: + privatelink.file.core.windows.net: + privatelink.gremlin.cosmos.azure.com: + privatelink.guestconfiguration.azure.com: + privatelink.his.arc.azure.com: + privatelink.managedhsm.azure.net: + privatelink.mariadb.database.azure.com: + privatelink.media.azure.net: + privatelink.mongo.cosmos.azure.com: + privatelink.monitor.azure.com: + privatelink.mysql.database.azure.com: + privatelink.notebooks.azure.net: + privatelink.ods.opinsights.azure.com: + privatelink.oms.opinsights.azure.com: + privatelink.postgres.database.azure.com: + privatelink.purview.azure.com: + privatelink.purviewstudio.azure.com: + privatelink.queue.core.windows.net: + privatelink.redis.cache.windows.net: + privatelink.redisenterprise.cache.azure.net: + privatelink.search.windows.net: + privatelink.service.signalr.net: + privatelink.servicebus.windows.net: + privatelink.siterecovery.windowsazure.com: + privatelink.sql.azuresynapse.net: + privatelink.table.core.windows.net: + privatelink.table.cosmos.azure.com: + privatelink.vaultcore.azure.net: + privatelink.web.core.windows.net: + + # region will be de-tokenized by the values set in resources_allowed_regions + regional_zones: + privatelink.region.azmk8s.io: + privatelink.region.backup.windowsazure.com: + privatelink.region.batch.azure.com: \ No newline at end of file diff --git a/templates/variables/service_regions.yaml b/templates/variables/service_regions.yaml new file mode 100644 index 000000000..8b5c38e38 --- /dev/null +++ b/templates/variables/service_regions.yaml @@ -0,0 +1,139 @@ +defaults: + firewall_premium_regions: + - australiacentral + - australiacentral2 + - australiaeast + - australiasoutheast + - brazilsouth + - brazilsoutheast + - canadacentral + - canadaeast + - centralindia + - centralus + - centraluseuap + - chinanorth2 + - chinaeast2 + - eastasia + - eastus + - eastus2 + - francecentral + - francesouth + - germanywestcentral + - japaneast + - japanwest + - koreacentral + - koreasouth + - northcentralus + - northeurope + - norwayeast + - southafricanorth + - southcentralus + - southindia + - southeastasia + - swedencentral + - switzerlandnorth + - uaecentral + - uaenorth + - uksouth + - ukwest + - usgovarizona + - usgovtexas + - usgovvirginia + - westcentralus + - westeurope + - westindia + - westus + - westus2 + - westus3 + + availability_zone_regions: + - australiaeast + - brazilsouth + - canadacentral + - centralus + - centralindia + - eastasia + - eastus + - eastus2 + - francecentral + - germanywestcentral + - japaneast + - koreacentral + - northeurope + - norwayeast + - uksouth + - southeastasia + - southcentralus + - swedencentral + - usgovvirginia + - westeurope + - westus2 + - westus3 + + synapse_privatelink_hub_regions: + - westus2 + - eastus + - northeurope + - westeurope + - southeastasia + - australiaeast + - westcentralus + - southcentralus + - eastus2 + - uksouth + - westus + - australiasoutheast + - eastasia + - brazilsouth + - centralus + - centralindia + - japaneast + - northcentralus + - canadacentral + - canadaeast + - koreacentral + - southafricanorth + - ukwest + - japanwest + - francecentral + - switzerlandnorth + - germanywestcentral + - norwayeast + - uaenorth + - westus3 + - jioindiawest + + storage_zrs_regions: + # Africa + - southafricanorth + + # Asia + - australiaeast + - centralindia + - eastasia + - japaneast + - koreacentral + - southeastasia + + # Canada + - canadacentral + + # Europe + - francecentral + - germanywestcentral + - northeurope + - norwayeast + - swedencentral + - uksouth + - westeurope + + # South America + - brazilsouth + + # US + - centralus + - eastus + - eastus2 + - southcentralus + - westus2 + - westus3 \ No newline at end of file