EF Core & ASP.NET Core: Read Connections Strings & Config Values from Environment Variables

by

If you’ve gone digging around in EF Core and ASP.NET Core, you’ve probably seen ConfigurationBuilder code that looks like this:

var builder = new ConfigurationBuilder()
    .SetBasePath(basePath)
    .AddJsonFile("appsettings.json")
    .AddJsonFile($"appsettings.{environmentName}.json", true)
    .AddEnvironmentVariables();
 
var config = builder.Build();
 
var connstr = config.GetConnectionString("default");

When you see generated code like this a couple zillion times, it’s easy to kind of forget to ask yourself what it means.  It works fine so nevermind the details.  ConfigurationBuilder adds the various configuration sources to the builder and then when you call Build() it creates the actual configuration settings for your application.  The calls for AddJsonFile() make sense — those set us up to read config values from appsettings.json.

But what’s that “AddEnvironmentVariables()” call doing there?

Well, one of our configuration value source options are the system environment variables.  If AddEnvironmentVariables() is the last item added to your ConfigurationBuilder — whether you’re running on Windows or Linux — it overrides any variables in your appsettings.json with values with local environment variables.

So let’s say that your appsettings.json looks like the file below.  It specifies a connection string named “default”.

{ 
   "ConnectionStrings": { 
     "default": "Server=192.168.5.1; Database=DbContextFactorySample3; user id=database-user; password=Pa$$word;" 
   } 
}

A lot of times, the connection string that’s specified in appsettings.json is the connection string value for the developer workstations and when you go to production, it’ll be a different value.  That production database connection string should never go in to version control and probably isn’t shared with the developers.  What an IT admin could do is specify the database connection string as an environment variable on the server and now that value is automatically picked up by EF Core.

You can try this out on your developer machine, too.  Go to the command line and set an environment variable named “ConnectionStrings__default” with a completely different value for the connection string.  Then run your app.  It should pick up the new connection string from the environment variable.

On Windows, you can set an environment variable by calling the following

set "ConnectionStrings__default=Server=the-production-database-server; Database=DbContextFactorySample2; Trusted_Connection=True;"

On Linux, if you want to temporarily set an environment variable, you can do this by executing

export ConnectionStrings__default="Server=the-production-database-server; Database=DbContextFactorySample2; Trusted_Connection=True;"

You can do this for other values in your appsettings.json, too.  Whenever you go to a new “level” in the json document just separate the values by using two underscores ‘__’.

Anyway, this can be a handy little trick for handling environment-specific configurations in your DevOps pipelines.

I hope you get some use out of this.

-Ben

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.