I am trying to follow guidance that would allow azure functions (v2) to use app settings json files for each environment (dev, test, stage, prod).
Approach 1 - Using ExecutionContext Based on this article, I attempted the following code. The settings are never returned from the local.settings.json which is included in the published code.
[FunctionName("ScheduleApp")]
public async Task Run([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, ILogger log, ExecutionContext context)
{
log.LogInformation($"ScheduleApp triggered...");
try
{
var configurationBuilder = new ConfigurationBuilder()
.SetBasePath(context.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
var y = configurationBuilder.GetConnectionStringOrSetting("somesetting");
var x = configurationBuilder["test"];
log.LogInformation($"x = {x}, y = {y});
}
catch (Exception ex)
{
log.LogInformation($"exception = {ex.Message}");
}
Approach 2 - Using startup.cs ConfigurationBuilder
FunctionOptions.cs is a class I wrote that is a set of properties that matches the configuration in the local.settings.json file Values collection. The IOptionsMonitor of this class is passed in the constructor of the azure function shown below. values from the json file are not returned in this approach either.
Startup.cs....
public override void Configure(IFunctionsHostBuilder builder)
{
var configurationBuilder = new ConfigurationBuilder();
var descriptor = builder.Services.FirstOrDefault(d => d.ServiceType == typeof(IConfiguration));
if (descriptor?.ImplementationInstance is IConfigurationRoot configuration)
{
configurationBuilder.AddConfiguration(configuration);
}
Configuration = configurationBuilder.Build();
builder.Services.AddOptions<FunctionOptions>();
builder.Services.Configure<FunctionOptions>(Configuration);
builder.Services.Configure<FunctionOptions>(Configuration.GetSection("Values"));
}
ScheduleApp.cs....
public ScheduleApp(IConfiguration configuration, IOptionsMonitor<FunctionOptions> optionsAccessor)
{
_functionOptions = optionsAccessor.CurrentValue;
_configuration = configuration;
}
[FunctionName("ScheduleApp")]
public async Task Run([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, ILogger log, ExecutionContext context)
{
log.LogInformation($"ScheduleApp triggered...");
try
{
var z = "";
if (_functionOptions != null)
z = _functionOptions.somesetting;
else
log.LogInformation("_funcionsOption is null");
log.LogInformation($"_funcionsOption = {z}");
}
catch (Exception ex)
{
log.LogInformation($"_funcionsOption exception, ex={ex.Message}");
}
Neither of these approaches yield the configuration values. I tried adding the .json files as content in the azure function. I played around with the environment variable AZURE_FUNCTIONS_ENVIRONMENT as I expected this would control which set of settings were used (by environment). Nothing is working.
I must be missing something. Can someone point towards what I'm missing or a working c# sample of either approach? Ideally it would also show how to manage each environment setting as in
- appsettings.dev.json
- appsettings.test.json
- appsettings.stage.json
- appsettings.prod.json