4

I am trying to deploy Redis with the help of the ARM template listed below - and then return its primary key (the secret string available in Azure portal for Redis under "Access keys" -> "Primary"):

portal screenshot

However I get the error message from my pipeline "AzureResourceManagerTemplateDeployment@3" task:

[error]Unable to evaluate template outputs: 'RedisCachePassword'. Please see error details and deployment operations. Please see https://aka.ms/arm-debug for usage details.

[error]Details:

[error]DeploymentOutputEvaluationFailed: The template output 'RedisCachePassword' is not valid: The language expression property 'primaryKey' can't be evaluated..

What is please wrong with my ARM template below? And how to be able to find the correct names in such cases?

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "redisCacheName": {
            "defaultValue": "my-redis",
            "type": "String"
        }
    },
    "variables": {
        "resourceName": "[concat(resourceGroup().name, '-', parameters('redisCacheName'))]"
    },
    "outputs": {
      "RedisCacheEndpoint": {
        "type": "string",
        "value": "[concat(reference(variables('resourceName')).hostName, ':', reference(variables('resourceName')).sslPort)]"
      },
      "RedisCachePassword": {
        "type": "string",
        "value": "[reference(variables('resourceName')).accessKeys.primaryKey]"
      }
    },
    "resources": [
        {
            "type": "Microsoft.Cache/Redis",
            "apiVersion": "2019-07-01",
            "name": "[variables('resourceName')]",
            "location": "[resourceGroup().location]",
            "properties": {
                "sku": {
                    "name": "Basic",
                    "family": "C",
                    "capacity": 1
                },
                "enableNonSslPort": false
            }
        }
    ]
}

Why does not [reference(variables('resourceName')).accessKeys.primaryKey] work?

Community
  • 1
  • 1
Alexander Farber
  • 21,519
  • 75
  • 241
  • 416

2 Answers2

3

Be aware that those outputs are in some ways quite visible. You might be better off invoking the listKeys command outside of your outputs. You can use it in other templates or execute the command separately via AzureCLI or Powershell.

Outputs are not secrets for Azure

If you know what you are doing, this is how you should be able to set it up:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "redisCacheName": {
            "defaultValue": "myredisinstance",
            "type": "String"
        }
    },
    "variables": {
        "resourceId": "[resourceId('Microsoft.Cache/Redis', parameters('redisCacheName'))]",
        "apiVersion": "[providers('Microsoft.Cache', 'redis').apiVersions[0]]"
    },
    "outputs": {
      "RedisCachePassword": {
        "type": "string",
        "value": "[listKeys(variables('resourceId'), variables('apiVersion')).primaryKey]"
      }
    },
    "resources": []
}

Here is some more information about how this works in general.

To "debug" such things, I like to use https://resources.azure.com, and look at the output and the "actions" tab:

enter image description here

Alex AIT
  • 17,361
  • 3
  • 36
  • 73
  • Thank you, but for some reason only the left tab "DATA (Get, Put)" in [Resource Explorer](https://resources.azure.com) is enabled for me. The next tab "Actions (Post, Delete)" is disabled. Maybe it is the setting of my (pretty big) Organisation? – Alexander Farber May 08 '20 at 16:06
  • 1
    Not sure, but it sound like it depends on some permissions – Alex AIT May 08 '20 at 20:46
1

Alex mentioned this but I'll state it a bit more strongly... don't put secrets in outputs. It means anyone with read permission on the deployment can access the secret of a resource they may not have access to. IOW, I may not even have access to that redisCache, but if I have access to the deployment, I also have access to that secret.

If you need to, output the resourceId of the redisCache and call listKeys where you need to consume it (Alex hinted at this too).

In most cases you don't even need to use the output, because the resource that needs the key, also knows the resourceId of the resource.

Technically, this is possible, just be aware of the surface area if you do it...

bmoore-msft
  • 8,376
  • 20
  • 22