ARM Template Building Blocks and Reference Architectures

The AzureCAT team actively assists customers with the largest, most complex projects built on the Azure platform.  In addition to the super work the team does helping Azure customers the AzureCAT team have released a set of ARM templates which can be used as building blocks for ARM deployments.  The team have made these templates available on GitHub and have also released a set of reference architectures that use these ARM building blocks.

What’s really nice, is that the ARM building blocks the AzureCAT team have created, are based on the work they have done with real customers.  This means these templates are road tested and have a huge amount of customer learnings and good practices ‘baked in’ to them.

The AzureCAT team has made extensive use of nesting and arrays within their ARM templates to reduce some of the complexity inherent in ARM.

Even if you don’t use the templates directly, they are a great place to start when building your own templates and offer an interesting insight into learnings the AzureCAT team has gained over the last two years.

Current building blocks released are:

Building block Link Description
Virtual network vnet-n-subnet Used to create a virtual network with any number of subnets
Network security groups networkSecurityGroups Used to create any number of NSGs, and link them to any number of NICs and/or subnets
User defined routes userDefinedRoutes Used to create any number of UDR tables, and link them to any number of subnets
Gateway connection vpn-gateway-vpn-connection Used to create a VPN or ExpressRoute gateway and necessary connections to another network
Virtual machines multi-vm-n-nic-m-storage Used to create any number of VMs, each with any number of NICs, and any number of data disks
Load balanced workload loadBalancer-backend-n-vm Used to create a load balancer with a collection of VMs in the backend
DMZ dmz Used to create a DMZ between an Azure VNet and any other network, or the Internet

 

Using ARMclient to directly access Azure ARM REST API’s and list ARM Policy details

While Azure-PowerShell and the Azure xplat CLI are excellent tools, there are times when connecting directly to the Azure ARM REST API is just easier.   One of these times is when you want to find out the contents of an Azure Resource Manager Policy.  While Its easy to use PowerShell to find out the policies applied to a Resource Group.

get-azureRMpolicyassignment -Scope /subscriptions/$mysubscription/resourceGroups/$myresourcegroup

Getting the details as to the contents of an Azure Resource Manager Policy can be quite a bit trickier.  This is one situation where calling the ARM Policy provider via the ARM REST API’s directly is the easiest answer.

ARMclient is an OSS project which makes the task of connecting to Azure’s ARM REST API incredibly easy.  David Ebbo has a great blog article here on the simple steps to install ARMClient.

Once ARMclient is installed its a simple matter of logging in to the Azure tenant and then calling the provider.  In this case,  /Microsoft.authorization/policydefinitions to list the ARM Policies for a given subscription.

armclient login
armclient get "https://management.azure.com/subscriptions/<$YourSubscriptionID>/providers/Microsoft.authorization/policydefinitions?api-version=2016-04-01"

Depending on the number of ARM Policies in the subscription the output from the ARMclient can be quite large.  If you know the name of the ARM Policy you whish to see the details for you can append this to the call that you make to the API.

armclient get "https://management.azure.com/subscriptions/<$YourSubscriptionID>/providers/Microsoft.authorization/policydefinitions/tags-owner?api-version=2016-04-01"

This will display the contents of just that policy.

armclient get "https://management.azure.com/subscriptions/<$YourSubscriptionID>/providers/Microsoft.authorization/policydefinitions/tags-owner?api-version=2016-04-01"
{
  "properties": {
    "policyType": "Custom",
    "description": "Policy to set owner tags",
    "policyRule": {
      "if": {
        "allof": [
          {
            "field": "tags",
            "exists": "true"
          },
          {
            "field": "tags.owner",
            "exists": "false"
          }
        ]
      },
      "then": {
        "effect": "append",
        "details": [
          {
            "field": "tags.owner",
            "value": "Daniel"
          }
        ]
      }
    }
  },
  "id": "/subscriptions/<$YourSubscriptionID>/providers/Microsoft.Authorization/policyDefinitions/tags-owner",
  "type": "Microsoft.Authorization/policyDefinitions",
  "name": "tags-owner"
}

As you can see the output passed back by the API is exactly the same JSON format which is used when creating the ARM Policies .

There is heaps that you can do with the ARMclient, one of my favourites is to list out all the resources in an Azure subscription.

armclient get "https://management.azure.com/subscriptions/<@YourSubscriptionID>/resources?api-version=2014-04-01"

As the output is in JSON format its very easy to manipulate as required.  You can also convert the output from ARMclient to a PowerShell object using ConvertFrom-JSON in your PowerShell scripts.

The following command will list just the virtual machines in a subscription.

armclient get "https://management.azure.com/subscriptions/<$YourSubscriptionID>/providers/Microsoft.compute/virtualMachines?api-version=2016-03-30"

To get a list of all available ARM providers which you can call using the ARM REST API, you can run the following ARMclient command.

armclient get "https://management.azure.com/subscriptions/<$YourSubscriptionID>/providers?$expand=resourceTypes/aliases&api-version=2015-11-01"

This will also give you the API versions supported by the different providers.  An API version must be appended to the end of all calls to the ARM REST API.

As well as ‘get’ commands, the ARMclient can also be used to modify Azure ARM resources by using ‘post’, ‘put’ and ‘delete’ operators.  The website resources.azure.com exposes similar functionality to the ARMclient.