Search code examples
azure-storageazure-blob-storageazure-resource-managerazure-rm-template

How can I get the path to an Azure Storage account's Container in ARM template


Question: Given access to the storage account/container resource, how can I generate the URL to the container in my ARM template?

I have an Azure Storage account and blob container that I'm dpeloying by ARM template.

I'm trying to save the SAS URI to write to blob storage in my keyvault.

I've been able to dereference the SAS URI query parameters like so:

  "variables": {
    "accountSasFunctionValues": {
      "signedServices": "bqt",
      "signedPermission": "rlacup",
      "signedResourceTypes": "oc",
      "signedExpiry": "2050-01-01T00:00:00Z"
    }
  },
.
.
.
... "value": "[listAccountSas(parameters('storageAccountName'), '2018-02-01', variables('accountSasFunctionValues')).accountSasToken]"

However I want to prefix this value with a path to the container, so I can just call "PUT" on the URI in a different service with my payload and uplaod it.

Something like "value": "[concat(getUri(concat('Microsoft.Storage/storageAccounts/blobServices/containers/', parameters('storageAccountName'), '/default/mycontainer')), '?', listAccountSas(parameters('storageAccountName'), '2018-02-01', variables('accountSasFunctionValues')).accountSasToken]" - notice the uri is prefixed to the sas uri query param.

We may need to deploy to different Azure Sovereign Clouds, so I don't want to inject the storage account name into an "https://.blob.core.windows.net" string, as the storage host may change per deployment too


Solution

  • I see the reference(...) expression can be used to get some data.

    "outputs": {
        "BlobUri": {
            "value": "[reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))).primaryEndpoints.blob]",
            "type" : "string"
        }
    }
    

    The reference call returns an object like so:

    {
       "creationTime": "2017-10-09T18:55:40.5863736Z",
       "primaryEndpoints": {
         "blob": "https://examplestorage.blob.core.windows.net/",
         "file": "https://examplestorage.file.core.windows.net/",
         "queue": "https://examplestorage.queue.core.windows.net/",
         "table": "https://examplestorage.table.core.windows.net/"
       },
       "primaryLocation": "southcentralus",
       "provisioningState": "Succeeded",
       "statusOfPrimary": "available",
       "supportsHttpsTrafficOnly": false
    }
    

    This gets me the primary endpoint for the blob storage account. I can then get the container endpoint with:

    [concat(reference(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))).primaryEndpoints.blob, 'mycontainer')]