Reputation: 682
Is it possible to use an appsettings.json file in Azure Functions?
There is documentation for environment variables here..
..however we use Octopus for deployments and would really like to have appsettings version controlled.
We have tried using
{
"frameworks": {
"net46": {
"dependencies": {
"Microsoft.Extensions.Configuration": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0"
}
}
}
}
but constantly get
2016-11-23T15:27:03.811 (12,16): error CS0012: The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.0.0
Even being able to supply/update environment variables via Octopus would be sufficient for our needs.
Please advise.
Upvotes: 33
Views: 57844
Reputation: 161
For anyone that comes across this in 2025, here's how I did it for a v4 Azure Function using isolated worker model. Because the default configuration loader relies on the environment, I did not reload the environment with Configuration builder, but it's up to you on how you want the configuration settings be applied. In the below example, I am preferring the setting in this order:
Don't forget to mark your appsettings.json as "copy if newer" in the properties for each *.json file so that they will get copied into your bin directory. I also like to make appsetting.json non-optional so that if it is missing the application fails immediately. This can help find any deployment errors.
Program.cs
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
var builder = FunctionsApplication.CreateBuilder(args);
builder
.ConfigureFunctionsWebApplication();
builder.Services
.AddApplicationInsightsTelemetryWorkerService()
.ConfigureFunctionsApplicationInsights();
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true)
.Build();
builder.Configuration
.AddConfiguration(configuration);
builder.Build().Run();
Upvotes: 0
Reputation: 466
Yes you can add an appsettings.json file to your function app.
var host = new HostBuilder()
.ConfigureAppConfiguration((context, confBuilder) => {
confBuilder.AddJsonFile("appsettings.json", optional: false);
if (context.HostingEnvironment.IsEnvironment("local"))
{
confBuilder.AddJsonFile("appsettings.local.json", optional: true);
}
})
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices((hostContext, services) =>
{
services
.AddApplicationInsightsTelemetryWorkerService()
.ConfigureFunctionsApplicationInsights();
services.ConfigureApp(hostContext.Configuration);
})
.Build();
host.Run();
The HostBuilder
is just the same you can use in any of yours exe so you can add any configuration file to it.
In the example the ConfigureApp
method is just an extension method:
public static class RegisterServices
{
public static IServiceCollection ConfigureApp(this IServiceCollection store, IConfiguration configuration)
{
store.AddSingleton(configuration.GetSection("MyCompany:MyApp:Pizza").Get<PizzaOptions>());
return store;
}
}
Do not forget to add your appsettings.json
to you prj
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
keep coding
Upvotes: 1
Reputation: 1730
Maybe this simple solution would be useful:
[assembly: FunctionsStartup(typeof(AzureFunctions.Startup))]
namespace AzureFunctions;
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
var context = builder.GetContext();
var config = context.Configuration; //Here you go!
}
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
{
var context = builder.GetContext();
builder.ConfigurationBuilder
.AddJsonFile(Path.Combine(context.ApplicationRootPath, "appsettings.json"), optional: true, reloadOnChange: false)
.AddJsonFile(Path.Combine(context.ApplicationRootPath, $"appsettings.{context.EnvironmentName}.json"), optional: true, reloadOnChange: false); //For example enviroment name can be: Development
}
}
Upvotes: 3
Reputation: 1682
Configuration source customization is available beginning in Azure Functions host versions 2.0.14192.0 and 3.0.14191.0.
To specify additional configuration sources, override the ConfigureAppConfiguration method in your function app's StartUp class.
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
namespace MyNamespace
{
public class Startup : FunctionsStartup
{
public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder
builder)
{
FunctionsHostBuilderContext context = builder.GetContext();
builder.ConfigurationBuilder
.AddJsonFile(Path.Combine(context.ApplicationRootPath,
"appsettings.json"), optional: true, reloadOnChange: false)
.AddJsonFile(Path.Combine(context.ApplicationRootPath, $"appsettings.
{context.EnvironmentName}.json"), optional: true, reloadOnChange: false)
.AddEnvironmentVariables();
}
}
}
// update configuration in csproject
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="appsettings">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
Instead of everytime using configuration, you can inject option class whenever required as below. From inside the Startup.Configure method, you can extract values from the IConfiguration instance into your custom type using the following code:
builder.Services.AddOptions<MyOptions>()
.Configure<IConfiguration>((settings, configuration) =>
{
configuration.GetSection("MyOptions").Bind(settings);
});
Function class:
using System;
using Microsoft.Extensions.Options;
public class HttpTrigger
{
private readonly MyOptions _settings;
public HttpTrigger(IOptions<MyOptions> options)
{
_settings = options.Value;
}
}
Upvotes: 11
Reputation: 31
Tried and test approach where we can:
Some code snips below:
/// <summary>
/// Represents the startup class of the function app.
/// </summary>
public class Startup : FunctionsStartup
{
private const string LocalSettingFileGenericName = "appsettings";
private const string LocalSettingFileExtension = "json";
/// <summary>
/// Configures the host builder for the function app.
/// </summary>
/// <param name="builder">The function app host builder.</param>
public override void Configure(IFunctionsHostBuilder builder)
{
try
{
builder.AddConfiguration((configurationBuilder) =>
{
var configuration = typeof(Startup).Assembly.GetCustomAttribute<AssemblyConfigurationAttribute>().Configuration;
var configurationFileName = !string.Equals(configuration, "Release")
? $"{LocalSettingFileGenericName}.{configuration.ToLowerInvariant()}.{LocalSettingFileExtension}"
: $"{LocalSettingFileGenericName}.{LocalSettingFileExtension}";
var configurationSource = configurationBuilder
.AddJsonFile(configurationFileName, false, true)
.AddEnvironmentVariables();
var partialConfigurationBuilder = configurationSource.Build();
var keyVaultName = partialConfigurationBuilder.GetSection(ConfigurationKeys.KeyvaultName)?.Value;
return configurationSource
.AddKeyVaultWithManagedIdentity(keyVaultName)
.Build();
});
IFunctionBuilderExtensions.cs
internal static class IFunctionsHostBuilderConfigurationsExtensions
{
private const string keyVaultGenericUri = "https://{0}.vault.azure.net/";
/// <summary>
/// Provides an extension method to add configuration provider.
/// </summary>
/// <param name="builder">The function app host builder.</param>
/// <param name="configBuilderFunc">The delegate to pointing to configuration builder.</param>
/// <returns>The function app host builder</returns>
public static IFunctionsHostBuilder AddConfiguration(
this IFunctionsHostBuilder builder,
Func<IConfigurationBuilder, IConfiguration> configBuilderFunc)
{
var configurationBuilder = builder.GetBaseConfigurationBuilder();
var configuration = configBuilderFunc(configurationBuilder);
builder.Services.Replace(ServiceDescriptor.Singleton(typeof(IConfiguration), configuration));
return builder;
}
/// <summary>
/// Provides an extension method to add Azure Key Vault as a configuration provider.
/// </summary>
/// <param name="builder">The configuration builder.</param>
/// <param name="keyvaultName">The azure key vault name.</param>
/// <param name="authenticationClientId">The AAD application clientId.</param>
/// <param name="authenticationClientSecret">The AAD application clientSecret.</param>
/// <returns>The configuration builder.</returns>
public static IConfigurationBuilder AddKeyVaultWithManagedIdentity(
this IConfigurationBuilder builder,
string keyvaultName)
{
if (string.IsNullOrWhiteSpace(keyvaultName))
{
return builder;
}
var serviceTokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(serviceTokenProvider.KeyVaultTokenCallback));
var keyVaultUri = string.Format(keyVaultGenericUri, keyvaultName);
builder.AddAzureKeyVault(
keyVaultUri,
keyVaultClient,
new DefaultKeyVaultSecretManager());
return builder;
}
private static IConfigurationBuilder GetBaseConfigurationBuilder(this IFunctionsHostBuilder builder)
{
var configurationBuilder = new ConfigurationBuilder();
var descriptor = builder.Services.FirstOrDefault(
service => service.ServiceType == typeof(IConfiguration));
if (descriptor?.ImplementationInstance is IConfiguration configRoot)
{
configurationBuilder.AddConfiguration(configRoot);
}
var rootConfigurationBuilder = configurationBuilder.SetBasePath(GetCurrentDirectory());
return rootConfigurationBuilder;
}
private static string GetCurrentDirectory()
{
var currentDirectory = Path.GetDirectoryName(
Assembly.GetExecutingAssembly().Location);
return currentDirectory.Replace("bin", "{Your settings directory}");
}
Example for wrapper implementation:
/// <summary>
/// Represents the configuration settings provider class.
/// </summary>
public class ConfigurationSettings : IConfigurationSettings
{
private readonly IConfiguration configurationSource;
/// <summary>
/// Initializes the class of type <see cref="ConfigurationSettings"/>.
/// </summary>
/// <param name="configurationSource">The configuration source.</param>
public ConfigurationSettings(
IConfiguration configurationSource)
{
this.configurationSource = configurationSource;
}
///<inheritdoc/>
public T GetSetting<T>(string key)
{
try
{
if (!configurationSource.GetSection(key).Exists())
{
throw new ConfigurationDoesNotExistException(
$"The configuration with key {key} does not exist in appsetting or key vault.");
}
return (T)Convert.ChangeType(configurationSource.GetSection(key)?.Value, typeof(T));
}
catch (InvalidCastException)
{
throw;
}
catch (Exception)
{
throw;
}
}
}
Upvotes: 2
Reputation: 286
In Azure Functions, setting are stored in local.settings.json (create this file if doesn't exist in your solution/ name should be exact as mentioned).
once you add setting file, you have to configure it under your Run() method as mentioned bellow,
When Accessing setting, use below
IConfigurationRoot config;
config["fromEmail"];
use below command to publish settings
func azure functionapp publish *YourAppName* --publish-local-settings -i
Upvotes: 3
Reputation: 1001
According to the changes made to the configuration files, you should only use local.settings.json since the appsettings.json was renamed to local.settings.json
Reference to the change: azure-functions-cli
Upvotes: 15
Reputation: 339
For your needs the answer is YES! Azure Functions can use appsettings.json for your configurations. But there are some ordering sequence that Azure will do when a Function is requested.
1º) Azure will look for that KEYS that you used on .GetEnvironmentVariables("[KEY]") method, through Keys that were configured on Application Settings blade in Azure Functions settings
2º) If Azure wasn't able to find out that configurations through Application Settings keys, then Azure will try looking for after appsettings.json file into your root folder of the Function that you working on.
3º) Finally, if Azure wasn't able to find out this keys either on Application Settings neither on appsettings.json file, then Azure will do the last attempt to find out web.config for looking for into this file appsettings section keys.
For your appreciation, you'll able to find out these configurations by the sample on my github repo: here and here
I hope that these information help you.
Upvotes: 27
Reputation: 5
For dependencies you should use/create the project.json inside your function. There you can specify your dependencies. Please check: https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp#package-management
For example:
{
"frameworks": {
"net46":{
"dependencies": {
"Microsoft.ProjectOxford.Face": "1.1.0"
}
}
}
}
Upvotes: -3
Reputation: 13558
Only environment variables are supported for app settings and connection strings. appsettings.json
is not supported.
However, you can use Azure Resource Manager (ARM) Templates to configure the settings for your Function App. Here's a blog post that describe this in more detail.
Upvotes: 9