Search code examples
c#azure-application-insights

How to configure program.cs to chose appsettings.[EnvironmentName].json


I have a .net core 6.0 project, where I am deploying a background service.

I have

appsettings.test.json

appsettings.staging.json

appsettings.json

Each configured to connect to different persistence layer.

Also, each has a different instrumentation key for application insights.

I can get the EITHER, the test or staging environment to deploy, but then the other other application insights ceases to function.

(I tried to copy the launchSetting.json file on deployment. That was just never overwritten)

But how do I ensure that the enviroment variable I have defined in my azure service, gets picked up in my program.cs file? And how do I debug which environment is actually chosen when the code has been deployed to azure and booted?

my program.cs file:

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices((hostServices, services) =>
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(hostServices.HostingEnvironment.ContentRootPath)
            .AddJsonFile($"appsettings.{hostServices.HostingEnvironment.EnvironmentName}.json", optional: false, reloadOnChange: true);
            
        var configuration = builder.Build();

        services.AddLogging();
        services.AddHostedService<Worker>();
        
        var aiOptions = new ApplicationInsightsServiceOptions
        {
            // Disables adaptive sampling.
            EnableAdaptiveSampling = false,
            // Disables QuickPulse (Live Metrics stream).
            EnableQuickPulseMetricStream = true
        };
        
        services.AddApplicationInsightsTelemetryWorkerService(aiOptions);
        ..........
);

Image of configuration value for environment

I have also added a variable: ASPNETCORE_ENVIRONMENT with the value "test" on my test resource.

And the corresponding configuration has been added to staging, but with the value "staging" instead.

However it seems that my environment variable does not use these particular values? How do I accomplish this?

EDIT:

I have now altered the worker service project, to be contained with a "normal" web-application project, this, allows me to host the worker service in the web-application, and this solves my immediate issue of sometimes the worker service doesn't start.

However, the environment variable issue persists. I still can only deploy whatever is in the "lauchsettings.json" file, the contents of this file is never overwritten by the azure configuration, and thus whatever environment is chosen in the source code, is what is deployed to all three nodes.

There must be a better way to debug errors of this kind, than "run a website that confirms the value of the environment selected", that is nuts, for something vital on a system like this?

If you search here on the azure web-api, you can see what the "console" logs locally on azure, and thus you can check your boot progress, provided you have added instrumentation messages. This allowed us to figure out why the service wasn't booting, and which environment variables were selected. Azure webapi


Solution

  • In Addition to @Guru Stron Answer.

    But how do I ensure that the enviroment variable I have defined in my azure service, gets picked up in my program.cs file?

    Add the below code in Program.cs file.

    var builder = WebApplication.CreateBuilder(args);
    var env = builder.Environment.EnvironmentName;
    IConfigurationBuilder myconfig = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json", true)
        .AddJsonFile($"appsettings.{env}.json", true)
        .AddEnvironmentVariables();
    

    We can display sample value and check which environment value is displayed.

    Check the below workaround to load values from appsettings.json based on the environment.

    • Here Iam setting Values in all the appsettings files.

    Example:

     Test Env: "values": "From Test Environment"
     Devel Env: "values": "Value from Development Environment"
     Production Env: "values": "From Production Environment"
    
    • As you are trying to access value from test environment, Iam setting the ASPNETCORE_ENVIRONMENT as test in Azure App Settings.

    In .cshtml file,

    @inject IConfiguration myconfig
    <h2>@myconfig["Values"]</h2>
    

    enter image description here

    Output: enter image description here

    Update :

    In Worker.cs file, Add the below lines of code.

            public IConfiguration _config;
            public Worker(ILogger<Worker> logger,IConfiguration config)
            {
                _logger = logger;
                _config = config;
            }
              protected override async Task ExecuteAsync(CancellationToken stoppingToken)
            {
                while (!stoppingToken.IsCancellationRequested)
                {
                    //var env = config.GetValue<string>("Values");
                    _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                    _logger.LogInformation(_config.GetValue<string>("Values"));
                    await Task.Delay(1000, stoppingToken);
                }
            }
    

    You can check this in local as well by setting the Environmnet Variable.

    enter image description here

    enter image description here

    Output: enter image description here