user1857450
user1857450

Reputation: 561

How to use secureObject or securestring returned from a linked ARM template

How do I use the value of a returned securestring or secureObject that is returned from a linked ARM template?

For example, one child linked template named CreateStorage

  1. creates an Azure storage account
  2. creates blob containers on that account
  3. creates a SAS key for the container
  4. returns the SAS key in the templates outputs section.

e.g. returning SAS in the templates outputs:

"outputs": {
    "createdContainerSas": {
        "type": "string",
        "value": "[concat('https://', variables('storageAccountName'), '.blob.core.windows.net/', variables('containerName'), '?', listServiceSas(variables('storageAccountName'), '2018-07-01', variables('importSasInputs')).serviceSasToken)]"
    }
}

The main template will then add the SAS key to the KeyVault so that it can be used by the rest of the application. The main template gets the value as follows:

"value": "[reference('CreateStorage').outputs.createdContainerSas.value]"

The problem is that currently the SAS key is returned as string meaning that it appears in plain text in the Azure deployments UI.

However, when I change the type of returned object to either securestring or secureObject, then when createdContainerSas.value is called, the follow error is encountered:

{\r\n \"code\": \"InvalidTemplate\",\r\n \"message\": \"Unable to process template language expressions for resource '/subscriptions/<my-subscription-id>/resourceGroups/<my-resource-group>/providers/Microsoft.Resources/deployments/CreateKeyVault' at line '310' and column '9'. 'The language expression property 'value' doesn't exist, available properties are 'type'.'\"\r\n }

So the .value property doesn't seem to exist when returning securestring or secureObject from child linked ARM templates.

The Microsoft docs at https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-templates-outputs say

Output values support the same types as template input parameters.

and both securestring and secureObject are working fine as template input parameters so I must be doing something wrong.

How do I use the value of a returned securestring or secureObject that is returned from a linked ARM template?

Upvotes: 8

Views: 5383

Answers (2)

Jan_V
Jan_V

Reputation: 4406

In addition to the answer of @4c74356b41.

There's also something on this in the Microsoft docs: https://learn.microsoft.com/en-US/azure/azure-resource-manager/templates/data-types#secure-strings-and-objects

Don't use secure strings or objects as output values. If you include a secure value as an output value, the value isn't displayed in the deployment history and can't be retrieved from another template. Instead, save the secure value in a key vault, and pass as a parameter from the key vault.

There's a sample on how to do this also in a getting started page.

"resources": [
    {
      "type": "Microsoft.KeyVault/vaults",
      "apiVersion": "2021-11-01-preview",
      "name": "[parameters('keyVaultName')]",
      "location": "[parameters('location')]",
      "properties": {
        "enabledForDeployment": "[parameters('enabledForDeployment')]",
        "enabledForDiskEncryption": "[parameters('enabledForDiskEncryption')]",
        "enabledForTemplateDeployment": "[parameters('enabledForTemplateDeployment')]",
        "tenantId": "[parameters('tenantId')]",
        "accessPolicies": [
          {
            "objectId": "[parameters('objectId')]",
            "tenantId": "[parameters('tenantId')]",
            "permissions": {
              "keys": "[parameters('keysPermissions')]",
              "secrets": "[parameters('secretsPermissions')]"
            }
          }
        ],
        "sku": {
          "name": "[parameters('skuName')]",
          "family": "A"
        },
        "networkAcls": {
          "defaultAction": "Allow",
          "bypass": "AzureServices"
        }
      }
    },
    {
      "type": "Microsoft.KeyVault/vaults/secrets",
      "apiVersion": "2021-11-01-preview",
      "name": "[format('{0}/{1}', parameters('keyVaultName'), parameters('secretName'))]",
      "properties": {
        "value": "[parameters('secretValue')]"
      },
      "dependsOn": [
        "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]"
      ]
    }

Full source: https://github.com/Azure/azure-quickstart-templates/tree/master/quickstarts/microsoft.keyvault/key-vault-secret-create

Via: https://learn.microsoft.com/en-us/azure/templates/microsoft.keyvault/vaults/secrets?pivots=deployment-language-arm-template

Upvotes: 0

4c74356b41
4c74356b41

Reputation: 72211

secureString\secureObject types are omitted from the input\output. you cannot "get" them. they are just being passed, that's it. That's why the are called secure. They are not being recorded anywhere. No real workaround.

In your case you just pull keys where you need them, you dont have to pull them in the nested template and pass them to the parent template.

Upvotes: 9

Related Questions