One of the main challenges when setting up Linked ARM templates is how to store the templates so that they are accessible by ARM without making them completely public. Microsoft recommends storing the templates in an Azure Storage Account and securing them with a SAS token. Shared Access Signature (SAS) tokens provide secure access to Azure Storage Account. The scope of the access can be limited to the account, containers, or objects. You can read more about SAS tokens here.
Until recently, one had to either use a Powershell script or a Copy to blob storage in Devops. However, you can now use the linkAccountSas function within the ARM template itself. You can set the SAS token properties based on the access you want to give. Below are some common properties:
utcNow('u')
function to dynamically create the expiration dateYou can also add other properties like signedIP to restrict access by IP address or range.
See below for an example:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"LinkedTemplateBaseUrl": {
"type": "string",
"metadata": {
"description": "Base url for the linked templates"
}
},
"StorageAccountName": {
"type": "string",
"metadata": {
"description": "Storage account for the linked templates"
}
},
"CurrentTime": {
"type": "string",
"defaultValue": "[utcNow('u')]"
}
},
"variables": {
"SasTokenProperties": {
"signedServices": "b",
"signedPermission": "r",
"signedExpiry": "[dateTimeAdd(parameters('CurrentTime'), 'PT30M')]",
"signedResourceTypes": "o"
}
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2020-10-01",
"name": "templateDeployment",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[concat(parameters('LinkedTemplateBaseUrl'), '/yetanother.template.json?', listAccountSas(resourceId('Microsoft.Storage/storageAccounts', parameters('StorageAccountName')), '2020-10-01', variables('SasTokenProperties')).accountSasToken)]",
"contentVersion": "1.0.0.0"
},
"parametersLink": {
"uri": "[concat(parameters('LinkedTemplateBaseUrl'), '/yetanother.parameters.json?', listAccountSas(resourceId('Microsoft.Storage/storageAccounts', parameters('StorageAccountName')), '2020-10-01', variables('SasTokenProperties')).accountSasToken)]",
"contentVersion": "1.0.0.0"
}
}
}
]
}