How to get configuration from Azure App Configuration to Function App? And how to do it when this azure app has dependencies to other projects?
At first this does not look like a difficult question. But many examples you find on stack overflow or in Microsoft documentation only cover one of two scenario's, app configuration or dependencies in start-up. In the case of our project we needed both in an azure function app. We wanted to use a timer function that utilizes the service of another project in the same solution. To do this we will need dependency injection. The rest of the solution already uses the app configuration manager in azure, so logical requirement would this azure function app to use it as well. This Blog covers a complete implementation of an timer triggered azure function with the use of secrets from Key vault and service injection and start-up class. You can skip to the part you need or go through it step by step.
- Basic knowledge of Azure
- (Optional)Azure Key Vault with enough rights to access it
- Azure App Configuration with enough rights to access it
- Visual Studio 2019
- SDK .Net Core 2.2
To get an overview of how to get configuration from Azure App Configuration to Function App? I've drawn up a little illustration of the architecture we are making:
The first thing we need create is an azure function.
Creating an Azure Function project
Let's open Visual studio (2019) and go to the solution that has the service project in it we'd like to call from a timer function. By right-clicking the solution we can add a project. As we select the project and name is we can select it to be a Timer Trigger with time interval '0 */5 * * * *'. For debug purpose this can be '0 */1 * * * *' if you prefer a shorter waiting time between calls. You should end up with this:
In the case of our solution we wanted to have a timer function to call a audit function in an audit service. This is a function in another project in your solution. To use this function we add this as dependency project to this project. Be sure to check compatible .Net core versions. If we inject the audit service in the function project an call the desired function it should look like this:
If we would run this, it will throw an error it cannot find the service.
To assemble all dependencies our injected service is dependent on we need a start-up class. It is similar to the one you might have to start your solution or Api-project. We add an start-up class to our project that looks like this:
I greyed-out some project specific dependencies for us. These are not useful for the example code. These are different for your project. To complete the start-up we add an assembly tag up top:
Getting configuration from azure
In most services you will be involved in authentication or making secure calls that require keys or connection string. For these kind of vulnerable data it is advisable to use secrets in Azure's Key vault. To set this up in the next part you will need access to your environments Key vault and Azure App Configuration. To start using secrets in app configuration we need to make an entry in Key vault that we can register in App Configuration. Add a new manual created secret in Key vault via 'generate/create' and give it a name and value. Open the created secret. You will find the secret identifier. Copy that, we will need that in the App Configuration.
Create a new Key vault reference in the Configuration explorer in app configuration. Give it a key and meaningful prefix to refer to your solution. As App Configuration might house more configuration for other projects you will be able to find your configurations more easily. To make a reference to your Key vault secret enter your secret identifier in input and hit 'apply'.
We can now use the key of your config to securely add the secret value in your code if we connect to the app config.
KeyVaultClient for your azure function
Let's get the configuration from azure to our function. Now we have entries we want to connect to App Configuration. To use Key vault as well we need an Key vault client. This requires these lines of code in a static initiation part of your function:
The clientId and secret are in your local.settings.json. Same goes for the connection string to your App configuration. Lets add the part that connects it together:
Now the App makes use of azure App Configuration. As we run the app there is something in the services that does not go quite right yet. We run the service from another identity so the configuration is a bit different then from other projects in the solution. We do not use a user identity but an app as identity to authenticate to use the function. So we need to set the correct configuration for our services. We add this to StartUp.cs below the added service singletons:
This concludes the complete setup of an azure function that calls a separate project in the solution. The start-up and retrieving of configuration is a little different from how this would be done in an Api. It is more rigid and needs a little tweak to get the configuration in up front to make it all work. The one thing we might also want to use in the function is feature flags to enable and disable the function call our other project. Like our auditing call it might be desirable to turn it of if this functionality is not desired for it are costly operations to run for instance. The current [documentation] on this is not conclusive yet. And the example in here only returns a false value. Which is the default. When we find a way for it work we will update this blog.
I hope this blog helped you figure out the more complex configuration for your azure function. If you have tips, comments or question on the information provided in this blog please let me know. A tip on how to get the Feature Manager running in an azure function is also very welcome. Thanks for reading.