Skip to content

Instantly share code, notes, and snippets.

@BernieWhite
Created October 14, 2019 01:56
Show Gist options
  • Save BernieWhite/8ffe083828e0c6555e2420365cd58910 to your computer and use it in GitHub Desktop.
Save BernieWhite/8ffe083828e0c6555e2420365cd58910 to your computer and use it in GitHub Desktop.
az-policy-template
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"policies": {
"value": [
{
"name": "allowedLocations",
"displayName": "Require allowed locations",
"description": "This policy requires resources to be deployed within allowed locations. Use to enforce your geo-compliance requirements.",
"category": "Compliance",
"parameters": {
"allowedLocations": {
"type": "Array",
"metadata": {
"description": "The list of locations that can be specified when deploying resources.",
"strongType": "location",
"displayName": "Allowed locations"
}
}
},
"policyRule": {
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/policyDefinition.json#",
"if": {
"not": {
"field": "location",
"in": "[parameters('allowedLocations')]"
}
},
"then": {
"effect": "deny"
}
}
},
{
"name": "storage-sse-encryption-blob",
"displayName": "Force blob storage at-rest encryption",
"description": "This policy automatically enables blob storage service encryption (SSE) for created storage accounts.",
"category": "Compliance",
"parameters": {},
"policyRule": {
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/policyDefinition.json#",
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
},
{
"not": {
"field": "Microsoft.Storage/storageAccounts/enableBlobEncryption",
"equals": "true"
}
}
]
},
"then": {
"effect": "append",
"details": [
{
"field": "Microsoft.Storage/storageAccounts/enableBlobEncryption",
"value": "true"
}
]
}
}
},
{
"name": "storage-sse-encryption-file",
"displayName": "Force file storage at-rest encryption",
"description": "This policy automatically enables file storage service encryption (SSE) for created storage accounts.",
"category": "Compliance",
"parameters": {},
"policyRule": {
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/policyDefinition.json#",
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
},
{
"not": {
"field": "Microsoft.Storage/storageAccounts/enableFileEncryption",
"equals": "true"
}
}
]
},
"then": {
"effect": "append",
"details": [
{
"field": "Microsoft.Storage/storageAccounts/enableFileEncryption",
"value": "true"
}
]
}
}
},
{
"name": "storage-secure-transfer",
"displayName": "Force storage secure transfer",
"description": "This policy automatically enables Secure Transfer Required for created storage accounts.",
"category": "Compliance",
"parameters": {},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
},
{
"not": {
"field": "Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly",
"equals": "true"
}
}
]
},
"then": {
"effect": "append",
"details": [
{
"field": "Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly",
"value": "true"
}
]
}
}
},
{
"name": "acr-adminUser",
"displayName": "Force disabling of ACR admin account",
"description": "This policy automatically disables the admin account for Azure Container Registry.",
"category": "Compliance",
"parameters": {},
"policyRule": {
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/policyDefinition.json#",
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.ContainerRegistry/registries"
},
{
"not": {
"field": "Microsoft.ContainerRegistry/registries/adminUserEnabled",
"equals": "false"
}
}
]
},
"then": {
"effect": "append",
"details": [
{
"field": "Microsoft.ContainerRegistry/registries/adminUserEnabled",
"value": "false"
}
]
}
}
},
{
"name": "vm-managedDisk",
"displayName": "Require managed disks",
"description": "This policy requires VMs to use managed disks.",
"category": "Compliance",
"parameters": {},
"policyRule": {
"if": {
"anyOf": [
{
"allOf": [
{
"field": "type",
"equals": "Microsoft.Compute/virtualMachines"
},
{
"field": "Microsoft.Compute/virtualMachines/osDisk.uri",
"exists": true
}
]
},
{
"allOf": [
{
"field": "type",
"equals": "Microsoft.Compute/VirtualMachineScaleSets"
},
{
"anyOf": [
{
"field": "Microsoft.Compute/VirtualMachineScaleSets/osDisk.vhdContainers",
"exists": true
},
{
"field": "Microsoft.Compute/VirtualMachineScaleSets/osdisk.imageUrl",
"exists": true
}
]
}
]
}
]
},
"then": {
"effect": "deny"
}
}
}
]
},
"initiatives": {
"value": [
{
"name": "compliance",
"displayName": "Resource compliance",
"description": "This is a initiative to compliance requirements.",
"category": "Compliance",
"parameters": {},
"policyDefinitions": [
{
"policyDefinitionId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/allowedLocations",
"parameters": {
"allowedLocations": {
"value": [
"eastus2",
"westus2",
"eastus",
"westus"
]
}
}
},
{
"policyDefinitionId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/storage-sse-encryption-blob",
"parameters": {}
},
{
"policyDefinitionId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/storage-sse-encryption-file",
"parameters": {}
},
{
"policyDefinitionId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/storage-secure-transfer",
"parameters": {}
},
{
"policyDefinitionId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/acr-adminUser",
"parameters": {}
},
{
"policyDefinitionId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/vm-managedDisk",
"parameters": {}
}
]
}
]
}
}
}
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"policies": {
"value": [
{
"name": "inheritTag",
"displayName": "Inherit tag from Resource Group",
"description": "Resources inherits tags from their parent resource group when not set.",
"category": "Metadata",
"policyRule": {
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/policyDefinition.json#",
"if": {
"allOf": [
{
"field": "[concat('tags[', parameters('tagName'), ']')]",
"exists": "false"
},
{
"not": {
"field": "type",
"equals": "Microsoft.Resources/subscriptions/resourceGroups"
}
}
]
},
"then": {
"effect": "append",
"details": [
{
"field": "[concat('tags[', parameters('tagName'), ']')]",
"value": "[resourceGroup().tags[parameters('tagName')]]"
}
]
}
},
"parameters": {
"tagName": {
"type": "String",
"metadata": {
"description": "The name of the tag to inherit.",
"displayName": "Tag name"
}
}
}
},
{
"name": "rgRequireTag",
"displayName": "Resource Group requires tag",
"description": "Resource group requires tag to be set.",
"category": "Metadata",
"parameters": {
"tagName": {
"type": "String",
"metadata": {
"displayName": "Tag name",
"description": "The name of the tag to require"
}
}
},
"policyRule": {
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/policyDefinition.json#",
"if": {
"allOf": [
{
"field": "[concat('tags[', parameters('tagName'), ']')]",
"exists": "false"
},
{
"field": "type",
"equals": "Microsoft.Resources/subscriptions/resourceGroups"
}
]
},
"then": {
"effect": "deny"
}
}
},
{
"name": "rgApplyTag",
"displayName": "Apply tag to Resource Group",
"description": "This policy automatically applies a tag based on Resource Group name prefix.",
"category": "Metadata",
"parameters": {
"tagName": {
"type": "String",
"metadata": {
"description": "The name of the tag to require.",
"displayName": "Tag name"
}
},
"tagValue": {
"type": "String",
"metadata": {
"description": "The value to automatically apply.",
"displayName": "Tag value"
}
},
"namePrefix": {
"type": "String",
"metadata": {
"description": "The resource group name prefix.",
"displayName": "Name prefix"
}
}
},
"policyRule": {
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/policyDefinition.json#",
"if": {
"allOf": [
{
"field": "[concat('tags[', parameters('tagName'), ']')]",
"exists": "false"
},
{
"field": "name",
"like": "[concat(parameters('namePrefix'), '*')]"
},
{
"field": "type",
"equals": "Microsoft.Resources/subscriptions/resourceGroups"
}
]
},
"then": {
"effect": "append",
"details": [
{
"field": "[concat('tags[', parameters('tagName'), ']')]",
"value": "[parameters('tagValue')]"
}
]
}
}
}
]
},
"initiatives": {
"value": [
{
"name": "standards",
"displayName": "Metadata standards",
"description": "This is a initiative to enforce naming and tagging standards for resources.",
"category": "Metadata",
"parameters": {},
"policyDefinitions": [
{
"policyDefinitionId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/rgRequireTag",
"parameters": {
"tagName": {
"value": "environment"
}
}
},
{
"policyDefinitionId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/rgRequireTag",
"parameters": {
"tagName": {
"value": "service"
}
}
},
{
"policyDefinitionId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/rgApplyTag",
"parameters": {
"tagName": {
"value": "cleanup-group"
},
"tagValue": {
"value": "demo"
},
"namePrefix": {
"value": "demo-"
}
}
},
{
"policyDefinitionId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/inheritTag",
"parameters": {
"tagName": {
"value": "environment"
}
}
},
{
"policyDefinitionId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyDefinitions/inheritTag",
"parameters": {
"tagName": {
"value": "service"
}
}
}
]
}
]
},
"assignments": {
"value": [
{
"name": "standards",
"displayName": "Metadata standards",
"description": "Enforces naming and tagging standards for resources.",
"initiatives": "standards"
}
]
}
}
}
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json",
"contentVersion": "1.0.0.0",
"parameters": {
"policies": {
"type": "array",
"defaultValue": [],
"metadata": {
"description": "The definitions for one or more policies to deploy."
}
},
"initiatives": {
"type": "array",
"defaultValue": [],
"metadata": {
"description": "The definitions for one or more initiatives to deploy."
}
},
"assignments": {
"type": "array",
"defaultValue": [],
"metadata": {
"description": "The assignments for one or more initiatives."
}
}
},
"variables": {
"initiativeWithSubscription": "[json(replace(string(parameters('initiatives')), '00000000-0000-0000-0000-000000000000', subscription().subscriptionId))]"
},
"resources": [
{
"condition": "[not(empty(parameters('policies')))]",
"name": "[parameters('policies')[copyIndex('policyIndex')].name]",
"type": "Microsoft.Authorization/policyDefinitions",
"copy": {
"count": "[length(parameters('policies'))]",
"name": "policyIndex"
},
"apiVersion": "2019-01-01",
"properties": {
"policyType": "Custom",
"mode": "All",
"displayName": "[parameters('policies')[copyIndex('policyIndex')].displayName]",
"description": "[parameters('policies')[copyIndex('policyIndex')].description]",
"policyRule": "[parameters('policies')[copyIndex('policyIndex')].policyRule]",
"metadata": {
"category": "[parameters('policies')[copyIndex('policyIndex')].category]"
},
"parameters": "[parameters('policies')[copyIndex('policyIndex')].parameters]"
}
},
{
"condition": "[not(empty(parameters('initiatives')))]",
"name": "[parameters('initiatives')[copyIndex('initiativeIndex')].name]",
"type": "Microsoft.Authorization/policySetDefinitions",
"copy": {
"count": "[length(parameters('initiatives'))]",
"name": "initiativeIndex"
},
"dependsOn": [
"policyIndex"
],
"apiVersion": "2019-01-01",
"properties": {
"policyType": "Custom",
"displayName": "[parameters('initiatives')[copyIndex('initiativeIndex')].displayName]",
"description": "[parameters('initiatives')[copyIndex('initiativeIndex')].description]",
"metadata": {
"category": "[parameters('initiatives')[copyIndex('initiativeIndex')].category]"
},
"parameters": "[parameters('initiatives')[copyIndex('initiativeIndex')].parameters]",
"policyDefinitions": "[variables('initiativeWithSubscription')[copyIndex('initiativeIndex')].policyDefinitions]"
}
},
{
"condition": "[not(equals(length(parameters('assignments')), 0))]",
"name": "[if(equals(length(parameters('assignments')), 0), 'empty', parameters('assignments')[copyIndex('assignmentIndex')].name)]",
"type": "Microsoft.Authorization/policyAssignments",
"copy": {
"mode": "Parallel",
"count": "[if(equals(length(parameters('assignments')), 0), 1, length(parameters('assignments')))]",
"name": "assignmentIndex"
},
"dependsOn": [
"initiativeIndex"
],
"apiVersion": "2019-01-01",
"properties": {
"displayName": "[parameters('assignments')[copyIndex('assignmentIndex')].displayName]",
"description": "[parameters('assignments')[copyIndex('assignmentIndex')].description]",
"policyDefinitionId": "[concat(subscription().id, '/providers/Microsoft.Authorization/policySetDefinitions/', parameters('assignments')[copyIndex('assignmentIndex')].initiatives)]",
"scope": "[subscription().id]",
"parameters": {},
"metadata": {}
}
}
]
}
@lazywinadmin
Copy link

Does the append approach work when you need to provide multiple tags ?
All the examples i find online looks like this, but does not seem to support multiple items

"then": {
                            "effect": "append",
                            "details": [
                                {
                                    "field": "[concat('tags[', parameters('tagName'), ']')]",
                                    "value": "[resourceGroup().tags[parameters('tagName')]]"
                                }
                            ]
                        }

@BernieWhite
Copy link
Author

@lazywinadmin the field is a one to one mapping, one tag one tag value. However the point of an initiative is to bundle multiple policies that might have different tags set together.

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