115 строки
6.5 KiB
HCL
115 строки
6.5 KiB
HCL
resource "azurerm_management_group_policy_assignment" "enterprise_scale" {
|
|
for_each = local.azurerm_management_group_policy_assignment_enterprise_scale
|
|
|
|
# Mandatory resource attributes
|
|
# The policy assignment name length must not exceed '24' characters, but Terraform plan is unable to validate this in the plan stage. The following logic forces an error during plan if an invalid name length is specified.
|
|
name = tonumber(length(each.value.template.name) > 24 ? "The policy assignment name '${each.value.template.name}' is invalid. The policy assignment name length must not exceed '24' characters." : length(each.value.template.name)) > 24 ? null : each.value.template.name
|
|
management_group_id = each.value.scope_id
|
|
policy_definition_id = each.value.template.properties.policyDefinitionId
|
|
|
|
# Optional resource attributes
|
|
location = try(each.value.template.location, null)
|
|
description = try(each.value.template.properties.description, "${each.value.template.name} Policy Assignment at scope ${each.value.scope_id}")
|
|
display_name = try(each.value.template.properties.displayName, each.value.template.name)
|
|
metadata = try(length(each.value.template.properties.metadata) > 0, false) ? jsonencode(each.value.template.properties.metadata) : null
|
|
parameters = try(length(each.value.parameters) > 0, false) ? jsonencode(each.value.parameters) : null
|
|
not_scopes = try(each.value.template.properties.notScopes, local.empty_list)
|
|
enforce = each.value.enforcement_mode
|
|
|
|
# Dynamic configuration blocks for overrides
|
|
# More details can be found here: https://learn.microsoft.com/en-gb/azure/governance/policy/concepts/assignment-structure#overrides-preview
|
|
dynamic "overrides" {
|
|
for_each = try({ for i, override in each.value.template.properties.overrides : i => override }, local.empty_map)
|
|
content {
|
|
value = overrides.value.value
|
|
dynamic "selectors" {
|
|
for_each = try({ for i, selector in overrides.value.selectors : i => selector }, local.empty_map)
|
|
content {
|
|
in = try(selectors.value.in, local.empty_list)
|
|
not_in = try(selectors.value.not_in, local.empty_list)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Dynamic configuration blocks
|
|
# The identity block only supports a single value
|
|
# for type = "SystemAssigned" so the following logic
|
|
# ensures the block is only created when this value
|
|
# is specified in the source template
|
|
dynamic "identity" {
|
|
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 = identity.value.type
|
|
identity_ids = can(identity.value.userAssignedIdentities) ? toset(keys(identity.value.userAssignedIdentities)) : null
|
|
}
|
|
}
|
|
|
|
# Optional Resource selectors block
|
|
# Only one of "in" or "not_in" should be used
|
|
# Each kind can be used only once
|
|
|
|
dynamic "resource_selectors" {
|
|
for_each = try({ for i, resourceSelector in each.value.template.properties.resourceSelectors : i => resourceSelector }, local.empty_map)
|
|
content {
|
|
name = resource_selectors.value.name
|
|
dynamic "selectors" {
|
|
for_each = try({ for i, selector in resource_selectors.value.selectors : i => selector }, local.empty_map)
|
|
content {
|
|
in = try(selectors.value.in, local.empty_list)
|
|
kind = selectors.value.kind
|
|
not_in = try(selectors.value.not_in, local.empty_list)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Optional Non-compliance messages
|
|
# The message will have the placeholder replaced with 'must' or 'should' by default dependent on the enforcement mode
|
|
# The language can the altered or localised using the variables
|
|
dynamic "non_compliance_message" {
|
|
for_each = local.policy_non_compliance_message_enabled ? (contains( # if noncompliance msgs enabled...
|
|
local.non_compliance_message_supported_policy_modes, # if non_compliance_message_supported_policy_modes contains
|
|
lookup(local.all_policy_modes, # ...the policy definition mode
|
|
each.value.template.properties.policyDefinitionId, #
|
|
local.policy_set_mode) # default use policy set mode
|
|
) ? lookup( # then... if the mode is supported then
|
|
each.value.template.properties, "nonComplianceMessages", local.default_non_compliance_message_list # lookup any custom non-compliance message if not use default
|
|
) : local.empty_list) : local.empty_list # if mode not supported then empty list, or is not enabled then empty list
|
|
content {
|
|
content = replace(lookup(non_compliance_message.value, "message", local.policy_non_compliance_message_default), local.non_compliance_message_enforcement_mode_placeholder, each.value.enforcement_mode ? local.non_compliance_message_enforcement_mode_replacements.default : local.non_compliance_message_enforcement_mode_replacements.donotenforce)
|
|
policy_definition_reference_id = lookup(non_compliance_message.value, "policyDefinitionReferenceId", null)
|
|
}
|
|
}
|
|
|
|
# Set explicit dependency on Management Group, Policy Definition and Policy Set Definition deployments.
|
|
# Additionally ensure the Policy Assignment is created after and destroyed before the User Assigned Identity
|
|
# this is to ensure that the deny delete policy is deleted before the identity is removed.
|
|
depends_on = [
|
|
azurerm_user_assigned_identity.management,
|
|
time_sleep.after_azurerm_management_group,
|
|
time_sleep.after_azurerm_policy_definition,
|
|
time_sleep.after_azurerm_policy_set_definition,
|
|
]
|
|
}
|
|
|
|
resource "time_sleep" "after_azurerm_policy_assignment" {
|
|
depends_on = [
|
|
time_sleep.after_azurerm_management_group,
|
|
time_sleep.after_azurerm_policy_definition,
|
|
time_sleep.after_azurerm_policy_set_definition,
|
|
azurerm_management_group_policy_assignment.enterprise_scale,
|
|
]
|
|
|
|
triggers = {
|
|
"azurerm_management_group_policy_assignment_enterprise_scale" = jsonencode(keys(azurerm_management_group_policy_assignment.enterprise_scale))
|
|
}
|
|
|
|
create_duration = local.create_duration_delay["after_azurerm_policy_assignment"]
|
|
destroy_duration = local.destroy_duration_delay["after_azurerm_policy_assignment"]
|
|
}
|