DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • How To Build AI-Powered Prompt Templates Using the Salesforce Prompt Builder
  • Automated Bug Fixing: From Templates to AI Agents
  • Dynamic File Upload Component in Salesforce LWC
  • Safeguarding Web Applications With Cloud Service Providers: Anti-CSRF Tokenization Best Practices

Trending

  • Rust, WASM, and Edge: Next-Level Performance
  • Monolith: The Good, The Bad and The Ugly
  • Event-Driven Microservices: How Kafka and RabbitMQ Power Scalable Systems
  • How to Create a Successful API Ecosystem

Nested ARM Templates: Modularity and Reuse

Perfect for complex templates or those that you want to reuse, see how to create nested ARM templates for your Azure deployments.

By 
Sam Cogan user avatar
Sam Cogan
·
Updated Oct. 24, 17 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
19.6K Views

Join the DZone community and get the full member experience.

Join For Free

Most example ARM templates use a single JSON file to contain all of the deployment details in a single place. This works fine for smaller deployments, but once you start doing larger deployments, working in teams, or wanting to reuse parts of your deployment templates, then you really need to start looking at nested templates.

Nesting templates describes the process of calling an ARM template from inside another. In this way, you can separate your logic into multiple files, call these files as required, and pass parameters and results between templates. Nesting has been supported in ARM from the beginning, and these nested templates are just treated like another resource.

Modularization

Splitting your template over multiple files can help with readability and organization, but one of the big benefits is modularization and reusability. If there are resources you regularly deploy in a specific configuration, you can wrap them up in their own template and reuse them as required throughout your different solutions.

If you take a look at Microsoft's Best Practices for ARM Templates, it contains the diagram below with a recommended approach to organizing your templates.

Nested template

Image from https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-template-best-practices

This technique allows for reusable templates shared between deployments and provides a shared resource template, which contains resources that are shared between multiple deployments — for example, a virtual network that is deployed and managed by a central function and referenced by this shared resource template.

Nesting Templates

There are two ways to include a nested template:

  • Inline in your main template
  • As separate JSON files called from your main template.

Inline Nesting

Inline nesting is really not something that I would recommend doing except where you have a very simple set of resources in your inline template. Inline testing essentially involves having a second template included inside your first like below:

"resources": [
        {
            "apiVersion": "2017-05-10",
            "name": "nestedTemplate",
            "type": "Microsoft.Resources/deployments",
            "resourceGroup": "crossSubscriptionDeployment",
            "subscriptionId": "623d50f1-4fa8-4e46-a967-a9214aed43ab",
            "properties": {
                "mode": "Incremental",
                "template": {
                    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.0",
                    "parameters": {},
                    "variables": {},
                    "resources": [
                        {
                            "type": "Microsoft.Storage/storageAccounts",
                            "name": "[parameters('StorageAccountName2')]",
                            "apiVersion": "2015-06-15",
                            "location": "West US",
                            "properties": {
                                "accountType": "Standard_LRS"
                            }
                        }
                    ]
                },
                "parameters": {}
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[parameters('StorageAccountName1')]",
            "apiVersion": "2015-06-15",
            "location": "West US",
            "properties": {
                "accountType": "Standard_LRS"
            }
        }
    ]


In this example, we have a resource of type Microsoft.Resources/deployments. This is the resource we use to call a nested template. This resource has a property of “template”, and inside this, we are putting the whole second template. As you can see, this has no benefit for the complexity of the file or for modularizing our work. The only reason you would do this is if something you are doing requires a nested template and you only have a few resources in that template. In this example, we are deploying some resources into a second resource group and subscription. Cross-RG and subscription deployments require the use of a nested template.

Nested Files

Nested files are the way I recommend you go. Here, we will reference a second JSON file from our main template. The nested template, the one you are calling from the main template, is no different from a normal template. You just define your resources as normal. Any information you require from the main template should be set up as parameters.

In your main template, you will again use a Microsoft.Resources/deployments resource, but instead of the template property, we will use templateLink:

  "variables": {
        "templatelink": "https://raw.githubusercontent.com/sam-cogan/Demos/master/DemoExamples/newStorageAccount.json"
    },
    "resources": [
        {
            "apiVersion": "2015-01-01",
            "name": "nestedTemplate",
            "type": "Microsoft.Resources/deployments",
            "properties": {
                "mode": "incremental",
                "templateLink": {
                    "uri": "[variables('templatelink')]",
                    "contentVersion": "1.0.0.0"
                },
                "parameters": {
                    "StorageAccountName": {
                        "value": "[parameters('StorageAccountName')]"
                    }
                }
            }
        }
    ]


As you can see, we are using the templateLink property to pass in a link to my second template file. One thing to be aware of here: The second template file needs to be reachable at deployment time, so this is running inside Azure. As such, it can’t just exist on my local machine — it needs to be hosted somewhere accessible. In this example, I am using GitHub, but you can use any HTTP service. If you want to keep the template secure, the best option is to use Azure Storage with a SAS token.

You can also see here that I am passing in a parameter (StorageAccountName). This will be received by my nested template as a parameter and used in the standard way. Obviously, as you are passing the parameters through from our main template, we need to make sure that all parameter data we need exists in our main template or is, in turn, passed into it as a parameter.

That’s all there is to it. When I want to deploy the template I just run a new-azurermresourcegroupdeployment from PowerShell, or whatever method you usually run the main template with, and provide parameters. It will handle running the nested templates.

Outputs

All ARM templates have an outputs section. In single file templates, this is mainly used to pass values back to the caller (PowerShell, etc.). With nested templates, we can use this to pass values back to the calling, top-level template, which can then be used in this template or even passed to other nested templates.

Creating an output is the same as in a normal template. Here we are passing the full details of the storage account created in the nested template.

"outputs": {
"storageAccountInfo": {
"value": "[reference(concat('Microsoft.Storage/storageAccounts/', parameters('StorageAccountName')),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0])]",
"type" : "object"
}


In the main template, we would then use this by referencing the nested template step and variable name:

"storageAccountInfo": { "value": "[reference('nestedTemplate').outputs.storageAccountInfo.value]" },


Next Steps

Using nested templates, you can become much more organized with your templates and start reusing your common templates throughout your different projects, even providing a library of building blocks that you can share with colleagues

If you are building complex sets of templates, I would very much recommend reading Microsoft’s best practice guidance on designing complex templates.

The examples used in this article, plus more, can be found in my GitHub Repo.

Template Arm (geography) Modularity (networks)

Published at DZone with permission of Sam Cogan, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How To Build AI-Powered Prompt Templates Using the Salesforce Prompt Builder
  • Automated Bug Fixing: From Templates to AI Agents
  • Dynamic File Upload Component in Salesforce LWC
  • Safeguarding Web Applications With Cloud Service Providers: Anti-CSRF Tokenization Best Practices

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!