Search code examples
spring-bootmicroservicesspring-cloud-config

How to create Spring Cloud Config Client with env specific configuration?


I have facing an issue with Spring Cloud Config Server and Eureka Server Profiling.
Let's say I have 3 services with their name ("spring.application.name") as :

myapp-svc
myapp-spring-cloud-config-svc
myapp-spring-eureka-svc

I want to deploy each service in 2 regions ( dev and prod ). In Dev region, each service will run on localhost and in prod it will have some different url. 'myapp-spring-cloud-config-svc' in dev region will point to local git repo, while in prod region it will point to remote git repo.I can have 2 configurations:

1) When I start 'myapp-svc' service in local, it should connect to 'myapp-spring-cloud-config-svc' in dev. I can do this by setting spring.cloud.config.uri = . But the issue with this set up is that the property needs to be defined in bootstrap.properties. So, If deploy 'myapp-svc' to prod, I will have to change config uri there to point it to prod config service which in turn would need another build creation. This doesn't seem like a good solution, what if I have 50 app related services, I can't change this property in each one of them before prod deployment. I tried setting spring.cloud.config.uri in application-dev.properties of 'myapp-svc' but it doesn't work. As per docs, it must be changed in bootstrap.

  So, how do I implement this without having to create new build for prod ?

2) I can first call eureka and then using eureka I can call config service here. The problem here is also same. If I use eureka to look up config then "eureka.client.serviceUrl.defaultZone" must be defined in "bootstrap.yml". See this:https://cloud.spring.io/spring-cloud-config/multi/multi__spring_cloud_config_client.html So, in this case too, I need to change eureka url before deploying this service to prod. Please help me on this...!! Here is how, the properties, yml looks like for each of the above mentioned services:

1) myapp-svc:
   1.1)bootstrap.yml  
        spring:
         application:
           name: myapp-svc 
         cloud:
           config:
             discovery:
               enabled: true
               serviceId: myapp-spring-cloud-config-svc
        eureka:
           client:
              serviceUrl:
                defaultZone: http://localhost:8762/eureka/
        server:
           port: 8082


    2) myapp-spring-cloud-config-svc:

      2.1)application-dev.properties:
           spring.cloud.config.server.git.uri=file:///C:/config-repo
           eureka.client.serviceUrl.defaultZone=http://localhost:8762/eureka

      2.2)application-prod.properties:
           spring.cloud.config.server.git.uri=https://github.com/<mygit Repo>

      2.3)bootstrap.proerties:
           spring.application.name=myapp-spring-cloud-config-svc
           server.port=8888


    3) myapp-spring-eureka-svc
       3.1)bootstrap.proerties
        spring.application.name=myapp-spring-eureka-svc
        server.port=8762

Solution

  • 1) You can have profile specific bootstrap-<profile>.properties (like for application-<profile>.properties) for each supported profile to avoid rebuilding your application for each env. Then just pass application profile using to your application during start-up. Spring will load correct bootstrap-<profile>.properties and will connect to proper configuration server (or eureka, etc). Example:

    java -jar your-app.jar --spring.profiles.active=dev
    

    2) You can pass your URLs externally as custom properties (same as with profile above) and have smth like this in bootstrap.properties. Example:

    spring.cloud.config.uri=${config.server.url}
    

    then pass --config.server.url= ... during start-up.

    3) You can pass Spring properties in the same way during start-up. Example:

    java -jar your-app.jar --spring.cloud.config.uri= ...
    

    4) You can use system env variables. Example:

    spring.cloud.config.uri=${SYSTEM_ENV_CLOUD_CONFIG_URI}