Create and publish a template spec

Completed

Let's look at how you create and publish a template spec.

Create a template

To create a template for use as a template spec, you write an Azure Resource Manager template (ARM template) just like you normally do. You can include parameters, variables, resources, and outputs.

You might use linked templates, which enable you to define parts of your deployment in separate files. When you work with template specs, linked templates can be embedded into the template spec and referenced from your main template.

It's important that your template is easy for anyone in your organization to understand and use, especially its parameters. Make sure you use clear and understandable parameter names. Use parameter properties and template metadata to provide information about the values that you expect your parameters to include, like in this example:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "environmentType": {
      "type": "string",
      "allowedValues": [
        "Production",
        "NonProduction"
      ],
      "metadata": {
        "description": "The type of the environment to deploy. This will determine the SKUs and cost of the resources."
      }
    },
    "key": {
      "type": "secureString",
      "metadata": {
        "description": "The secret key to use."
      }
    },
    "location": {
      "type": "string",
      "metadata": {
        "description": "The Azure region into which the resources should be deployed."
      }
    },
    "sqlServerCount": {
      "type": "int",
      "maxValue": 5,
      "metadata": {
        "description": "The number of Azure SQL logical servers to create."
      }
    }
  },
  "resources": []
}

In the example, the template parameters use the allowedValues, maxValue, and description properties to make clear what the parameters are for and what the effect of setting their values is. The template also includes the secureString type to indicate that the key parameter contains secret data.

It's important that your template is easy for anyone in your organization to understand and use, especially the parameters. Make sure you use clear and understandable parameter names. Use parameter decorators to provide information about the values that you expect your parameters to include, like in this example:

@description('The type of the environment to deploy. This will determine the SKUs and cost of the resources.')
@allowed([
  'Production'
  'NonProduction'
])
param environmentType string

@secure()
@description('The secret key to use.')
param key string

@description('The Azure region into which the resources should be deployed.')
param location string

@description('The number of Azure SQL logical servers to create.')
@maxValue(5)
param sqlServerCount int

In the example, the template parameters use the @allowed, @maxValue, and @description decorators to make clear what the parameters are for and what the effect of setting their values is. The template also includes the secure decorator to indicate that the key parameter contains secret data.

When someone deploys a template spec by using the Azure portal, the portal:

  • Shows the parameter name and description.
  • Hides the text entry for secure parameters.
  • Enforces the allowed values, length limits, and value limits that you define.

This screenshot illustrates the entry of parameter values:

Screenshot that shows the Azure portal interface for entering parameter values for a template spec deployment.

It's important to think about how users use your template spec, and ensure that your parameters are clear and understandable.

Publish the template spec to Azure

After your template is written, instead of submitting the template to Azure for deployment, you publish the template spec.

Important

When you publish a Bicep file as a template spec, your Bicep code is converted to a JSON template. The process of converting your Bicep code to JSON removes some of the information in your Bicep file. For example, your comments, symbolic names for resources, and the order in which you define your resources might be missing or different in JSON. This means you can't easily publish a Bicep file as a template spec and then get the original Bicep file back (also called roundtripping). It's a good idea to keep a copy of your original Bicep code in a code repository like Git, especially when you work with template specs.

To create a template spec, use the New-AzTemplateSpec cmdlet. The following example shows how you can create a template spec for your storage account template:

New-AzTemplateSpec `
  -Name StorageWithoutSAS `
  -Location westus `
  -DisplayName 'Storage account with SAS disabled' `
  -Description 'This template spec creates a storage account, which is preconfigured to disable SAS authentication.' `
  -Version '1.0' `
  -TemplateFile main.bicep
New-AzTemplateSpec `
  -Name StorageWithoutSAS `
  -Location westus `
  -DisplayName 'Storage account with SAS disabled' `
  -Description 'This template spec creates a storage account, which is preconfigured to disable SAS authentication.' `
  -Version '1.0' `
  -TemplateFile azuredeploy.json

Let's look at each of the parameters:

  • -Name is the resource name of the template spec, which can't include spaces.
  • -Location is the location in which the template spec metadata should be created. You can deploy the template spec into any region though.
  • -DisplayName is a human-readable name, which can include spaces.
  • -Description is a human-readable description, which you can use to provide detail about the contents of the template spec and when someone might use it.
  • -Version is the version of the template spec. You learn about versions later in this module.
  • -TemplateFile is the path to the ARM template to create the template spec for.

To create a template spec, use the az ts create command. The following example shows how you can create a template spec for your storage account template:

az ts create \
  --name StorageWithoutSAS \
  --location westus \
  --display-name "Storage account with SAS disabled" \
  --description "This template spec creates a storage account, which is preconfigured to disable SAS authentication." \
  --version 1.0 \
  --template-file main.bicep
az ts create \
  --name StorageWithoutSAS \
  --location westus \
  --display-name "Storage account with SAS disabled" \
  --description "This template spec creates a storage account, which is preconfigured to disable SAS authentication." \
  --version 1.0 \
  --template-file azuredeploy.json

Let's look at each of the arguments:

  • --name is the resource name of the template spec, which can't include spaces.
  • --location is the location in which the template spec metadata should be created. You can deploy the template spec into any region though.
  • --display-name is a human-readable name, which can include spaces.
  • --description is a human-readable description, which you can use to provide detail about the contents of the template spec and when someone might use it.
  • --version is the version of the template spec. You learn about versions later in this module.
  • --template-file is the path to the ARM template to create the template spec for.

Tip

You can also define a template spec within an ARM template! Because a template spec is itself an Azure resource, you can deploy a template that defines a resource with the type Microsoft.Deployments/templateSpecs.