Spring Cloud Config for Centralized Microservice configuration

Anupriya Kumawat
5 min readMay 23, 2022

--

Microservices approach now has become an industry standard, the microservice architecture is very powerful and in wide use across large and small tech companies.

Spring boot is very popular framework which is being used widely to create microservices.

Problem

It is easy to create dozen and hundreds of microservices for a project using spring boot framework, but the problem is, each microservice has it’s own configurations that too with different-2 environment like development, staging and production. Which makes it more complicated.

when we want to change the configuration of a microservice we need go to the corresponding microservice and change a particular file of an environment(development, staging, production), change its configuration and then restart the application for the change to take effect.

Spring-cloud-config provide the solution for the same.

Spring Cloud Config

Spring Cloud Config provides server-side and client-side support for externalized configuration in a distributed system. With the Config Server, you have a central place to manage external properties for applications across all environments. The concepts on both client and server map identically to the Spring Environment and PropertySource abstractions, so they fit very well with Spring applications.

spring cloud config dependency is integrated with spring boot framework.
spring cloud config provides support for storing/reading the configuration from git repository and Amazon S3 etc.

In order to work with spring cloud config we need
1. a dedicated “config server” app from which each microservice can download its configuration data.
2. a Github repository as configuration storage.
3. a config client micro service to consume configuration from config server which are saved in Git Storage.

Spring cloud config server

The cloud config server behave as an intermediate application between spring boot applications/client and Github configuration storage.

Config Server Implementation : Create a spring boot application using https://start.spring.io/ .

Add the following dependencies :

implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.cloud:spring-cloud-config-server'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

Open your application’s main class and add the @EnableConfigServer annotation:

The main part of the application is a config class, more specifically a @SpringBootApplication, which pulls in all the required setup through the auto-configure annotation @EnableConfigServer:

Annotate the Main Class with @EnableConfigServer:

@SpringBootApplication
@EnableConfigServer
public class DemoConfigServerApplication {

public static void main(String[] args) {
SpringApplication.run(DemoConfigServerApplication.class, args);
}

}

By default Spring cloud config uses Git backend as configuration storage, so we are going with the same.

Add the below properties in the application properties file with Git config storage details.

server.port=8888
spring.application.name=clientServer
spring.cloud.config.server.default-label=master
spring.cloud.config.server.git.uri=https://github.com/kumawatanupriya/demo-cloud-config.git
management.endpoints.web.exposure.include=*
management.endpoint.env.post.enabled=true

Now start the config server, the Github config storage URL defined in config server properties has some property values based on application name and environment , now server can query the config using following paths.

/{application}/{profile}[/{label}] 
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

The {label} placeholder refers to a Git branch, {application} to the client’s application name, and the {profile} to the client’s current active application profile.

Note : please find the config server code here.

Spring cloud config client

Now create a new application/microservice whose config properties will be stored in Git storage defined in config-server properties file.
you can use this url https://start.spring.io/ to create the spring boot app.

Add the following dependencies.

implementation 'org.springframework.boot:spring-boot-starter-web'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-config'
implementation 'org.springframework.boot:spring-boot-starter-webflux'

See the difference, we used spring-cloud-config-server dependency in server application and using spring-cloud-starter-config dependency in client application.

Now in order to fetch our server, the configuration must be placed in the application.properties file using spring.config.import property.

spring.application.name=demo
spring.config.import=configserver:http://localhost:8888
management.endpoints.web.exposure.include=*
management.endpoint.env.post.enabled=true
spring.profiles.active=test

Note : Active profile is test so client will read the configurations from demo-test.properties file available in git storage.

The demo application has a property names inventory.initial.mode.
it’s value is stored in demo-test.properties file in Git backend defined in config server. check the git repo here.

Using @RefreshScope to refresh the property inventory.initial.mode value in application context.

@Component("inventoryMode")
@NoArgsConstructor
@ConfigurationProperties(prefix = "inventory.initial")
@RefreshScope
public class InventoryMode {

private String mode;

public void setMode(String mode) {
this.mode = mode;
}

public String getMode() {
return mode;
}
}

Controller to check the value:

@RestController
@Validated
@RequiredArgsConstructor
@NoArgsConstructor
public class StatusController {

@Autowired
InventoryMode inventoryMode;

@GetMapping("/mode")
public String getMethod() throws RuntimeException {
return inventoryMode.getMode();

}
}

Now run the client config application. And check the default value of above property saved in Github.

InventoryMode class has @Component annotation, this component will be re-created when a configuration refresh occurs, in this case giving an updated value for inventory.initial.mode will re-create the bean.

You can refresh an application’s configuration by including the Spring Boot Actuator dependency, exposing the /actuator/refresh endpoint, and sending an empty POST request.

The Spring Boot Actuator has already been included in your microservice’s dependencies.

Note : Please read more about Spring Boot Actuator here.

Now Change the inventory.initial.mode in Github repository manually OR you can expose an /actuator/env endpoint(already exposed in client, check above properties) and send POST request and in body pass the latest value of inventory.initial.mode .

Now in order to refresh the property in the application context hit a /actuator/refresh.

It will refresh the property by re-creating the bean of InventoryMode class, without restarting the demo config-client application.

Check the value:

Before Spring Cloud Config :

Different micro services handling it’s own configurations

After Spring Cloud Config :

Now we’re able to create a configuration server to provide a set of configuration files from a Git repository to client applications.

Happy Reading !!!

--

--