Modularizing Azure Infrastructure Code Using Azure Resource Manager (ARM) Linked Templates

In programming paradigm, complex application code is broken into small, more manageable modules for better visibility, manageability and re-usability. Similarly, as complexity of Azure Infrastructure code increases, you might want to split the code into multiple modules which are easy to comprehend, more manageable and re-usable in future.

Azure Resource Manager (ARM) Linked and Nested Templates render this capability to break down your code into many related templates and then deploy them together through a main template.

In this beginner-friendly article, I shall be discussing following key areas of ARM Linked Templates to help you create and deploy ARM Linked templates:

  1. What is Azure Resource Manager Linked Template
  2. ARM Linked Template Deployment Methods
  3. How to Use ARM Linked Template
  4. When to Use ARM Linked Template
  5. ARM Linked Template Example – Create a Storage Account and Virtual Network
  6. How to Deploy an ARM Linked Template
  7. Deployment Result
  8. Conclusion

What is Azure Resource Manager (ARM) Linked Template

Azure Resource Manager (ARM) Linked Template refers to the methodology of connecting separate template files via links referenced to each individual template in a main template. Linked templates consist of a main template (parent) and several other templates (child) referenced in the main template via a reference link or a relative path.

ARM Linked Template Deployment Methods

The linked template cannot be stored as a local file or as a file that is only accessible on your local network. Instead, linked template must be accessible over the internet. Depending on how a linked template is accessed from main template, ARM Linked templates can be deployed in two different ways:

  • Using TemplateLink URI Method

By using this method, you must provide a URI (Uniform Resource Identifier) value for the linked template that is accessible over HTTP or HTTPS, in order to reference a linked template from main template. For context, URI is a sequence of characters that identify a physical or logical resource, usually on internet.

For this purpose, you must place your child or linked template on a publicly accessible endpoint such as GitHub or Azure Storage account.

  • Using TemplateLink RelativePath Method

To use this method, you must place remote linked template at a location relative to the parent template. One option is to place both the main and linked template in an Azure storage account.

In this tutorial, I shall be using TemplateLink URI method to deploy linked templates. Main template will be stored locally on my PC while Linked templates will be stored in a GitHub repository and accessed via internet.

Two separate linked templates will be created; one for deploying storage account and other for deploying virtual network. Both these templates will be linked to main template using a URI path.

How to Use ARM Linked Template

To use linked templates, you need to add a Microsoft.Resources/deployment resource to your main template and configure templateLink property with the location of your linked template using either URI or RelativePath property.

When to Use ARM Linked Template

For simple solution, a single ARM template is easier to understand and maintain. However, for complex solution, ARM Linked templates should be used to break down the infrastructure code into several modules. Each module will usually contain code for one or more related resources. These individual modules can easily be re-used in future deployments.

ARM Linked Template Example – Create a Storage Account and Virtual Network

Let’s take an example of creating a storage account and virtual network using linked templates.

In case you find difficulty in understanding the basics of ARM template or create / deploy new ARM template, refer to my blog on below link:

https://cloudpulse.blog/a-step-by-step-guide-to-azure-resource-manager-arm-templates/

  1. Create a new folder on your computer for saving ARM template files. I have created D:\AZ-Linked-Temp in my case.
  2. Now open VS Code -> Open Folder from File menu -> Select D:\AZ-Linked-Temp. This will select D:\AZ-Linked-Temp folder as your Workspace where you could save all your JSON files for this project.

Create Main (Parent) Template

First, we need to create a main template.

  1. Open New File from File menu and name it as mainTemp.json. Press enter -> Create File. This will create a blank JSON file with the mentioned name.
  2. Next, create a parameter named projectName. This parameter will be used as a prefix to name storage account and virtual network.
    ARM linked template main Template parameters
  3. Now we need to create two variables named storageTempPath and vnetTempPath. These variables will store URI path to our storage account template and vnet template respectively. For now, keep value of these variables blank. We will assign them values later.
    ARM linked template main Template variables
  4. Next, we need to create a deployment resource for storage account template. Place your cursor in the template resources block, type arm-linked, and select arm-linked-template-uri snippet
    ARM linked template main Template arm linked-scaffolding
  5. A new deployment resource named “linkedDeployment1” with default properties shall be added to the template
    6-ARM linked template-main Template-deployment-resource
  6. Change the name of deployment resource to “storageDepTemplate”. Update templateLink: uri property to call variable storageTempPath. Also, update deployment resource parameters as mentioned in the snap.
    ARM linked template-mainTemp-storage-deployment-resource-properties
  7. Now, we need to create another deployment resource for virtual network template. Place your cursor in the template resources block, type arm-linked, and select arm-linked-template-uri snippet
    ARM linked template-mainTemp-arm-linked-scaffolding-2
  8. A new deployment resource named “linkedDeployment1” with default properties shall be added to the template
    ARM linked template-mainTemp-deployment-resource-2
  9. Change the name of deployment resource to “vnetDepTemplate”. Update templateLink: uri property to call variable vnetTempPath. Also, update deployment resource parameters as mentioned in the snap.
    ARM linked template-main Template-vnet-deployment-resource-properties

