diff --git a/docs/wiki/[Examples]-Configure-Policy-UserAssignedIdentity.md b/docs/wiki/[Examples]-Configure-Policy-UserAssignedIdentity.md new file mode 100644 index 000000000..f9d24e611 --- /dev/null +++ b/docs/wiki/[Examples]-Configure-Policy-UserAssignedIdentity.md @@ -0,0 +1,270 @@ + +## Overview + +This page describes how to use the module to configure an Azure Policy Assignment with the user managed identity. Azure policies who implement a deploy if not exist require an identity to have the right permission to deploy the missing resources. + +By leveraging the user managed identities, customers can reduce the number of system identities created by the assignments by using a user managed identity. The other benefit of using a user managed identity is the decouple the role assignment from the policy. + +You can also review a working existing example located in examples/400-multi-with-orchestration + +In this page, we will create a policy assignment template to override an existing policy assignment currently using a SystemIdentity. We will then assign an existing user managed identity to that policy assignment. + +>**IMPORTANT**: To allow the declaration of custom or expanded templates, you must create a custom library folder within the root module and include the path to this folder using the `library_path` variable within the module configuration. In our example, the directory is `lib`. + +## Create Policy Assignment template file + +In your `lib` directory create a `policy_assignments` subdirectory if you don't already have one. You can learn more about archetypes and custom libraries in [this article](https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/wiki/%5BUser-Guide%5D-Archetype-Definitions). + +> **NOTE:** Creating a `policy_assignments` subdirectory is a recommendation only. If you prefer not to create one or to call it something else, the role assignment will still work. + +In the `policy_assignments` subdirectory, create a `policy_assignment_es_deploy_vmss_monitoring.tmpl.json.tftpl` file. This file will contain the role assignment for the `vmss_monitoring` initiative. + +> **NOTE:** If you reuse an existing name, this policy assignment will override the default policy assignment from the shared module library. It could be a good way to migrate your existing SystemAssigned to UserAssiged (User Managed Identity). By using a different name you will not change the current assignments. + +In this example, we demonstrate how to upgrade an existing policy assignment from SystemAssigned to UserAssigned. + +Copy the bellow code into the `policy_assignment_es_deploy_vmss_monitoring.tmpl.json.tftpl` file. + +```json +${jsonencode( + { + "type": "Microsoft.Authorization/policyAssignments", + "apiVersion": "2022-06-01", + "name": "Deploy-VMSS-Monitoring", + "location": "${default_location}", + "dependsOn": [], + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + for msi_id in userAssignedIdentities.Deploy-VMSS-Monitoring : msi_id => {} + } + }, + "properties": { + "description": "Enable Azure Monitor for the Virtual Machine Scale Sets in the specified scope (Management group, Subscription or resource group). Takes Log Analytics workspace as parameter. Note: if your scale set upgradePolicy is set to Manual, you need to apply the extension to the all VMs in the set by calling upgrade on them. In CLI this would be az vmss update-instances.", + "displayName": "Enable Azure Monitor for Virtual Machine Scale Sets", + "policyDefinitionId": "/providers/Microsoft.Authorization/policySetDefinitions/75714362-cae7-409e-9b99-a8e5075b7fad", + "enforcementMode": "Default", + "nonComplianceMessages": [ + { + "message": "Azure Monitor {enforcementMode} be enabled for Virtual Machines Scales Sets." + } + ], + "parameters": { + "logAnalytics_1": { + "value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/${root_scope_id}-mgmt/providers/Microsoft.OperationalInsights/workspaces/${root_scope_id}-la" + } + }, + "scope": "${current_scope_resource_id}", + "notScopes": [] + } +} +)} + +``` + +Pay attention to the following identity section. It has been modified to process a variable that will come from the ***template_file_variables*** + +```json +"identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + for msi_id in userAssignedIdentities.Deploy-VMSS-Monitoring : msi_id => {} + } +}, +``` + +This template will read + +```hcl +var.template_file_variables.userAssignedIdentities["Deploy-VMSS-Monitoring"] +``` + +## Configuration file + +There is not a single way to retrieve the existing user managed identity and pass it to the module. The most common ways are using a terraform variable file (*.tfvars), you can also create your user managed identity and reference it inline to the module in the variable ***template_file_variables*** + +Create a file called `template_file_variables.auto.tfvars` or `template_file_variables.tfvars` in your root module. Then copy the content and make sure to adjust the resource id of the user managed identity. + +```json +template_file_variables = { + userAssignedIdentities = { + # Put the name of the policy assignment to better recognise the which user managed identity is assigned to which policy assignment + "Deploy-VMSS-Monitoring" = [ + # Even if it is a list (to comply with api and official document), only 1 user MSI is supported + "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/msi/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ms1" + ] + } +} +``` + +The next section is describing how to pass the user managed identity resource id to the module. + +## Map template_file_variables to your module's parameters + +In order to process the ***template_file_variables*** from the tfvars you must verify you have added the ***template_file_variables*** into your `variables.tf` or equivalent and map it to the module. + +```hcl +variable "template_file_variables" { + type = any + description = "If specified, provides the ability to define custom template variables used when reading in template files from the built-in and custom library_path." + default = {} +} +``` + +```hcl +module "alz" { + # To enable correct testing of our examples, we must source this + # module locally. Please remove the local `source = "../../../../"` + # and uncomment the remote `source` and `version` below. + source = "../../../../" + # source = "Azure/caf-enterprise-scale/azurerm" + # version = "" # change this to your desired version, https://www.terraform.io/language/expressions/version-constraints + + providers = { + azurerm = azurerm + azurerm.connectivity = azurerm + azurerm.management = azurerm + } + + # Base module configuration settings + root_parent_id = data.azurerm_client_config.current.tenant_id + root_id = var.root_id + root_name = var.root_name + library_path = "${path.module}/lib" + default_location = "eastus" + + # Enable creation of the core management group hierarchy + # and additional custom_landing_zones + deploy_core_landing_zones = true + custom_landing_zones = local.custom_landing_zones + + # Configuration settings for identity resources is + # bundled with core as no resources are actually created + # for the identity subscription + deploy_identity_resources = true + configure_identity_resources = local.configure_identity_resources + subscription_id_identity = var.subscription_id_identity + + # The following inputs ensure that managed parameters are + # configured correctly for policies relating to connectivity + # resources created by the connectivity module instance and + # to map the subscription to the correct management group, + # but no resources are created by this module instance + deploy_connectivity_resources = false + configure_connectivity_resources = var.configure_connectivity_resources + subscription_id_connectivity = var.subscription_id_connectivity + + # The following inputs ensure that managed parameters are + # configured correctly for policies relating to management + # resources created by the management module instance and + # to map the subscription to the correct management group, + # but no resources are created by this module instance + deploy_management_resources = false + configure_management_resources = var.configure_management_resources + subscription_id_management = var.subscription_id_management + + template_file_variables = var.template_file_variables + +} +``` + +Another way to pass the user managed indentity is using the inline approach (partial script) + +```hcl +module "alz" { + # To enable correct testing of our examples, we must source this + # module locally. Please remove the local `source = "../../../../"` + # and uncomment the remote `source` and `version` below. + source = "../../../../" + # source = "Azure/caf-enterprise-scale/azurerm" + # version = "" # change this to your desired version, https://www.terraform.io/language/expressions/version-constraints + + providers = { + azurerm = azurerm + azurerm.connectivity = azurerm + azurerm.management = azurerm + } + + ...Removed... + + template_file_variables = { + userAssignedIdentities = { + "Deploy-VMSS-Monitoring" = [ + azurerm_user_assigned_identity.msi1.id + ] + } + } + +} + +# or a data source if already created +resource "azurerm_user_assigned_identity" "msi1" { + location = azurerm_resource_group.example.location + name = "msi1" + resource_group_name = azurerm_resource_group.example.name +} + +``` + +## Trigger the deployment + +You should now kick-off your Terraform workflow (init, plan, apply) again to apply the updated configuration. This can be done either locally or through a pipeline. +When your workflow has finished, the `Deploy-VMSS-Monitoring` policy assignment will be assigned at the Landing Zones Management Group. + +```hcl +# module.core.module.alz.data.azapi_resource.user_msi["/providers/Microsoft.Management/managementGroups/myorg/providers/Microsoft.Authorization/policyAssignments/Deploy-VMSS-Monitoring"] will be read during apply + # (depends on a resource or a module with changes pending) + <= data "azapi_resource" "user_msi" { + + id = (known after apply) + + location = (known after apply) + + output = (known after apply) + + parent_id = (known after apply) + + resource_id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/msi/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ms1" + + response_export_values = [ + + "properties.principalId", + ] + + tags = (known after apply) + + type = "Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30" + } + + # module.core.module.alz.azurerm_management_group_policy_assignment.enterprise_scale["/providers/Microsoft.Management/managementGroups/myorg/providers/Microsoft.Authorization/policyAssignments/Deploy-VMSS-Monitoring"] will be updated in-place + ~ resource "azurerm_management_group_policy_assignment" "enterprise_scale" { + id = "/providers/Microsoft.Management/managementGroups/myorg/providers/Microsoft.Authorization/policyAssignments/Deploy-VMSS-Monitoring" + name = "Deploy-VMSS-Monitoring" + # (9 unchanged attributes hidden) + + ~ identity { + ~ identity_ids = [ + + "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/msi/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ms1", + ] + ~ type = "SystemAssigned" -> "UserAssigned" + # (2 unchanged attributes hidden) + } + + # (1 unchanged block hidden) + } + + # module.core.module.alz.module.role_assignments_for_policy["/providers/Microsoft.Management/managementGroups/myorg/providers/Microsoft.Authorization/policyAssignments/Deploy-VMSS-Monitoring"].azurerm_role_assignment.for_policy["/providers/Microsoft.Management/managementGroups/myorg/providers/Microsoft.Authorization/roleAssignments/1e6eb635-dc9a-54d5-9bb5-7506132bff67"] must be replaced +-/+ resource "azurerm_role_assignment" "for_policy" { + ~ id = "/providers/Microsoft.Management/managementGroups/myorg/providers/Microsoft.Authorization/roleAssignments/1e6eb635-dc9a-54d5-9bb5-7506132bff67" -> (known after apply) + name = "1e6eb635-dc9a-54d5-9bb5-7506132bff67" + ~ principal_id = "9ce8936e-cdd6-4a7c-a2a5-0e695c9ef8a5" # forces replacement -> (known after apply) # forces replacement + ~ principal_type = "ServicePrincipal" -> (known after apply) + ~ role_definition_name = "Virtual Machine Contributor" -> (known after apply) + + skip_service_principal_aad_check = (known after apply) + # (2 unchanged attributes hidden) + } + + # module.core.module.alz.module.role_assignments_for_policy["/providers/Microsoft.Management/managementGroups/myorg/providers/Microsoft.Authorization/policyAssignments/Deploy-VMSS-Monitoring"].azurerm_role_assignment.for_policy["/providers/Microsoft.Management/managementGroups/myorg/providers/Microsoft.Authorization/roleAssignments/55ffe1be-e389-5d46-9488-8d6915a8b60e"] must be replaced +-/+ resource "azurerm_role_assignment" "for_policy" { + ~ id = "/providers/Microsoft.Management/managementGroups/myorg/providers/Microsoft.Authorization/roleAssignments/55ffe1be-e389-5d46-9488-8d6915a8b60e" -> (known after apply) + name = "55ffe1be-e389-5d46-9488-8d6915a8b60e" + ~ principal_id = "9ce8936e-cdd6-4a7c-a2a5-0e695c9ef8a5" # forces replacement -> (known after apply) # forces replacement + ~ principal_type = "ServicePrincipal" -> (known after apply) + ~ role_definition_name = "Log Analytics Contributor" -> (known after apply) + + skip_service_principal_aad_check = (known after apply) + # (2 unchanged attributes hidden) + } + +Plan: 2 to add, 1 to change, 2 to destroy. +``` diff --git a/docs/wiki/_Sidebar.md b/docs/wiki/_Sidebar.md index 26a549073..3a6c7ee9a 100644 --- a/docs/wiki/_Sidebar.md +++ b/docs/wiki/_Sidebar.md @@ -41,6 +41,7 @@ - [Create custom policies, initiatives and assignments][wiki_create_custom_policies_policy_sets_and_assignments] - [Override module role assignments][wiki_override_module_role_assignments] - [Control policy enforcement mode]([Examples]-Deploy-policies-without-enforcing-them) + - [Policy assignments with user assigned managed identities]([Examples]-Configure-Policy-UserAssignedIdentity) - [Level 400][wiki_examples_level_400] - [Deploy using module nesting][wiki_deploy_using_module_nesting] - [Deploy using multiple module declarations with orchestration][wiki_deploy_using_multiple_module_declarations_with_orchestration] diff --git a/examples/400-multi-with-orchestration/main.tf b/examples/400-multi-with-orchestration/main.tf index 18b0dcccb..32f25e491 100644 --- a/examples/400-multi-with-orchestration/main.tf +++ b/examples/400-multi-with-orchestration/main.tf @@ -66,4 +66,5 @@ module "core" { subscription_id_connectivity = local.subscription_id_connectivity subscription_id_identity = local.subscription_id_identity subscription_id_management = local.subscription_id_management + template_file_variables = var.template_file_variables } diff --git a/examples/400-multi-with-orchestration/modules/core/lib/policy_assignment_es_deploy_vmss_monitoring.tmpl.json.tftpl b/examples/400-multi-with-orchestration/modules/core/lib/policy_assignment_es_deploy_vmss_monitoring.tmpl.json.tftpl new file mode 100644 index 000000000..2597e5e4d --- /dev/null +++ b/examples/400-multi-with-orchestration/modules/core/lib/policy_assignment_es_deploy_vmss_monitoring.tmpl.json.tftpl @@ -0,0 +1,34 @@ +${jsonencode( + { + "type": "Microsoft.Authorization/policyAssignments", + "apiVersion": "2022-06-01", + "name": "Deploy-VMSS-Monitoring", + "location": "${default_location}", + "dependsOn": [], + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + for msi_id in userAssignedIdentities.Deploy-VMSS-Monitoring : msi_id => {} + } + }, + "properties": { + "description": "Enable Azure Monitor for the Virtual Machine Scale Sets in the specified scope (Management group, Subscription or resource group). Takes Log Analytics workspace as parameter. Note: if your scale set upgradePolicy is set to Manual, you need to apply the extension to the all VMs in the set by calling upgrade on them. In CLI this would be az vmss update-instances.", + "displayName": "Enable Azure Monitor for Virtual Machine Scale Sets", + "policyDefinitionId": "/providers/Microsoft.Authorization/policySetDefinitions/75714362-cae7-409e-9b99-a8e5075b7fad", + "enforcementMode": "Default", + "nonComplianceMessages": [ + { + "message": "Azure Monitor {enforcementMode} be enabled for Virtual Machines Scales Sets." + } + ], + "parameters": { + "logAnalytics_1": { + "value": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/${root_scope_id}-mgmt/providers/Microsoft.OperationalInsights/workspaces/${root_scope_id}-la" + } + }, + "scope": "${current_scope_resource_id}", + "notScopes": [] + } +} +)} + diff --git a/examples/400-multi-with-orchestration/modules/core/main.tf b/examples/400-multi-with-orchestration/modules/core/main.tf index b13607b0e..b834130f7 100644 --- a/examples/400-multi-with-orchestration/modules/core/main.tf +++ b/examples/400-multi-with-orchestration/modules/core/main.tf @@ -74,4 +74,6 @@ module "alz" { configure_management_resources = var.configure_management_resources subscription_id_management = var.subscription_id_management + template_file_variables = var.template_file_variables + } diff --git a/examples/400-multi-with-orchestration/modules/core/variables.tf b/examples/400-multi-with-orchestration/modules/core/variables.tf index 9860b592f..e0536b72f 100644 --- a/examples/400-multi-with-orchestration/modules/core/variables.tf +++ b/examples/400-multi-with-orchestration/modules/core/variables.tf @@ -44,3 +44,9 @@ variable "configure_management_resources" { type = any description = "Configuration settings for \"management\" resources." } + +variable "template_file_variables" { + type = any + description = "If specified, provides the ability to define custom template variables used when reading in template files from the built-in and custom library_path." + default = {} +} \ No newline at end of file diff --git a/examples/400-multi-with-orchestration/template_file_variables.auto.tfvars b/examples/400-multi-with-orchestration/template_file_variables.auto.tfvars new file mode 100644 index 000000000..1ec31183c --- /dev/null +++ b/examples/400-multi-with-orchestration/template_file_variables.auto.tfvars @@ -0,0 +1,7 @@ +template_file_variables = { + userAssignedIdentities = { + "Deploy-VMSS-Monitoring" = [ + "/subscriptions/dfa7c595-ef32-42e4-be9d-68fb9ef0c853/resourceGroups/msi/providers/Microsoft.ManagedIdentity/userAssignedIdentities/ms1" + ] + } +} \ No newline at end of file diff --git a/examples/400-multi-with-orchestration/variables.tf b/examples/400-multi-with-orchestration/variables.tf index fa5f86b7f..6e9dbd879 100644 --- a/examples/400-multi-with-orchestration/variables.tf +++ b/examples/400-multi-with-orchestration/variables.tf @@ -77,3 +77,9 @@ variable "management_resources_tags" { demo_type = "Deploy management resources using multiple module declarations" } } + +variable "template_file_variables" { + type = any + description = "If specified, provides the ability to define custom template variables used when reading in template files from the built-in and custom library_path." + default = {} +} \ No newline at end of file diff --git a/locals.policy_assignments.tf b/locals.policy_assignments.tf index e2b17a60e..fa9194964 100644 --- a/locals.policy_assignments.tf +++ b/locals.policy_assignments.tf @@ -53,7 +53,7 @@ locals { policy_assignments_with_managed_identity = { for assignment in local.es_policy_assignments : assignment.resource_id => assignment.template.properties.policyDefinitionId - if assignment.template.identity.type == "SystemAssigned" + if assignment.template.identity.type == "SystemAssigned" || assignment.template.identity.type == "UserAssigned" } } diff --git a/resources.policy_assignments.tf b/resources.policy_assignments.tf index 2c8c35a96..b75765e42 100644 --- a/resources.policy_assignments.tf +++ b/resources.policy_assignments.tf @@ -38,13 +38,14 @@ resource "azurerm_management_group_policy_assignment" "enterprise_scale" { # ensures the block is only created when this value # is specified in the source template dynamic "identity" { - for_each = { - for ik, iv in try(each.value.template.identity, local.empty_map) : - ik => iv - if lower(iv) == "systemassigned" - } + for_each = ( + try(each.value.template.identity, local.empty_map) == local.empty_map + ? [] + : [for ik, iv in tomap({ "type" = each.value.template.identity.type }) : each.value.template.identity if iv != "None"] + ) content { - type = "SystemAssigned" + type = identity.value.type + identity_ids = can(identity.value.userAssignedIdentities) ? toset(keys(identity.value.userAssignedIdentities)) : null } } diff --git a/resources.role_assignments.tf b/resources.role_assignments.tf index 4e3d4be38..8d72e1746 100644 --- a/resources.role_assignments.tf +++ b/resources.role_assignments.tf @@ -32,8 +32,12 @@ module "role_assignments_for_policy" { # Mandatory resource attributes policy_assignment_id = each.key scope_id = azurerm_management_group_policy_assignment.enterprise_scale[each.key].management_group_id - principal_id = azurerm_management_group_policy_assignment.enterprise_scale[each.key].identity[0].principal_id - role_definition_ids = each.value + principal_id = ( + lookup(azurerm_management_group_policy_assignment.enterprise_scale[each.key].identity[0], "type") == "UserAssigned" + ? jsondecode(data.azapi_resource.user_msi[each.key].output).properties.principalId # workarround as azurerm_management_group_policy_assignment does not export the principal_id when using UserAssigned identity + : azurerm_management_group_policy_assignment.enterprise_scale[each.key].identity[0].principal_id + ) + role_definition_ids = each.value # Optional resource attributes additional_scope_ids = local.empty_list @@ -49,6 +53,21 @@ module "role_assignments_for_policy" { } +# The data source will retrieve the principalId of a user msi +# used for the policy assignment +# +data "azapi_resource" "user_msi" { + for_each = { + for ik, iv in local.es_role_assignments_by_policy_assignment : ik => iv + if try(local.azurerm_management_group_policy_assignment_enterprise_scale[ik].template.identity.type, null) == "UserAssigned" + } + + resource_id = one(azurerm_management_group_policy_assignment.enterprise_scale[each.key].identity[0].identity_ids) + type = "Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31" + + response_export_values = ["properties.principalId"] +} + # The following resource is left to help manage the # upgrade to using module.role_assignments_for_policy # To be removed in `v2.0.0` diff --git a/tests/modules/settings/main.tf b/tests/modules/settings/main.tf new file mode 100644 index 000000000..41d629c61 --- /dev/null +++ b/tests/modules/settings/main.tf @@ -0,0 +1,17 @@ +data "azurerm_client_config" "core" {} + +locals { + umi_name = "id-identity" + umi_resource_group_name = "rg-identity" +} + +resource "azurerm_resource_group" "example" { + name = local.umi_resource_group_name + location = var.primary_location +} + +resource "azurerm_user_assigned_identity" "example" { + location = azurerm_resource_group.example.location + name = local.umi_name + resource_group_name = azurerm_resource_group.example.name +} diff --git a/tests/modules/settings/settings.core.tf b/tests/modules/settings/settings.core.tf index 59f0ea765..db724d69e 100644 --- a/tests/modules/settings/settings.core.tf +++ b/tests/modules/settings/settings.core.tf @@ -190,5 +190,8 @@ locals { "northcentralus", "southcentralus", ] + subscription_id = data.azurerm_client_config.core.subscription_id + umi_resource_group_name = local.umi_resource_group_name + umi_name = local.umi_name } } diff --git a/tests/modules/settings/terraform.tf b/tests/modules/settings/terraform.tf new file mode 100644 index 000000000..a775c4f5f --- /dev/null +++ b/tests/modules/settings/terraform.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">= 3.74.0" + } + } +} diff --git a/tests/modules/test_001_baseline/baseline_values.json b/tests/modules/test_001_baseline/baseline_values.json index 7f5d34769..f48d186b4 100644 --- a/tests/modules/test_001_baseline/baseline_values.json +++ b/tests/modules/test_001_baseline/baseline_values.json @@ -1,6 +1,43 @@ { "root_module": { "child_modules": [ + { + "resources": [ + { + "address": "module.settings.azurerm_resource_group.example", + "mode": "managed", + "type": "azurerm_resource_group", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/azurerm", + "schema_version": 0, + "values": { + "location": "northeurope", + "managed_by": null, + "name": "rg-identity", + "tags": null, + "timeouts": null + }, + "sensitive_values": {} + }, + { + "address": "module.settings.azurerm_user_assigned_identity.example", + "mode": "managed", + "type": "azurerm_user_assigned_identity", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/azurerm", + "schema_version": 1, + "values": { + "location": "northeurope", + "name": "id-identity", + "resource_group_name": "rg-identity", + "tags": null, + "timeouts": null + }, + "sensitive_values": {} + } + ], + "address": "module.settings" + }, { "resources": [ { diff --git a/tests/modules/test_002_add_custom_core/baseline_values.json b/tests/modules/test_002_add_custom_core/baseline_values.json index 681116695..68c58bf2a 100644 --- a/tests/modules/test_002_add_custom_core/baseline_values.json +++ b/tests/modules/test_002_add_custom_core/baseline_values.json @@ -1,6 +1,43 @@ { "root_module": { "child_modules": [ + { + "resources": [ + { + "address": "module.settings.azurerm_resource_group.example", + "mode": "managed", + "type": "azurerm_resource_group", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/azurerm", + "schema_version": 0, + "values": { + "location": "northeurope", + "managed_by": null, + "name": "rg-identity", + "tags": null, + "timeouts": null + }, + "sensitive_values": {} + }, + { + "address": "module.settings.azurerm_user_assigned_identity.example", + "mode": "managed", + "type": "azurerm_user_assigned_identity", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/azurerm", + "schema_version": 1, + "values": { + "location": "northeurope", + "name": "id-identity", + "resource_group_name": "rg-identity", + "tags": null, + "timeouts": null + }, + "sensitive_values": {} + } + ], + "address": "module.settings" + }, { "resources": [ { @@ -1573,38 +1610,37 @@ "provider_name": "registry.terraform.io/hashicorp/azurerm", "schema_version": 0, "values": { - "description": "Deploy resource group containing Log Analytics workspace and linked automation account to centralize logs and monitoring. The automation account is aprerequisite for solutions like Updates and Change Tracking.", - "display_name": "Configure Log Analytics workspace and automation account to centralize logs and monitoring", + "description": "Deploy-Log-Analytics.", + "display_name": "Deploy-Log-Analytics", "enforce": false, "identity": [ { - "identity_ids": null, - "type": "SystemAssigned" + "identity_ids": [ + "/subscriptions/2a8527ca-5340-49aa-8931-ea03669451a0/resourceGroups/rg-identity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id-identity" + ], + "type": "UserAssigned" } ], "location": "northeurope", "management_group_id": "/providers/Microsoft.Management/managementGroups/root-id-1-management", "name": "Deploy-Log-Analytics", - "non_compliance_message": [ - { - "content": "Log Analytics workspace and automation account should be configured to centralize logs and monitoring.", - "policy_definition_reference_id": null - } - ], + "non_compliance_message": [], "not_scopes": [], "overrides": [], - "parameters": "{\"automationAccountName\":{\"value\":\"root-id-1-automation\"},\"automationRegion\":{\"value\":\"northeurope\"},\"dataRetention\":{\"value\":\"60\"},\"rgName\":{\"value\":\"root-id-1-mgmt\"},\"sku\":{\"value\":\"pergb2018\"},\"workspaceName\":{\"value\":\"root-id-1-la\"},\"workspaceRegion\":{\"value\":\"northeurope\"}}", + "parameters": "{\"automationAccountName\":{\"value\":\"root-id-1-automation\"},\"automationRegion\":{\"value\":\"northeurope\"},\"dataRetention\":{\"value\":\"60\"},\"effect\":{\"value\":\"DeployIfNotExists\"},\"rgName\":{\"value\":\"root-id-1-mgmt\"},\"sku\":{\"value\":\"pergb2018\"},\"workspaceName\":{\"value\":\"root-id-1-la\"},\"workspaceRegion\":{\"value\":\"northeurope\"}}", "policy_definition_id": "/providers/Microsoft.Authorization/policyDefinitions/8e3e61b3-0b32-22d5-4edf-55f87fdb5955", "resource_selectors": [], "timeouts": null }, "sensitive_values": { "identity": [ - {} - ], - "non_compliance_message": [ - {} + { + "identity_ids": [ + false + ] + } ], + "non_compliance_message": [], "not_scopes": [], "overrides": [], "resource_selectors": [] @@ -7901,6 +7937,32 @@ }, "sensitive_values": {} }, + { + "address": "module.test_core.data.azapi_resource.user_msi[\"/providers/Microsoft.Management/managementGroups/root-id-1-management/providers/Microsoft.Authorization/policyAssignments/Deploy-Log-Analytics\"]", + "mode": "data", + "type": "azapi_resource", + "name": "user_msi", + "index": "/providers/Microsoft.Management/managementGroups/root-id-1-management/providers/Microsoft.Authorization/policyAssignments/Deploy-Log-Analytics", + "provider_name": "registry.terraform.io/azure/azapi", + "schema_version": 0, + "values": { + "identity": [], + "name": null, + "resource_id": "/subscriptions/2a8527ca-5340-49aa-8931-ea03669451a0/resourceGroups/rg-identity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id-identity", + "response_export_values": [ + "properties.principalId" + ], + "timeouts": null, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31" + }, + "sensitive_values": { + "identity": [], + "response_export_values": [ + false + ], + "tags": {} + } + }, { "address": "module.test_core.random_id.telem[0]", "mode": "managed", diff --git a/tests/modules/test_003_add_mgmt_conn/baseline_values.json b/tests/modules/test_003_add_mgmt_conn/baseline_values.json index 9b0d1d4a2..f9ec94704 100644 --- a/tests/modules/test_003_add_mgmt_conn/baseline_values.json +++ b/tests/modules/test_003_add_mgmt_conn/baseline_values.json @@ -1,6 +1,43 @@ { "root_module": { "child_modules": [ + { + "resources": [ + { + "address": "module.settings.azurerm_resource_group.example", + "mode": "managed", + "type": "azurerm_resource_group", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/azurerm", + "schema_version": 0, + "values": { + "location": "northeurope", + "managed_by": null, + "name": "rg-identity", + "tags": null, + "timeouts": null + }, + "sensitive_values": {} + }, + { + "address": "module.settings.azurerm_user_assigned_identity.example", + "mode": "managed", + "type": "azurerm_user_assigned_identity", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/azurerm", + "schema_version": 1, + "values": { + "location": "northeurope", + "name": "id-identity", + "resource_group_name": "rg-identity", + "tags": null, + "timeouts": null + }, + "sensitive_values": {} + } + ], + "address": "module.settings" + }, { "resources": [ { @@ -7237,13 +7274,15 @@ "provider_name": "registry.terraform.io/hashicorp/azurerm", "schema_version": 0, "values": { - "description": "Deploy resource group containing Log Analytics workspace and linked automation account to centralize logs and monitoring. The automation account is aprerequisite for solutions like Updates and Change Tracking.", - "display_name": "Configure Log Analytics workspace and automation account to centralize logs and monitoring", + "description": "Deploy-Log-Analytics.", + "display_name": "Deploy-Log-Analytics", "enforce": false, "identity": [ { - "identity_ids": null, - "type": "SystemAssigned" + "identity_ids": [ + "/subscriptions/2a8527ca-5340-49aa-8931-ea03669451a0/resourceGroups/rg-identity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id-identity" + ], + "type": "UserAssigned" } ], "location": "northeurope", @@ -7251,20 +7290,24 @@ "name": "Deploy-Log-Analytics", "non_compliance_message": [ { - "content": "Log Analytics workspace and automation account should be configured to centralize logs and monitoring.", + "content": "This resource should be compliant with the assigned policy.", "policy_definition_reference_id": null } ], "not_scopes": [], "overrides": [], - "parameters": "{\"automationAccountName\":{\"value\":\"root-id-1-automation\"},\"automationRegion\":{\"value\":\"northeurope\"},\"dataRetention\":{\"value\":\"60\"},\"rgName\":{\"value\":\"root-id-1-mgmt\"},\"sku\":{\"value\":\"pergb2018\"},\"workspaceName\":{\"value\":\"root-id-1-la\"},\"workspaceRegion\":{\"value\":\"northeurope\"}}", + "parameters": "{\"automationAccountName\":{\"value\":\"root-id-1-automation\"},\"automationRegion\":{\"value\":\"northeurope\"},\"dataRetention\":{\"value\":\"60\"},\"effect\":{\"value\":\"DeployIfNotExists\"},\"rgName\":{\"value\":\"root-id-1-mgmt\"},\"sku\":{\"value\":\"pergb2018\"},\"workspaceName\":{\"value\":\"root-id-1-la\"},\"workspaceRegion\":{\"value\":\"northeurope\"}}", "policy_definition_id": "/providers/Microsoft.Authorization/policyDefinitions/8e3e61b3-0b32-22d5-4edf-55f87fdb5955", "resource_selectors": [], "timeouts": null }, "sensitive_values": { "identity": [ - {} + { + "identity_ids": [ + false + ] + } ], "non_compliance_message": [ {} @@ -13579,6 +13622,32 @@ }, "sensitive_values": {} }, + { + "address": "module.test_core.data.azapi_resource.user_msi[\"/providers/Microsoft.Management/managementGroups/root-id-1-management/providers/Microsoft.Authorization/policyAssignments/Deploy-Log-Analytics\"]", + "mode": "data", + "type": "azapi_resource", + "name": "user_msi", + "index": "/providers/Microsoft.Management/managementGroups/root-id-1-management/providers/Microsoft.Authorization/policyAssignments/Deploy-Log-Analytics", + "provider_name": "registry.terraform.io/azure/azapi", + "schema_version": 0, + "values": { + "identity": [], + "name": null, + "resource_id": "/subscriptions/2a8527ca-5340-49aa-8931-ea03669451a0/resourceGroups/rg-identity/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id-identity", + "response_export_values": [ + "properties.principalId" + ], + "timeouts": null, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31" + }, + "sensitive_values": { + "identity": [], + "response_export_values": [ + false + ], + "tags": {} + } + }, { "address": "module.test_core.random_id.telem[0]", "mode": "managed", diff --git a/tests/modules/test_lib/policy_assignments/policy_assignment_test_id.tmpl.json b/tests/modules/test_lib/policy_assignments/policy_assignment_test_id.tmpl.json new file mode 100644 index 000000000..84d9aaf45 --- /dev/null +++ b/tests/modules/test_lib/policy_assignments/policy_assignment_test_id.tmpl.json @@ -0,0 +1,46 @@ +{ + "name": "Deploy-Log-Analytics", + "type": "Microsoft.Authorization/policyAssignments", + "apiVersion": "2019-09-01", + "properties": { + "description": "Deploy-Log-Analytics.", + "displayName": "Deploy-Log-Analytics", + "notScopes": [], + "parameters": { + "workspaceName": { + "value": "${root_scope_id}-la" + }, + "automationAccountName": { + "value": "${root_scope_id}-automation" + }, + "workspaceRegion": { + "value": "${default_location}" + }, + "automationRegion": { + "value": "${default_location}" + }, + "dataRetention": { + "value": "30" + }, + "sku": { + "value": "pergb2018" + }, + "rgName": { + "value": "${root_scope_id}-mgmt" + }, + "effect": { + "value": "DeployIfNotExists" + } + }, + "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/8e3e61b3-0b32-22d5-4edf-55f87fdb5955", + "scope": "${current_scope_resource_id}", + "enforcementMode": "DoNotEnforce" + }, + "location": "${default_location}", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "/subscriptions/${subscription_id}/resourceGroups/${umi_resource_group_name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/${umi_name}": {} + } + } +} \ No newline at end of file