A template spec is used to store your Azure Resource Manager (ARM) templates securely in Azure environment. Microsoft.Resources/templateSpecs is the resource type for template specs.
Using template specs you can share ARM templates with users in your organization. They also support versioning which we will see later in this post.
Why to use template specs?
Suppose you are working on Infrastructure development using ARM templates in your organization. There are several issues when trying to share these templates with other teams. If the templates are stored in a repository or storage account, users won't be able to access it unless they have required permissions. Even if permission is granted users will deploy using their own local version of templates which can eventually become outdated as you keep on updating the template.
Template Specs in Azure are protected by Azure Role-Based Access Control (RBAC). So you can securely store the templates in a resource group and control access using RBAC in Azure itself. When the reference architectures in your organization change over time, you can update the template specs with newer versions.
Create a new template spec with linked template
When you create a template spec, you just pass the main template file to the CLI commands. If there are linked templates referenced inside the main template file, those will be packaged together with the main template in a single template spec resource.
Create a main template named azuredeploy.json
with the following JSON in your working directory:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appServicePlanName": {
"type": "string",
"metadata": {
"description": "Enter a name for app service plan"
}
},
"appServiceName": {
"type": "string",
"metadata": {
"description": "Enter a name for app service"
}
}
},
"functions": [],
"variables": {},
"resources": [
{
"name": "webappDeployment",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2020-06-01",
"properties": {
"mode": "Incremental",
"templateLink": {
"relativePath": "artifacts/webapp.json"
},
"parameters": {
"appServicePlanName": {
"value": "[parameters('appServicePlanName')]"
},
"appServiceName": {
"value": "[parameters('appServiceName')]"
}
}
}
}
],
"outputs": {}
}
Note the deployment resource in above template references a linked template webapp.json
. We will create this linked template next.
In your working directory create a new directory named artifacts
and create a template named webapp.json
inside the directory with the following JSON:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appServicePlanName": {
"type": "string",
"metadata": {
"description": "Name of app service plan"
}
},
"appServiceName": {
"type": "string",
"metadata": {
"description": "Name of app service"
}
}
},
"functions": [],
"variables": {},
"resources": [
{
"name": "[parameters('appServicePlanName')]",
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2019-08-01",
"kind": "app",
"location": "[resourceGroup().location]",
"sku": {
"name": "S1"
}
},
{
"name": "[parameters('appServiceName')]",
"type": "Microsoft.Web/sites",
"apiVersion": "2019-08-01",
"kind": "app",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]"
],
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')]"
}
}
],
"outputs": {}
}
Deploy the template spec
To deploy the template spec, you can use various Azure tools like PowerShell, Azure CLI, Azure portal, REST, and other supported SDKs and clients. We will use Powershell to deploy our template spec.
Open a Powershell terminal in your working directory and run the following Powershell cmdlets to create a new resource group:
$rg = "TemplateSpecsRG"
New-AzResourceGroup `
-Name $rg `
-Location eastus
Then run the New-AzTemplateSpec
cmdlet to create a new template spec based on the above templates:
New-AzTemplateSpec `
-Name webappSpec `
-Version "1.0" `
-ResourceGroupName $rg `
-Location eastus `
-TemplateFile "azuredeploy.json"
When the cmdlet executes successfully, you can view the deployed spec using Get-AzTemplateSpec
cmdlet:
> Get-AzTemplateSpec -ResourceGroupName $rg -Name webappSpec
Id : /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/TemplateSpecsRG/providers/Microsoft.Resou
rces/templateSpecs/webappSpec
Name : webappSpec
ResourceGroupName : TemplateSpecsRG
SubscriptionId : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Location : eastus
Versions : 1.0
CreationTime(UTC) : 2/17/2021 5:42:57 AM
LastModifiedTime(UTC) : 2/17/2021 5:43:02 AM
In the portal too, you can navigate to the resource group and view the template spec resource:
When you go to the template spec resource screen, you can find that it contains a main template and the linked template that we deployed. Note that the version you entered is also displayed as Latest Version.
You can also drill down on the templates and see the content in the portal itself.
Modify the template spec
Now suppose the architecture gets updated and a new storage account needs to be added along with the web app. We will modify the existing template spec to add a new storage account as a linked template.
Modify the azuredeploy.json
file and add a new deployment resource. The modified template should like as below:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appServicePlanName": {
"type": "string",
"metadata": {
"description": "Enter a name for app service plan"
}
},
"appServiceName": {
"type": "string",
"metadata": {
"description": "Enter a name for app service"
}
},
"storageAccountName": {
"type": "string",
"metadata": {
"description": "Enter a name for storage account"
}
},
"storageAccountType": {
"type": "string",
"defaultValue": "Standard_LRS",
"metadata": {
"description": "Specify the storage account type"
}
}
},
"functions": [],
"variables": {},
"resources": [
{
"name": "webappDeployment",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2020-06-01",
"properties": {
"mode": "Incremental",
"templateLink": {
"relativePath": "artifacts/webapp.json"
},
"parameters": {
"appServicePlanName": {
"value": "[parameters('appServicePlanName')]"
},
"appServiceName": {
"value": "[parameters('appServiceName')]"
}
}
}
},
{
"name": "storageAccountDeployment",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2020-06-01",
"properties": {
"mode": "Incremental",
"templateLink": {
"relativePath": "artifacts/storageAccount.json"
},
"parameters": {
"storageAccountName": {
"value": "[parameters('storageAccountName')]"
},
"storageAccountType": {
"value": "[parameters('storageAccountType')]"
}
}
}
}
],
"outputs": {}
}
Create a new template storageAccount.json
in the artifacts
directory with the following JSON:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountName": {
"type": "string",
"metadata": {
"description": "Storage Account Name"
}
},
"storageAccountType": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_ZRS",
"Premium_LRS"
],
"metadata": {
"description": "Storage Account type"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-04-01",
"name": "[parameters('storageAccountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "[parameters('storageAccountType')]"
},
"kind": "StorageV2",
"properties": {}
}
],
"outputs": {}
}
Now re-deploy the template spec with a newer Version
:
New-AzTemplateSpec `
-Name webappSpec `
-Version "1.1" `
-ResourceGroupName $rg `
-Location eastus `
-TemplateFile "azuredeploy.json"
If you enter the same version as the previous one, it will overwrite the template spec. You can either update the existing version or publish a new version as needed.
Now when you run the Get-AzTemplateSpec
cmdlet, you can see two versions for your template spec in the output:
> Get-AzTemplateSpec -ResourceGroupName $rg -Name webappSpec
Id : /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/TemplateSpecsRG/providers/Microsoft.Resou
rces/templateSpecs/webappSpec
Name : webappSpec
ResourceGroupName : TemplateSpecsRG
SubscriptionId : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Location : eastus
Versions : {1.0, 1.1}
CreationTime(UTC) : 2/17/2021 5:42:57 AM
LastModifiedTime(UTC) : 2/17/2021 6:00:07 AM
After the cmdlet executes, verify that the Latest Version is updated in the portal and a new artifact storageAccount.json
is added to the template spec
This way you can develop and share ARM templates quickly with the users in your organization.
You can also refer to the below Youtube video on Microsoft Azure channel.
Start leveraging template specs right away!
Top comments (0)