Search code examples
javaspringspring-bootspring-cloudspring-cloud-config

Spring profiles not ordering correctly when obtaining config from Spring Cloud Config Server


I have a Spring Boot application obtaining configuration from Spring Cloud config server (native mode). The base application.yml file in the config location loaded by the config server contains the following:

eureka:
  client:
    service-url:
      defaultZone: ${BOOT_EUREKA_LOCATIONS:http://instance1.localhost:7761/eureka,http://instance2.localhost:7762/eureka,http://instance3.localhost:7763/eureka}
  register-with-eureka: true
---
spring:
  profiles: test
eureka:
  client:
    register-with-eureka: false #no registration on Eureka when testing
    service-url:
      defaultZone: ${BOOT_EUREKA_LOCATIONS:http://sparky:8761/eureka}

When hitting the endpoint for config server (http://mygateway/config-server/myapp/test), I get back the following for the "myapp" application running in profile "test":

{
"name": "myapp",
"profiles": [
    "test"
],
"label": null,
"version": null,
"state": null,
"propertySources": [
    {
        "name": "file:////wherever/application.yml#test",
        "source": {
            "spring.profiles": "test",
            "eureka.client.register-with-eureka": false,
            "eureka.client.service-url.defaultZone": "${BOOT_EUREKA_LOCATIONS:http://sparky:8761/eureka}"
        }
    },
    {
        "name": "file:////whereever/application.yml",
        "source": {
            "eureka.client.service-url.defaultZone": "${BOOT_EUREKA_LOCATIONS:http://instance1.localhost:7761/eureka,http://instance2.localhost:7762/eureka,http://instance3.localhost:7763/eureka}"

When running myApp in the test profile, the value of eureka.client.service-url.defaultZone is http://instance1.localhost:7761/eureka,http://instance2.localhost:7762/eureka,http://instance3.localhost:7763/eureka, which is unexpected.

I would have expected the entry in the test profile to override it (as it does if you have the application.yml locally). Thoughts on why I wouldn't be getting the value from the "test" profile when using the value in myApp?

My intent would be to add the "default" values at the top, and have the "profile" override any non-standard defaults.

Update: myApp/env does NOT show the "application.yml#test" loaded, however it shows the test profile, but only the default values returned back from the config server (not the #test ones):

{
  "profiles": [
    "test"
  ],
  "server.ports": {
    "local.server.port": 7761
  },
  "configService:file:////wherever/application.yml": {
    "eureka.client.service-url.defaultZone": "http://instance1.localhost:7761/eureka,http://instance2.localhost:7762/eureka,http://instance3.localhost:7763/eureka"

Solution

  • It was a complete user error. I was setting the default "test" active profile in the application.yml instead of passing in as an environment variable or bootstrap.yml, therefore it wasn't loaded soon enough for the config server hit.