【问题标题】:Azure Function ARM Deployment with listkeys results in BadRequest Error使用 listkeys 部署 Azure Function ARM 导致 BadRequest 错误
【发布时间】:2020-06-11 05:43:05
【问题描述】:

我有一个简单的 ARM 模板,它部署了两个 Azure Functions、一个应用服务计划和一个存储帐户:

唯一的“特殊”之处在于,function-key-issue-two 函数将 function-key-issue-one 函数中的 默认主机密钥 添加为应用设置:

"FunctionOneKey": "[listkeys(concat(variables('functionTwoAppId'), '/host/default/'),'2016-08-01').functionKeys.default]",

如果我将此模板部署到 new 资源组,它会第一次工作。每次后续部署都会失败,并在资源 function-key-issue-one/default 上出现 Bad Request 错误:

操作细节如下:

{
    "Code": "BadRequest",
    "Message": "Encountered an error (ServiceUnavailable) from host runtime.",
    "Target": null,
    "Details": [
        {
            "Message": "Encountered an error (ServiceUnavailable) from host runtime."
        },
        {
            "Code": "BadRequest"
        },
        {
            "ErrorEntity": {
                "Code": "BadRequest",
                "Message": "Encountered an error (ServiceUnavailable) from host runtime."
            }
        }
    ],
    "Innererror": null
}

如果我删除 FunctionOneKey 应用程序设置,部署工作。此外,如果我没有指定应用程序设置WEBSITE_RUN_FROM_PACKAGE,部署也可以。

