Azure / azure-functions-host

The host/runtime that powers Azure Functions
https://functions.azure.com
MIT License
1.92k stars 442 forks source link

Race condition when using function host key for other resource in ARM template #7381

Open jimmyvdberg opened 3 years ago

jimmyvdberg commented 3 years ago

Since a few months I get a race condition when using function keys / host keys via ARM template. I try to create a function key in the ARM template. In the same ARM template I add a KeyVault secret, with this newly generated function key as a value. When I look at this value in KeyVault I see the old function key (from the previous ARM template deployment) is stored there. This seems like a race condition.

I also see in the resource group deployment log that indeed the KeyVault secret was created earlier than the generation of this function key was finished.

I am depending on the function app and function key in both the KeyVault as in the KeyVault secret with dependsOn. I would expect the secret in KeyVault would than be created after the new function key is generated.

I am saying since a few months, because this used to work in the past. I can confirm it worked on 7th of January 2021, which is the last ARM deployment we did up until now. We didn't make any changes in between.

I striped down our own ARM template to the example below; When using this example and deploying it twice, you will see that in KeyVault the old function key is placed in the value.

Some additional info:

ARM template ```JSON { "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": {}, "variables": { "functionAppServicePlanName": "[concat(resourceGroup().name, '-functions')]", "functionStorageAccountName": "[concat(uniqueString(resourceGroup().name), 'functions')]", "functionAppServiceName": "[concat(resourceGroup().name, '-functions')]", "keyVaultName": "[resourceGroup().name]" }, "resources": [ { "type": "Microsoft.KeyVault/vaults", "apiVersion": "2018-02-14", "name": "[variables('keyVaultName')]", "location": "[resourceGroup().location]", "dependsOn": [ "[resourceId('Microsoft.Web/sites', variables('functionAppServiceName'))]", "[resourceId('Microsoft.Web/sites/host/functionKeys', variables('functionAppServiceName'), 'default', 'customkey')]" ], "properties": { "tenantId": "[subscription().tenantId]", "sku": { "family": "A", "name": "standard" }, "enableSoftDelete": true, "accessPolicies": [ { "tenantId": "[reference(concat('Microsoft.Web/sites/', variables('functionAppServiceName')), '2018-11-01', 'Full').identity.tenantId]", "objectId": "[reference(concat('Microsoft.Web/sites/', variables('functionAppServiceName')), '2018-11-01', 'Full').identity.principalId]", "permissions": { "secrets": [ "get" ] } } ] }, "resources": [ { "name": "[concat(variables('keyVaultName'), '/', variables('functionStorageAccountName'), '-storage-connection-string')]", "type": "Microsoft.KeyVault/vaults/secrets", "apiVersion": "2018-02-14", "location": "[resourceGroup().location]", "dependsOn": [ "[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]", "[resourceId('Microsoft.Storage/storageAccounts', variables('functionStorageAccountName'))]" ], "properties": { "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',variables('functionStorageAccountName'), ';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('functionStorageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]" } }, { "name": "[concat(variables('keyVaultName'), '/functionkey')]", "type": "Microsoft.KeyVault/vaults/secrets", "apiVersion": "2018-02-14", "location": "[resourceGroup().location]", "dependsOn": [ "[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]", "[resourceId('Microsoft.Web/sites', variables('functionAppServiceName'))]", "[resourceId('Microsoft.Web/sites/host/functionKeys', variables('functionAppServiceName'), 'default', 'customkey')]" ], "properties": { "value": "[listkeys(concat(resourceId('Microsoft.Web/sites', variables('functionAppServiceName')), '/host/default/'),'2020-12-01').functionKeys.customkey]" } } ] }, { "type": "Microsoft.Storage/storageAccounts", "apiVersion": "2019-04-01", "kind": "StorageV2", "location": "[resourceGroup().location]", "name": "[variables('functionStorageAccountName')]", "properties": { "accessTier": "Hot" }, "sku": { "name": "Standard_LRS" } }, { "apiVersion": "2020-12-01", "type": "Microsoft.Web/serverfarms", "name": "[variables('functionAppServicePlanName')]", "location": "[resourceGroup().location]", "sku": { "name": "Y1", "tier": "Dynamic" } }, { "apiVersion": "2020-12-01", "type": "Microsoft.Web/sites", "name": "[variables('functionAppServiceName')]", "kind": "functionapp", "location": "[resourceGroup().location]", "properties": { "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('functionAppServicePlanName'))]", "httpsOnly": true }, "resources": [ { "type": "config", "name": "appsettings", "apiVersion": "2018-11-01", "dependsOn": [ "[resourceId('Microsoft.Web/Sites', variables('functionAppServiceName'))]", "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]", "[resourceId('Microsoft.Storage/storageAccounts', variables('functionStorageAccountName'))]" ], "properties": { "AZURE_FUNCTIONS_ENVIRONMENT": "Production", "FUNCTIONS_WORKER_RUNTIME": "dotnet", "FUNCTIONS_EXTENSION_VERSION": "~3", "WEBSITE_RUN_FROM_PACKAGE": "1", "WEBSITE_CONTENTSHARE": "[toLower(variables('functionAppServiceName'))]", "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('@Microsoft.KeyVault(SecretUri=', reference(resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), concat(variables('functionStorageAccountName'), '-storage-connection-string'))).secretUriWithVersion, ')')]", "AzureWebJobsStorage": "[concat('@Microsoft.KeyVault(SecretUri=', reference(resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), concat(variables('functionStorageAccountName'), '-storage-connection-string'))).secretUriWithVersion, ')')]" } }, { "type": "Microsoft.Web/sites/host/functionKeys", "apiVersion": "2020-12-01", "name": "[concat(variables('functionAppServiceName'), '/default/customkey')]", "properties": { "name": "customkey" }, "dependsOn": [ "[resourceId('Microsoft.Web/Sites', variables('functionAppServiceName'))]" ] } ], "identity": { "type": "SystemAssigned" }, "dependsOn": [ "[resourceId('Microsoft.Web/serverfarms', variables('functionAppServicePlanName'))]" ] } ] } ```
brettsam commented 3 years ago

@mathewc -- are function keys cached in Antares? Could that be causing what he's seeing here?