Deep Dive into Spring Boot Config Server Composite

Introduction
In today’s microservices architecture, managing configuration across multiple services and environments is crucial for maintaining consistency and flexibility. Spring Cloud Config Server provides a centralized way to manage external properties for applications across all environments. One of its powerful features is the ability to use a composite environment repository, allowing you to combine multiple configuration sources seamlessly.
In this article, we’ll explore how to set up and use composite repositories in Spring Boot 3, complete with practical examples to help you implement this feature in your projects.
Need help with Spring Framework? Master Spring TER, a ChatGPT model, offers real-time troubleshooting, problem-solving, and up-to-date Spring Boot info. Click master-spring-ter for free expert support!
1. Understanding Spring Cloud Config Server
Spring Cloud Config Server is a central place to manage external properties for applications across all environments. It provides:
- Centralized Configuration Management: Store and serve configuration properties from a central location.
- Version Control Integration: Leverage Git or other version control systems to manage configurations.
- Environment-Specific Configurations: Support for different configurations per environment (development, staging, production).
By externalizing configuration, applications can be reconfigured at runtime without redeployment, enhancing flexibility and scalability.
2. What is a Composite Environment Repository?
A Composite Environment Repository in Spring Cloud Config Server allows you to combine multiple configuration sources into a single logical repository. This means you can:
- Merge configurations from different repositories (e.g., multiple Git repos, local files, Vault, JDBC).
- Prioritize certain repositories over others.
- Provide fallback configurations if a primary source is unavailable.
This feature is particularly useful when:
- Migrating configurations from one system to another.
- Combining shared and application-specific configurations.
- Integrating secure configurations from Vault with versioned configurations in Git.
3. Setting Up a Spring Boot 3 Config Server
Let’s start by setting up a basic Config Server using Spring Boot 3.
Step 1: Create a New Spring Boot Application
Use Spring Initializr to generate a new Spring Boot project with the following dependencies:
- Spring Cloud Config Server
- Spring Boot Actuator (optional, for monitoring)
Step 2: Update build.gradle
or pom.xml
For Gradle (build.gradle):
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.0' // Use the latest version
id 'io.spring.dependency-management' version '1.1.0'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-config-server'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:2022.0.3"
}
}
For Maven (pom.xml):
<project xmlns="http://maven.apache.org/POM/4.0.0" ...>
<!-- ... -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
<!-- Use the latest version -->
</parent>
<!-- ... -->
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2022.0.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Step 3: Enable Config Server
Create a main application class and annotate it with @EnableConfigServer
.
package com.example.configserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
Step 4: Configure Application Properties
In src/main/resources/application.yml
, set up the basic configuration.
server:
port: 8888
spring:
application:
name: config-server
4. Configuring Composite Repositories
Now, let’s configure the Config Server to use composite repositories.
4.1 Using Multiple Git Repositories
To combine configurations from multiple Git repositories:
spring:
profiles:
active: composite
cloud:
config:
server:
composite:
- type: git
uri: https://github.com/your-org/shared-config.git
search-paths:
- common
- type: git
uri: https://github.com/your-org/app-specific-config.git
search-paths:
- {application}
Explanation:
spring.profiles.active: composite
: Activates the composite configuration.spring.cloud.config.server.composite
: Defines a list of repositories.- First Repository (
shared-config.git
): - Contains common configurations shared across applications.
search-paths: common
specifies the directory within the repo.- Second Repository (
app-specific-config.git
): - Contains configurations specific to applications.
search-paths: {application}
allows dynamic resolution based on the application name.
4.2 Combining Git and Native File System
To combine a Git repository with local file system configurations:
spring:
profiles:
active: composite
cloud:
config:
server:
composite:
- type: git
uri: https://github.com/your-org/config-repo.git
search-paths:
- {application}
- type: native
search-locations: classpath:/config-overrides
Explanation:
- First Repository: Same as before, pulling from Git.
- Second Repository (
native
): - Reads configurations from the local classpath (
src/main/resources/config-overrides
). - Useful for overriding configurations during development or in emergencies.
4.3 Incorporating Vault or JDBC Sources
To include secure configurations from Vault and properties from a database:
spring:
profiles:
active: composite
cloud:
config:
server:
composite:
- type: vault
host: vault.example.com
port: 8200
scheme: https
backend: secret
- type: jdbc
sql: SELECT KEY, VALUE FROM CONFIG_PROPERTIES WHERE APPLICATION=? AND PROFILE=?
order: 1
- type: git
uri: https://github.com/your-org/config-repo.git
search-paths:
- {application}
order: 2
Explanation:
- Vault Repository:
- Retrieves secure configurations from a Vault server.
- JDBC Repository:
- Fetches configurations from a database using the provided SQL query.
order
: Determines the precedence of repositories (lower number = higher priority).- Git Repository:
- Serves as a fallback if configurations are not found in the higher-priority repositories.
5. Client Application Configuration
Client applications need to point to the Config Server to fetch configurations.
Step 1: Add Dependencies
In the client application’s build.gradle
or pom.xml
, include:
- Spring Cloud Starter Config
Gradle:
implementation 'org.springframework.cloud:spring-cloud-starter-config'
Maven:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
Step 2: Configure bootstrap.yml
Create a bootstrap.yml
(or bootstrap.properties
) file in src/main/resources
:
spring:
application:
name: my-application
cloud:
config:
uri: http://localhost:8888
fail-fast: true
Explanation:
spring.application.name
: The name used to fetch configurations (matches{application}
in search paths).spring.cloud.config.uri
: URL of the Config Server.fail-fast: true
: Fails the application startup if the Config Server is not available.
6. Testing the Composite Configuration
Step 1: Start the Config Server
Run the Config Server application.
Step 2: Verify Configurations
Access the Config Server endpoints to verify that configurations are being merged correctly.
- For specific application and profile:
http://localhost:8888/{application}/{profile}
- Example:
http://localhost:8888/my-application/dev
Step 3: Check the Response
The response will be a JSON object containing properties from all configured repositories, merged according to their order.
Step 4: Run the Client Application
Start the client application and ensure it fetches the configurations correctly.
Step 5: Logging
Enable debug logging to see detailed information:
logging:
level:
org.springframework.cloud.config: DEBUG
7. Best Practices
- Ordering Matters: Use the
order
property to control the precedence of repositories. - Secure Sensitive Data: Store sensitive configurations in secure repositories like Vault.
- Version Control: Keep your configurations versioned in Git for traceability.
- Environment Segregation: Use profiles (
dev
,staging
,prod
) to separate configurations. - Fallback Mechanisms: Include local or default configurations as fallbacks.
8. Conclusion
Using a composite environment repository in Spring Boot Config Server allows for flexible and powerful configuration management across your microservices. By combining multiple sources, you can centralize configurations, manage sensitive data securely, and ensure that your applications are configured consistently across all environments.
With Spring Boot 3 and Spring Cloud 2022.x, setting up and managing composite repositories is straightforward. We encourage you to explore this feature and incorporate it into your microservices architecture to enhance your configuration management strategy.