0

I have a bunch of nested ARM templates meant to be deployed using Azure PS.

The only way to do that is to host those templates in a Azure blob container and then generate SAS token and send these 2 parameters in the main ARM template (which points to the nested ones).

Here is my PS that generates the SAS token:

$SasToken = ConvertTo-SecureString -AsPlainText -Force (New-AzureStorageContainerSASToken -Container $StorageContainerName -Context $StorageAccount.Context -Permission r -ExpiryTime (Get-Date).AddHours(4))

Here are 2 parts of my deployment script which pass the token to the main ARM template:

$Parameters['_artifactsLocationSasToken'] = $SasToken

and

New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $TemplateFile).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) `
    -ResourceGroupName $ResourceGroupName `
    -TemplateFile $TemplateFile `
    -TemplateParameterObject $Parameters `
    -Force -Verbose `
    -ErrorVariable ErrorMessages

Here is the declaration for the receiving parameter to the main ARM template:

"_artifactsLocationSasToken": {
      "type": "securestring"
    }

Here is the nested resource template (which happens to be a cosmos db) in the same main ARM template:

{
      "apiVersion": "2017-05-10",
      "dependsOn": [
        "[concat('Microsoft.Resources/deployments/', variables('vnetConfig').Name)]"
      ],
      "name": "[variables('cosmosDbConfig').Name]",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "uri": "[concat(parameters('_artifactsLocation'), '/', variables('nestedTemplatesFolder'), '/cosmosdb.json', parameters('_artifactsLocationSasToken'))]"
        },
        "parameters": {
          "cosmosDbConfig": {
            "value": "[variables('cosmosDbConfig')]"
          }
        }
      },
      "type": "Microsoft.Resources/deployments"
    }

When I run these, I get this error:

Error: Code=InvalidTemplate; Message=Deployment template validation failed: 'The provided value for the template parameter '_artifactsLocationSasToken' at line '16' and column '39' is not valid.'

If I hard code the SAS token in the nested template resource (in main template) and change the type from securestring to string, it just works! What is it that I am missing?

bit
  • 4,407
  • 1
  • 28
  • 50

2 Answers2

0

Seems you missed the uri() in the templateLink, try the one as below, see this sample which also uses securestring.

"templateLink": {
          "uri": "[uri(concat(parameters('_artifactsLocation'), '/', variables('nestedTemplatesFolder'), '/cosmosdb.json', parameters('_artifactsLocationSasToken')))]"
        }
Joy Wang
  • 39,905
  • 3
  • 30
  • 54
0

I have found that you can reproduce this problem i.e. "Template validation failed" when passing a SAS token to an ARM template, as a parameter.

In my case, the SAS token was being used for the "WEBSITE_RUN_FROM_PACKAGE" App Setting of an Azure Function App.

My solution to this problem, was to prefix the value of the SAS token (that I passed from PowerShell, to the ARM template) with something - so that it was no longer a valid URL. For example, if you prefix the SAS token with an underscore and pass that to the ARM template, this problem no longer occurs. You can then strip off the underscore prefix from within the ARM template.

user1793093
  • 129
  • 5