Essential tips for building a large Azure blueprint

Azure Blueprint allows an organization to design and build a standardized and repeatable cloud templates in Azure that meet pre-defined reference architecture as well as corporate compliance and policy for cloud deployment.

Building a simple blueprint shouldn’t take time. However in a real-world scenario, as well as when you work for large organization you may need to build a complex blueprint that require multiple dependencies. This article is going to give you key essential tips to help you simplify building a large and complex Azure blueprint.

Logical Architecture

A logical architecture would be just a diagram showing which resources you are going to deploy in Azure.  The diagram shows you the deployment of Windows virtual machine along with different services such as Virtual Network, Azure Bastion, Storage Account, Log Analytics and Key Vault. This one is not a complex deployment but it would give you an idea how a logical architecture diagram would look like.

With logical architecture diagram you may have an idea on what need to be deployed first. In the above example we see that prior to deploying a virtual machine an Azure virtual network with other network resource types should be ready.

Dependency Map

Dependency map is simply a map showing you what are dependencies of each logical component if any. Continue to use the example above:

  • Virtual network is a dependency of virtual machine, Azure bastion service.
  • Log Analytics workspace is a dependency of virtual machine log.
  • Key Vault is a dependency of virtual machine disk encryption

Depending on how much of detail you would like, the dependency level may vary. In some cases you may need be aware of non-dependency resource in order to resolve cloud resource deployment conflict. For example if your virtual machine has multiple script extension resource type, you may need to set a dependency to ensure no conflict may occur during the deployment.

As a cloud architect, you may need to draw a dependency map. Below is a sample one:

Sample dependency – all logs are written to a single log analytics workspace

Dependency mapping will help you figure out what you should put in dependOn element in your artifact and blueprint definition.

Blueprint As Code

For small and simple blueprint, you can use Azure Portal to create one (see this example). However, advanced or large blueprint couldn’t be achieved with Azure Portal especially when you need global parameters (e.g. Project Code, Project Stage or Cutsom Tag) to follow your own standard naming convention.

Another reason why blueprint as code is recommended is to support building a CICD pipeline for your blueprint. Managing blueprint as code will help simplify the development and deployment.

Global Parameter

When it comes to building a blueprint that follows reference architecture, there are usually global parameters. One of the very common ones are naming standard convention. You would like your resource name to be followed like {project_code}-{project_stage}-{service_name} . With global parameter you can resuse in individual artifact. This example below gives you an idea on how a global parameter look like. In the example we see tagging, project code, project stage, resource group location and log retention parameters and their values are applied to all resource artifact.

Note that global parameter is different from local parameters. Global parameter is the one that are used in one more/all artifacts while local parameters are used specifically for an artifact.

You should  create a spreadsheet of global parameters that you may think your blueprint use. It ideally has the following info:

  • Parameter Name
  • Display Name
  • Description
  • Global/Local (Yes/No)
  • Optional: Artifact (Use in which of artifact if not a global parameter)

Naming Global Parameter

Global parameter name should be different from artifact parameter. This can help distinguish between the two types of parameters and you won’t be confused when using them. See the example below in an artifact in which artifact parameter value is referenced by global parameter.

