Tuesday, June 7, 2016

Best Practices for Creating Azure Resource Manager Templates -Part II

This post is second part of the series : Best Practices for Creating ARM Template, If you haven't already seen please go ahead and check the First part- Best Practices For Creating ARM template

11. Use ARM Template expression function such as trim(), toLower() as a data cleaning measure to ensure input consistency

12. ARM Termination Protection-For Critical Resource always implement Resource Lock

For resources where you have to constrain the ability to commit write actions and protect against accidental deletions, Azure Resource Lock can be a way to go.Check more on how to implement Resource Lock-

  "type": "extensions",
  "name": "Microsoft.EnterpriseCloud.Monitoring",
  "apiVersion": "[variables('apiVersion')]",
  "location": "[resourceGroup().location]",
  "dependsOn": [
    "[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
  "properties": {
    "publisher": "Microsoft.EnterpriseCloud.Monitoring",
    "type": "MicrosoftMonitoringAgent",
    "typeHandlerVersion": "1.0",
    "autoUpgradeMinorVersion": true,
    "settings": {
      "workspaceId": "[parameters('workspaceId')]"
    "protectedSettings": {
      "workspaceKey": "[parameters('workspaceKey')]"

13. EnableLog Analytics To Azure VM's- Use OMS

If you are using VMs in Azure you should always opt for some monitoring and analyzing capabilities for them.OMS offers log analytic capabilities that enable you to collect and analyze machine data from virtually any source.Using data generated across devices, operating systems, workloads and user actions, OMS provides instant access to critical information through one integrated console. You can troubleshoot across multiple data sources and easily identify the root cause of operational and security issue.
Log Analytics (OMS) supports a majority of Windows and Linux variations available in Azure today,and because it's been pitched as IT management solution for the hybrid cloud you can manage any instance in any cloud, including on-premises, Azure, AWS, Windows Server, Linux, VMware, and OpenStack

  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "",
  "parameters": {
    "lockedResource": {
      "type": "string"
  "resources": [
      "name": "[concat(parameters('lockedResource'), '/Microsoft.Authorization/utLock')]",
      "type": "Microsoft.Storage/storageAccounts/providers/locks",
      "apiVersion": "2015-01-01",
      "properties": {
        "level": "CannotDelete"
  ] } 
The OMS Workspace ID and OMS Workspace Key are required to onboard the OMS Service and can be found in the OMS Portal under Settings > Connected Sources

14. Tag the resources properly

Tagging provides you the ability to include metadata about your resource.Common use cases are to include references to environment types, team or division , individuals accountable.It provides subscription wide taxonomy The benefit of tags is that they can be pulled together in billing roll up or within a summary view.

"tags": { "
   "ProjectName": "[parameters(projectName)]",
   "EnvironmentType" :"[parameters('environmentType')]"
} ,

15. Have the habit for pre-deployment validation

Azure Resource Manager as it stand today has two-part validation: before and during deployment. The before deployment checks whether a template is syntactically correct and that it would be accepted by the Azure Resource Manager. Then the during deployment validation (runtime) checks for resource dependencies within your Azure subscription. The templates may seem valid, but until they are deployed as there is no fool-proof way to guarantee that it is a working template. However, as a good practice when deploying templates, make pre-deployment validation a habit as it will catch most obvious errors detected by Azure Resource Manager.

16. Don't Pass your Passwords as Plain-text:Use Azure key Vault With ARM Template

With template-based deployments that include passwords stored in parameter files (or other insecure stores), there is always the risk of leaking the password should someone access the particular file.

As an It guy we should always took to lock down environments so that only the right groups of users can login and modify the configurations.

Once you have stored your passwords as a Secret in a Key Vault, its ready to be accessed via ARM Template.

The way you can supply Key Vault Secrets to ARM templates is via use of parameters file.

"osProfile": {
    "computername": "[variables('vmName')]",
    "adminUsername": "[parameters('adminUsername')]",
    "adminPassword": "[parameters('adminPassword')]"
We can feed in the Secret we pushed to our Key Vault using the below snippet in our parameters file.

"adminPassword": {
     "reference": {
        "keyVault": {
   "id": "/subscriptions/{subscription-guid}/resourceGroups/{keyvault-rg}/providers/Microsoft.KeyVault/vaults/ProvisioningVault"
        "secretName": "LocalAdminPass"

 Separation of Keys from Deployments
A best practice is to maintain separate ARM templates for-
  1. Creation of vaults (which will contain the key material)
  2. Deployment of the VMs (with URI references to the keys contained in the vaults)
17. Include the Output Section
Whenever possible return some output to validate the Deployment.With Outputs section, users can specify values that are returned from deployment.For example,  you could return the URI to access a deployed resource.
  "siteUri" : {
"type" : "string",
"value": "[concat('http://',reference(resourceId('Microsoft.Web/sites', parameters('siteName'))).hostNames[0])]"
18. Use Audit Logs For Deployment Operations

Audit logs would be your first place for troubleshoot because it contains all write operations (PUT, POST, DELETE) performed on your resources.
It also helps you determine who made what changes to the subscription(s) and related Azure resources.In Future these logs can be processed for audit compliance purpose as well.

19. Disable Windows Automatic Updates  

To disable windows updates at provisioning time it self, you have to disable the same under "windowsConfiguration" Setting.This particular section comes under osProfile -

 "osProfile": {
          "computerName": "[variables('vmName')]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]",
          "windowsConfiguration": {
            "enableAutomaticUpdates": false

20. Template Formatting 
  • Pass your template through a JSON validator to remove extraneous commas, parenthesis, brackets that may cause an error during deployment. Try JSONlint or a linter package for your favorite editing environment (Visual Studio Code, Atom, Sublime Text, Visual Studio, etc.)
  • Format your JSON for better readability. You can use a JSON formatter package for your local editor. In Visual Studio, format the document with Ctrl+K, Ctrl+D. In VS Code, use Alt+Shift+F. If your local editor doesn't format the document, you can use an online formatter.


  1. ARM Template file size can't exceed beyond 1 mb 
  2. ARM Parameter Template file Size can't exceed beyong 64 kb 
  3. If parameter name value contains "." character, the arm template deployment will fail in azure portal(bug).EG-My.Database 
  4. Variables doesn't support ARM template expression function such as "reference()"

Related Articles : Best Practice For Creating ARM Template


  1. >>> If parameter name value contains "." character, the arm template deployment will fail in azure portal(bug).EG-My.Database

    I think this has been fixed.

  2. • Nice and good article. It is very useful for me to learn and understand easily. Thanks for sharing your valuable information and time. Please keep updatingAzure Online Training

  3. A good quality SEO service can provide relevant, consistent web traffic to your website(s). This guide will allow you, as a non-expert, to distinguish between good and bad SEO providers. There are many of both kinds, this guide should help you to find the good ones.Blog Comment