2
votes

I was able to use the Key Vault inside a function app as described here but when I tried to use the Key Vault to hold the connection string of a function with a queue trigger I have issues with the storage account connection string. The function seems to find the parameter I provide but either doesn't get the secret back or doesn't like the information when it throws the error No valid combination of account information found.

My function is defined as:

        [FunctionName("ReadQueueForMessage")]
        public static async Task Run([QueueTrigger("%AzureQueueTrigger%", Connection = "AzureWebJobsStorage")] string myQueueItem,
            Binder binderinputblob,
            ILogger log)

This works fine if I just define the connection string in my local.settings.json. What I'm trying to do is instead of just putting the connection string in the json file, I want to point the function to the Key Vault with this syntax:

"AzureWebJobsStorage": "@Microsoft.KeyVault(SecretUri=https://myappkeyvault.vault.azure.net/secrets/myapp-AzureWebJobsStorage-Queue/the-guid-of-secret)",

I did go to the Key Vault and update the access policies to include the function app so it can read/list the secrets. The documentation here shows making an update to the configuration after it was deployed to Azure. I'm trying to test first in Visual Studio. Maybe that is the issue? Or is it not possible at all to use the secret in this manner?

2
this would definitely work with regular code, not sure about bindings though4c74356b41

2 Answers

3
votes

I'm trying to test first in Visual Studio.

For now using Azure Key Vault references with Azure Functions does not support to work on local, as confirmed by Azure Functions team. If you still want to test on local, you could implemented an incomplete local workaround like this issue.

I test on portal and it works well. You could refer to the following steps as below:

1.In VS Function.cs, then publish to azure:

 public static void Run([QueueTrigger("queue", Connection = "AzureWebJobsStorage")]string myQueueItem, TraceWriter log)
 {
     log.Info($"C# Queue trigger function processed: {myQueueItem}");
     string connectionString = System.Environment.GetEnvironmentVariable("AzureWebJobsStorage");
     log.Info($"The connection string is {connectionString}");
 }

2.Set AzureWebJobsStorage on Appsettings setting on portal.

enter image description here

3.Then it will work fine.

enter image description here

1
votes

With the Nuget packages Azure.Extensions.AspNetCore.Configuration.Secrets and Azure.Identity you can now use the KeyVault as a configuration provider, the same way as in ASP.NET Core. You need to add a class derived from FunctionsStartup to add the KeyVault as a configuration provider, see Add FunctionsStartup class with the KeyVault as a configuration provider.

If you add the AzureWebJobsStorage connection string as a secret to the KeyVault, you can remove it from the Configuration section of your Function App in Azure. Make sure to turn on System assigned in the Identity section and in the KeyVault add an Access Policy with the Secret permissions Get and List for your Function App.

When you run your Function App local for debugging, Azure.Identity automatically uses your Microsoft Account for access to the KeyVault, if it has at least Get and List access to the secrets.

Unfortunately, when you test local, the Function App does NOT read AzureWebJobsStorage from the configuration/KeyVault, but requires it to be stored in local.settings.json. To prevent storing keys on your local computer, you can set AzureWebJobsStorage to "UseDevelopmentStorage=true" in local.settings.json.

For detailed instructions see: Create Azure Function App with Dependency Injection and the Key Vault as Configuration Provider.

Example project: https://github.com/Forestbrook/FunctionWithKeyVaultAndDI