"parameters": {
  "resourceTags": {
    "value": "[parameters('g_resourceTags')]"
  "projectCode": {
    "value": "[parameters('g_projectCode')]"
  "projectStage": {
    "value": "[parameters('g_projectStage')]"

In the example, we put a letter ‘g‘ as a prefix in global parameter (g stands for global).

Az.Blueprint Module

Given the fact that you can build your own module to be used within your pipeline or inside your development team. However I’d recommend you to try Az.Blueprint first before cooking an own one. The module provides you common operations such as creating a new blueprint, getting a blueprint, importing an artifact or so on.

The only note with the use of Az.Blueprint is that you would need to follow some standards. For example when using Import-AzBlueprintWithArtifact   your blueprint directory need to follow some rules (e.g. all artifact templates must be stored in a directory named artifacts). To understand more details on how this module works behind the scene you can decompile the module DLL and read the code. Below is decompiled function named GetValidatedFilePathForBlueprint() that gives you an idea on what it does does – finding blueprint.json in your directory.

protected string GetValidatedFilePathForBlueprint(string path)
    string path2 = ((IEnumerable<string>) AzureSession.get_Instance().get_DataStore().GetFiles(path, "*.*", SearchOption.TopDirectoryOnly)).Select<string, string>((Func<string, string>) (file => Path.GetFileName(file))).FirstOrDefault<string>((Func<string, bool>) (name => string.Equals(name, "blueprint.json", StringComparison.OrdinalIgnoreCase)));
    if (path2 == null)
    throw new Exception("Cannot locate Blueprint.json in: " + path + ".");
    return Path.Combine(path, path2);

There is still a limitation though. You would have to put everything in one single blueprint.json file. That said managing a long list of parameters would be kind of painful. You may need an enhancement to read each blueprint for each artifact so you could manage local artifact parameter easier.

Boilerplate template

Before putting your hands on writing template definition for your blueprint you should create a boilerplate template to ensure it follows blueprint standard as well as to avoid errors when using Az.Blueprint module.

For artifact template:

    "kind": "template",
    "id": "/providers/Microsoft.Blueprint/blueprints/azsec_foundation/artifacts/loganalytics_blueprint",
    "type": "Microsoft.Blueprint/blueprints/artifacts",
    "name": "loganalytics_blueprint",
    "properties": {
        "resourceGroup": "projectResourceGroup",
        "displayName": "Log Analytics template",
        "description": "A blueprint to deploy Log Analytics",
        "template": {
            "$schema": "",
            "contentVersion": "",
            "parameters": {

            "variables": {

            "resources": [

            "outputs": {

        "parameters": {
        "dependsOn": [

For blueprint definition template:

    "id": "/providers/Microsoft.Blueprint/blueprints/azsec_foundation",
    "type": "Microsoft.Blueprint/blueprints",
    "name": "azsec_foundation",
    "properties": {
        "targetScope": "subscription",
        "displayName": "AzSec Foundation Blueprint",
        "description": "AzSec Foundation Blueprint provides foundation templates for a new project",
        "parameters": {

        "resourceGroups": {

For assignment template:

    "identity": {

    "location": "",
    "properties": {
        "blueprintId": "subscriptions/61a6179d-bb2d-4ccd-8c56-4d3ff2e13119/providers/Microsoft.Blueprint/blueprints/azsec_foundation",
        "resourceGroups": {

        "parameters": {


You can get the template from here.

Azure ARM Validation

This is extremely important. First, everything inside template element in artifact template is actually things that you normally see in azuredeploy.json when deploying Azure ARM template. The problem with Azure Blueprint is that during the assignment it may give you an unclear information if the deployment of an artifact is failed. Tracing in Azure Activity Log may give nothing if the error is part of the artifact template itself (e.g. unsupported value in a parameter or missing required resource property).

Before blueprint assignment, you should deploy your artifact independently. Give artifact’s parameters default values then validate (Test-AzResourceGroupDeployment  and New-AzResourceGroupDeployment  should help) and try to deploy in a resource group to see if the deployment is succeeded.

secureString Consideration

If you intend to use secureString for your parameter here is what you should know. By default, when you define a secureString, Azure Blueprints will enforce it to be a value stored in Azure Key Vault. If you do blueprint assignment from Azure Portal it may give you a surprise. To solve the issue simply define assignment parameter as code, sample is as follows

"g_vmLocalAdminPassword": {
    "reference": {
        "keyVault": {
            "id": "/subscriptions/aa2201b1-a52a-1199-11ec-930c4deb35e8/resourceGroups/azsec-rg/providers/Microsoft.KeyVault/vaults/shared-kv"
        "secretName": "vmLocalAdminPassword"


Building a complex Azure blueprint does require a plan, as well as an architecture diagram and artifact blueprint document. If you don’t have a systematic approach you would have to refactor your blueprint which leads to time consuming and effort.

Below are helpful references that can be used along with this article:

This entry was posted in Governance & Compliance and tagged , . Bookmark the permalink.

8 Responses to Essential tips for building a large Azure blueprint

Leave a Reply