This chapter covers Azure Template Specs, a feature that allows you to store and manage Azure Resource Manager (ARM) templates as versioned, immutable resources within Azure itself. Template Specs are a key part of the Compute domain (Objective 3.4) on the AZ-104 exam, which focuses on deploying and managing infrastructure as code. Approximately 10-15% of exam questions touch on ARM templates and related deployment technologies, with Template Specs appearing in 2-3 questions as a modern alternative to traditional template storage. Understanding Template Specs is critical for demonstrating your ability to implement repeatable, governed deployments in enterprise environments.
Jump to a section
Imagine you are a construction company that builds houses using detailed blueprints. Instead of handing out loose blueprints to each crew, you store them in a central library with a catalog number. When a crew needs to build a house, they check out the blueprint by catalog number—no copying, no version confusion. The library ensures everyone uses the exact same blueprint, and updates are controlled: you revise the master copy, and all future checkouts get the new version. Template Specs work the same way. They are versioned, immutable blueprints stored in a central registry (Azure Resource Manager). Instead of emailing ARM templates or storing them in GitHub, you publish them as Template Specs in a resource group. Any user with read access can deploy them by referencing the spec's resource ID and version. The spec itself is immutable once published; to update, you create a new version. This prevents drift where teams modify templates locally. The library (Template Spec) also tracks who used which version, giving you an audit trail. Just as a blueprint library prevents contractors from using outdated or modified plans, Template Specs enforce governance and repeatability in Azure deployments.
What Are Azure Template Specs?
Azure Template Specs are a resource type (Microsoft.Resources/templateSpecs) that allows you to store ARM templates as versioned, immutable artifacts within Azure. Introduced in 2020, they solve the problem of managing ARM templates outside Azure—in GitHub, storage accounts, or as files—by providing a built-in, governed registry. Each Template Spec can contain one or more versions, and each version is immutable once created (you cannot modify it, only create a new version). This immutability ensures that deployments using a specific version always use the exact same template, eliminating drift.
Why Template Specs Exist
Before Template Specs, teams had to manage ARM templates in external repositories or storage accounts. This led to several problems: - Versioning chaos: Different teams might use different versions of the same template, leading to inconsistent deployments. - Permission sprawl: You had to manage access to storage accounts or Git repos separately from Azure RBAC. - Governance gaps: No built-in way to enforce that only approved templates are used. - Audit difficulty: Tracking which template version was used for a deployment required manual logging.
Template Specs address these by integrating templates directly into Azure Resource Manager, leveraging Azure RBAC for access control, and providing native versioning.
How Template Specs Work Internally
When you create a Template Spec, you define it in a specific Azure region and resource group. The Template Spec resource itself is a container for versions. Each version is a separate sub-resource that contains the ARM template JSON (or Bicep file) and any linked templates. The version is identified by a semantic version string (e.g., "1.0.0").
Internally, Template Specs are stored in Azure Resource Manager's backend, which replicates the data within the region. When you deploy a Template Spec, Azure Resource Manager reads the template from the spec, validates it, and executes the deployment. The deployment is tracked in Azure Activity Log, which records the Template Spec resource ID and version used.
Key Components and Defaults
Template Spec resource: The parent resource, defined with a name, location, and optional display name/description. The resource provider is Microsoft.Resources/templateSpecs.
Template Spec version: A child resource with a version name (e.g., "1.0"), the ARM template JSON (or Bicep file), and optional linked templates packaged as a .zip file. The version name is a string, but best practice is to use semantic versioning.
Immutable versions: Once a version is created, it cannot be changed. To update, you must create a new version.
Maximum template size: The ARM template JSON within a version can be up to 4 MB. Linked templates are packaged into a .zip file that can be up to 4 MB as well.
Maximum number of versions per spec: No documented hard limit, but practical limits apply based on Azure Resource Manager quotas.
RBAC permissions: To create a Template Spec, you need Contributor or Owner on the resource group. To deploy a Template Spec, you need Reader access to the Template Spec (or the resource group containing it) and Contributor on the target resource group.
Configuration and Verification Commands
You can manage Template Specs using the Azure portal, Azure CLI, Azure PowerShell, or ARM API. Below are the key commands:
Create a Template Spec (Azure CLI):
# Create the Template Spec resource (container)
az ts create \
--name MyTemplateSpec \
--resource-group MyResourceGroup \
--location eastus \
--display-name "My Template Spec" \
--description "This is a template spec for web app deployment"
# Create a version from a local ARM template file
az ts version create \
--name MyTemplateSpec \
--resource-group MyResourceGroup \
--version "1.0.0" \
--template-file azuredeploy.jsonDeploy a Template Spec:
az deployment group create \
--resource-group TargetResourceGroup \
--template-spec "/subscriptions/{sub-id}/resourceGroups/MyResourceGroup/providers/Microsoft.Resources/templateSpecs/MyTemplateSpec/versions/1.0.0" \
--parameters "{...}"List versions:
az ts version list --name MyTemplateSpec --resource-group MyResourceGroupDelete a version:
az ts version delete --name MyTemplateSpec --resource-group MyResourceGroup --version "1.0.0"PowerShell equivalents:
# Create Template Spec
New-AzTemplateSpec -Name MyTemplateSpec -ResourceGroupName MyResourceGroup -Location eastus
# Add version
New-AzTemplateSpecVersion -ResourceGroupName MyResourceGroup -TemplateSpecName MyTemplateSpec -Version "1.0.0" -TemplateFile azuredeploy.json
# Deploy
New-AzResourceGroupDeployment -ResourceGroupName TargetResourceGroup -TemplateSpecId "/subscriptions/.../versions/1.0.0"Interaction with Related Technologies
Template Specs integrate with:
- Azure Policy: You can enforce that deployments must use only approved Template Specs via Azure Policy. For example, deny deployments that do not reference a specific Template Spec.
- Azure Blueprints: Blueprints can reference Template Specs as artifacts, allowing you to include governed templates in a blueprint definition.
- Bicep: Bicep files can be published as Template Specs using the bicep build command to generate ARM JSON, then publishing that JSON. Bicep also supports deploying a module directly from a Template Spec.
- Azure DevOps: In CI/CD pipelines, you can use the AzureResourceManagerTemplateDeployment task to deploy a Template Spec version.
- Azure Resource Manager: Template Specs are a first-class resource, meaning you can manage them through ARM, use tags, and apply locks.
Detailed Mechanism of Deployment
When you deploy a Template Spec, Azure Resource Manager performs these steps:
1. Authentication: The user or service principal must have Microsoft.Resources/templateSpecs/read on the Template Spec version, and Microsoft.Resources/deployments/write on the target resource group.
2. Template retrieval: ARM reads the template JSON from the Template Spec version. If the template includes linked templates, those are retrieved from the packaged .zip file.
3. Validation: The template is validated for syntax, resource types, and parameter requirements.
4. Deployment execution: ARM processes the template, creating or updating resources as defined.
5. Audit logging: The deployment is logged in Activity Log with the Template Spec resource ID and version.
Versioning Strategy
Because versions are immutable, you should plan a versioning strategy. Common approaches: - Semantic versioning: Major.Minor.Patch (e.g., 2.1.0). Major changes for breaking changes, minor for new features, patch for fixes. - Date-based: e.g., 2024.01.15. Useful for compliance. - Sequential: e.g., v1, v2. Simple but less informative.
You can also use tags (like "latest") by creating a version with that name, but it's not recommended because tags are not immutable.
Limitations
Regional only: Template Specs are stored in a single region and are not geo-replicated by default. You must manually export and import to another region for disaster recovery.
No cross-subscription deployment directly: The Template Spec must be in the same subscription as the deployment context, but you can deploy across resource groups within the same subscription. For cross-subscription, you need to use a linked template or a deployment script.
No built-in UI: Unlike Azure Quickstart Templates, there is no gallery UI for Template Specs; you must use CLI, PowerShell, or portal.
Exam Relevance
On the AZ-104 exam, you may be asked to:
Identify the correct way to create a Template Spec version.
Understand that Template Specs provide immutable versioning.
Know that Template Specs can be used with Azure Policy to enforce governance.
Differentiate between Template Specs and other template storage methods (e.g., storage account, GitHub).
Recognize that Template Specs support linked templates packaged as a .zip file.
Summary of Key Points
Template Specs store ARM templates as versioned, immutable resources in Azure.
Each version is immutable; updates require creating a new version.
Access is controlled via Azure RBAC.
Linked templates can be included in a .zip file.
Template Specs integrate with Azure Policy, Blueprints, Bicep, and DevOps.
Maximum template size is 4 MB per version.
Template Specs are regional; no built-in geo-replication.
Create the Template Spec Container
First, you create the Template Spec resource itself, which acts as a container for versions. This is done in a resource group that will hold the spec. You must specify a name, location (Azure region), and optionally a display name and description. The resource provider is Microsoft.Resources/templateSpecs. At this point, no template is stored; you are just creating the logical container. For exam purposes, remember that the Template Spec resource itself does not contain a template—it is just a placeholder for versions.
Publish a Template Spec Version
Next, you publish a version of the template. This is a child resource under the Template Spec container. You provide a version name (string, often semantic), and the ARM template JSON file. If the template references linked templates, you package them into a .zip file and upload that. The version is immutable—once created, you cannot modify it. Any changes require a new version. The maximum size for the template JSON is 4 MB, and the .zip file for linked templates is also limited to 4 MB. The version name is not automatically incremented; you must specify it explicitly.
Assign RBAC Permissions
Before others can deploy the Template Spec, you must grant them appropriate permissions. To deploy a Template Spec, a user needs at least Reader role on the Template Spec (or the resource group containing it) and Contributor (or Owner) on the target resource group where resources will be created. The Reader permission allows them to read the template content, which is necessary for ARM to retrieve it during deployment. You can also grant permissions at the subscription level. For exam, know that the minimum deployment permission is Reader on the spec and Contributor on the target resource group.
Deploy the Template Spec
To deploy, you reference the Template Spec version by its full resource ID. The deployment command (az deployment group create or New-AzResourceGroupDeployment) uses the --template-spec parameter instead of --template-file. ARM then retrieves the template from the spec, validates it, and creates the resources in the target resource group. The deployment is logged in Activity Log with the Template Spec ID and version. You can pass parameters just like a regular ARM template deployment. The deployment itself is a standard ARM deployment, so you can use all the usual features like output, dependsOn, etc.
Manage and Audit Versions
Over time, you will create multiple versions of a Template Spec. You can list all versions using CLI or PowerShell. Each version is immutable, so you cannot delete a version that is currently in use by a deployment (though there is no hard enforcement—you can delete it, but existing deployments will still reference it in logs). To update, you create a new version. You can also use Azure Policy to audit or enforce that deployments use only specific versions. Activity Log records all deployments, including the Template Spec version used, providing a full audit trail.
Enterprise Scenario 1: Centralized Governance for Multi-Team Deployments
A large enterprise with multiple development teams uses Template Specs to enforce standardized infrastructure. The cloud center of excellence (CCoE) publishes approved ARM templates for common workloads (e.g., web apps, VMs, databases) as Template Specs in a central resource group. Each team has Reader access to the specs and Contributor access to their own resource groups. When a team needs to deploy a web app, they use the approved spec version 2.1.0. This ensures all web apps follow security baselines (e.g., mandatory NSG rules, encryption). If a team tries to deploy a custom template, Azure Policy denies it unless it references an approved Template Spec. The CCoE updates the spec to version 2.2.0 with new compliance requirements; teams slowly migrate by changing their deployment scripts to reference the new version. This prevents drift and reduces audit findings. Performance is not an issue because Template Specs are lightweight; the bottleneck is the deployment itself. Misconfiguration occurs when teams are granted too broad permissions (e.g., Contributor on the spec resource group), allowing them to create their own versions, defeating governance.
Enterprise Scenario 2: Disaster Recovery with Regional Template Specs
A financial services company uses Template Specs to store disaster recovery (DR) templates. They have two Azure regions: primary (East US) and DR (West US). They create identical Template Specs in both regions, each containing the same versions. In the primary region, they deploy the spec version 1.0.0 to production. For DR, they have a runbook that deploys the same spec version from the West US spec. Because Template Specs are regional, they must manually synchronize versions between regions. They use Azure DevOps pipelines to publish new versions to both regions simultaneously. A common mistake is assuming Template Specs are geo-replicated—they are not. During a regional outage, if the primary spec is unavailable, the DR region spec must be created beforehand. They also use Azure Policy to ensure that all deployments use the spec from the correct region based on the deployment location.
Scenario 3: Compliance Auditing for Regulated Industries
A healthcare organization needs to prove that all deployments use approved templates. They use Template Specs exclusively and disable the ability to deploy raw ARM templates via Azure Policy (deny deployment if templateLink is not a Template Spec). Each deployment is logged with the spec version. Auditors can query Activity Log to see which version was used for each resource group. The organization uses a versioning scheme like YYYY.MM.DD.REV (e.g., 2024.03.15.2). When a compliance update is required, they publish a new version and update policy to require the latest version. This ensures all new deployments use the updated template. A common pitfall is forgetting to update existing deployments—the policy only affects new deployments, not existing ones. They must also ensure that the Template Specs themselves are backed up, as they are not automatically replicated.
What AZ-104 Tests on Template Specs
The AZ-104 exam objective 3.4 includes deploying and managing infrastructure as code using ARM templates. Template Specs are specifically tested as a method to store and share templates. Expect 2-3 questions that may ask:
How to create a Template Spec version (using CLI, PowerShell, or portal).
The immutability of versions.
The minimum permissions required to deploy a Template Spec.
How Template Specs differ from storing templates in a storage account or GitHub.
Integration with Azure Policy.
Common Wrong Answers and Why Candidates Choose Them
Wrong Answer 1: "You can update a Template Spec version by editing the template JSON." - Why chosen: Candidates are used to editing files; they forget that versions are immutable. - Reality: You cannot modify a version; you must create a new version.
Wrong Answer 2: "Template Specs are automatically geo-replicated." - Why chosen: Many Azure resources like storage accounts offer geo-redundancy; candidates assume Template Specs do too. - Reality: Template Specs are regional. You must manually export and import to another region.
Wrong Answer 3: "To deploy a Template Spec, you need Contributor on the Template Spec." - Why chosen: Candidates think you need write permissions to use it. - Reality: You only need Reader on the Template Spec; Contributor on the target resource group is sufficient.
Wrong Answer 4: "Template Specs can contain multiple templates in one version." - Why chosen: Candidates confuse versions with multiple templates. - Reality: Each version contains exactly one ARM template (plus linked templates in a .zip).
Specific Numbers and Terms on the Exam
Maximum template size: 4 MB
Version immutability: versions cannot be changed after creation
RBAC: Reader on spec, Contributor on target RG
Resource provider: Microsoft.Resources/templateSpecs
Linked templates: packaged as .zip
CLI command: az ts version create
Edge Cases and Exceptions
You can delete a version even if it is referenced by active deployments, but those deployments still appear in logs.
Template Specs can be exported as ARM templates using the portal's "Export template" feature, but that exports the spec definition, not the version content directly.
If you use Bicep, you can publish a Bicep file as a Template Spec by first building it to ARM JSON.
Template Specs support tags at the resource level, but not at the version level.
How to Eliminate Wrong Answers
Focus on the concept of immutability: any answer suggesting modification of an existing version is wrong. For permissions, remember the principle of least privilege: Reader is enough to read the template. For geo-replication, note that only the spec is regional; the template is not automatically copied. When in doubt, think about governance: Template Specs are designed for control and audit, so answers that suggest flexibility (like editing versions) are likely incorrect.
Template Specs store ARM templates as versioned, immutable resources in Azure.
Each version is immutable; to update, create a new version.
Minimum deployment permissions: Reader on Template Spec, Contributor on target resource group.
Linked templates must be packaged as a .zip file within the version (max 4 MB).
Template Specs are regional; no automatic geo-replication.
Use Azure CLI command 'az ts version create' to publish a version.
Template Specs can be enforced via Azure Policy to ensure governance.
The resource provider is Microsoft.Resources/templateSpecs.
These come up on the exam all the time. Here's how to tell them apart.
Template Specs
Versioned and immutable; each version is a separate resource.
Integrated with Azure RBAC; no separate SAS tokens needed.
Native integration with Azure Policy and Blueprints.
Maximum template size 4 MB per version.
Cannot be used directly with Azure DevOps unless via ARM task.
Storage Account for Templates
No built-in versioning; you must manage versions manually (e.g., folders or file names).
Access via SAS tokens or public access; more complex permission management.
No direct integration with Azure Policy; requires custom policies.
Maximum file size depends on storage account limits (e.g., 2 TB per file).
Easier to use in DevOps pipelines with direct file references.
Mistake
Template Spec versions can be updated after creation.
Correct
Template Spec versions are immutable. Once a version is created, you cannot modify it. To update, you must create a new version with a different version name.
Mistake
Template Specs are automatically geo-replicated.
Correct
Template Specs are stored in a single Azure region. There is no built-in geo-replication. You must manually export and import them to another region for disaster recovery.
Mistake
You need Contributor permissions on the Template Spec to deploy it.
Correct
To deploy a Template Spec, you only need Reader permissions on the Template Spec (or its resource group). Contributor permissions are required on the target resource group where resources will be created.
Mistake
A single Template Spec version can contain multiple ARM templates.
Correct
Each Template Spec version contains exactly one ARM template. However, that template can reference linked templates, which are packaged as a .zip file within the version.
Mistake
Template Specs can only be created using the Azure portal.
Correct
Template Specs can be created and managed using the Azure portal, Azure CLI, Azure PowerShell, and REST API. The CLI and PowerShell are commonly tested on the exam.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
No. Template Spec versions are immutable. Once a version is created, you cannot change it. If you need to update the template, you must create a new version with a different version name (e.g., increment from 1.0.0 to 1.0.1). This ensures that deployments using a specific version are always consistent.
To deploy a Template Spec, you need at least Reader permissions on the Template Spec resource (or the resource group containing it) and Contributor permissions on the target resource group where the resources will be created. The Reader permission allows Azure Resource Manager to read the template content from the spec during deployment.
When creating a Template Spec version, you can package linked templates into a .zip file and upload it along with the main template. The main template should reference the linked templates using relative paths. The .zip file size is limited to 4 MB. Use the --linked-templates parameter in Azure CLI or the -LinkedTemplateArtifactUri parameter in PowerShell.
No. Template Specs are stored in a single Azure region. They are not automatically replicated to other regions. For disaster recovery, you must manually create the same Template Spec in multiple regions and synchronize versions across them using automation.
Yes. You can compile a Bicep file to ARM JSON using `bicep build` and then publish the resulting JSON as a Template Spec version. Additionally, Bicep supports deploying modules directly from a Template Spec using the `module` keyword with the spec's resource ID.
You can create an Azure Policy that denies deployments unless they reference an approved Template Spec. For example, a policy can check the `templateLink` property in the deployment and ensure it matches a specific Template Spec resource ID. This prevents users from deploying arbitrary ARM templates.
You can delete a version even if it is referenced by active deployments. However, existing deployments will still appear in the Activity Log with the version information. New deployments will fail if they reference the deleted version. It is best practice to only delete versions that are no longer in use.
You've just covered Azure Template Specs — now see how well it sticks with free AZ-104 practice questions. Full explanations included, no account needed.
Done with this chapter?