From e963d04cd2a0c5fe296caca7475a9ba2f52ba4ce Mon Sep 17 00:00:00 2001 From: Henderson Andrade Date: Wed, 10 Jun 2026 10:24:09 -0300 Subject: [PATCH] Improve deny-resource-without-tag: add description, empty-value check, excludedResourceTypes param --- .../azurepolicy.json | 33 +++++++++++++++---- .../azurepolicy.parameters.json | 11 ++++++- .../azurepolicy.rules.json | 18 ++++++++-- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/policyDefinitions/Tags/deny-resource-without-tag/azurepolicy.json b/policyDefinitions/Tags/deny-resource-without-tag/azurepolicy.json index 4c7a54a4..b2947417 100644 --- a/policyDefinitions/Tags/deny-resource-without-tag/azurepolicy.json +++ b/policyDefinitions/Tags/deny-resource-without-tag/azurepolicy.json @@ -3,9 +3,9 @@ "type": "Microsoft.Authorization/policyDefinitions", "properties": { "displayName": "Deny-resource-without-tag", - "description": "need to add description", + "description": "Requires that a specified tag exists and is not empty on resources. Resource types that do not support tags can be excluded via the excludedResourceTypes parameter. Does not apply to resource groups (mode Indexed).", "metadata": { - "version": "1.0.0", + "version": "1.1.0", "category": "Tags" }, "mode": "Indexed", @@ -14,9 +14,18 @@ "type": "String", "metadata": { "displayName": "Tag name", - "description": "Name of the tag to enforce" + "description": "Name of the tag to enforce, such as 'Environment' or 'CostCenter'." } }, + "excludedResourceTypes": { + "type": "Array", + "metadata": { + "displayName": "Excluded Resource Types", + "description": "Resource types to exclude from this policy. Useful for resource types that do not support tags.", + "strongType": "ResourceType" + }, + "defaultValue": [] + }, "effect": { "type": "String", "metadata": { @@ -33,10 +42,22 @@ }, "policyRule": { "if": { - "allof": [ + "allOf": [ + { + "field": "type", + "notIn": "[parameters('excludedResourceTypes')]" + }, { - "field": "[concat('tags[', parameters('tagName'), ']')]", - "exists": "false" + "anyOf": [ + { + "field": "[concat('tags[', parameters('tagName'), ']')]", + "exists": "false" + }, + { + "field": "[concat('tags[', parameters('tagName'), ']')]", + "equals": "" + } + ] } ] }, diff --git a/policyDefinitions/Tags/deny-resource-without-tag/azurepolicy.parameters.json b/policyDefinitions/Tags/deny-resource-without-tag/azurepolicy.parameters.json index 07e9b47f..f32e3056 100644 --- a/policyDefinitions/Tags/deny-resource-without-tag/azurepolicy.parameters.json +++ b/policyDefinitions/Tags/deny-resource-without-tag/azurepolicy.parameters.json @@ -3,9 +3,18 @@ "type": "String", "metadata": { "displayName": "Tag name", - "description": "Name of the tag to enforce" + "description": "Name of the tag to enforce, such as 'Environment' or 'CostCenter'." } }, + "excludedResourceTypes": { + "type": "Array", + "metadata": { + "displayName": "Excluded Resource Types", + "description": "Resource types to exclude from this policy. Useful for resource types that do not support tags.", + "strongType": "ResourceType" + }, + "defaultValue": [] + }, "effect": { "type": "String", "metadata": { diff --git a/policyDefinitions/Tags/deny-resource-without-tag/azurepolicy.rules.json b/policyDefinitions/Tags/deny-resource-without-tag/azurepolicy.rules.json index 2cd08ba9..ee25de53 100644 --- a/policyDefinitions/Tags/deny-resource-without-tag/azurepolicy.rules.json +++ b/policyDefinitions/Tags/deny-resource-without-tag/azurepolicy.rules.json @@ -1,9 +1,21 @@ { "if": { - "allof": [ + "allOf": [ { - "field": "[concat('tags[', parameters('tagName'), ']')]", - "exists": "false" + "field": "type", + "notIn": "[parameters('excludedResourceTypes')]" + }, + { + "anyOf": [ + { + "field": "[concat('tags[', parameters('tagName'), ']')]", + "exists": "false" + }, + { + "field": "[concat('tags[', parameters('tagName'), ']')]", + "equals": "" + } + ] } ] },