Create Azure Storage Account (Child) Deployment Template

Now, we need to create a child template for Azure storage account deployment.

  1. Open New File from File menu and name it as storageTemp.json. Press enter -> Create File. This will create a blank JSON file with the mentioned name.
    ARM linked template-storage-template
  2. Next, create two parameters named projectName and location as depicted in snap below. projectName parameter will be used as a prefix to name storage account while location parameter will be used to specify deployment region of the storage account.
    ARM linked template-storage-Temp-parameters
  3. Next, we need to create a storage account resource. Change name, displayName and location property as per the snap below. As Storage Account name must be unique across Azure Cloud, we generate a unique name by concatenating projectName with a 13 place alphanumeric value generated through uniquestring() function. 
    ARM linked template-storage-template-resource

Create Azure Virtual Network Deployment (Child) Template

Now, we need to create a child template for Azure virtual network deployment.

  1. Open New File from File menu and name it as vnetTemp.json. Press enter -> Create File. This will create a blank JSON file with the mentioned name.
    ARM linked template-vnet-Temp
  2. Next, create two parameters named projectName and location as depicted in snap below. projectName parameter will be used as a prefix to name vnet while location parameter will be used to specify deployment region of the virtual network.
    ARM linked template-vnet-temp-parameters
  3. Next, we need to create a vnet resource. Place your cursor in the template resources block, type arm-vnet, and select arm-vnet snippet
    ARM linked template-vnet-temp-arm-vnet-scaffolding
  4. A new resource named “virtualNetwork1” with default properties shall be added to the template
    ARM linked template-vnet-temp-new-vnet-resource
  5. Change name, displayName and location property as per the snap below. Note that I have used format() function to define name of vnet resource. format() function is used to create dynamic strings by inserting values into a string pattern. Its syntax is format(string, arg1, arg2, …) where placeholders like {0}, {1} and non-changing text are used in place of string value. {0} refers to arg1, {1} refers to arg2 and so on. In our case, -vnet- is non-changing text.
    ARM linked template-vnet-temp-vnet-resource-properties
  6. The dependsOn element enables you to define a resource as dependent on one or more resources. A resource cannot be deployed unless its dependency mentioned in the dependson element has been fulfilled by creating the mentioned resource first. A vnet resource depends on Network Security Group which is why this appears in default snippet. However, for ease of deployment in this tutorial, remove depends on element highlighted in snap below so that we don’t have to create Network Security Group resource.
    ARM linked template-vnet-temp-vnet-resource-dependson
  7. Remove networkSecurityGroup property in the subnets section as well.
    ARM linked template-vnet-temp-vnet-resource-nsg
  8. Remember to remove , at the end of addressprefix.
    ARM linked template-vnet-temp-vnet-resource-semicolon

Stage Linked Templates on GitHub

