1

My Application settings of Azure function app, has keyvault reference like @Microsoft.KeyVault(SecretUri=https://myvalut.vault.azure.net/secrets/mySecret/), whenever new version of "mySecret" introduced in keyvault, Azure function still renders the old/stale value not the latest value/version of "mySecret".

If I open up app setting using KUDU (https://myhttpfunc.scm.azurewebsites.net/api/settings) I can see "mySecret":"onemoretry" where "onemoretry" is the old value. Only Azure func app restart updates "mySecret" with new value.

How to make Azure function which uses keyvault reference to fetch latest value/version of the targeted keyvault secret as & when it get updated, without Azure function restart?

191180rk
  • 735
  • 2
  • 12
  • 37

2 Answers2

1

The reference is intended for application configuration, which is typically fetched and cached on startup or first use (the latter in this case). It's not intended to fetch every time. If you want lifetime management via ETags, for example, you might consider Azure Application Configuration. If you need those values to be encrypted at rest with only a limited set of people able to access, you'll not be able to use secrets this way but instead will have to call into Azure Key Vault yourself, but you should still cache the value for a limited time: Key Vault has very low rate limits, so if your function gets a lot of calls in a short period of time some of those may get throttled and fail (there is a built-in retry policy, but that won't help if requests keep getting queued up in rapid succession).

For example, you could just fetch the secret yourself (assumes C# since it wasn't evident what language you were using):

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");

There are a number of in-memory caching mechanisms you could use depending on how your function is triggered, such as a timer that fires every so often and updates the secret itself. Key Vault doesn't support ETags, so each request will be for the key regardless of whether it's changed. You could query if the version changed, but that saves you little (you'd have to fetch the full secret anyway, so that's 2 requests where you could just fetch the secret in 1 request at each interval).

Heath
  • 2,986
  • 18
  • 21
  • Already consider the scenario of creating KeyVaultClient but it DOESN'T suit to our requirement where we have queue trigger & cosmos db trigger based azure functions where queue /cosmos db connection strings have to be read from keyvault using keyvault reference. Even tried to update function appsettings via kudu api with latest values while updating keyvault secret but still function is NOT taking/considering the latest updated appsetting value but it uses cached value from somewhere.Any other suggestion to overcome caching.? – 191180rk Apr 15 '20 at 15:43
  • 1
    Again, this is application configuration - typically done on startup. It would be no different than if you read environment variables or from a source file like .env on startup. It's not that Key Vault doesn't support getting the latest value, but that the configuration APIs were designed to do that since applications only start up once (unless, of course, restarted). You can hook up [Event Grid triggers to Key Vault](https://docs.microsoft.com/azure/key-vault/general/event-grid-tutorial), but you'd still need to restart your app unless you move reading secrets to app logical as I showed. – Heath Apr 17 '20 at 00:17
0

You can use the Resource Explorer. When you've found what you want to edit, it will actually tell you the endpoint you'll have to hit in order to interact with it.

Application settings will be available under:
subscriptions -> resourceGroups -> [your app's resource group] -> providers -> Microsoft.Web -> sites -> [your app name] -> config -> appsettings

You can thus use PUT with the supplied endpoint and alter the values as you need.

I haven't tried to use the REST API, and it might not work as you want it to; where the values you update should override what is cached.

More info:
https://learn.microsoft.com/en-us/rest/api/appservice/WebApps/UpdateApplicationSettings http://blog.davidebbo.com/2015/12/calling-arm-using-plain-rest.html

Kristin
  • 1,336
  • 7
  • 23
  • Not the solution expected. If Keyvault secret get updated I want Azure function automatically to get the latest secret version value via key vault reference. Why as I developer I have to take the responsibility of updating Azure function ApplicationSettings whenever I changes Keyvault secret value. – 191180rk Apr 04 '20 at 13:28
  • @191180rk When you create new versions, are you doing this manually? – Kristin Apr 04 '20 at 13:55
  • @ eli, Yes. By using azure protal/cli by connecting azure keyvault – 191180rk Apr 04 '20 at 15:36
  • @191180rk Could you write a batch script that both creates a new version and at the same time updates the function app's application settings with the newly created version, using the REST API? `az rest` can do the REST calls. – Kristin Apr 04 '20 at 17:27
  • @ eli, these are pretty hard to accept as solution, There should be a better way out. – 191180rk Apr 04 '20 at 17:31
  • @191180rk If what most likely would be a 10-line script is an "unacceptable" solutions, I don't know what you're expecting here. Could you maybe indicate at to what you'd say was "an acceptable" solution? As in, what are your expectations for a solution for it to be "OK" in your book? I can almost certainly guarantee you, there are no "KeyVaultTrigger" out there, that'll do this "automagically" for you. – Kristin Apr 05 '20 at 01:24
  • Its not about making you upset. My concern is why @Microsoft.KeyVault(secreturi) is NOT enclosing intelligence to sense the change in KV secret value & refresh app service config cache? though it is not possible to provide as out-of-box feature at least it should be possible via pro-grammatically using SDK. Like latest Azure App Configuration service facilitates cache refresh on source file change. – 191180rk Apr 05 '20 at 16:05
  • Tried out updating the function app's application settings with the newly created version of keyvault secret by using the REST API & the application settings value get updated as expected but still function is rendering the previous value of the keyvault secret not the latest value what is updated in the function app's application settings. Why? & how to overcome it? – 191180rk Apr 07 '20 at 16:45
  • @191180rk what if you invoke the API call `applySlotConfig` or `resetSlotConig`? They're available from `subscriptions -> resourceGroups -> [your app's resource group -> providers -> Microsoft.Web -> sites -> [your app name]`, go to "Actions (POST, DELETE)" tab. – Kristin Apr 07 '20 at 20:06