How to map Azure Functions secrets from Key Vault automatically

隐身守侯 提交于 2019-12-05 11:28:34

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)
        {
            // Gets the default configuration
            var serviceConfig = builder.Services.FirstOrDefault(s => s.ServiceType.Equals(typeof(IConfiguration)));
            var rootConfig = (IConfiguration)serviceConfig.ImplementationInstance;

            // Creates a new config based on the default one and adds the keyvault configuration builder
            var keyvaultName = rootConfig["keyVaultName"];
            var config = new ConfigurationBuilder()
                .AddConfiguration(rootConfig).AddAzureKeyVault($"https://{keyvaultName}.vault.azure.net/").Build();

            // Replace the existing config
            builder.Services.AddSingleton<IConfiguration>(config);
        }
    }
}

My Azure functions uses MSI:

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:

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

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.

more details check this

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

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.

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,

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,

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!