Environment variables configuration in .NET Core
Asked Answered
B

3

20

I'm using the .NET Core 1.1 in my API and am struggling with a problem:

  1. I need to have two levels of configurations: appsettings.json and environment variables.
  2. I want to use the DI for my configurations via IOptions.
  3. I need environment variables to override appsettings.json values.

So I do it like this so far:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables();
}

public IServiceProvider ConfigureServices(IServiceCollection services)
{
     // Something here
     services.Configure<ConnectionConfiguration>(options =>
            Configuration.GetSection("ConnectionStrings").Bind(options));
     // Something there
}

With my appsettings.json composed like this

{
    "ConnectionStrings": {
        "ElasticSearchUrl": "http://localhost:4200",
        "ElasticSearchIndexName": "myindex",
        "PgSqlConnectionString": "blablabla"
    }
}

I get all the configurations mapped to my class ConnectionConfiguration.cs. But I cannot get the environment variables to be mapped as well. I tried the names like: ConnectionStrings:ElasticSearchUrl, ElasticSearchUrl, even tried specifying the prefix to .AddEnvironmentVariables("ConnectionStrings") without any result.

How should I name the environment variables so it can be mapped with services.Configure<TConfiguration>()?

Biforate answered 4/9, 2017 at 13:53 Comment(5)
When you tried naming the variable to "ConnectionStrings:ElasticSearchUrl", what happened? What was the resulting key in the configuration? Can you make sense of the second part of the accepted answer in this question: #37874464 ?Rusel
@lenkan, I get nothing from the EV, the model is filled with nulls. I definitely checked the very same part of the documentation, but it didn't help me. In fact, I can't even see the variables I just put in in System.Environment.GetEnvironmentVariables().Biforate
Ah, so the real problem is that you are not able to read the environment variables. That has nothing to do with the ConfigurationBuilder. I would try to solve that issue first.Rusel
Yeah, I believe the problem is that since I already debugged it all, and everything should work fine. The paths are okay, even .GetSection works, but the variables are so wrong (((Biforate
Can anyone suggest me how to use prefixed environment variables here. I have tried using .AddEnvironmentVariables(prefix:"you-prefix"); and read required env variable like configuration["env-variable-name-without-prefix"] But I did not get the correct value. What i'm doing wrong here?Diphenylhydantoin
A
28

The : separator doesn't work with environment variable hierarchical keys on all platforms. __, the double underscore, is supported by all platforms and it is automatically replaced by a :

Try to name the environment variable like so ConnectionStrings__ElasticSearchUrl

Source

Ayeshaayin answered 8/7, 2020 at 11:45 Comment(1)
In addition, in case you have to override array settings, you can use something like this: Serilog__WriteTo__0__Args__serverUrlMelancon
F
7

Have a look at ASP.NET Core Configuration with Environment Variables in IIS

To do the same with environment variables, you just separate the levels with a colon (:), such as HitchhikersGuideToTheGalaxy:MeaningOfLife.

In your case you'll use ConnectionStrings:ElasticSearchUrl as mentioned in your question.

Also notice the following:

When you deploy to IIS, however, things get a little trickier, and unfortunately the documentation on using configuration with IIS is lacking. You go into your server's system settings and configure all your environment variables. Then, you deploy your app to IIS, and it... explodes, because it's missing those necessary settings.

Turns out, in order to use environment variables with IIS, you need to edit the advanced settings for your App Pool. There, you'll find a setting called "Load User Profile". Set that to True. Then, recycle the App Pool to load in the environment variables. Note: you must do this even if your environment variables are added as "System variables", rather than "User variables".

Fultz answered 20/12, 2017 at 5:0 Comment(1)
Thank you for this answer, I was trapped in an infinite loop and you escaped me!Hunnicutt
M
3

I believe you're looking for this:

var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();
        this.Configuration = builder.Build();

I've 3 configurations

  1. dev-final
  2. dev-local
  3. dev-test

And 4 *.json files

  • appsettings.json
  • appsettnigs.dev-final.json
  • appsettings.dev-local.json
  • appsettings.dev-test.json

appsettings.json holds global configuration values, and the other files specific ones.

Maguire answered 4/9, 2017 at 15:21 Comment(6)
Not at all, he is trying to scope the environment variables like he is doing with the appsetting.json.Rusel
Sounds wrong to me. Why would you create a enviroment specific config file and then overwrite things in this configuration file by a another environment variable? Simply change the value in the specific file.Maguire
Perhaps, but sometimes you just want temporary config that is not really part of a specific environment. Thus, you might not want the overhead of editing a config file for that. Then a good option is to use environment variables or command line arguments to override entries in the configuration file. So I think the use case is valid.Rusel
TBH I host my app in the AWS and I need to switch to different Index versions without redeploying the app.Biforate
@Rusel I belive it is. I've never tried it, but the code from your link looks like the one I posted.Maguire
@Maguire Fair enough. I was trying to point out that the last part of that answer was talking about overriding configuration file settings with environment variables though.Rusel

© 2022 - 2024 — McMap. All rights reserved.