Skip to content

Instantly share code, notes, and snippets.

@jesseloudon
Created February 7, 2021 08:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jesseloudon/84d120b01f51f9d761d67b841f05cf51 to your computer and use it in GitHub Desktop.
Save jesseloudon/84d120b01f51f9d761d67b841f05cf51 to your computer and use it in GitHub Desktop.
Example of creating 1x Terraform AzureRM policyset and 1x assignment using built-in policies and passing in parameter_values
resource "azurerm_policy_set_definition" "example" {
name = "foundations"
policy_type = "Custom"
display_name = "Foundations"
description = "Contains built-in policies for Foundations"
metadata = jsonencode({ category = "Custom", version = "1.0.0", source = "Terraform" })
dynamic "policy_definition_reference" { #built-in policies without parameter_values
for_each = data.azurerm_policy_definition.builtin_policies_foundations
content {
policy_definition_id = policy_definition_reference.value["id"]
reference_id = policy_definition_reference.value["display_name"]
parameter_values = null
}
}
policy_definition_reference {
policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/cccc23c7-8427-4f53-ad12-b6a63eb452b3"
reference_id = "Allowed virtual machine size SKUs"
parameter_values = jsonencode({ "listOfAllowedSKUs" : { value = ["Standard_B2s", "Standard_A2", "Standard_D2_v3", "Standard_D4_v3", "Standard_D8_v3"] } })
}
policy_definition_reference {
policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c"
reference_id = "Allowed locations"
parameter_values = jsonencode({ "listOfAllowedLocations" : { value = ["Australia East", "Australia Southeast", "Australia Central", "Australia Central 2"] } })
}
policy_definition_reference {
policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/f772fb64-8e40-40ad-87bc-7706e1949427"
reference_id = "Certificates should not expire within the specified number of days"
parameter_values = jsonencode({ "daysToExpire" : { value = 28 } })
}
policy_definition_reference {
policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/cee51871-e572-4576-855c-047c820360f0"
reference_id = "Certificates using RSA cryptography should have the specified minimum key size"
parameter_values = jsonencode({ "minimumRSAKeySize" : { value = 2048 } })
}
}
resource "azurerm_policy_assignment" "example" {
name = "foundations"
scope = data.azurerm_subscription.current.id
policy_definition_id = azurerm_policy_set_definition.example.id
description = "Contains built-in policies for Foundations"
display_name = "Foundations"
location = "Australia Southeast"
metadata = { category = "Custom", version = "1.0.0", source = "Terraform" }
}
variable "builtin_policies_foundations" {
type = list
description = "List of built-in policy definitions (display names) for the foundations policyset"
default = [
"Automation account variables should be encrypted",
"Audit VMs that do not use managed disks",
"Diagnostic logs in Virtual Machine Scale Sets should be enabled",
"Unattached disks should be encrypted",
"Virtual machines should be migrated to new Azure Resource Manager resources",
"Diagnostic logs in Azure Data Lake Store should be enabled",
"[Preview]: Certificates should have the specified maximum validity period",
"Diagnostic logs in Key Vault should be enabled",
"[Preview]: Firewall should be enabled on Key Vault",
"Key vaults should have purge protection enabled",
"Diagnostic logs in Logic Apps should be enabled",
"Activity log should be retained for at least one year",
"Azure Monitor log profile should collect logs for categories 'write,' 'delete,' and 'action'",
"Azure Monitor should collect activity logs from all regions",
"Azure Monitor solution 'Security and Audit' must be deployed",
"Azure subscriptions should have a log profile for Activity Log",
"The Log Analytics agent should be installed on virtual machines",
"[Preview]: All Internet traffic should be routed via your deployed Azure Firewall",
"App Service should use a virtual network service endpoint",
"Flow log should be configured for every network security group",
"Key Vault should use a virtual network service endpoint",
"RDP access from the Internet should be blocked",
"SQL Server should use a virtual network service endpoint",
"SSH access from the Internet should be blocked",
"Storage Accounts should use a virtual network service endpoint",
"Web Application Firewall (WAF) should be enabled for Application Gateway",
"Web Application Firewall (WAF) should use the specified mode for Application Gateway",
"Diagnostic logs in Search services should be enabled",
"Subscriptions should have a contact email address for security issues",
"Azure Defender for App Service should be enabled",
"Azure Defender for Azure SQL Database servers should be enabled",
"Azure Defender for container registries should be enabled",
"Azure Defender for Key Vault should be enabled",
"Azure Defender for Kubernetes should be enabled",
"Azure Defender for servers should be enabled",
"Azure Defender for SQL servers on machines should be enabled",
"Azure Defender for Storage should be enabled",
"Email notification for high severity alerts should be enabled",
"Email notification to subscription owner for high severity alerts should be enabled",
"Internet-facing virtual machines should be protected with network security groups",
"IP Forwarding on your virtual machine should be disabled",
"Log Analytics agent health issues should be resolved on your machines",
"Log Analytics agent should be installed on your virtual machine for Azure Security Center monitoring",
"Management ports should be closed on your virtual machines",
"Non-internet-facing virtual machines should be protected with network security groups",
"Security Center standard pricing tier should be selected",
"[Preview]: Sensitive data in your SQL databases should be classified",
"Service principals should be used to protect your subscriptions instead of management certificates",
"Subnets should be associated with a Network Security Group",
"Diagnostic logs in Service Bus should be enabled",
"Azure SQL Database should have the minimal TLS version of 1.2",
"SQL Auditing settings should have Action-Groups configured to capture critical activities",
"SQL Managed Instance should have the minimal TLS version of 1.2",
"SQL servers should be configured with 90 days auditing retention or higher.",
"Vulnerability Assessment settings for SQL server should contain an email address to receive scan reports",
"Vulnerability assessment should be enabled on SQL Managed Instance",
"Vulnerability assessment should be enabled on your SQL servers",
"[Preview]: Storage account public access should be disallowed",
"Storage accounts should allow access from trusted Microsoft services",
"Storage accounts should be migrated to new Azure Resource Manager resources"
]
}
data "azurerm_policy_definition" "builtin_policies_foundations" {
count = length(var.builtin_policies_foundations)
display_name = var.builtin_policies_foundations[count.index]
}
data "azurerm_subscription" "current" {
}
provider "azurerm" {
version = "~> 2.0"
features {}
skip_provider_registration = true
}
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
}
}
required_version = ">= 0.13"
}
@jesseloudon
Copy link
Author

