- Manage Azure PowerShell global settings - Fri, Sep 22 2023
- Create and manage append blobs with PowerShell - Wed, Oct 12 2022
- Permanently delete a Key Vault in Azure using PowerShell - Fri, Feb 4 2022
With many built-in policies, you can easily start implementing governance and manage compliance throughout your organization. For advanced scenarios, you can also create your own custom policy definitions and flexibly assign them to the desired scopes based on your needs.
Here are some useful scenarios that can be implemented with Azure Policy:
- Enforcing resource naming conventions based on specified patterns for new resources
- Allowing only specific regions for certain resource types
- Denying the creation of public IP addresses across the organization
- Denying public access to resources such as storage accounts
- Enabling features, such as Azure Monitor on Azure resources
- Forcing supported resources to use private links.
First, let's zoom in on Azure Policy objects to understand how they work before diving into PowerShell commands to manage Azure Policies.
Azure Policy objects
Policy definition
Each Azure policy has a definition in JSON format comprising rules, parameters, conditions, and effects. With these elements defined in the policy definition, you can flexibly control resources based on the target scenario.
Policy initiative
A policy initiative is a set of policy definitions. They act like a single object when you assign them to a resource. You can combine multiple policy definitions to better address your organization's needs.
Policy rule
A policy rule is a section in a policy definition where you specify the policy's conditions using "If" and "Then" blocks.
Policy effects
Each policy definition must have an "effect" as part of its policy rule, which allows the policy to determine what action will be taken when there is a match between the policy rule and the target resource object. The supported effects that can be used in policy definitions are as follows:
- Append
- Audit
- AuditIfNotExists
- Deny
- DeployIfNotExists
- Disabled
- Modify
For example, if you specify Audit as the effect in the policy definition, then Azure Policy will only audit the resources. Therefore, it will never block any resource creation or try to remediate noncompliant resources. If the effect is set to DeployIfNotExists, the Azure Policy will check the target and take the necessary actions to deploy missing resources based on the defined action plan in the policy definition.
Policy assignment
Policy assignments are used to declare where the policy definitions are applied. You can create a policy assignment by linking an existing policy definition and specifying the target scope. In this way, the same policy definition object can be reused with another policy assignment.
Policy scope
This determines which resources to apply the policy to, based on the specified Azure Resource Manager resource path. A scope can be a single resource, a resource group, a subscription, or a management group. Exclusions and exemptions can also be configured to control the target scope in a more granular way.
Policy compliance
When policies are applied to specific scopes, the resources in the target scopes are evaluated at specific times. This evaluation occurs whenever a resource or policy object is created, updated, or deleted. There is also a regular compliance check that evaluates the resources every 24 hours, even if nothing has changed.
Policy remediation
Azure Policy also supports remediation when a resource is evaluated as noncompliant by an Azure policy. With remediation tasks, Azure policies can create deployments or modify existing resources to make them compliant.
Now we will perform common Azure Policy tasks using PowerShell.
Assign a built-in policy to a resource group
First, let's list all available built-in policy definitions on Azure with the following command:
Get-AzPolicyDefinition -Builtin | select -ExpandProperty Properties | select Displayname
As listed above, hundreds of built-in policy definitions are available to use.
Now, we'll assign one of the built-in policy definitions, named "[Preview]: Storage account public access should be disallowed" and assign it to a resource group called AzurePolicyTest. With this assignment, we will be blocking public access on storage accounts within that resource group.
$PolicyDefinition = Get-AzPolicyDefinition -Builtin | where{$_.properties.displayname -eq "[Preview]: Storage account public access should be disallowed"} New-AzPolicyAssignment -Name DenyStorageAccountPublicAccess -Scope "/subscriptions/81391d2a-c61e-47f3-94db-eb5d319d509c/resourceGroups/AzurePolicyTest" -DisplayName DenyStorageAccountPublicAccess -PolicyDefinition $PolicyDefinition -EnforcementMode Default -PolicyParameterObject @{"effect"="deny"}
So when we try to create a storage account with public access enabled, we get the following error message, saying that the resource was disallowed by the Policy DenyStorageAccountPublicAccess we just created.
Create a custom policy and assign it to a subscription
Now, we will create our own custom policy definition and assign it to an entire subscription.
Here is an example of a JSON definition that enforces a naming convention for resource groups:
$CustomDefiniton = ' { "mode": "All", "policyRule": { "if": { "allOf": [ { "field": "type", "equals": "Microsoft.Resources/subscriptions/resourceGroups" }, { "field": "location", "equals": "westeurope" }, { "field": "name", "notLike": "rg-*" } ] }, "then": { "effect": "deny" } }, "parameters": {} } ' $PolicyDefinition = New-AzPolicyDefinition -Name CustomPolicyDefinition -DisplayName CustomPolicyDefinition -Policy $CustomDefiniton $NonComplianceMessages = @(@{Message="RG name is not allowed in the Western Europe region. Please make sure the RG name starts with 'rg-'"}) New-AzPolicyAssignment -Name DenyNonCompliantResourceGroupNames -Scope "/subscriptions/81391d2a-c61e-47f3-94db-eb5d319d509c" -DisplayName DenyNonCompliantResourceGroupNames -PolicyDefinition $PolicyDefinition -NonComplianceMessage $NonComplianceMessages
When we try to create a resource group in the Western Europe region with a name that is not allowed by the policy, the policy fails with the message that we defined earlier.
If we need to exclude scopes, such as resource groups, subscriptions, or individual resources, we can simply define those scopes using the -NotScope parameter with the New-AzPolicyAssignment cmdlet.
So, if we want to assign a policy definition to an entire subscription except for a specific resource group, then we should use the following command:
New-AzPolicyAssignment -Name PolicyAssignmentName -Scope "/subscriptions/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -DisplayName PolicyAssignmentName -PolicyDefinition $PolicyDefinition -NonComplianceMessage $NonComplianceMessages -NotScope "/subscriptions/ xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/RGtoExclude"
Report policy compliance status
The policy compliance status for a specific policy assignment can be checked easily using the following command:
Get-AzPolicyState -Filter "ComplianceState eq 'NonCompliant'" -PolicyAssignmentName DenyNonCompliantResourceGroupNames | select ResourceGroup, ResourceLocation
The same data can also be found in the Azure Portal.
Use the following command to generate a summary:
Get-AzPolicyStateSummary
Normally, policy compliance status can be updated manually without having to wait 24 hours for the next compliance evaluation cycle. To run a manual compliance scan, use the command below:
Subscribe to 4sysops newsletter!
Start-AzPolicyComplianceScan
Conclusion
Azure policies have many useful capabilities for dynamically controlling Azure resources while implementing governance across the organization. The availability of numerous tools and platforms to control automatic deployments for new and existing resources enables DevOps teams to manage their environments reliably. With Blueprint support, it is even easier for large enterprises to implement predefined templates, such as ISO 270001, CAF Foundation, and HIPAA, to support regulatory requirements.
Hi. Thanks for the article. Regarding Tagging, Azure Policy seems to focus on only Adding/appending/inheriting tags. What I want to know, is how can one create a policy that will apply an action only if a specific Tag is found on a resource in the subscription?