Now, we need to stage both the linked templates on GitHub.

  1. Sign in to your GitHub account. In case you don’t have an account, create a new account.
    ARM linked template-Github-login
  2. Create a new repository by clicking New button as depicted in snap below. A GitHub repository is a folder-like structure on GitHub where you store your code, its history, and can collaborate with others.
    ARM linked template-Github-new-repository
  3. Give a name to the repository. In our case, I have named it azure-arm-linked-template. Click on Create Repository. A new repository will be created.
    ARM linked template-Github-new-repository-2
  4. Now we need to create two files in the repository for storing code of our ARM Linked templates. Click on creating a new file as depicted in the snap.
    ARM linked template-Github-new-file
  5. Name this file as storageTemp.json. Copy storageTemp.json template content from VS Code on your PC and paste in this file. Hit Commit Changes button.
    ARM linked template-Github-new-file-storage-Template
  6. A message popup window will appear. You may change the commit message. Hit Commit Changes button again.
    ARM linked template-Github-new-file-storage-Template-2
  7. You will see that a new storageTemp.json file is created in the azure-arm-linked-template repository.
    ARM linked template-Github-new-file-storage-Template-view
  8. Now, we need to create another file to store our second template content. Click Add file -> Create new file
    ARM linked template-Github-add-new-file
  9. Name this file as vnetTemp.json. Copy vnetTemp.json template content from VS Code on your PC and paste in this file. Hit Commit Changes button.
    ARM linked template-Github-add-new-file-vnet-template
  10. A message popup window will appear. You may change the commit message. Hit Commit Changes button again.
    ARM linked template-Github-add-new-file-vnet-template-2
  11. You will see that a new vnetTemp.json file is created in the azure-arm-linked-template repository.
    ARM linked template-Github-view-new-file-vnet-template-
  12. Open storageTemp.json file by clicking it. Click on Raw button. This will open raw version of the code contained in the file without formatting incorporated by GitHub. To use reference to linked templates in our main template, we must refer to the link containing raw code.
    ARM linked template-Github-storage-template-code
  13. Copy web address of the raw content, as shown in the snap.
    ARM linked template-Github-storage-template-code-raw-link
  14. Now switch to VS Code and copy this web address as value of storageTempPath variable.
    ARM linked template-Github-storage-template-uri
  15. Next, open vnetTemp.json file by clicking it. Click on Raw button. This will open raw version of the code contained in the file without formatting incorporated by GitHub.
    ARM linked template-Github-vnet-template-code
  16. Copy web address of the raw content, as shown in the snap.
    ARM linked template-Github-vnet-template-code-raw-link
  17. Now switch to VS Code and copy this web address as value of vnetTempPath variable.
    ARM linked template-Github-vnet-template-uri

How to Deploy an ARM Linked Template

To deploy ARM Linked template to Azure, you only need to deploy main template. Linked templates are deployed automatically from the main template.

Connect to Az Account
  1. Connect to your AZ account from VS Code Terminal window. Make sure that you have an active account with Azure to deploy your solution.
  2. Set context to your subscription.
Create Resource Group
  1. Next, you need to create a resource group for grouping your resources. Type New-AzResourceGroup -Name rg-Linked-Templates -Location centralus to create a new resource group in Central US region (you can choose any location of your choice).
    ARM linked template-deploy-new-resource-group
  2. Next, run following command to set this resource group as default resource group.

Set-AzDefault -ResourceGroupName rg-Linked-Templates
ARM linked template-set-new-resource-group-default

Deploy Main template to Azure

Run following command to create three environment variables.

$templateFile is used to contain path to the JSON main template file.

$todayDate is used to store current date.

$deploymentName is used to assign a name to the deployment. This is created by appending template file name and current date.

Now, run following command to deploy the template using ResourceGroup deployment scope:

Note: Backtick or Tilde (‘) is a line continuation character in Powershell and used to split a long command across multiple lines.
ARM linked template-deploy-main-template

Deployment Result

Great! our ARM template is successfully deployed. You can notice the ProvisioningState: Succeeded message in below snap.
ARM linked template-deploy-main-template-result

Now let’s switch to Azure Portal to verify that our ARM template is successfully deployed. Go to Resource Groups -> rg-Linked-Templates. Click on the rg-Linked-Templates resource group. Then click on Deployments under Settings. You will notice that three new deployments are created. These deployments refer to three templates used in the tutorial namely main template, storage account template & vnet template.
ARM linked template-Azure-portal-new-deployment

Now click on Overview under the same resource group to verify the newly created storage account and virtual network. You can spot a new storage account and virtual network within the resource group.
ARM linked template-Azure-portal-resource-group

Next, click on the storage account. You will observe that it has the same properties as defined by us in ARM template.
ARM linked template-Azure-portal-new-storage-account

Next, click on the virtual network. You will observe that it has the same properties as defined by us in ARM template.
ARM linked template-Azure-portal-new-vnet

Conclusion

Azure Resource Manager (ARM) Linked template provide a great way to modularize our templates for better visibility, manageability and future re-use. Whenever you feel overwhelmed by infrastructure code in a single template, make use of linked templates to split your code.

Share Your Thoughts

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