Got Azure? Get ARM Policies! aka.ms/Azure/Policies

Azure Resource Manager (ARM) Policies

In my Azure Online IaaS Operations guide (aka.ms/Azure/IaaSOpsGuide) I have a complete section on Azure Resource Manager (ARM) tidbits you need to know about. But in this post, I wanted to talk specifically about one aspect of ARM, ARM Policies. The question is; can you live without them?  Same answer as you would ask about laws, rules, group policies, and a bunch of other ways to control people's behavior.  Of course in a perfect would where everyone does exactly as they know they should or shouldn't do, and mistakes never ever happen; then none of these things are ever ever needed.  So for simplicity, we'll assume you don't live in that perfect world, because it doesn't exist!

To learn what the policies do, all the details are listed on TechNet But for brevity's sake, let's give you the quick bullets:

  • With policies, you can prevent users in your organization from breaking conventions that are needed to manage your organization's Azure resources
  • Policies in Azure have two parts ot make them happen
    • Policy Definitions
      • Creating what will be locked down through a combination of
        • Conditional/Logical operators
          • Conditions evaluate if a field or source meets certain criteria
            • supported fields include: name, kind, type, location, tags, tags. *, and property alias.
          • Logical Operators: Not, And, Or
        • Effect i.e. if the condition above is met, then we can either DENY, AUDIT or APPEND the request
        • Read more
      • You can make them in advance, and then apply when and where they are needed through...
    • Policy Assignments
      • Telling WHERE the Policy definition (scope) will be applied. At the..
        • Subscription
        • Azure Resource Group (s)
        • Azure Resource (S)
  • To be able to use policy, the user must be authenticated through RBAC. Unlike RBAC, policy is a default allow and explicit deny system.
  • Through policies, you can control the types of Azure resources that can be provisioned or restrict the locations in which the resources can be provisioned.

Here is one way to look at RBAC, ARM Policy Definitions and Assignments...

ARM Policies

To have one or more policies, that is the question

As I started to dive into these, I thought maybe it would be a good idea to consider monolithic polices, where they make sense.  For example, every time I want a Storage Account and or storage account created, I may want to have a policy definition to apply to that resource or resource group that has many things all together.  In one such policy definition I could have:

  • LRS, GRS, RA-GRS Redundancy options only allowed
  • East and West US regions only
  • Storage Naming convention to enforce
  • etc.

When I first thought of this, it really sounded like a good idea.  Until I tested it. Here is the problem.  In the error message it will tell you only the name of the policy impacting the deployment of that resource.  For example, if you didn't name your resource based on the naming convention that you had in your policy definition as shown above, the error message will only tell you the name of the policy applied using that definition. So even if you included "naming" in the name of that definition and policy, upon a failure, with such a monolithic policy, you would not know what caused the failure.  Therefore, by having a separate definition and then a separate policy per resource, when it fails, you would know that the policy that contains only one definition would be the cause of the breach of policy enforcement.

Use Azure CLI to make Policies

As of the posting of this blog, the TechNet Article Use Policy to manage resources and control access tells how to create policy definitions and assignments through REST API and PowerShell, but is not yet updated for our CLI friends.  I did find an example in another page titled Control access to resources, so I have summarized some of that here,  are also listed some sample Azure CLI Policy commands.

Summary of Steps

This example from the TechNet article enforces the regions where resoures can be created

# Create an ARM Policy Definition and Policy Assignment Example

azure login
azure config mode arm

# SAVE THE First JSON part in a policy.json file into C:\temp
{
"if" : {
"not" : {
"field" : "location",
"in" : ["eastus" , "westus"]
}
},
"then" : {
"effect" : "deny"
}
}

# Then Run
azure policy definition create MyPolicy -p c:\temp\policy.json

# Next Assign the policy at a given scope (Subscription, Resource Group, Azure Resource)
azure policy assignment create MyPolicyAssignment -p /subscriptions/########-####-####-####-############/providers/Microsoft.Authorization/policyDefinitions/MyPolicy -s /subscriptions/########-####-####-####-############/

Azure CLI Sample Commands for Policies

Commands to manage your policy definitions
azure policy definition create [options] <name> <policy>
azure policy definition set [options] <name>
azure policy definition list [options]
azure policy definition show [options] <name>
azure policy definition delete [options] <name>

Commands to manage your policy assignments
Azure policy assignment create [options] <name> <policyDefinitionId> <scope>
Azure policy assignment set [options] <name> <scope>
Azure policy assignment list [options]
Azure policy assignment show [options] <name> <scope>
Azure policy assignment delete [options] <name> <scope>

Azure policy definition create -h
Creates a new policy definition
Usage: policy definition create [options] <name> <policy>

Options:
-h, --help output usage information
-v, --verbose use verbose output
-vv more verbose with debug output
--json use json output
-n --name <name> the policy definition name
-p --policy <policy> the rule for policy definition. This should be a path to a file name containing the rule.
--policy-string <policyString> a JSON-formatted string containing the policy rule.
-d --display-name <display-name> the display name for policy definition.
--description <description> the description for policy definition.
--subscription <subscription> the subscription identifier