8
votes

I was wondering if it's possible to initialize the queue trigger or even the blob trigger off a connection string that is read from azure vault.

Right now, we have to set these data connection via environment settings via blade properties. However, I wanted to just use the service principal to retrieve the token for the azure key vault to get all these connection strings.

I'm trying to figure how to get this working in java.

Thanks, Derek

5
Edited my post with a real solutionThomas

5 Answers

12
votes

This feature is tracked and in progress here:

EDIT 28/11/2018: It is currently in preview

Former answer 07/10/2018 This solution won't work for Triggers using the consumption plan.

In the mean time I did some research about your problem and it is possible to read config from key vault if you use Azure Function v2.

I've created an Azure Functions v2 (.NET Standard) from Visual Studio.

It uses:

  • NETStandard.Library v2.0.3
  • Microsoft.NET.Sdk.Functions v1.0.22
  • Microsoft.Azure.WebJobs v3.0.0
  • Microsoft.Azure.WebJobs.Extensions.Storage v3.0.0

Because Azure Functions v2 uses ASP.NET core, I was able to reference this link to configure my functions app to use Azure Key Vault:

Azure Key Vault configuration provider in ASP.NET Core

  1. I've added this nuget package:

I've configured my app to use this nuget package:

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;

[assembly: WebJobsStartup(typeof(FunctionApp1.WebJobsExtensionStartup), "A Web Jobs Extension Sample")]
namespace FunctionApp1
{
    public class WebJobsExtensionStartup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder builder)
        {
            // Get the existing configuration
            var serviceProvider = builder.Services.BuildServiceProvider();
            var existingConfig = serviceProvider.GetRequiredService<IConfiguration>();

            // Create a new config based on the existing one and add kv
            var configuration = new ConfigurationBuilder()
                .AddConfiguration(existingConfig)
                .AddAzureKeyVault($"https://{existingConfig["keyVaultName"]}.vault.azure.net/")
                .Build();
        
            // replace the existing configuration
            builder.Services
                .Replace(ServiceDescriptor.Singleton(typeof(IConfiguration), configuration));
        }
    }
}

My Azure functions uses MSI:

Azure Functions - Managed Service Identity

I've granted Read/List secrets permissions to the function app on my key vault:

I have a small queue triggered function:

public static class Function2
{
    [FunctionName("Function2")]
    public static void Run([QueueTrigger("%queueName%", Connection = "queueConnectionString")]string myQueueItem, ILogger log)
    {
        log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
    }
}

The queueName is defined in the local.settings.json file (App settings blade once deployed):

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "keyVaultName": "thomastestkv",
    "queueName": "myqueue"
  }
}

The queueConnectionString is configured in my keyvault:

Azure Key Vault - Secrets

4
votes

Sourcing Application Settings from Key Vault The Key Vault references feature makes it so that your app can work as if it were using App Settings as they have been, meaning no code changes are required. You can get all of the details from our Key Vault reference documentation, but I’ll outline the basics here.

This feature requires a system-assigned managed identity for your app. Later in this post I’ll be talking about user-assigned identities, but we’re keeping these previews separate for now.

You’ll then need to configure an access policy on your Key Vault which gives your application the GET permission for secrets. Learn how to configure an access policy.

Lastly, set the value of any application setting to a reference of the following format:

@Microsoft.KeyVault(SecretUri=secret_uri_with_version)

Where secret_uri_with_version is the full URI for a secret in Key Vault. For example, this would be something like: https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931

enter image description here

That’s it! No changes to your code required!

For this initial preview, you need to explicitly set a secret version, as we don’t yet have built-in rotation handling. This is something we look forward to making available as soon as we can.

User-assigned managed identities (public preview) Our existing support for managed identities is called system-assigned. The idea is that the identity is created by the platform for a specific application and is tied to the lifecycle of the application. If you delete the application, the identity is removed from Azure Active Directory immediately.

Today we’re previewing user-assigned identities, which are created as their own Azure resource and then assigned to a given application. A user-assigned identity can also be assigned to multiple applications, and an application can have multiple user-assigned identities.

enter image description here

more details check this

1
votes

Update

This is now GA

This was just released as preview a couple days ago.

This feature requires a system-assigned managed identity for your app. Later in this post I’ll be talking about user-assigned identities, but we’re keeping these previews separate for now.

You’ll then need to configure an access policy on your Key Vault which gives your application the GET permission for secrets. Learn how to configure an access policy.

Lastly, set the value of any application setting to a reference of the following format:

@Microsoft.KeyVault(SecretUri=secret_uri_with_version)

Where secret_uri_with_version is the full URI for a secret in Key Vault. For example, this would be something like: https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931

Using Keyvault integration within the function runtime

0
votes

I just implemented it in Java following below two references.

  1. https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references

  2. https://medium.com/statuscode/getting-key-vault-secrets-in-azure-functions-37620fd20a0b

in java use System.getenv("SECRET_KEY") to read the values from your app settings.

Happy to help if you need further assistance.

0
votes

I have already given my answer in above, this answer is for @Matt Sanders's comment, i just want to explain how MSI working in the Azure Environment,

"I have 2 user assigned identities, 1 has permissions to KeyVault, the other does not. How can you specify the correct user assigned an identity to use for retrieving the secret? I'm guessing this is not possible and User Assigned Identities are not supported even though they are listed in your answer. – Matt Sanders"

when you want to use Azure Manage Identity Service, your application must register in the Azure AD, for an example, lets say multiple users accessing your web application and, within your web application, you 'r trying to access vVault's secrets, In that case, vault doesnt care about the users that consume your application, it cares about the application,

please reffer below image,

enter image description here

I as showing the picture, only Azure Function added as an Identity to the vault, other applications are not,

so whoever using Azure function can access vault's secrets, according to this example only A and B can access secrets,