20

Using typesafe config, how do I override the reference configuration with an environment variable? For example, lets say I have the following configuration:

foo: "bar"

I want it to be overriden with the environment variable FOO if one exists.

David Rabinowitz
  • 29,904
  • 14
  • 93
  • 125
  • You can try other approaches like: http://stackoverflow.com/questions/24966621/overriding-multiple-config-values-in-typesafe-config-when-using-an-uberjar-to-de/24967100#24967100. I would suggest overriding them with `-D` JVM args - you don't need to know ahead of time/implement anything. – yǝsʞǝla Jul 07 '16 at 02:18
  • Thanks, but my problem with this suggestions is that I need to either convert the given environment variables to another file (and convert the keys on the fly) in order to use the referenced answer, or to specifically mention every parameter as a system property - which is what I do at the moment - but it is hard to manage and causes a lot of double maintanance – David Rabinowitz Jul 07 '16 at 07:03
  • You need to mention only the parameters that you are overriding either in config file or as CMD args. No need to list out all values – yǝsʞǝla Jul 07 '16 at 07:07
  • True, but I have an application which I pack into a docker image, and then the ops team can override many of the configuration parameters. We have tried it and it is hard to manage. – David Rabinowitz Jul 07 '16 at 07:09

3 Answers3

17

If I correctly understood your question, the answer is here. You can do

foo: "bar"
foo: ${?FOO}
Marco C
  • 706
  • 4
  • 6
  • 3
    I guessed I've missed that part, however it makes the configuration file very cumbersome - I need to duplicate all the fields I want to override, and I need to know I would want to override a certain variable. – David Rabinowitz Jul 05 '16 at 09:37
  • @DavidRabinowitz For the record, I've currently had to work with Golang configs working as you expected here (auto-substitution from env with same name). My stance is that the "cumbersome" hocon solution gives you much greater flexibility and avoid you going thru hoops to customize as needed. Which is quite relevant when env-vars provides values, and the naming might not be free for you to choose (i.e. DevOps) – pagoda_5b Jul 14 '21 at 07:33
15

The official doc now describes it very clearly and supports multiple options for this. Here is a brief summary...

Most common way is to use this form:

basedir = "/whatever/whatever"
basedir = ${?FORCED_BASEDIR}

If env variable is set, then it will override your default value, otherwise it will be left intact.

A more convenient way is to use JVM property -Dconfig.override_with_env_vars=true to override any config variable. In this case you don't have to create duplicate declarations. You env variables will have to be named with prefix CONFIG_FORCE_. See how env var to config name mapping works in the docs. As an example: CONFIG_FORCE_a_b__c___d will be mapped to a.b-c_d.

Finally, if you want to roll out your own mapping, which is similar to the option described above without using override_with_env_vars you can use some shell hacking as described below.

If you have to use environment variables and if their naming is consistent with config names you can use a bash script like this to automatically convert from your environment vars to JVM cmd args. These -D JVM args will override Typesafe Config values. Example:

# export my_PROP1=1
# export my_PROP2=2
#
# props=$(env | grep my_ | awk '{print "-D"$_}' ORS=' ')
#
# echo "JVM executable command is: java $props some.jar"
JVM executable command is: java -Dmy_PROP2=2 -Dmy_PROP1=1  some.jar

Convert upper to lower case, do substring operations on env vars as you please if they don't directly map to your config values.

yǝsʞǝla
  • 16,272
  • 2
  • 44
  • 65
2

I am using the System property -Dconfig.override_with_env_vars=true. With it all properties are automatically overridden via environment variables.

Harold L. Brown
  • 8,423
  • 11
  • 57
  • 109