Quickstart: Create and deploy a template spec with Bicep

This quickstart describes how to create and deploy a template spec with a Bicep file. A template spec is deployed to a resource group so that people in your organization can deploy resources in Microsoft Azure. Template specs let you share deployment templates without needing to give users access to change the Bicep file. This template spec example uses a Bicep file to deploy a storage account.

When you create a template spec, the Bicep file is transpiled into JavaScript Object Notation (JSON). The template spec uses JSON to deploy Azure resources. Currently, you can't use the Microsoft Azure portal to import a Bicep file and create a template spec resource.

Prerequisites

Create Bicep file

You create a template spec from a local Bicep file. Copy the following sample and save it to your computer as main.bicep. The examples use the path C:\templates\main.bicep. You can use a different path, but you'll need to change the commands.

The following Bicep file is used in the PowerShell and CLI tabs. The Bicep file tab uses a different template that combines Bicep and JSON to create and deploy a template spec.

@allowed([
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GRS'
  'Standard_GZRS'
  'Standard_LRS'
  'Standard_RAGRS'
  'Standard_RAGZRS'
  'Standard_ZRS'
])
@description('Storage account type.')
param storageAccountType string = 'Standard_LRS'

@description('Location for all resources.')
param location string = resourceGroup().location

var storageAccountName = 'storage${uniqueString(resourceGroup().id)}'

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: storageAccountType
  }
  kind: 'StorageV2'
  properties: {}
}

output storageAccountNameOutput string = storageAccount.name

Create template spec

The template spec is a resource type named Microsoft.Resources/templateSpecs. To create a template spec, use Azure CLI, Azure PowerShell, or a Bicep file.

This example uses the resource group name templateSpecRG. You can use a different name, but you'll need to change the commands.

  1. Create a new resource group to contain the template spec.

    New-AzResourceGroup `
      -Name templateSpecRG `
      -Location westus2
    
  2. Create the template spec in that resource group. Give the new template spec the name storageSpec.

    New-AzTemplateSpec `
      -Name storageSpec `
      -Version "1.0" `
      -ResourceGroupName templateSpecRG `
      -Location westus2 `
      -TemplateFile "C:\templates\main.bicep"
    

Deploy template spec

Use the template spec to deploy a storage account. This example uses the resource group name storageRG. You can use a different name, but you'll need to change the commands.

  1. Create a resource group to contain the new storage account.

    New-AzResourceGroup `
      -Name storageRG `
      -Location westus2
    
  2. Get the resource ID of the template spec.

    $id = (Get-AzTemplateSpec -ResourceGroupName templateSpecRG -Name storageSpec -Version "1.0").Versions.Id
    
  3. Deploy the template spec.

    New-AzResourceGroupDeployment `
      -TemplateSpecId $id `
      -ResourceGroupName storageRG
    
  4. You provide parameters exactly as you would for a Bicep file deployment. Redeploy the template spec with a parameter for the storage account type.

    New-AzResourceGroupDeployment `
      -TemplateSpecId $id `
      -ResourceGroupName storageRG `
      -storageAccountType Standard_GRS
    

Grant access

If you want to let other users in your organization deploy your template spec, you need to grant them read access. You can assign the Reader role to a Microsoft Entra group for the resource group that contains template specs you want to share. For more information, see Tutorial: Grant a group access to Azure resources using Azure PowerShell.

Update Bicep file

After the template spec was created, you decided to update the Bicep file. To continue with the examples in the PowerShell or CLI tabs, copy the sample and replace your main.bicep file.

The parameter storageNamePrefix specifies a prefix value for the storage account name. The storageAccountName variable concatenates the prefix with a unique string.

@allowed([
  'Premium_LRS'
  'Premium_ZRS'
  'Standard_GRS'
  'Standard_GZRS'
  'Standard_LRS'
  'Standard_RAGRS'
  'Standard_RAGZRS'
  'Standard_ZRS'
])
@description('Storage account type.')
param storageAccountType string = 'Standard_LRS'

@description('Location for all resources.')
param location string = resourceGroup().location

@maxLength(11)
@description('The storage account name prefix.')
param storageNamePrefix string = 'storage'

var storageAccountName = '${toLower(storageNamePrefix)}${uniqueString(resourceGroup().id)}'

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: storageAccountType
  }
  kind: 'StorageV2'
  properties: {}
}

output storageAccountNameOutput string = storageAccount.name

Update template spec version

Rather than create a new template spec for the revised template, add a new version named 2.0 to the existing template spec. Users can choose to deploy either version.

  1. Create a new version of the template spec.

    New-AzTemplateSpec `
      -Name storageSpec `
      -Version "2.0" `
      -ResourceGroupName templateSpecRG `
      -Location westus2 `
      -TemplateFile "C:\templates\main.bicep"
    
  2. To deploy the new version, get the resource ID for the 2.0 version.

    $id = (Get-AzTemplateSpec -ResourceGroupName templateSpecRG -Name storageSpec -Version "2.0").Versions.Id
    
  3. Deploy the new version and use the storageNamePrefix to specify a prefix for the storage account name.

    New-AzResourceGroupDeployment `
      -TemplateSpecId $id `
      -ResourceGroupName storageRG `
      -storageNamePrefix "demo"
    

Clean up resources

To clean up the resources you deployed in this quickstart, delete both resource groups. The resource group, template specs, and storage accounts will be deleted.

Use Azure PowerShell or Azure CLI to delete the resource groups.

Remove-AzResourceGroup -Name "templateSpecRG"

Remove-AzResourceGroup -Name "storageRG"
az group delete --name templateSpecRG

az group delete --name storageRG

Next steps