Dynamically pass a SAS token into your ARM template via PowerShell

There are scenarios where you may need to pass an Azure Storage Shared Access Signature (SAS) token into your Azure Resource Manager (ARM) template. For example, you might want to deploy an App Service with Application and/or Web Server diagnostic logs set to log to Blob Storage, or you might want to deploy site content as a blob to App Service via the MSDeploy ARM extension.


Since your blobs might contain sensitive information, storing the SAS token in your template file or even in your parameters file can pose a security risk. Nor do you want to manually enter the sas token during deployment because this would defeat the purpose of automated deployment.


Instead, you can dynamically generate the sas token and then pass it in as a secure string parameter when you run your ARM deployment script.


Below is an example of how to do this with ARM PowerShell. These steps assume that you are already authenticated with your Azure account (ie your Service Principal) that has authorization to get Storage keys & deploy your resources, Essentially, the process is as follows:

  1. Get one of the Storage keys via Get-AzureRmStorageAccountKey .
  2. Generate a SAS token (in this example, via New-AzureStorageContainerSASToken ).
  3. Convert the SAS token to a Secure String. For simplicity in the below example, I converted the entire constructed SasURL (which contains the SAS token) to Secure String. The reason we convert to Secure String is to conceal the value during deployment.
  4. Pass the SAS token (or in this example, the SAS URL for simplicity) into New-AzureRmResourceGroupDeployment as a parameter (separate from your parameters file).
  5. In your ARM template, create a parameter with a name that matches the name of the secure string parameter you are passing into New-AzureRmResourceGroupDeployment. In your ARM template, make sure to set this parameter type as SecureString.




$TemplateFile = "C:\myfakepath\template.json"; $TemplateParameterFile = "C:\myfakepath\template.parameters.json"; $ResourceGroupName = "MyFakeResourceGroup"; $storageAccountName = "MyFakeStorageAccount"; $Container = "myfakecontainer"; <# In this example we are using the primary Storage key to generate the sas token, but you can use the secondary Storage key if you choose to #> $storageKey0 = (Get-AzureRmStorageAccountKey -AccountName $storageAccountName -ResourceGroupName $ResourceGroupName).Value[0]; $context = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageKey0; $sasTokenPlain = New-AzureStorageContainerSASToken -Context $context -Container $Container -Permission "rwd"; $SasUrlPlain = "https://$storageAccountName.blob.core.windows.net/$Container$sasTokenPlain"; <# converting the sasURL to secure string. Be sure to define the sasUrl parameter in your template as a SecureString #> $SasUrl = ConvertTo-SecureString $SasUrlPlain -AsPlainText -Force; <# For more info about New-AzureStorageContainerSASToken, see the following documentation: https://docs.microsoft.com/en-us/powershell/module/azure.storage/new-azurestoragecontainersastoken?view=azurermps-6.4.0 #>   $OptionalParameters = New-Object -TypeName Hashtable; $OptionalParameters['sasUrl'] = $SasUrl; $DeploymentName = "myfakedeployment"; New-AzureRmResourceGroupDeployment -Name $DeploymentName -ResourceGroupName $ResourceGroupName -TemplateFile $TemplateFile -TemplateParameterFile $TemplateParameterFile @OptionalParameters;

Abbreviated template snippet:

"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "", "parameters": { "siteName": { "type": "String" }, "sasUrl": { "type": "SecureString" } } "resources": [ { "type": "Microsoft.Web/sites/config", "name": "[concat(parameters('siteName'), '/logs')]", "httpLogs": { "azureBlobStorage": { "sasUrl": "[parameters('sasUrl')]", "retentionInDays": 1, "enabled": true } },