【问题标题】:Issue with Azure function configuration object cachingAzure 函数配置对象缓存问题
【发布时间】:2020-04-04 10:41:25
【问题描述】:

Azure 函数应用的我的应用程序设置,有 keyvault 引用,如 @Microsoft.KeyVault(SecretUri=https://myvalut.vault.azure.net/secrets/mySecret/), 每当 keyvault 中引入新版本的“mySecret”时,Azure 函数仍会呈现旧的/陈旧的值,而不是“mySecret”的最新值/版本。

如果我使用 KUDU (https://myhttpfunc.scm.azurewebsites.net/api/settings) 打开应用设置,我可以看到 "mySecret":"onemoretry" 其中 "onemoretry" 是旧值。只有 Azure func 应用重新启动会使用新值更新“mySecret”。

如何使使用 keyvault 引用的 Azure 函数在更新时获取目标 keyvault 机密的最新值/版本,而无需重新启动 Azure 函数?

【问题讨论】:

    标签: azure-functions azure-keyvault azure-functions-runtime azure-function-app azure-security


    【解决方案1】:

    该参考适用于应用程序配置,通常在启动或首次使用时获取并缓存(在本例中为后者)。它并不打算每次都获取。例如,如果您想通过 ETags 进行生命周期管理,您可以考虑使用 Azure 应用程序配置。如果您需要对这些值进行静态加密,只有有限的一组人可以访问,您将无法以这种方式使用机密,而是必须自己调用 Azure Key Vault,但您仍应缓存有限时间内的价值:Key Vault 的速率限制非常低,因此如果您的函数在短时间内收到大量调用,其中一些调用可能会受到限制并失败(有一个内置的重试策略,但'如果请求继续快速连续排队,则无济于事)。

    例如,您可以自己获取秘密(假设 C#,因为不清楚您使用的是什么语言):

    var vaultUri = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL") ?? throw new InvalidOperationException();
    var client = new SecretClient(new Uri(vaultUri), new DefaultAzureCredential());
    KeyVaultSecret secret = await client.GetSecretAsync("my-secret");
    

    根据函数的触发方式,您可以使用多种内存缓存机制,例如每隔一段时间触发并更新密钥本身的计时器。 Key Vault 不支持 ETag,因此无论是否更改,每个请求都将针对该密钥。您可以查询版本是否更改,但这可以节省一点(无论如何您都必须获取完整的秘密,所以这是 2 个请求,您可以在每个间隔的 1 个请求中获取秘密)。

    【讨论】:

    • 已经考虑过创建 KeyVaultClient 的场景,但它不适合我们的要求,我们有队列触发器和基于 cosmos db 触发器的 azure 函数,其中必须使用从 keyvault 读取队列/cosmos db 连接字符串密钥库参考。甚至尝试通过 kudu api 使用最新值更新功能 appsettings,同时更新 keyvault 机密,但功能仍然不采用/考虑最新更新的 appsetting 值,但它使用来自某处的缓存值。任何其他克服缓存的建议。?
    • 同样,这是应用程序配置 - 通常在启动时完成。这与您在启动时读取环境变量或从 .env 之类的源文件中读取没有什么不同。并不是 Key Vault 不支持获取最新值,而是配置 API 旨在执行此操作,因为应用程序只启动一次(当然,除非重新启动)。您可以连接Event Grid triggers to Key Vault,但您仍然需要重新启动您的应用程序,除非您按照我的说明将阅读秘密移至应用程序逻辑。
    【解决方案2】:

    您可以使用Resource Explorer。当您找到要编辑的内容时,它实际上会告诉您必须点击的端点才能与之交互。

    应用程序设置将在以下位置提供:
    subscriptions -> resourceGroups -> [your app's resource group] -> providers -> Microsoft.Web -> sites -> [your app name] -> config -> appsettings

    因此,您可以将 PUT 与提供的端点一起使用,并根据需要更改值。

    我没有尝试使用 REST API,它可能无法按您的意愿工作;您更新的值应该覆盖缓存的值。

    更多信息:
    https://docs.microsoft.com/en-us/rest/api/appservice/WebApps/UpdateApplicationSettings http://blog.davidebbo.com/2015/12/calling-arm-using-plain-rest.html

    【讨论】:

    • 不是预期的解决方案。如果 Keyvault 机密得到更新,我希望 Azure 函数通过密钥保管库参考自动获取最新的机密版本值。为什么作为开发人员,每当我更改 Keyvault 机密值时,我都必须负责更新 Azure 函数 ApplicationSettings。
    • @191180rk 当你创建新版本时,你是手动做的吗?
    • @eli,是的。通过连接 azure keyvault 使用 azure protal/cli
    • @191180rk 您能否编写一个批处理脚本来创建新版本,同时使用 REST API 使用新创建的版本更新函数应用的应用程序设置? az rest 可以进行 REST 调用。
    • @eli,这些作为解决方案很难接受,应该有更好的出路。
    猜你喜欢
    • 1970-01-01
    • 2012-06-14
    • 2014-10-18
    • 1970-01-01
    • 2021-01-24
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    相关资源
    最近更新 更多