Azure Functions — Modular based custom settings

Cheranga Hatangala
4 min readApr 13, 2020

In a previous article I explained how to load custom settings and to inject them as dependencies to your classes.

In here we are going to use custom JSON files to represent different configurations and how we can register them as dependencies.

The source code for this post can be found in here

Why do we need this?

There can be situations where your function app have many settings. This can be due to because of; it integrates with multiple other services or depending on the requirements or deployed environment you would like to customize the functions behavior.

When this happens your local settings file gets bloated with lots of settings. Also it’s the same when you deploy the function app.

So in this type of scenario we might need to separate our settings into their own module so that they can be easily managed and loaded.

ConfigurationBuilder to the rescue

With the recent changes in .NET core you can easily associate different sources of configurations to your application. So what we have to do in here is to use that feature in our function app.

  • First install Microsoft.Azure.Functions.Extensions nuget package.
  • Create a class inheriting from FunctionsStartup so that you can register the application dependencies.
  • Add your custom JSON files which will include their own settings. As shown below. Make them as CopyAlways or CopyIfNewer .
databaseconfig.json
ordersapiconfig.json
  • Create classes to represent the settings.
  • Now use the custom JSON files and load them to a ConfigurationBuilder instance and register it as the configuration provider for the function app.
"Most important thing to do is here is the setting of the base path for the configuration builder. This path can be obtained by the ExecutionContextOptions which is automatically registered as a dependency when the Azure function app starts up. I have found this is the only reliable way to get the path so that it will work both in your local and when deployed to Azure as well."
  • So by now using these custom JSON files you can extract the settings through sections and register them as dependencies.
  • Now you can create your function and inject the custom setting as a dependency.

The above function just returns the configured settings. It’s for demonstrative purposes only so that we could see what are the values have been set in the configurations.

How about deployment?

Well, the best practice is to use ARM templates for deployment. When doing so we can set up the configuration settings in the ARM template as parameters, so once it’s deployed you can see the settings according to the parameters.

But in here, the settings are maintained in separate files. So if you would like to pass values you need to do so through pipeline variables.

Please see below the pipeline variables which I have setup when deploying it to Azure.

All the nested settings must be joined with a “.” and, you can define different values in different scopes. But for demonstration I have defined all the variables in the “Release” scope, which means all environments will get the same value once deployed.

Then as the last step, in your Azure App Service Deploy task, edit the JSON transformation section, so that the configuration files will be updated accordingly.

That’s all. Now when you deploy your function app it will get the values set in the pipeline variables. But you will not see these values in the settings section of the deployed function app in the portal.

Disadvantages of this approach

Some of the setting values can be sensitive data. Best practice is to include these values in an AKV and reference them in your function settings. Then after deploying when you browse to the portal, you’ll not be able to see this sensitive data directly as well.

With this approach you cannot do that.

Conclusion

If you would like to separate the application into multiple projects including their respective configuration files this might be a good approach so that you can have a more cohesive and less coupled modules. But at the same time it comes with a cost of managing sensitive data and, managing multiple configuration files.

Thanks!

--

--