Azure Policies are used to enforce rules on different Azure resources. This will ensure those resources are compliant with any corporate standards or with regulatory requirements. Examples of policies include limiting the regions resources can be deployed to or limiting virtual machines to specific SKU sizes. These policies are then evaluated and resources are marked compliant or non-compliant based on the rules in the policy. In this article, I’m going to cover how to create a policy to evaluate if resources have a specific tag and value associated with them. The creation, deployment, and evaluation will all be completed using Azure PowerShell commands.

For this demo, I have two virtual networks deployed (vnet1 and vnet2) to a resource group (policy-demo-rg). Vnet1 has a tag of Audit with a value of “True”, and vnet2 has a tag of Audit with a value of “False”. I’m going to create a policy to ensure all my resources in this group have an Audit value of “True”.

First, I need to find a built-in policy that I want to use. Running Get-AzPolicyDefinition is going to fill the screen with a lot of information, and I found it difficult to find which policy to use. Information about each policy is saved as an object in the Properties field. Instead, re-run the command and use the where filter to find policies with “tag” in the display name and save this to a variable:

$policies = Get-AzPolicyDefinition | where {$_.Properties.DisplayName -like "*tag*"}

Viewing the $policies.properties.displayName property will give me the names of matching policies to see if any look like what I’m trying to accomplish:

Lucky enough, the first one named Require tag and its value is exactly what I’m looking for. I’m going to re-run the Get-AzPolicyDefinition command, filter based on this name, and save it to $tagPolicy.

$tagPolicy = Get-AzPolicyDefinition | where {$_.Properties.DisplayName -eq "Require tag and its value"}

I can view additional policy properties using the $tagPolicy variable, such as any parameters it needs during the policy assignment:

Another option for finding a policy is to search the metadata tag on the policy, such as finding any policies categorized with “tags”:

Get-AzPolicyDefinition | where {$_.properties.metadata.category -contains "tags"}

With the policy identified, now I need to create the policy assignment. I need to provide a name for the policy assignment, the scope (in this case, the resource group ID), and the policy definition (my $tagPolicy variable). Lastly, I need to pass the tag name and value to the policy assignment using the -PolicyParameterObject parameter. This tag name and value is what will be checked for compliance. In the example below, I’m creating the object in the command but it could probably also be saved to a variable beforehand.

New-AzPolicyAssignment -Name "Require Audit Tag" -Scope "/subscriptions/<subscriptionGuid>/resourceGroups/policy-demo-rg" -PolicyDefinition $tagPolicy -PolicyParameterObject @{tagName="Audit""True"}

In order to view the results, use the Get-AzPolicyState cmdlet along with specify the PolicyAssignmentName and the ResourceGroupName:

Get-AzPolicyState -PolicyAssignmentName "Require Audit Tag" -ResourceGroupName "policy-demo-rg"

However, Azure Policy takes some time to determine compliance on the resources. I checked the policy state immediately after creating it, but it did not return any results as it has nothing to report until the policy has completed its compliance check:

After about 15 minutes, I re-ran the command and got back results showing the resources’ compliance state. This is just a screenshot of partial results:

If you have a lot of resources and want to filter for just the non-compliant ones, use the -Filter parameter along with “IsCompliant eq false”:

Get-AzPolicyState -PolicyAssignmentName "Require Audit Tag" -ResourceGroupName "policy-demo-rg" -Filter "IsCompliant eq false"

Hint: For some reason the Filter wants “false” to be lowercase; it returned this result when it was capitalized:

*InvalidFilterInQueryString: Could not find a property named 'False' on type
'Microsoft.WindowsAzure.Governance.Policy.Provider.PolicyState'*

If the policy definition is no longer needed, use the Remove-AzPolicyAssignment and specify the name and scope:

Remove-AzPolicyAssignment -Name "Require Audit Tag" -Scope "/subscriptions/<subscriptionGuid>/resourceGroups/policy-demo-rg"

Questions or comments? If so, drop me a note below or find me on Twitter or LinkedIn to discuss further.