Azure Policies
Azure policies are a set of rules that enforce specific guidelines and best practices for resources in an Azure management group,subscription or directly on the resource itself. They help ensure compliance, governance, and cost management by preventing unexpected costs and resource sprawl. Azure policies are based on JSON files and can be applied at different levels of the Azure resource hierarchy.
Azure Built-in policies are pre-defined policies provided by Microsoft that help ensure compliance, security, and best practices for Azure resources.
Azure Initiatives
Azure Initiatives are a set of policies grouped together as a single unit for easier management and deployment. They allow you to define complex governance scenarios by combining multiple policies and provide a way to enforce them at scale across your Azure environment.
Managing Azure Policies and Initiatives with Terraform
To Handle built-in policies with Terraform. You can use terraform data blocks to retrienve them and group them in a Policy Initiative or Policy Set in Terrform terms.
locals.tf
Let’s define the list of built-in policies that we want to use in our management group. It’s important to ensure that the display name matches the built-in policy name defined by Azure, otherwise, the policy won’t be found by our data blocks. Some policies require parameters, thus we have that attribute defined.
locals {
globapolicies = {
diskspublicaccess = {
display_name = "Managed disks should disable public network access"
},
storageaccpublicaccess = {
display_name = "Storage accounts should disable public network access"
},
storageaccsecuretransfer = {
display_name = "Configure secure transfer of data on a storage account"
},
azmonitoragentonwindowsvms = {
display_name = "Windows virtual machines should have Azure Monitor Agent installed"
},
azmonitoragentonlinuxsvms = {
display_name = "Linux virtual machines should have Azure Monitor Agent installed"
},
gwsubnetswithoutnsg = {
display_name = "Gateway subnets should not be configured with a network security group"
},
nicswithoutpubip = {
display_name = "Network interfaces should not have public IPs"
},
azvirtualmachinesbkpaudit = {
display_name = "Azure Backup should be enabled for Virtual Machines"
},
azvirtualmachinesdraudit = {
display_name = "Audit virtual machines without disaster recovery configured"
},
allowedlocation = {
display_name = "Allowed locations"
parameters = jsonencode({
"listOfAllowedLocations" : { "value" : ["westeurope"] }
})
},
allowedlocationforrg = {
display_name = "Allowed locations for resource groups"
parameters = jsonencode({
"listOfAllowedLocations" : { "value" : ["westeurope"] }
})
},
inheritappidtagfromrg = {
display_name = "Inherit a tag from the resource group if missing"
parameters = jsonencode({
"tagName" : { "value" : "TAGVALUE" }
})
}
}
}
data.tf
Let’s loop through the varibles in locals.tf and retrieve the policy definition of each one.
data "azurerm_management_group" "my_mg" {
name = "my-management-group"
}
data "azurerm_policy_definition" "policy_def" {
for_each = local.globapolicies
display_name = each.value["display_name"]
}
az-global-policies.tf
Then, let’s create the definition of our initiative (policy set). It is all of our policies grouped under one initiative. We will then use this initiative definition (policy set definition) to create the adequate assignment on our management group.
resource "azurerm_policy_set_definition" "my_policyset_def" {
name = "MyInitiative"
policy_type = "Custom"
display_name = "Global policy set for my Azure resources"
management_group_id = data.azurerm_management_group.my_mg.id
dynamic "policy_definition_reference" {
for_each = local.globapolicies
content {
policy_definition_id = data.azurerm_policy_definition.policy_def[policy_definition_reference.key].id
reference_id = policy_definition_reference.key
parameter_values = lookup(policy_definition_reference.value, "parameters", null)
}
}
}
resource "azurerm_management_group_policy_assignment" "my_policyset_assignment" {
name = "MyInitiative-assignment"
location = "francecentral"
policy_definition_id = azurerm_policy_set_definition.my_policyset_def.id
management_group_id = data.azurerm_management_group.my_mg.id
identity {
type = "SystemAssigned"
}
}