jesseloudon commented Feb 7, 2021

README

Input Variables

The below list variable is used to define built-in policies (display names) for the foundation deployment.
This list will require updating as Microsoft add/modify/remove their built-in policies.

  • var.builtin_policies_foundations - (list)

A data source lookup then uses this list to retrieve the built-in policy IDs for use by the policyset.

  • data.azurerm_policy_definition.builtin_policies_foundations - (data source lookup on policy definitions)

Built-in Policies missing default parameter values

Some Microsoft built-in policies are missing default parameter values and require a string, integer, or array to be passed into a policyset.
The method to achieve this requirement is shown below for a policyset.
These built-in policies are not listed in var.builtin_policies_foundations described above so policy_definition_id and reference_id needs to be manually specified as demonstrated below.

  policy_definition_reference {
    policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/cccc23c7-8427-4f53-ad12-b6a63eb452b3"
    reference_id         = "Allowed virtual machine size SKUs"
    parameter_values     = jsonencode({ "listOfAllowedSKUs" : { value = ["Standard_B2s", "Standard_A2", "Standard_D2_v3", "Standard_D4_v3", "Standard_D8_v3"] } })
  }

  policy_definition_reference {
    policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4c"
    reference_id         = "Allowed locations"
    parameter_values     = jsonencode({ "listOfAllowedLocations" : { value = ["Australia East", "Australia Southeast", "Australia Central", "Australia Central 2"] } })
  }

  policy_definition_reference {
    policy_definition_id = "/providers/Microsoft.Authorization/policyDefinitions/f772fb64-8e40-40ad-87bc-7706e1949427"
    reference_id         = "Certificates should not expire within the specified number of days"
    parameter_values     = jsonencode({ "daysToExpire" : { value = 28 } })
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment