Menu Home

Custom Azure Portal Dashboard with ARM Templates

For a while it has been possible to create custom dashboards in the new azure portal (portal.azure.com). This feature is pretty useful if you want to get a quick overview from a single page. It can also be used to build big screen dashboards for IT operations.

A simple example of a dashboard focused on consumption and burn rate (good when you are using a MSDN subscription like me) could look like this.

azure-portal-dashboard

If you haven’t to customize a dashboard yet, then Trevor Sullivan have a quick 7 minutes Channel9 video you can watch on how to get started.
https://channel9.msdn.com/Blogs/trevor-cloud/azure-portal-dashboards
Alternatively you can read the official documentation on the topic here. Both of these resources show you how to setup and configure a dashboard manually.

But when you have configured an awesome dashboard, and you want to be able to redeploy it with an ARM (Azure Resource Manager) template? Or maybe you want to ship a ready-made dashboard with your ARM template of an Azure infrastructure that you provide to your customers, are you then out of luck? Of course not, the dashboards are just another Azure resource, and thus there is a resource provider for deploying them, it is named Microsoft.Portal/Dashboards, and it is not really documented (or at least I couldn’t find any documentation).

But we don’t need documentation, I have before on the blog mentioned a neat little tool, ARMclient that can be used to quickly call the Azure Resoure Manager API to query it for information.

So imaging you create a dashboard like the shown earlier, and now you want to turn it into an ARM template.

  • The first you need to Share the dashboard, by clicking the Share button share-dashboard
  • After clicking Share, you need to pay attention to which resource group you place the dashboard in
    share-dashboard-resource-group
  • When the dashboard have been shared, you can navigate to it, the URL in the browser should look something like
    https://portal.azure.com/#dashboard/arm/subscriptions/<YOUR-SUBSCRIPTION-ID>/resourcegroups/dashboards/providers/microsoft.portal/dashboards/<YOUR-DASHBOARD-ID>
  • Next step is to login, with the ARMClient tool
  • Once logged in, you can download the Microsoft.Portal/Dashboard Azure resources, that goes into the ARM template with the ARMClient tool by running armclient get https://management.azure.com/subscriptions/<YOUR-SUBSCRIPTION-ID>/resourcegroups/dashboards/providers/microsoft.portal/dashboards?api-version=2015-08-01-preview > dashboard.js
    on
  • Depending on the number of dashboards you have in the Resource group, the output file dashboard.json might get pretty lengthy, as it contains the complete definition for your dashboards, now it is just a matter of copying the parts you like into an ARM template

An example of an ARM template that contains the dashboard shown earlier can be found in https://github.com/sjkp/azure.arm.dashboards or for your reference here

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": { 
      "dashboardName": {
          "type": "string",
          "defaultValue":  "Simons dashboard"
      }    
  },
  "variables": {
   
  },
  "resources": [
      {      
      "name": "b2ce4e85-e3c4-401f-b9f3-aa52afdbf517",
      "type": "Microsoft.Portal/dashboards",
      "location": "centralus",
      "apiVersion": "2015-08-01-preview",
      "tags": {
        "hidden-title": "[parameters('dashboardName')]"
      },
      "properties": {
        "lenses": {
          "0": {
            "order": 0,
            "parts": {
              "0": {
                "position": {
                  "x": 6.0,
                  "y": 0.0,
                  "rowSpan": 4,
                  "colSpan": 6
                },
                "metadata": {
                  "inputs": [],
                  "type": "Extension/HubsExtension/StartboardPartInstance/Browse",
                  "viewState": {
                    "content": {
                      "selectableData": {
                        "activatedItems": [],
                        "selectedItems": []
                      }
                    }
                  }
                }
              },
              "1": {
                "position": {
                  "x": 12.0,
                  "y": 1.0,
                  "rowSpan": 1,
                  "colSpan": 2
                },
                "metadata": {
                  "inputs": [],
                  "type": "Extension/HubsExtension/StartboardPartInstance/FeedbackTileStart"
                }
              },
              "2": {
                "position": {
                  "x": 12.0,
                  "y": 0.0,
                  "rowSpan": 1,
                  "colSpan": 2
                },
                "metadata": {
                  "inputs": [],
                  "type": "Extension/HubsExtension/StartboardPartInstance/WhatsNewTileStart"
                }
              },
              "3": {
                "position": {
                  "x": 6.0,
                  "y": 4.0,
                  "rowSpan": 4,
                  "colSpan": 6
                },
                "metadata": {
                  "inputs": [
                    {
                      "name": "subscriptionId",
                      "value": "[subscription().subscriptionId]"
                    }
                  ],
                  "type": "Extension/Microsoft_Azure_Billing/Blade/CreditSubscriptionDetailBlade/Lens/CostsLens/PartInstance/b_CreditSubscriptionDetailBlade_part3"
                }
              },
              "4": {
                "position": {
                  "x": 12.0,
                  "y": 2.0,
                  "rowSpan": 1,
                  "colSpan": 1
                },
                "metadata": {
                  "inputs": [],
                  "type": "Extension/HubsExtension/StartboardPartInstance/AzurePortalTileStart"
                }
              },
              "5": {
                "position": {
                  "x": 0.0,
                  "y": 4.0,
                  "rowSpan": 4,
                  "colSpan": 6
                },
                "metadata": {
                  "inputs": [
                    {
                      "name": "subscriptionId",
                      "value": "[subscription().subscriptionId]"
                    }
                  ],
                  "type": "Extension/Microsoft_Azure_Billing/Blade/CreditSubscriptionDetailBlade/Lens/CostsLens/PartInstance/BurnRateCredit"
                }
              },
              "6": {
                "position": {
                  "x": 0.0,
                  "y": 0.0,
                  "rowSpan": 4,
                  "colSpan": 6
                },
                "metadata": {
                  "inputs": [],
                  "type": "Extension/HubsExtension/StartboardPartInstance/ServicesHealthPartStart"
                }
              }
            }
          }
        },
        "metadata": {
          "model": {
            "timeRange": {
              "value": {
                "relative": {
                  "duration": 1,
                  "timeUnit": 3
                }
              },
              "type": "MsPortalFx.Composition.Configuration.ValueTypes.TimeRange"
            }
          }
        }
      }
    }      
  ],
  "outputs": {
  }
}

The template is pretty self-explaining, the type of the different parts in the properties object are of course completely undocumented but since we got them using the ARMclient tool, they should be fine to use, but I’m not sure Microsoft gives any guarantees on changing the names, and thus breaking your template. Then name of the dashboard is just a hardcoded guid, as it serves as the unique reference for this specific dashboard. API-version should be 2015-08-01-preview as that is the only version that the Resource Provider is supported in at the moment. The title of the dashboard is stored in a special tag called hidden-title, misuse of the tags if you ask me, but I guess it was too difficult to add a property named dashboardTitle or something similar to the properties object :).

Categories: Software

Simon J.K. Pedersen

2 replies

  1. I just tried this out today and got a result that looks nothing like an ARM Template and has nowhere near enough content to include the various dashboards I have setup… Has the functionality changed and it does not work anymore, or am I missing a step to take the .js to usable content for a .json ARM Template. I’d love to be able to automate my dashboards to keep up with my IaC efforts…

  2. ah-ha! My error, I was not updating the URL to point at management.azure.com…

Leave a Reply

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