From 88f1afed29503bff637830a919fb74ab2a08e151 Mon Sep 17 00:00:00 2001 From: Sadik Tekin Date: Fri, 6 Jan 2023 14:41:20 +0000 Subject: [PATCH] 2.7.1 (#63) Role Assignment syntax --- README.md | 27 +++++++------------ examples/README.md | 4 +-- examples/assignments_team_a.tf | 6 ++--- examples/definitions.tf | 4 +-- modules/def_assignment/README.md | 7 +++-- modules/def_assignment/TEMPLATE.md | 7 +++-- modules/def_assignment/variables.tf | 2 +- modules/set_assignment/variables.tf | 2 +- ...es_types.json => deny_resource_types.json} | 2 +- 9 files changed, 30 insertions(+), 31 deletions(-) rename policies/General/{deny_resources_types.json => deny_resource_types.json} (96%) diff --git a/README.md b/README.md index 1c22239..71d0e38 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ 📦examples ├──📜assignments_mg.tf ├──📜backend.tf + ├──📜built-in.tf ├──📜data.tf ├──📜definitions.tf ├──📜exemptions.tf @@ -72,9 +73,9 @@ └──📜build_guest_config_packages.ps1 (build and publish azure policy guest configuration packages) ``` -## Custom Policy Definitions Module +## [Custom Policy Definitions Module](modules/definition) -This module depends on populating `var.policy_name` and `var.policy_category` to correspond with the respective custom policy definition `json` file found in the [local library](policies). You can also parse in other template files and data sources at runtime, see the [definition module readme](modules/definition) for examples and acceptable inputs. +This module depends on populating `var.policy_name` and `var.policy_category` to correspond with the respective custom policy definition `json` file found in the [local library](policies). You can also parse in other template files and data sources at runtime, see the [module readme](modules/definition) for examples and acceptable inputs. ```hcl module whitelist_regions { @@ -88,7 +89,7 @@ module whitelist_regions { > 📘 [Microsoft Docs: Azure Policy definition structure](https://learn.microsoft.com/en-us/azure/governance/policy/concepts/definition-structure) -## Policy Initiative (Set Definitions) Module +## [Policy Initiative (Set Definitions) Module](modules/initiative) Dynamically create a policy set based on multiple custom or built-in policy definition references to simplify assignments. @@ -111,7 +112,7 @@ module platform_baseline_initiative { > 📘 [Microsoft Docs: Azure Policy initiative definition structure](https://learn.microsoft.com/en-us/azure/governance/policy/concepts/initiative-definition-structure) -## Policy Definition Assignment Module +## [Policy Definition Assignment Module](modules/def_assignment) ```hcl module org_mg_whitelist_regions { @@ -132,7 +133,7 @@ module org_mg_whitelist_regions { > 📘 [Microsoft Docs: Azure Policy assignment structure](https://learn.microsoft.com/en-us/azure/governance/policy/concepts/assignment-structure) -## Policy Initiative Assignment Module +## [Policy Initiative Assignment Module](modules/set_assignment) ```hcl module org_mg_platform_diagnostics_initiative { @@ -162,20 +163,12 @@ module org_mg_platform_diagnostics_initiative { null = "The Default non-compliance message for all member definitions" "DeployApplicationGatewayDiagnosticSetting" = "The non-compliance message for the deploy_application_gateway_diagnostic_setting definition" } - - # specify a list of role definitions or omit to use those defined in the policies - role_definition_ids = [ - data.azurerm_role_definition.contributor.id - ] - - # specify a different role assignment scope or omit to use the policy assignment scope - role_assignment_scope = data.azurerm_management_group.team_a.id } ``` -## Policy Exemption Module +## [Policy Exemption Module](modules/exemption) -Use the [exemption module](modules/exemption) in favour of `not_scopes` to create an auditable time-sensitive Policy exemption +Use the exemption module in favour of `not_scopes` to create an auditable time-sensitive Policy exemption ```hcl module exemption_team_a_mg_deny_nic_public_ip { @@ -214,7 +207,7 @@ Azure Policy supports the following types of effect: ### 👥Role Assignments -Role assignments and remediation tasks will be automatically created if the Policy Definition contains a list of [Role Definitions](https://learn.microsoft.com/en-us/azure/governance/policy/how-to/remediate-resources#configure-policy-definition). You can override these with explicit ones, [as seen here](examples/assignments_org.tf#L52-L58), or specify `skip_role_assignment=true` to omit creation. By default these will scope at the policy assignment but can be changed by setting `role_assignment_scope`. +Role assignments and remediation tasks will be automatically created if the Policy Definition contains a list of [Role Definitions](policies/Tags/inherit_resource_group_tags_modify.json#L46). You can override these with explicit ones, [as seen here](examples/assignments_org.tf#L40), or specify `skip_role_assignment=true` to omit creation, this is also skipped when using User Managed Identities. By default role assignment scopes will match the policy assignment but can be changed by setting `role_assignment_scope`. ### ✅Remediation Tasks @@ -230,7 +223,7 @@ To trigger an on-demand [compliance scan](https://learn.microsoft.com/en-us/azur - Should be Defined as **high up** in the hierarchy as possible. - Should be Assigned as **low down** in the hierarchy as possible. - - Multiple scopes can be exempt from policy inheritance by specifying `assignment_not_scopes`. + - Multiple scopes can be exempt from policy inheritance by specifying `assignment_not_scopes` or using the [exemption module](modules/exemption). - Policy **overrides RBAC** so even resource owners and contributors fall under compliance enforcements assigned at a higher scope (unless the policy is assigned at the ownership scope). ![Policy Definition and Assignment Scopes](img/scopes.svg) diff --git a/examples/README.md b/examples/README.md index c4f0882..be8977f 100644 --- a/examples/README.md +++ b/examples/README.md @@ -24,7 +24,7 @@ This examples folder demonstrates an effective deployment of Azure Policy Defini | [configure\_asc](#module\_configure\_asc) | ..//modules/definition | n/a | | [configure\_asc\_initiative](#module\_configure\_asc\_initiative) | ..//modules/initiative | n/a | | [deny\_nic\_public\_ip](#module\_deny\_nic\_public\_ip) | ..//modules/definition | n/a | -| [deny\_resources\_types](#module\_deny\_resources\_types) | ..//modules/definition | n/a | +| [deny\_resource\_types](#module\_deny\_resource\_types) | ..//modules/definition | n/a | | [deploy\_resource\_diagnostic\_setting](#module\_deploy\_resource\_diagnostic\_setting) | ..//modules/definition | n/a | | [exemption\_subscription\_diagnostics\_settings](#module\_exemption\_subscription\_diagnostics\_settings) | ..//modules/exemption | n/a | | [inherit\_resource\_group\_tags\_modify](#module\_inherit\_resource\_group\_tags\_modify) | ..//modules/definition | n/a | @@ -38,7 +38,7 @@ This examples folder demonstrates an effective deployment of Azure Policy Defini | [storage\_enforce\_https](#module\_storage\_enforce\_https) | ..//modules/definition | n/a | | [storage\_enforce\_minimum\_tls1\_2](#module\_storage\_enforce\_minimum\_tls1\_2) | ..//modules/definition | n/a | | [team\_a\_mg\_deny\_nic\_public\_ip](#module\_team\_a\_mg\_deny\_nic\_public\_ip) | ..//modules/def_assignment | n/a | -| [team\_a\_mg\_deny\_resources\_types](#module\_team\_a\_mg\_deny\_resources\_types) | ..//modules/def_assignment | n/a | +| [team\_a\_mg\_deny\_resource\_types](#module\_team\_a\_mg\_deny\_resource\_types) | ..//modules/def_assignment | n/a | | [team\_a\_mg\_inherit\_resource\_group\_tags\_modify](#module\_team\_a\_mg\_inherit\_resource\_group\_tags\_modify) | ..//modules/def_assignment | n/a | | [whitelist\_regions](#module\_whitelist\_regions) | ..//modules/definition | n/a | diff --git a/examples/assignments_team_a.tf b/examples/assignments_team_a.tf index 12c2e9d..ec50218 100644 --- a/examples/assignments_team_a.tf +++ b/examples/assignments_team_a.tf @@ -1,9 +1,9 @@ ################## # General ################## -module "team_a_mg_deny_resources_types" { +module "team_a_mg_deny_resource_types" { source = "..//modules/def_assignment" - definition = module.deny_resources_types.definition + definition = module.deny_resource_types.definition assignment_scope = data.azurerm_management_group.team_a.id assignment_effect = "Audit" @@ -40,7 +40,7 @@ module "team_a_mg_inherit_resource_group_tags_modify" { assignment_effect = "Modify" skip_remediation = var.skip_remediation remediation_scope = data.azurerm_subscription.current.id # change the scope of remediation tasks, defaults to assignment_scope - identity_ids = [data.azurerm_user_assigned_identity.policy_rem.id] + identity_ids = [data.azurerm_user_assigned_identity.policy_rem.id] # use User Managed Identities assignment_parameters = { tagName = "environment" diff --git a/examples/definitions.tf b/examples/definitions.tf index 9270fb5..c1b43e2 100644 --- a/examples/definitions.tf +++ b/examples/definitions.tf @@ -1,9 +1,9 @@ ################## # General ################## -module "deny_resources_types" { +module "deny_resource_types" { source = "..//modules/definition" - policy_name = "deny_resources_types" + policy_name = "deny_resource_types" display_name = "Deny Azure Resource types" policy_category = "General" management_group_id = data.azurerm_management_group.org.id diff --git a/modules/def_assignment/README.md b/modules/def_assignment/README.md index e2906ec..07a267a 100644 --- a/modules/def_assignment/README.md +++ b/modules/def_assignment/README.md @@ -37,10 +37,13 @@ module team_a_mg_inherit_resource_group_tags_modify { assignment_effect = "Modify" skip_remediation = var.skip_remediation + # specify a list of role definitions or omit to use those defined in the policies role_definition_ids = [ - data.azurerm_role_definition.contributor + data.azurerm_role_definition.contributor.id ] - role_assignment_scope = "omit this to assign at same scope as policy assignment" + + # specify a different role assignment scope or omit to use the policy assignment scope + role_assignment_scope = data.azurerm_management_group.team_a.id assignment_parameters = { tagName = "environment" diff --git a/modules/def_assignment/TEMPLATE.md b/modules/def_assignment/TEMPLATE.md index 711e51f..49dedd0 100644 --- a/modules/def_assignment/TEMPLATE.md +++ b/modules/def_assignment/TEMPLATE.md @@ -37,10 +37,13 @@ module team_a_mg_inherit_resource_group_tags_modify { assignment_effect = "Modify" skip_remediation = var.skip_remediation + # specify a list of role definitions or omit to use those defined in the policies role_definition_ids = [ - data.azurerm_role_definition.contributor + data.azurerm_role_definition.contributor.id ] - role_assignment_scope = "omit this to assign at same scope as policy assignment" + + # specify a different role assignment scope or omit to use the policy assignment scope + role_assignment_scope = data.azurerm_management_group.team_a.id assignment_parameters = { tagName = "environment" diff --git a/modules/def_assignment/variables.tf b/modules/def_assignment/variables.tf index dbfba6b..da7b826 100644 --- a/modules/def_assignment/variables.tf +++ b/modules/def_assignment/variables.tf @@ -162,7 +162,7 @@ locals { identity_type = length(try(coalescelist(var.role_definition_ids, lookup(jsondecode(var.definition.policy_rule).then.details, "roleDefinitionIds", [])), [])) > 0 ? length(var.identity_ids) > 0 ? { type = "UserAssigned" } : { type = "SystemAssigned" } : {} # try to use policy definition roles if explicit roles are ommitted - role_definition_ids = var.skip_role_assignment == false && local.identity_type == { type = "SystemAssigned" } ? try(coalescelist(var.role_definition_ids, lookup(jsondecode(var.definition.policy_rule).then.details, "roleDefinitionIds", [])), []) : [] + role_definition_ids = var.skip_role_assignment == false && try(values(local.identity_type)[0], "") == "SystemAssigned" ? try(coalescelist(var.role_definition_ids, lookup(jsondecode(var.definition.policy_rule).then.details, "roleDefinitionIds", [])), []) : [] # policy assignment scope will be used if omitted role_assignment_scope = try(coalesce(var.role_assignment_scope, var.assignment_scope), "") diff --git a/modules/set_assignment/variables.tf b/modules/set_assignment/variables.tf index 4e18308..20ba07b 100644 --- a/modules/set_assignment/variables.tf +++ b/modules/set_assignment/variables.tf @@ -165,7 +165,7 @@ locals { identity_type = length(try(coalescelist(var.role_definition_ids, try(var.initiative.role_definition_ids, [])), [])) > 0 ? length(var.identity_ids) > 0 ? { type = "UserAssigned" } : { type = "SystemAssigned" } : {} # try to use policy definition roles if explicit roles are ommitted - role_definition_ids = var.skip_role_assignment == false && local.identity_type == { type = "SystemAssigned" } ? try(coalescelist(var.role_definition_ids, try(var.initiative.role_definition_ids, [])), []) : [] + role_definition_ids = var.skip_role_assignment == false && try(values(local.identity_type)[0], "") == "SystemAssigned" ? try(coalescelist(var.role_definition_ids, try(var.initiative.role_definition_ids, [])), []) : [] # evaluate policy assignment scope from resource identifier assignment_scope = try({ diff --git a/policies/General/deny_resources_types.json b/policies/General/deny_resource_types.json similarity index 96% rename from policies/General/deny_resources_types.json rename to policies/General/deny_resource_types.json index 7d8bceb..54d97fc 100644 --- a/policies/General/deny_resources_types.json +++ b/policies/General/deny_resource_types.json @@ -1,6 +1,6 @@ { "type": "Microsoft.Authorization/policyDefinitions", - "name": "deny_resources_types", + "name": "deny_resource_types", "properties": { "metadata": { "category": "General"