What is Azure Resource Manager?

With the introduction of the new Azure Portal (preview) it possible to view resources (such as websites, virtual machines and databases) as a single logical unit. This logical unit is called a resource group. The following screenshot shows a resource group called ecommerce-westus which contains a website, SQL database and an Application Insights instance.

Resource groups aren't visible in the old portal, but almost everything within your Azure subscription exists within a set of resource groups that were created by default when the preview portal opened for business. If you access the new portal, press the Browse button on the jump bar (the icons down the left hand side of the screen) and navigate to resource groups you should see a whole bunch listed. Some will have real names - others will have something like Default-*.

The benefit of resource groups is that they allow an Azure administrator to roll-up billing and monitoring information for resources within a resource group and manage access to those resources as a set. This can be extremely useful when you have a single subscription but you need to do cost recovery on the resources used by a customer or internal department.

Note that there currently exists a limitation whereby subscribers that have an EA-based (Enterprise Agreement) account cannot see billing information. I presume this is because EA customers have a special pricelist with volume discounts applied. If you have an EA and you want better visibility over your spend you might like to check out EA Insights, a tool developed by Readify and hosted at Readify Labs to help us understanding our own Azure usage.

Besides billing, monitoring and access control, resource groups can help streamline the provisioning process in Azure by allowing an administrator to upload a template which contains pre-baked configuration for all the resources within a resource group. Azure will then take control of provisioning those resources as-per the administrator's instructions.

Azure Resource Manager

Azure Resource Manager (ARM) is the technology within the Azure platform which is responsible for provisioning the resources. Within the portal you don't directly interact with ARM other than associating resources that you create manually with a pre-existing resource group. Currently, if you want to create a resource group you need to do so whilst creating a resource, or use either the Azure Resource Manager REST API, or the Azure PowerShell module.

If you just want to create a resource group by itself the Azure PowerShell module is probably the easiest way to get started. Use the link above to download and install the tools on your local machine. Once you've done that you are going to want to issue the following commands from the Microsoft Azure PowerShell prompt.

# Create a credential object contains the credentials you use to access https://portal.azure.com
$credential = Get-Credential

# Use the credentials to download account setings and a list of accessible subscriptions.
Add-AzureAccount -Credential $credential

# Dump out a list of Azure subscriptions to the screen, and note the one you want to use.
Get-AzureSubscription

# Tell the shell to use a specific subscription.
Select-AzureSubscription -Current [name of subscription]

# Switch to Azure Resource Manager mode.
Switch-AzureMode AzureResourceManager

# Dump out a list of existing resource groups.
Get-AzureResourceGroup

# Create a new resource group.
New-AzureResourceGroup [name of resource group]  

There are quite a few commands there, but most of it is just setting up your Azure PowerShell environment. The important command to remember is Switch-AzureMode AzureResourceManager which swaps out all the usual Azure PowerShell cmdlets for ones that work with the Azure Resource Manager.

To be honest, I'm not sure why the ARM commands need to be seperated but thats just the way it is for now. Once you've switched modes you can dump out a list of ARM supported cmdlets by issuing the following command:

Get-Command -Module AzureResourceManager  
# Command Output
CommandType     Name                                               Version    Source  
-----------     ----                                               -------    ------
Cmdlet          Add-AzureAccount                                   0.8.7.1    AzureResourceManager  
Cmdlet          Add-AzureEnvironment                               0.8.7.1    AzureResourceManager  
Cmdlet          Get-AzureAccount                                   0.8.7.1    AzureResourceManager  
Cmdlet          Get-AzureEnvironment                               0.8.7.1    AzureResourceManager  
Cmdlet          Get-AzureLocation                                  0.8.7.1    AzureResourceManager  
Cmdlet          Get-AzurePublishSettingsFile                       0.8.7.1    AzureResourceManager  
Cmdlet          Get-AzureResource                                  0.8.7.1    AzureResourceManager  
Cmdlet          Get-AzureResourceGroup                             0.8.7.1    AzureResourceManager  
Cmdlet          Get-AzureResourceGroupDeployment                   0.8.7.1    AzureResourceManager  
Cmdlet          Get-AzureResourceGroupGalleryTemplate              0.8.7.1    AzureResourceManager  
Cmdlet          Get-AzureResourceGroupLog                          0.8.7.1    AzureResourceManager  
Cmdlet          Get-AzureSubscription                              0.8.7.1    AzureResourceManager  
Cmdlet          Get-AzureTag                                       0.8.7.1    AzureResourceManager  
Cmdlet          Import-AzurePublishSettingsFile                    0.8.7.1    AzureResourceManager  
Cmdlet          New-AzureResource                                  0.8.7.1    AzureResourceManager  
Cmdlet          New-AzureResourceGroup                             0.8.7.1    AzureResourceManager  
Cmdlet          New-AzureResourceGroupDeployment                   0.8.7.1    AzureResourceManager  
Cmdlet          New-AzureTag                                       0.8.7.1    AzureResourceManager  
Cmdlet          Remove-AzureAccount                                0.8.7.1    AzureResourceManager  
Cmdlet          Remove-AzureEnvironment                            0.8.7.1    AzureResourceManager  
Cmdlet          Remove-AzureResource                               0.8.7.1    AzureResourceManager  
Cmdlet          Remove-AzureResourceGroup                          0.8.7.1    AzureResourceManager  
Cmdlet          Remove-AzureSubscription                           0.8.7.1    AzureResourceManager  
Cmdlet          Remove-AzureTag                                    0.8.7.1    AzureResourceManager  
Cmdlet          Save-AzureResourceGroupGalleryTemplate             0.8.7.1    AzureResourceManager  
Cmdlet          Select-AzureSubscription                           0.8.7.1    AzureResourceManager  
Cmdlet          Set-AzureEnvironment                               0.8.7.1    AzureResourceManager  
Cmdlet          Set-AzureResource                                  0.8.7.1    AzureResourceManager  
Cmdlet          Set-AzureResourceGroup                             0.8.7.1    AzureResourceManager  
Cmdlet          Set-AzureSubscription                              0.8.7.1    AzureResourceManager  
Cmdlet          Stop-AzureResourceGroupDeployment                  0.8.7.1    AzureResourceManager  
Cmdlet          Switch-AzureMode                                   0.8.7.1    AzureResourceManager  
Cmdlet          Test-AzureResourceGroupTemplate                    0.8.7.1    AzureResourceManager  