稍后使用 AzureFunctionApp@1 Azure DevOps 任务作为 Zip 包部署功能代码(这就是我将 WEBSITE_RUN_FROM_PACKAGE 设置为 1 的原因。


如何重现:

我使用的 ARM 模板在 here 可用。 您可以使用它来部署它。 e. G。 New-AzResourceGroupDeployment cmdlet:

New-AzResourceGroupDeployment -ResourceGroupName 'function-key-issue-rg' -TemplateFile "D:\sources\issues\functionDeployment\azuredeploy.json" -name "azuredeploy-$(New-Guid)"

更新 1:

ServiceUnavailable错误的原因可能是因为Kudu添加了一个带有重写规则的web.config(因为我使用WEBSITE_RUN_FROM_PACKAGE但没有部署该功能):

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name = "Site Unavailable" stopProcessing = "true">
                    <match url = ".*" />
                    <action type = "CustomResponse" statusCode = "503" subStatusCode = "0" statusReason = "Site Unavailable" statusDescription = "Could not download zip" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

我的下一个尝试是通过设置来阻止 Kudu 这样做 SCM_TOUCH_WEBCONFIG_AFTER_DEPLOYMENT0(参见:Don't touch web.config at the end of the deployment)。现在看起来,后续部署有时会成功:

但仍然不是一个可靠的解决方案 :-/.


更新 2:

  • Azure 函数运行时~2 存在相同问题。
  • 将 Azure Function 切换到 Linux 也不能解决问题。

更新 3:


知道这里有什么问题吗?有什么解决方法吗?

【问题讨论】:

  • 部署成功时资源的部署顺序是否一致?不确定,但您是否尝试过更改部署顺序(使用dependsOn),以便function-key-issue-one 及其所有子资源在诸如function-key-issue-two 之类的任何东西开始之前完成?
  • 是的,错误和成功部署的顺序相同。我也已经尝试过使用不同的 dependsOn 配置 - 没有成功。不过,感谢您的帮助!

标签: azure azure-devops azure-functions azure-resource-manager


【解决方案1】:

我认为你可以改变在你的函数之间建立通信的方式,你也会解决你的问题。我建议您使用 Azure 托管标识来配置函数之间的通信,而不是使用功能键。请查看this article 了解我所说的更多细节。

【讨论】:

  • 感谢 Hugo,这通常是一个有效的解决方法。但是,我的 Azure 函数每秒被调用多次。在这个用例中使用托管身份对性能的影响太大了。
  • 您会收到一个额外的请求来验证您的访问令牌,所以老实说,我认为这不会影响您的性能。通过这样做,您肯定是在遵循 Microsoft 确定的最佳实践。
  • 您是对的,为此使用托管标识被认为是最佳实践。但正如我所说,对于我的特定用例而言,性能影响太大了。我需要找到另一个解决方案。此外,我对部署失败的原因感兴趣,因为它应该可以工作 - 而且它在我第一次部署模板时工作......
  • 你看过this thread。有人报告与您遇到的相同异常,显然是使用 Linux + Consumption 计划时出现中断或缓慢的已知问题。你的职能是这样的吗?
【解决方案2】:

首先,我建议使用 Azure KeyVault 作为密钥的默认存储,如此处所述。 但似乎,这也与一些关于 Appservice 和 Package Deployments 的问题有关。 看看这里:https://github.com/microsoft/azure-pipelines-tasks/issues/10961 和这里:https://github.com/microsoft/azure-pipelines-tasks/issues/11444。 文档还说这样的话: https://docs.microsoft.com/de-de/azure/azure-functions/run-functions-from-deployment-package

希望这会有所帮助。

【讨论】:

  • 我尝试将功能键写入 Azure KeyVault,但得到相同的错误(listkey 功能不起作用)。感谢您的帮助。
【解决方案3】:

我在模板中遇到了类似的问题,将 EventGrid 主题订阅者部署到主题。 json 模板中 listkey() 函数的出现导致了相同的、非常非描述性的错误消息。

我已将 ARM 模板架构更新为 Azure 支持的最新架构:2019-08-01

像这样: 文件的第一行: "$schema": "https://schema.management.azure.com/schemas/2019-08-01/deploymentParameters.json#",

和内联,在 listkeys 函数中:

listkeys(concat(resourceId('Microsoft.Web/sites', parameters('functionAppName')), '/host/default'), '2019-08-01').functionKeys.default)

现在,至少对我来说,随后的几个部署再次起作用。

【讨论】:

  • 不幸的是,我在第二次部署后仍然收到错误 :-(。无论如何感谢 KatteKylling!
  • 这真的很糟糕,因为它让我觉得问题可能在任何给定时间再次发生。
  • 现在,它突然又停止工作了。多次、相同、重复的尝试现在导致它在 6 次尝试中的最后一次工作(6 次失败 5 次)。这是通过发布管道运行模板部署时。在 Azure 门户中重复部署时,大约有一半的时间会失败。所以我上面的解决方案恐怕真的不是解决方案。
【解决方案4】:

我遇到了几乎相同的问题。我需要提供它自己的主机密钥的 Azure 函数。在几个不同的测试场景之后,我的结论是在 Azure Function App 部署完成和主机密钥可用之间存在一些延迟。

我目前的解决方法是在 KeyVault 中创建一个密钥,然后在两个不同的地方使用这个密钥:

  1. 在 Azure 函数中创建新的主机密钥
  2. 提供 Azure Function 应用设置

一些示例代码:

从 PS 在 KeyVault 中生成密钥

$secureSecret = ConvertTo-SecureString New-Guid.ToString() -AsPlainText -Force

Set-AzureKeyVaultSecret -VaultName $keyVaultName -Name "azure-function-key" -SecretValue $secureSecret

创建主机密钥并将其传递给函数

请注意,parameters('internalKey') 将来自 KeyVault 参考

"apiVersion": "2019-08-01",
"type": "Microsoft.Web/sites",
"kind": "functionapp",
"name": "[variables('functionAppName')]",
"location": "[variables('location')]",
"resources": [{
   "dependsOn": ["[resourceId(resourceGroup().name, 'Microsoft.Web/sites', variables('functionAppName'))]"],
   "type": "Microsoft.Web/sites/host/functionKeys",
   "apiVersion": "2018-11-01",
   "name": "[concat(variables('functionAppName'), '/default/internalkey')]",
   "properties": {
      "name": "internalkey",
      "value": "[parameters('internalKey')]"
   }
},
{
   "apiVersion": "2019-08-01",
   "name": "appsettings",
   "type": "config",
   "dependsOn": [
      "[resourceId(resourceGroup().name, 'Microsoft.Web/sites', variables('functionAppName'))]"
   ],
   "properties": {
      "FUNCTIONS_EXTENSION_VERSION": "~3",
      "HostFunctionKey": "[parameters('internalKey')]"
   }
}]

即使您尝试使用新主机密钥的listKeys 方法,它也不会获得价值。第一次它会失败,如果它已经改变,它会连续多次获得以前的值。

【讨论】:

    【解决方案5】:

    我在使用 ARM 模板部署函数应用和应用设置时也遇到了这个问题。

    在反复使用 Azure 支持后,我们意识到应用设置的持久性会导致 Function App 在部署期间重新启动,这会导致 503 Service Unavailable 在它重新启动时出现。这会在部署仍在进行时发生,这会导致Microsoft.Web/sites/host 出现间歇性故障。尽管 ARM 部署模式设置为 incremental,但对于功能应用设置似乎完全忽略了这一点。

    Function App 的诊断设置将为您列出硬重启,并可能让您深入了解导致它的应用设置。

    Azure 支持建议将应用设置分离到 ARM 模板中自己的 Microsoft.Web/sites/config 部分,其中 dependsOn 函数应用已完成部署。我还没有尝试过,这也违背了 Function App ARM 示例中的内容,它们是 Microsoft.Web/sites 的子 config 资源。

    【讨论】:

      【解决方案6】:

      我最近遇到这个问题,联系了 Azure Functions 团队,我从他们那里了解到:(我使用的 ARM 模板应该是相同的逻辑,不同的方法)

      1- 使用 WEBSITE_RUN_FROM_PACKAGE = 1 必须在部署 Zip 文件之前设置,这意味着添加 ZipDeploy 与部署 AppSettings 之间的依赖关系。

      为什么? 如果一开始没有设置此标志,该函数将获取 ZipFile 并将其解压缩到 wwroot 文件夹,导致空的 SitePackage 文件夹并破坏部署和功能。此标志使函数将 zip 文件上传到函数共享文件系统中data/SitePackage 下的文件夹,还有一个具有相关 Zip 名称的package.txt

      这个标志不应该来回更改,因为它会因为混淆是将 zip 上传到 SitePackages 还是将其提取到 wwroot 而破坏部署。

      如果第一次转旗,我给出了答案,第一次部署可能会失败,你需要再试一次。

      2- 使用 WEBSITE_RUN_FROM_PACAKAGE 时,该函数会经历一种重启,这是写在文档 here 上的,您会看到部署后重启完成。

      因此“listKeys”步骤可能会在重新启动并导致失败,您需要做的是在功能部署后添加一个“等待”步骤 1-2 分钟,以确保一切都已完成。

      祝你好运

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-19
        • 2020-12-05
        • 1970-01-01
        相关资源
        最近更新 更多