My coworkers and teammates often reach out to me with similar questions regarding the best practices for creating and applying Azure Policy. That tendency encouraged me to compile this starter guide for Azure Policy, which is based on my practical experience in multiple projects and covers the 20% baseline that allows you to implement 80% of typical use cases, aka the Pareto principle.
Learn the topic
RTFM stands for “read the fucking manual,” bro.
Seriously, I mean, read the Microsoft Azure Policy docs first. Microsoft is doing a great job with documenting their services and solutions recently, and without knowing the basic Azure Policy principles, it will be really hard for you to grasp the concepts. After investigating what Azure Policy is for, I suggest looking through the list of built-in policies to get an idea about typical use cases for different Azure service types.
The two most important points to pay attention to initially are understanding Azure Policy effects and Azure Policy deployment scopes. The effects will give you some insights into what you can actually do with the policies. At the same time, the deployment scope will save you time for troubleshooting why you cannot assign a policy deployed at the subscription level to another subscription.
The evaluation of logical conditions in policy rules, I would say less critical. It might cause you some headache initially, but as soon as you understand how the double negation works, you shall be fine.
Although Azure policies can modify the configuration of existing Azure resources and even deploy new resources, I suggest starting with auditing resource configuration (Audit and AuditIfNotExists effects) and putting some guardrails (Deny effect) in your environment as the latter ones are easier to learn and understand.
Apart from the official documentation, I definitely recommend watching a few learning courses about Azure Governance on Pluralsight:
- Mastering Microsoft Azure Governance by James Bannan
- Microsoft Azure DevOps Engineer: Implementing Infrastructure Control and Compliance by John Savill
They are just a few hours long and can provide you with a really good starting point to advance your Azure Policy learning.
Make an assessment
“Think first before you act.” An unknown guru.
Before making any changes in your environment, i.e., assigning a new Azure Policy to your subscription, it is worth knowing first what policies are already in effect and their compliance results. Besides, assigned policies are evaluated in a specific order you should be aware of. Otherwise, it is easy to mess up your Azure environment: policies usually control something on a global scale (a whole subscription or management group), therefore impacting lots of resources.
In 80 percent of use cases, using the Azure portal to assess what existing policy and initiative assignments are and their compliance state will be the right choice – when there are only a few policies applied, no need to overcomplicate things.
In more advanced scenarios, when an organization already deployed dozens of custom Azure Policy definitions and extensively uses them at the management group level and on the individual subscriptions, manual assessment is somewhat complicated. Here I can suggest using AzGovViz– a community build solution (a PowerShell script) that can help you quickly create a comprehensive report in different formats containing all the details about Azure Policy configuration in your environment and more. You can event integrate AzGovViz with Azure DevOps pipelines to document the policy configuration as part of your deployments.
Create your policy
“Let’s roll up your sleeves and get to work!” A motivational speech.
Even though Microsoft already provided us with lots of useful built-in ready-to-use policies, I encourage you to not hurry on assigning them left and right. You will never understand how Azure Policy works to the full extent until you learn how to create and manage your custom policies.
A typical antipattern to avoid is dozens of individually assigned policies when they should be applied as a group via a policy initiative.
Firstly, you can look into the source code of built-in Azure policies (check the last column with the links to GitHub) and use it as a draft for your custom policy or initiative definitions. Alternatively, you can go straight to the Azure Policy Samples repository on GitHub, clone it, and explore with your coding tools.
Probably, the best coding experience with Azure Policy as of now is to use Visual Studio Code with Azure Policy extension for it. Additionally, I suggest installing the ARM Tools extension. It will significantly help you with syntax validation, snippets, and auto-completion if you decide to define your policies in ARM templates to make your deployment experience more consistent.
Recently, Microsoft has updated its docs with some ARM snippets for policy definitions, policy set definitions (aka policy initiatives), and their assignments. Still, those articles miss many nuances and details, and I suggest checking out my work on Azure Policies and my repository for sample Azure Policies on GitHub.
For more advanced cases, check the recent updates to Azure Policy on AzPolicyAdvertizer. As documenting new policies usually takes some time, AzPolicyAdvertizer closes that gap by providing short information about policies and recent changes to them.
A common use case is to duplicate a built-in policy logic in your custom definition completely. The reason for that is the way how Azure Policy engine handles updates to the existing definitions. When you update a definition, all existing policy assignment of it will automatically be using the new definition. Although there are some controls for backward compatibility, and Microsoft usually doesn’t introduce breaking changes in the existing definitions, many teams prefer to have full control over their configuration.
“Damn it! I said, test it first!” A senior developer, fixing a bug in production.
I honestly must warn you that testing Azure Policy is not an easy task. Nevertheless, I strongly encourage you to test your policy work before putting it into use. Considering the usual scope the policies are applied and the effects they can make (change configuration, deploy new resources), the results of careless policy assignments can be quite devastating to your environment.
First of all, you need to ensure that the syntax of your policy or initiative is correct. Whether you define your definitions in JSON policy format or ARM templates, the Visual Studio Code extensions mentioned above should help you find and fix basic syntax errors. If you stick with the ARM template option, you can use Test-Az*Deployment Azure PowerShell cmdlets to validate your templates’ syntax against Azure Resource Manager APIs. Unfortunately, the policy-related cmdlets in the Az.Resources module don’t support any testing options yet.
As a matter of caution, set the policy ‘enforcementMode’ parameter into the disabled state when creating assignments for your tested policies so you can safely audit their work results.
Secondly, be aware that Azure Policy assignments don’t come into effect immediately. There is a policy evaluation delay, which is around 30 minutes or so. Also, auditing your resources might take some time as the Azure Policy engine needs to evaluate all resources against policy rules within the assigned scope. In other words, you cannot test the results of your policy work immediately. Apart from that, the delay effectively complicates automated tests for Azure Policy.
Although there is an option to initiate an on-demand evaluation scan, it still won’t make the whole process much faster if a policy needs to process thousands of resources.
Due to all the complications, I would say that the testing process for your policies will be manual or semi-manual in most cases. You will validate the syntax, deploy the definitions into a test environment, i.e., a dedicated subscription, assign them to a test scope, deploy some resources to test the expected policy behavior, and check results on the portal. In the end, the code for Azure Policy is not something that is often updated, and manual testing can be a reasonable tradeoff to creating automated test cases.
However, in advanced scenarios, when you need to create and maintain more than a handful of simple policies, creating automated Azure Policy tests as part of your CI/CD pipeline is a must. I’m planning to cover this topic in detail in a separate post as it requires quite a lot of explanation not explicitly tied to Azure Policy.
“Do. Or do not. There is no try.” Master Yoda to young Skywalker.
As I already mentioned, before actually deploying your custom policy or initiative definitions, you should clearly understand what the deployment scopes are. Besides, you should also understand how Azure Policy inclusions, exclusions, and exemptions work. Apart from that, you should have a clear distinction between a policy/initiative definition and its assignment: you should deploy the definition and assign it to your scope to make your Azure policy work.
Technically, you can deploy policies and create assignments using any supported method: the portal, Azure CLI, Azure PowerShell, Azure REST API, etc. It’s really up to you to choose which one o them fits your configuration management and deployment practices.
When I started working with Azure Policy myself, I was a bit frustrated with the default programming experience of maintaining two separate files for each definition and came up with a solution on how to deploy Azure Policy with ARM templates. However, things have changed since then, and now the policies are defined in a single file. A slight improvement, but the Azure PowerShell cmdlets still require lots of additional parameters that should be duplicated on their usage.
Optionally, you can try using the AzOps deployment framework, which could be a good choice for large environments when you run your Azure Governance as a separate project.
Just be consistent in the way you do your deployments and preferably manage Azure Policy as a part of your CI/CD pipelines.
Check the results
“A man reaps what he sows” A proverb.
Finally, your first policy is deployed, the assignment is created, and it’s time to see what we have got.
Using the Azure portal to get Azure Policy compliance results would be the most obvious and probably the most reasonable choice at the beginning – it won’t heart to keep things simple.
For advanced scenarios, when you are already proficient with managing Azure Policy from deployment pipelines, you might want to check how you can get Policy insights with code to evaluate them in your test cases. Also, take a look at the Az.PolicyInsights PowerShell module, and what kind of data you can extract with it.
Just reading this guide won’t make you an expert in Azure Policy. For that, you need to have some practice too. So, give it a try – look into your Azure infrastructure, find some areas you can improve with Azure Policy (trust me, there is always something that can be improved 😉), come up with a solution, test it, apply and reap the benefits!
If you have any questions about this topic, put them in the comments below 👇.