A little while ago, we looked at Azure Resource Manager (ARM) and how important it is for managing “version 2” of Azure. If you don’t know what ARM is, read that article first.

Paul Schnackenburg

Paul Schnackenburg works part time as an IT teacher as well as running his own business in Australia. He has MCSE, MCT, MCTS and MCITP certifications. Follow his blog TellITasITis.

What’s been lacking in Azure up until now has been a comprehensive framework for IT to be able to add governance to the business’s cloud deployments, compounding the shadow IT problem. In early October, 2015, Azure added Azure Resource Manager Policies to control what can be deployed to Azure and by whom, and where it can be hosted.

Marrying ARM, policies, and RBAC ^

Policies use a default allow system, meaning that if you haven’t explicitly denied something it’ll be permitted. This is in contrast to Azure Roles-Based Access Control (RBAC), which uses default deny. A policy can be scoped to a whole subscription, a Resource Group (RG), or an individual resource in an RG, which is exactly the same as RBAC permission scopes.

To give an analogy, you can set NTFS permissions on the root of a drive. Doing so will apply to all folders on that drive (unless you exempt them). Alternatively, you can set the permissions on a folder, which will apply to all the files (objects) in that folder. Or you could assign permission to an individual file. And, just like in the NTFS example, in most cases you’ll probably set some overall policies for the entire subscription and then set some policies on RGs; however, you’ll rarely set policies on individual objects.

Policies are defined in Java Script Object Notation (JSON) just like ARM templates. First, you define one or more conditions, and you can use Not, And (expressed as allOf), or Or (anyOf) to combine these conditions. The conditions can be defined with Equals, Like, Contains, In, and ContainsKey. Fields to build your conditions with are Name, Kind, Type, Location, Tags, Tags.*. The effect field can be set to either Deny or Audit; the latter isn’t mentioned in the official documentation—only in an Azure Con 2015 September presentation.

Here’s an example of how you can limit deployments to Australia only:

ARM policies are initially aimed at the following governance scenarios: requiring that a cost center tag is attached to any new deployments, limiting deployments to specific regions, limiting what resources can be deployed, and enforcing a naming convention.

No GUI at this time ^

Like so many new features in Azure, this one comes with two ways to interact with it: using the API or using PowerShell. Since I’m allergic to REST APIs, I’ll show you how to create a policy using PowerShell. Start by downloading the latest version of Azure PowerShell. I used the latest 1.0 preview.

Log in to your subscription with Add-AzureAccount. If you have several subscriptions, use Set-AzureSubscription –SubscriptionID <GUID> to set the correct one. The cmdlets are
-AzureRmPolicyDefinition with the New, Get, Set, and Remove verbs and are applied with the ‑AzureRMPolicyAssignment cmdlet.

First, we create a policy definition with:

Creating an ARM policy definition

Creating an ARM policy definition

Unlike what the official documentation says, I then had to run the following to capture the new policy in a variable:

Then, we apply our new policy to a subscription (in my case, you could apply this to a particular RG or resource) with:

Applying a policy to a subscription

Applying a policy to a subscription

That’s all there is to it. This is a simple policy that gives the expected “forbidden” result when I try to create a VM in the East US region.

Attempting deployment of a VM in East US fails

Attempting deployment of a VM in East US fails

Conclusion ^

ARM policies are certainly the next logical step in Azure governance, and they cover the most logical restrictions most businesses will want to implement. But, as with most things in Azure, I really miss a GUI to create them. If I want to limit what types of resources people can create, it would be preferable to pick them from a list in a GUI instead of having to add them in text in PowerShell. Just like with ARM templates, I suspect that support for ARM policies will be added to Visual Studio, and that’s where you can build with a more visual approach.

Win the monthly 4sysops member prize for IT pros


