As your Azure usage increases, you will inevitably need to grant rights to other users to create and manage resources. Often, you need to apply limits to what these users can do with their Azure subscription. Role Based Access Control allows you to put users into roles that grant them access to specific top-level resources (virtual machines, storage, SQL etc.). What RBAC doesn’t do, however, is limit what you can do with those resources. Take VMs: You can grant a user RBAC rights so they can only create VMs and not other resources, but you can’t define an RBAC role that stops them creating 20 G5 VMs and racking up the Azure bill. That is where Resource Policies come in.
Resource policies are JSON-based rules that define what can and can’t be created inside either a subscription or a resource group. Resource policies can be applied to most resource types, but there are some that do not yet support it. Generally, if a resource supports tags and locations, then it will support resource policies. Policies support reuse, in that a single policy can be applied to many subscriptions or resource groups and can be parameterized to make them even more flexible.
In this pair of articles, we will take a look at resource policies and how you can make use of them. We'll start with some built-in policies and then look at customized ones in Part 2.
Before we look at setting up policies, it's good to understand the rules around them. The default stance with policy rights is the opposite of RBAC. In RBAC rights, by default, you are denied everything and then explicitly allowed certain roles. In Resource Policies, you are by default allowed to do anything in a subscription or RG, and you need to explicitly deny things in a policy.
To be able to apply policies to resource groups or subscriptions, you need the “Microsoft.Authorization/policyassignments/write” permission on the required subscription or RG. To be able to create custom policies, you also need the “Microsoft.Authorization/policydefinitions/write” permission.
Note that these rights, by default, are only provided in the RBAC “owner” role. If you want to grant these to someone who is not an owner of a subscription, then you will need to create a custom role and apply them.
Azure provides some ready-made policies out of the box. All you need to do is configure these and apply them to your required scope. If your requirement for restrictions is included in these policies, then they are very easy to set up. These built-in policies are:
- Allowed locations
- Allowed resource types
- Allowed storage account SKUs
- Allowed virtual machine SKUs
- Apply tag and default value
- Enforce tag and value
- Not allowed resource types
- Require SQL Server version 12.0
- Require storage account encryption
You will note that for some of these, there are both “Allowed” and “Not Allowed ” rules. This is helpful if you are looking to whitelist or blacklist — you have the choice to do either. This is especially useful for resources policies, where there are a lot of different resources to choose from.
We’ll take the example of restricting VM sizes. We’ll look at doing this in the Azure portal, but this can also be done through PowerShell.
In the portal, we can browse to the subscription (or resource group) we want to apply the restriction to and select the “Policies” blade.
Click add, then in the blade that opens, we can see the available policies in the dropdown.
We’ll go ahead and select the “Allowed virtual machine SKUs” option, then in the “Allowed SKUs” section, we will select which VM sizes we want to allow.
We will then enter a friendly display name for the policy as well as an ID. The ID needs to be unique within the scope (subscription or RG) and meet the naming standard in the help hover-over.
Once we click OK, that policy is now assigned to my subscription. If I attempt to create a VM now that does match those sizes, it will let me run through the create-a-VM wizard (it would be nice if it stopped you earlier), but once you submit the VM for deployment, it will shortly fail. The one downside to this failing-at-deployment approach is that if you are deploying other resources prior to the VM being deployed (Availability Sets, storage, Network Cards etc.) then these will still be created and will still need to be cleaned up
Should you wish to edit the policy, say to change the VMs that are allowed, then you can go back to the subscription, into policies, and you will see the list of your applied policies.
Select the policy you want to change, then select edit.
All of the other built-in policies function in a similar manner, with differing parameter options. The simple ones, like requiring storage account encryption, don’t really have any parameters to select:
Whereas allowing or restricting resource types has a long list of choices:
The built-in resource policies provide easy-to-use options for some very common scenarios, and for some, that will do exactly what they want. But if you need more advanced restrictions, this is where custom policies come into play. With custom policies, we can define our own rules using JSON and publish them to then be assigned to our subscriptions. We’ll take a look at how to do this in Part 2.