Notice that there aren't any commands there that are related to specific resources, such as virtual machines, websites or databases. The ARM commands are all about working with resources and resource groups generically. So the question then becomes - how do we use this to get stuff up into the cloud?

Resource Group Templates

Rather than issuing individual PowerShell commands to provisioning things like virtual machines, Azure Resource Manager requires that an administrator (or developer) defines all their required resources in a single file called a template. A template is just a JSON (JavaScript Object Notation fo the uninitiated) which lists out each resource and their relationships. At the top level a template file has the following structure.

{
  "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json",
  "contentVersion": "1.0.0.0",
  "parameters": {}
  "resources": []
}

You can see from this that a template contains a set of resources, and the creation of those resources can be parameterised to make them reusable (without editing the template again). Unfortunately there isn't a lot of documentation available about all of the resource types that are available to create so we are left to our own devices to reverse engineer them from existing templates.

Azure Resource Manager Tools

To help you get started editing your own templates, you should download and install the Azure Resource Manager Tools extension for Visual Studio 2013 (currently in preview). The extension adds a new project type to Visual Studio called a Cloud App from the Azure Gallery.

I'm sure that name is temporary but the idea behind this project time is to allow you to create your own templates using an existing one as a starting point. The current version of the tool only includes a template for a Website, or a Website + SQL.

After progressing through the wizard you end up with a solution structure including a web application project and a cloud deployment project. The cloud deployment project is what we are interested in. It contains three files:

Scripts\Publish-AzureResourceGroup.ps1  
Templates\WebSiteSQLDatabase.json  
Templates\WebSiteSQLDatabase.param.dev.json  

The Publish-AzureResourceGroup.ps1 file contains Azure Resource Manager commands to take the two JSON files and upload to Azure to start the provisioning process.

#Requires -Version 3.0

<#  
This is a preview release. What else would you like this script  
to do for you?  Send us feedback here: http://go.microsoft.com/fwlink/?LinkID=399398  
#>

Set-StrictMode -Version 3

Switch-AzureMode AzureResourceManager

# Create or update the resource group using our template file and template parameters
New-AzureResourceGroup  
    -Name 'AzureCloud1'
    -TemplateFile '..\Templates\WebSiteSQLDatabase.json'
    -TemplateParameterFile '..\Templates\WebSiteSQLDatabase.param.dev.json'
    -Force -Verbose

If you open either of the *.json files you will get the benefit of intellisense but I it can still be hard to figure out what you need to do to add an entirely new resource without any examples to use. Right now there is no definitive set of documentation which describes all the resources.

Part of this could be down to the architecture of the Azure Resource Management platform. ARM itself is really just a coordination layer across a set of underlying resource providers, and each resource provider defines the structure of the JSON that goes into the template document. Some of the Azure teams responsible for integrating with Azure Resource Manager probably haven't settled on the structure of their resource definitions.

So how do we figure out what resources we can create?

Resource Group Template Examples

As I mentioned earlier, without solid documentation we need to reverse engineer the elements for each different resource type. Fortunately this one little trick can help you get started. Azure Resource Manager includes a gallery of pre-baked templates. You can use the Get-AzureResourceGroupGalleryTemplate PowerShell command to dump out a list of all of the available templates. As you can see from the following PowerShell invocation there are quite a few templates to choose from:

Get-AzureResourceGroupGalleryTemplate | Measure-Object Count  
# Command Output
Count    : 1547  
Average  :  
Sum      :  
Maximum  :  
Minimum  :  
Property :  

If you want a really good collection of example Azure Resource Manager templates to work with, simply issue the following command and you'll get a directory full of 1547 different *.json files.

Get-AzureResourceGroupGalleryTemplate | Save-AzureResourceGroupGalleryTemplate  
# Command Output
Path  
----
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7MySQL.0.1.0-preview.json  
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7MySQL.0.2.0-preview.json  
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7MySQL.0.2.1-preview.json  
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7MySQL.0.2.2-preview.json  
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7MySQL.0.2.3-preview.json  
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7MySQL.0.2.4-preview.json  
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7MySQL.0.2.5-preview.json  
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7SQL.0.1.0-preview.json  
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7SQL.0.2.0-preview.json  
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7SQL.0.2.1-preview.json  
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7SQL.0.2.2-preview.json  
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7SQL.0.2.3-preview.json  
C:\Sandboxes\ARM\Acquiacom.AcquiaDrupal7SQL.0.2.4-preview.json  
...

The above command will run for quite some time, but at the end you'll have quite a directory full of sample templates to look through and start the learn the syntax for certain resource types. Its also a good way to appreciate the full breadth of applications and services that have been pre-configured to run on Azure.

Summary

Azure Resource Manager is an important underlying technology which is going to be used in a variety of places across the Azure platform. If your team is using Azure and looking to apply devops principles then you should be looking at Azure Resource Manager, resource groups, and resource group templates as a way of defining your infrastructure requirements in code.

I'm looking forward to seeing some improved tooling and documentation in the future but in the meantime some of the techniques I've shown above should get you started.