Search code examples
spring-bootenvironment-variablesspring-boot-configuration

Why env variable is not overwriting the spring's configuration?


I have a spring-boot application with a ConfigurationProperties class. I am deploying the app with helm + kubernetes so passing the env variables to overwrite the config values. But somehow, some variables are not overwritten by this env variables and I cannot see why. The config class looks like:

@ConstructorBinding
@ConfigurationProperties("abc-config")
data class AbcConfiguration(
    private var authorizationConfigs: List<TokenGrantConfiguration> = listOf(),
) {}

class TokenGrantConfiguration(
    clientId: String,
    clientSecret: String,
)

And my env variables are like:

ABC_CONFIG_AUTHORIZATION_CONFIGS_0_CLIENT_ID="some_client_id"
ABC_CONFIG_AUTHORIZATION_CONFIGS_0_CLIENT_SECRET="some_client_secret"

Just to add, my app also has the SPRING_APPLICATION_JSON variable as :

{
    abc-config: {
      "authorization-configs": [
        {
          "clientId": "",
          "clientSecret": ""
        }
      ]
    }
}

So when I run the app, the clientId and secret values are both empty, not overwritten by the env variables. I have also checked with System.env("...") to check if the env variables are set right and they seem are right.

Any ideas what I am missing?

Thanks


Solution

  • The rules for mapping environment variable names to Spring properties are:

    • Replace dots (.) with underscores (_).
    • Remove any dashes (-).
    • Convert to uppercase.

    If your property names are hyphenated or camel-cased, the environment variable name does not have an extra underscore between the human-readable words; they are just mashed together.

    In your code, the name abc-config would map to an environment-variable component ABCCONFIG, the property clientId to CLIENTID, and so on. The environment variable name I'd expect to work is

    ABCCONFIG_AUTHORIZATIONCONFIGS_0_CLIENTID="some_client_id"