Azure is a great platform. Users have access to a very broad range of hardware and services that can enable IT to transform how the business operates. However, sometimes there’s just too much choice, and administrators need to restrict the ability of contributors to deploy or use certain features. The obvious restriction is limiting VM size – not many organizations have a use for the very large instances, such as the G-Series or N-Series VMs. Those SKUs are very costly, and even a short run time of a few days can make or break a small IT budget. Another popular restriction is limiting the geographic regions available. This is important for some organizations with data residency concerns, but it may also be something to investigate for those with large teams or developers who manage their own infrastructure – deploying into Australia from the UK adds a lot of latency! Administrators could also prevent deployments of services they’re pretty certain that their org won’t need, but that does hamper the org’s ability to make good use of Azure.
In Azure, you can implement these controls by implementing Resource Policies. Like most things in Azure, you’ll find the most control through PowerShell and JSON. In this case, there is no UI to control the Resource Policy. Resource Policies consist of two parts: the Resource Policy Definition and the Resource Policy Assignments. Policies can be created with some generalization (i.e. you can use parameters, just like a ARM Template), and then applied with more specific configuration to the subscription or resource group you want to control.
Below is a very basic Resource Policy that denies creation or resizing of VMs outside of the specified SKUs – Standard_D2_v2 and Standard_A2:
{ "if": { "allOf": [ { "field": "type", "equals": "Microsoft.Compute/virtualMachines" }, { "not": { "allof": [ { "field": "Microsoft.Compute/virtualMachines/sku.name", "in": ["Standard_D2_v2","Standard_A2"] } ] } } ] }, "then": { "effect": "deny" } }
The template contains an if-then statement. In more human-readable format, it reads something like “If the SKU.Name field of any Virtual Machine is not Standard_D2_v2 or Standard_A2, deny the action”.
If an administrator was to apply this to the subscription, then attempt to create a VM that is disallowed, the error is somewhat cryptic:
The resource action 'Microsoft.Compute/virtualMachines/write' is disallowed by one or more policies. Policy identifier(s): '[{\"policyDefintionId\":\"/subscriptions/00000000-1111-2222-3333-bbbbbbbbbbbb/providers/Microsoft.Authorization/policyDefinitions/skuPolicyDefinition/\"
If you implement Resource Policies, it’s pretty important to make sure that the people who may be impacted by the policies know what this error means, or it could really impact productivity. As with most events in Azure, actions are logged. If a user encounters a Resource Policy, it will be visible in the Azure Audit Log as an operation: “Microsoft.Authorization/policies/deny/action”. After implementing policies, I recommend monitoring these events, and proactively contact users who are impacted for the same reason – it’s not an obvious error message.
If you’d like more information on Resource Policies, Microsoft’s official documentation on the subject is light, but should get you started. You can find it here: https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-policy. You can also drop me a line here if you’re having trouble with your policy and I can see if I can help.