Hacker News new | ask | show | jobs
by JohnCurran 1183 days ago
I have been having a ridiculous time trying to find out just how to override an appsettings json variable (DBConnection string) with an environment variable. Could not find any good answer. What is the right way?
4 comments

Configuration is applied in layers. If you’re using the default setup you get the following layers applied in this order:

1. appsettings.json

2. appsettings.{env}.json

3. user secrets (only in Development environment)

4. environment variables

5. command line args

You can full customize the setup if you desire, there are packages to support things like external secret stores. If you Google ‘Asp.Net core configuration” there’s a MS page that goes into great detail on all of this.

Anyway, your env vars must match the name as you’d structure it in a json object, but with the periods replace with double underscores. So ConnectionStrings.MyConnection becomes CONNECTIONSTRINGS__MYCONNECTION, FeatureFlags.Product.EnableNewIdFormat becomes FEATUREFLAGS__PRODUCT__ENABLENEWIDFORMAT, etc.

Awesome overview, stuff like this is often hard for newcomers to find/figure out. I'm sure it's in the docs somewhere but people often miss it.

One nitpick: environment vars don't have to be capitalized. You can do ConnectionStrings__MyConnection so the casing matches what you see in appsettings.json.

And a word of warning: make sure to understand how the configuration overrides work. If you have appsettings.json define an array of auth servers with 5 elements, then in appsettings.Production.json (or env variables) define an array of auth servers with only 1, auth servers 2-5 from the default appsettings.json will still be there! (something similar to this may or may not have caused a scare in the past)

Yep, it really just works with key/value pairs, so config overrides happen to individual keys. The config system itself doesn't really have a concept of nested objects or arrays. The config provider that reads the json file takes the path, like JobSettings[0].JobName, and transforms it into into a key like JobSettings:0:JobName (IIRC).

I tend to avoid using arrays in config because of the unexpected behavior, and the risk of overriding something you didn't mean to. Anywhere you'd use an array you can usually use an object and bind it to a Dictionary<string, Whatever>, then ignore the keys.

Word of caution. Azure functions implements appSettings differently.
Thank you - I had read that portion of the docs but for whatever reason that part of it just didn’t click. For some reason it made me think I could only use some special subset of env vars that were prefixed with ASPNET_CORE or similar
You can have multiple appsettings files and are additive. Eg, you can have appsettings.production.json which only contains an override for the connection string in the base appsettings.json.
I believe GP is asking about using runtime environment variables passed in through the shell or injected when starting a Docker container, i.e. the 12factor.net approach.
I think it's just:

builder.Configuration.AddEnvironmentVariables();

Then you can use an env variable like "Foo__Bar=X" to override Foo.Bar from your appsettings json.

If using the default builder, environment variables are included automatically as a configuration provider.
Probably not the right way, but if all else fails just prefix with

  System.Environment.GetEnvironmentVariable("NAME") ?? ...