Related Posts

  1. Aivendil 2 years ago


    I appreciate your articles about Microsoft Azure Cloud. I have a question I am struggling to find the answer for and hope that you can help or at least guide me.

    I am helping to build an Azure environment and the client wants to have several separate VNETs in one region. They have ExpressRoute connection to their onpremise network. What they want is to have:
    - two VNETs connected to the ExpressRoute directly
    - same two VNETS connected to each other (I know that they can communicate with each other as long as they are linked to the same ExpressRoute circuit, but how would the traffic flow? Will it be counted as ER traffic or shall it flow through Azure backbone as if I had a VNET-to-VNET connection?)
    - two other VNETs should only be connected to the first ones and not to the ER circuit itslef

    This raises a problem, because I cannot create a VNET-to-VNET connection on the same Virtual Network Gateway that I use for ExpressRoute.

    So the questions are:
    - Can I have more than one Virtual Network Gateway for one VNET? (PowerShell commands I use throw an error that I can't but I was not able to find this limitation anywhere)
    - Is the traffic between two VNETs connected to the same ExpressRoute circuit counted as VNET-to-VNET or as an ER traffic?
    - How this is usually done? I can't believe that I am the first person trying to have several VNETs only some of which are linked to ExpressRoute circuit, but all of which are connected between each other! Still I cannot find any guidelines on how to build this!

    Can you help me with any of these questions or at least suggest where to dig?


  2. Author
    Paul Schnackenburg 2 years ago

    Hi Aivendil,

    Thanks for your questions, sorry about the delay in answering (holidays and all that).

    I don't think I can answer all of these. My favourite place to find the details on this sort of stuff in Azure documentation. There are a couple of places I would suggest:
    You could also ask on that blog - perhaps they'd know more.
    According to this page, https://azure.microsoft.com/en-gb/documentation/articles/expressroute-faqs/, the following applies:
    You can link up to 10 virtual networks to an ExpressRoute circuit.
    You can authorize up to 10 other Azure subscriptions to use a single ExpressRoute circuit. This limit can be increased by enabling the ExpressRoute premium feature.
    Virtual machines deployed in virtual networks connected to the same ExpressRoute circuit can communicate with each other.

    None of that really answers your questions though. I suspect that you should be able to build a vnet.xml (can be exported from the Azure console) file with all the right configurations and then import that. Have you tried that?

    Hope that helps a little bit 🙂


  3. Rustem Gumbeev 2 years ago

    Will try searching that blog for useful info.

    As for manually edditing the xml file - I thought that this was only possible in the Classic model. Can I do that in ARM?


    • Author
      Paul Schnackenburg 2 years ago

      Hi again,

      You are right - it's no longer possible to edit the network configuration file using Resource Manager. I had it in my mind that you still could but no go. I learn something new every day - thanks 🙂


  4. Rustem Gumbeev 2 years ago

    Just to confirm - Aivendil is me. I registered on 4sysops to make followup easier and also since I found a lot of interesting stuff here and decided to visit it more often:)


  5. Techie 3 months ago

    Thanks nice article

    i was wondering why this cmdlet does not work

    -Scope "/subscriptions/$($Sub.Subscription.SubscriptionId)/resourceGroups/$($rg.ResourceId))"

    i want to apply policy to entire subscription, help is much appreciated,



  6. Author
    Paul Schnackenburg 3 months ago

    Hi Techie,

    I'm not sure why that doesn't work (and there's not enough context in your question to figure out why). I did find the following two articles that might shed some light on your dilemma, neither of them have your syntax.




    Hope that helps,

    Paul Schnackenburg


  7. Techie 3 months ago

    Thank you paul, yes that is correct i had followed marcel blog to apply that policy,

    I had created a VMsize limitation policy,

    $PolicyAssignmentName = “VMLimitLocationsTest”
    $RG = Get-AzureRmResourceGroup -Name “AzureResourcePolicyTest”
    $Scope = “/subscriptions/$($Sub.Subscription.SubscriptionId)/resourceGroups/$($RG.ResourceGroupName)”

    while running above it gives me error. then i followed your article and defined scope in the powershell cmdlet itself " -Scope  /subscription/XXXX/ it was run successfully,  but i wanted to know whether my syntax is correct for the first scope ,

    just new to powershell variables "$($Sub.Subscription.SubscriptionId)" not sure if this is correct.

    Thank you again for your time

    Thanks for


  8. Author
    Paul Schnackenburg 3 months ago

    Hi again Techie,

    I'm not actually sure if that syntax is correct, although it looks right to me.

    Does it work, as in can a test user create a VM in a location you're not allowing or not?

    Otherwise perhaps someone else in the 4sysops forums can chime in about the syntax of the variable?

    /Paul Schnackenburg


  9. Techie 3 months ago

    Thank you Paul for your help, i will check and confirm,

    I have implemented the policy and its working,  A standard error shows to user "

    The template deployment failed with error: 'The resource with id: '/subscriptions/XXX/resourceGroups/AzurePolicyTest/providers/Microsoft.Compute/virtualMachines/enforcemn' was disallowed by policy with message: 'The resource action 'Microsoft.Compute/virtualMachines/write' is disallowed by one or more policies. Policy identifier(s): '[{"policyDefinitionId":"/subscriptions/XX/providers/Microsoft.Authorization/policyDefinitions/enforcementtwo/","policyDefinitionName":"nforcementtwo","policyDefinitionEffect":"deny","policyAssignmentId":"/subscriptions/XXX"

    I would want to know if this error message can be turned to a standard message like " Pls contact your  IT "


  10. Author
    Paul Schnackenburg 3 months ago

    Hi again Techie,

    No, as far as I know (and I had a look online, including at MS's documentation) there's no way to customize the error messages. I get the feeling that ARM policies are a little bit of a side project at MS which is a shame. I think they're absolutely critical, at least for enterprise environments where governance is key.

    Thanks for sharing your adventures in ARM policies with us.



Leave a reply

Your email address will not be published. Required fields are marked *



Please ask IT administration questions in the forum. Any other messages are welcome.

© 4sysops 2006 - 2017

Log in with your credentials


Forgot your details?

Create Account