Azure-quickstart-templates: Q: Cannot set function key - sample needed

Created on 11 Nov 2019  路  4Comments  路  Source: Azure/azure-quickstart-templates

Provision Function App

Issue Details

Trying to make use of function keys resource according to this https://docs.microsoft.com/en-us/azure/templates/microsoft.web/2018-02-01/sites/functions/keys and getting error:
New-AzResourceGroupDeployment : 08:09:00 - Error: Code=InvalidRequestContent; Message=The request content was invalid and could not be deserialized: 'Could not find member 'value' on object of type 'TemplateResource'.

{
      "apiVersion": "2015-08-01",
      "type": "Microsoft.Web/sites",
      "name": "[variables('functions_name')]",
      "location": "[variables('location')]",
      "tags": {
        "ccm": "[variables('ccmvalue')]"
      },
      "kind": "functionapp",
      "identity": {
        "type": "SystemAssigned"
      },
      "dependsOn": [
        "[variables('appserviceplan_functions_name')]"
      ],
      "properties": {
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('appserviceplan_functions_name'))]",
        "siteConfig": {
          "http20Enabled": true
        }
      },
      "resources": [
        {
          "type": "config",
          "apiVersion": "2018-11-01",
          "name": "appsettings",
          "dependsOn": [
            "nestedTemplate",
            "[variables('functions_spomanagement_name')]"
          ],
          "properties": {
            "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.Insights/components/', variables('appinsights_name')), '2015-05-01').InstrumentationKey]",
            "AzureWebJobsStorage": "[concat('@Microsoft.KeyVault(SecretUri=', reference(resourceId(parameters('rg-api-name'), 'Microsoft.KeyVault/vaults/secrets', variables('kv_dss_name'), variables('secrets_storageaccount_connectionstringname')), '2018-02-14').secretUriWithVersion, ')')]",
            "FUNCTIONS_EXTENSION_VERSION": "~1",
            "FUNCTIONS_WORKER_RUNTIME": "[variables('functions_worker_runtime')]",
            "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('@Microsoft.KeyVault(SecretUri=', reference(resourceId(parameters('rg-api-name'),'Microsoft.KeyVault/vaults/secrets', variables('kv_dss_name'), variables('secrets_storageaccount_connectionstringname')), '2018-02-14').secretUriWithVersion, ')')]",
            "WEBSITE_CONTENTSHARE": "[toLower(variables('functions_management_name'))]"
          }
        }
        // THIS IS WHAT CAUSES ERROR
        //{
        //  "name": "variables('keys_managementinvocation')",
        //  "type": "Microsoft.Web/sites/functions/keys",
        //  "apiVersion": "2018-02-01",
        //  "value": "[parameters('managementinvocationkey')]"
        //}
      ]
    },

Most helpful comment

I was able to figure it out with MSFT support. This is a top level resource just like creating a function or app service plan. Here's a working example:
{ "type": "Microsoft.Web/sites/host/functionKeys", "apiVersion": "2018-11-01", "name": "[concat(variables('functionAppName'), '/default/sharedAccessKey')]", // if you want to create function level key, please replace "default" with {function name} "properties": { "name": "sharedAccessKey", "value": "[parameters('key')]" }, "dependsOn": [ "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]" ] },

All 4 comments

I was able to figure it out with MSFT support. This is a top level resource just like creating a function or app service plan. Here's a working example:
{ "type": "Microsoft.Web/sites/host/functionKeys", "apiVersion": "2018-11-01", "name": "[concat(variables('functionAppName'), '/default/sharedAccessKey')]", // if you want to create function level key, please replace "default" with {function name} "properties": { "name": "sharedAccessKey", "value": "[parameters('key')]" }, "dependsOn": [ "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]" ] },

Just wanted to say +1, I hit this problem today. The ARM template documentation is wrong and does not reflect what it actually takes to deploy this resource (for example the properties member isn't even listed).

Cross referencing a similar docs issue: https://github.com/MicrosoftDocs/azure-docs/issues/66001. It appears the type that works isn't the same as the docs for this either.

Running into an issue that appears to be caching related, that I thought was relevant here. I'm trying to maintain the current key if one exists already. To do that I've updated my resource as such:

{
      "apiVersion": "2018-11-01",
      "name": "[concat(parameters('functionsAppName'), '/default/clientKey')]",
      "type": "Microsoft.Web/sites/host/functionKeys",
      "properties": {
        "name": "clientKey",
        "value": "[if(contains(listKeys(concat(resourceId('Microsoft.Web/sites', parameters('functionsAppName')), '/host/default/'), '2018-11-01').functionKeys, 'clientKey'), listKeys(concat(resourceId('Microsoft.Web/sites', parameters('functionsAppName')), '/host/default/'), '2018-11-01').functionKeys.clientKey, '')]"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Web/sites', parameters('functionsAppName'))]"
      ]
    }

This effectively preserves the existing value if it's already set. The error comes with my output:

"outputs": {
    "x-functions-key": {
      "type": "string",
      "value": "[listKeys(concat(resourceId('Microsoft.Web/sites', parameters('functionsAppName')), '/host/default/'), '2018-11-01').functionKeys.clientKey]"
    }
  }

On first run I get this error: The template output 'x-functions-key' is not valid: The language expression property 'clientKey' doesn't exist, available properties are 'default'.. (Code:DeploymentOutputEvaluationFailed), but if I check the Azure Portal it's clear that 'clientKey' has been created.

Its as if the listKeys result is being cached when the resource makes the query, and then when I try to get the new key for the output I only have access to the data without the new key.

Note: I also tried using a condition on the resource, but I got complaints about using listKeys in the condition - seems like they aren't supported in conditions.

Updated: I tried to work around this via nested deployments without much luck. I tried with both linked templates and embedded ones with

"expressionEvaluationOptions": {
    "scope": "inner"
 }

to no avail. =(

Updated Again: Was able to finally get a work around that hasn't failed, yet... Using the 'reference' function instead of list keys in the output seems to sidestep the caching problem. E.g.:

"outputs": {
    "x-functions-key": {
      "type": "string",
      "value": "[reference(resourceId('Microsoft.Web/sites/host/functionKeys', parameters('functionsAppName'), 'default', 'clientKey')).value]"
    }
  }
Was this page helpful?
0 / 5 - 0 ratings

Related issues

qhdevon43 picture qhdevon43  路  10Comments

stephenmontgomery picture stephenmontgomery  路  6Comments

Kennethtruyers picture Kennethtruyers  路  4Comments

bbakermmc picture bbakermmc  路  9Comments

jjminio picture jjminio  路  6Comments