283 строки
12 KiB
HCL
283 строки
12 KiB
HCL
# The following locals are used to extract the Policy Assignment
|
|
# configuration from the archetype module outputs.
|
|
locals {
|
|
es_policy_assignments_by_management_group = flatten([
|
|
for archetype in values(module.management_group_archetypes) :
|
|
archetype.configuration.azurerm_policy_assignment
|
|
])
|
|
es_policy_assignments_by_subscription = local.empty_list
|
|
es_policy_assignments = concat(
|
|
local.es_policy_assignments_by_management_group,
|
|
local.es_policy_assignments_by_subscription,
|
|
)
|
|
}
|
|
|
|
# The following locals are used to build the map of Policy
|
|
# Assignments to deploy and then split them by scope type.
|
|
locals {
|
|
azurerm_policy_assignment_enterprise_scale = {
|
|
for assignment in local.es_policy_assignments :
|
|
assignment.resource_id => assignment
|
|
}
|
|
azurerm_management_group_policy_assignment_enterprise_scale = {
|
|
for pak, pav in local.azurerm_policy_assignment_enterprise_scale :
|
|
pak => pav
|
|
if length(regexall(local.regex_scope_is_management_group, pav.scope_id)) > 0
|
|
}
|
|
}
|
|
|
|
# To support the creation of Role Assignments for Policy Assignments
|
|
# using a Managed Identity, we need to identify the associated
|
|
# Role Definition(s) relating to the assigned Policy [Set] Definition
|
|
# within each Policy Assignment. This requires the following logic
|
|
# to determine which Role Assignments to create.
|
|
|
|
# This information is then passed to the `policy_assignments`
|
|
# sub-module which is used to create the resources.
|
|
|
|
# Generate a list of internal Policy Definitions and Policy
|
|
# Set Definitions.
|
|
locals {
|
|
internal_policy_definition_ids = [
|
|
for policy_definition in local.es_policy_definitions :
|
|
policy_definition.resource_id
|
|
]
|
|
internal_policy_set_definition_ids = [
|
|
for policy_set_definition in local.es_policy_set_definitions :
|
|
policy_set_definition.resource_id
|
|
]
|
|
}
|
|
|
|
# Determine which Policy Assignments use a Managed Identity.
|
|
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" || assignment.template.identity.type == "UserAssigned"
|
|
}
|
|
}
|
|
|
|
# Determine which of these Policy Assignments assign a Policy
|
|
# Definition or Policy Set Definition which is either built-in,
|
|
# or deployed to Azure using a process outside of this module.
|
|
locals {
|
|
# Policy Set Definitions
|
|
policy_assignments_with_managed_identity_using_external_policy_set_definition = {
|
|
for policy_assignment_id, policy_set_definition_id in local.policy_assignments_with_managed_identity :
|
|
policy_assignment_id => [
|
|
policy_set_definition_id,
|
|
]
|
|
if length(regexall(local.resource_types.policy_set_definition, policy_set_definition_id)) > 0
|
|
&& contains(local.internal_policy_set_definition_ids, policy_set_definition_id) != true
|
|
&& contains(keys(local.custom_policy_roles), policy_set_definition_id) != true
|
|
}
|
|
}
|
|
|
|
# Generate list of Policy Set Definitions to lookup from Azure.
|
|
locals {
|
|
azurerm_policy_set_definition_external_lookup = {
|
|
for policy_set_definition_id in keys(transpose(local.policy_assignments_with_managed_identity_using_external_policy_set_definition)) :
|
|
policy_set_definition_id => {
|
|
name = basename(policy_set_definition_id)
|
|
management_group_id = regex(local.regex_split_resource_id, policy_set_definition_id)[0] == "/providers/Microsoft.Management/managementGroups/" ? regex(local.regex_split_resource_id, policy_set_definition_id)[1] : null
|
|
}
|
|
}
|
|
}
|
|
|
|
# Perform a lookup of the Policy Set Definitions not deployed by this module.
|
|
data "azurerm_policy_set_definition" "external_lookup" {
|
|
for_each = local.azurerm_policy_set_definition_external_lookup
|
|
|
|
name = each.value.name
|
|
management_group_name = each.value.management_group_id
|
|
}
|
|
|
|
# Create a list of Policy Definitions IDs used by all assigned Policy Set Definitions
|
|
locals {
|
|
policy_definition_ids_from_internal_policy_set_definitions = {
|
|
for policy_set_definition in local.es_policy_set_definitions :
|
|
policy_set_definition.resource_id => [
|
|
for policy_definition in policy_set_definition.template.properties.policyDefinitions :
|
|
policy_definition.policyDefinitionId
|
|
]
|
|
}
|
|
policy_definition_ids_from_external_policy_set_definitions = {
|
|
for policy_set_definition_id, policy_set_definition_config in data.azurerm_policy_set_definition.external_lookup :
|
|
policy_set_definition_id => [
|
|
for policy_definition in policy_set_definition_config.policy_definition_reference :
|
|
policy_definition.policy_definition_id
|
|
]
|
|
}
|
|
policy_definition_ids_from_policy_set_definitions = merge(
|
|
local.policy_definition_ids_from_internal_policy_set_definitions,
|
|
local.policy_definition_ids_from_external_policy_set_definitions,
|
|
)
|
|
}
|
|
|
|
# Maps of all external and internal policy assignment definition ids
|
|
locals {
|
|
external_policies_from_local_assignments = [
|
|
for assignment in local.es_policy_assignments :
|
|
assignment.template.properties.policyDefinitionId
|
|
if length(regexall(local.resource_types.policy_definition, assignment.template.properties.policyDefinitionId)) > 0
|
|
&& contains(local.internal_policy_definition_ids, assignment.template.properties.policyDefinitionId) != true
|
|
]
|
|
|
|
internal_policies_from_local_assignments = [
|
|
for assignment in local.es_policy_assignments :
|
|
assignment.template.properties.policyDefinitionId
|
|
if length(regexall(local.resource_types.policy_definition, assignment.template.properties.policyDefinitionId)) > 0
|
|
&& contains(local.internal_policy_definition_ids, assignment.template.properties.policyDefinitionId) == true
|
|
]
|
|
}
|
|
|
|
# Identify all Policy Definitions which are external to this module
|
|
locals {
|
|
# From Policy Assignments using Policy Set Definitions
|
|
external_policy_definition_ids_from_policy_set_definitions = distinct(flatten([
|
|
for policy_definition_ids in values(local.policy_definition_ids_from_policy_set_definitions) : [
|
|
for policy_definition_id in policy_definition_ids :
|
|
policy_definition_id
|
|
if contains(local.internal_policy_definition_ids, policy_definition_id) != true
|
|
]
|
|
]))
|
|
external_policy_definitions_from_azurerm_policy_set_definition_external_lookup = {
|
|
for policy_definition_id in local.external_policy_definition_ids_from_policy_set_definitions :
|
|
policy_definition_id => {
|
|
name = basename(policy_definition_id)
|
|
management_group_id = regex(local.regex_split_resource_id, policy_definition_id)[0] == "/providers/Microsoft.Management/managementGroups/" ? regex(local.regex_split_resource_id, policy_definition_id)[1] : null
|
|
}
|
|
}
|
|
# From Policy Assignments using Policy Definitions
|
|
external_policy_definitions_from_internal_policy_assignments = {
|
|
for policy_definition_id in distinct(local.external_policies_from_local_assignments) :
|
|
policy_definition_id => {
|
|
name = basename(policy_definition_id)
|
|
management_group_id = regex(local.regex_split_resource_id, policy_definition_id)[0] == "/providers/Microsoft.Management/managementGroups/" ? regex(local.regex_split_resource_id, policy_definition_id)[1] : null
|
|
}
|
|
}
|
|
# Then create a single list containing all Policy Definitions to lookup from Azure
|
|
azurerm_policy_definition_external_lookup = merge(
|
|
local.external_policy_definitions_from_azurerm_policy_set_definition_external_lookup,
|
|
local.external_policy_definitions_from_internal_policy_assignments
|
|
)
|
|
}
|
|
|
|
# Perform a lookup of the Policy Definitions not deployed by this module.
|
|
data "azurerm_policy_definition" "external_lookup" {
|
|
for_each = local.azurerm_policy_definition_external_lookup
|
|
|
|
name = each.value.name
|
|
management_group_name = each.value.management_group_id
|
|
}
|
|
|
|
# Extract the Role Definition IDs from the internal and external
|
|
# Policy Definitions, then combine into a single lookup map.
|
|
# Loop on list of roleDefinitionIds ensures correct character
|
|
# case to prevent duplicate values
|
|
locals {
|
|
internal_policy_definition_roles = {
|
|
for policy_definition in local.es_policy_definitions :
|
|
policy_definition.resource_id => try(
|
|
[
|
|
for role_definition in policy_definition.template.properties.policyRule.then.details.roleDefinitionIds :
|
|
"/providers/Microsoft.Authorization/roleDefinitions/${basename(role_definition)}"
|
|
],
|
|
local.empty_list
|
|
)
|
|
}
|
|
external_policy_definition_roles = {
|
|
for policy_definition_id, policy_definition_config in data.azurerm_policy_definition.external_lookup :
|
|
policy_definition_id => try(
|
|
[
|
|
for role_definition in jsondecode(policy_definition_config.policy_rule).then.details.roleDefinitionIds :
|
|
"/providers/Microsoft.Authorization/roleDefinitions/${basename(role_definition)}"
|
|
],
|
|
local.empty_list
|
|
)
|
|
}
|
|
policy_definition_roles = merge(
|
|
local.internal_policy_definition_roles,
|
|
local.external_policy_definition_roles,
|
|
)
|
|
}
|
|
|
|
# Merge the map of Policy Definitions from internal and
|
|
# external Policy Set Definitions then generate the map
|
|
# of roles for each.
|
|
locals {
|
|
policy_set_definition_roles = {
|
|
for policy_set_definition_id, policy_definition_ids in local.policy_definition_ids_from_policy_set_definitions :
|
|
policy_set_definition_id => distinct(flatten([
|
|
for policy_definition_id in policy_definition_ids :
|
|
local.policy_definition_roles[policy_definition_id]
|
|
]))
|
|
}
|
|
}
|
|
|
|
# Merge the map of roles for Policy Definitions and
|
|
# Policy Set Definitions.
|
|
locals {
|
|
policy_roles = merge(
|
|
local.policy_definition_roles,
|
|
local.policy_set_definition_roles,
|
|
local.custom_policy_roles
|
|
)
|
|
}
|
|
|
|
# Construct the map used to determine the list of
|
|
# Role Assignments to create for the Managed Identities
|
|
# used by Policy Assignments.
|
|
locals {
|
|
es_role_assignments_by_policy_assignment = {
|
|
for policy_assignment_id, policy_id in local.policy_assignments_with_managed_identity :
|
|
policy_assignment_id => lookup(local.policy_roles, policy_id, local.empty_list)
|
|
}
|
|
}
|
|
|
|
# Default Non-compliance message list when none is provided
|
|
locals {
|
|
default_non_compliance_message_list = local.policy_non_compliance_message_default_enabled ? [
|
|
{
|
|
message = local.policy_non_compliance_message_default
|
|
}
|
|
] : local.empty_list
|
|
}
|
|
|
|
# Non-compliance message replacements based on enforcement mode
|
|
# If the policy assignment is enforced the message with include 'must', if not it will say 'should'
|
|
locals {
|
|
non_compliance_message_enforcement_mode_replacements = {
|
|
default = local.policy_non_compliance_message_enforced_replacement
|
|
donotenforce = local.policy_non_compliance_message_not_enforced_replacement
|
|
}
|
|
non_compliance_message_enforcement_mode_placeholder = local.policy_non_compliance_message_enforcement_placeholder
|
|
}
|
|
|
|
# A list of policy definitions to exlude from having a default non-compliance message as they don't support compliance messages.
|
|
locals {
|
|
non_compliance_message_not_supported_definitions = local.policy_non_compliance_message_not_supported_definitions
|
|
}
|
|
|
|
# A list of policy modes that support non-compliance messages. A special setting is included for Policy Sets as they do not have a mode.
|
|
locals {
|
|
policy_set_mode = "PolicySet"
|
|
non_compliance_message_supported_policy_modes = ["All", "Indexed", local.policy_set_mode]
|
|
}
|
|
|
|
# Get the mode of the policy definitions for both internal and external policy definitions. Replacing with a fall back for older azurerm providers that don't support `mode` on the data source
|
|
locals {
|
|
external_policy_modes = {
|
|
for policy_definition in data.azurerm_policy_definition.external_lookup :
|
|
policy_definition.id => lookup(policy_definition, "mode", contains(local.non_compliance_message_not_supported_definitions, policy_definition.id) ? "NotSupported" : "All")
|
|
}
|
|
internal_policy_modes = {
|
|
for policy_definition_id in distinct(local.internal_policies_from_local_assignments) :
|
|
policy_definition_id => local.es_policy_definitions[index(local.es_policy_definitions.*.template.name, basename(policy_definition_id))].template.properties.mode
|
|
}
|
|
all_policy_modes = merge(
|
|
local.internal_policy_modes,
|
|
local.external_policy_modes
|
|
)
|
|
}
|