Centralized Configuration Management with Spring Cloud Config Server
An enterprise-grade, deep-dive guide to designing, implementing, securing, and scaling centralized configuration in distributed microservices architectures using Spring Boot 3.x, Spring Cloud, HashiCorp Vault, and Apache Kafka.
Table of Contents
- 1. Introduction to Centralized Configuration
- 2. What is Spring Cloud Config? (AEO Featured Snippet)
- 3. Architectural Blueprint & Workflows
- 4. Designing the Git Configuration Repository
- 5. Step-by-Step Implementation: The Config Server
- 6. Step-by-Step Implementation: The Config Client (Spring Boot 3.x)
- 7. Advanced Security: Symmetric & Asymmetric Encryption
- 8. Enterprise Secrets Management with HashiCorp Vault
- 9. Dynamic Configurations with Spring Cloud Bus and Kafka
- 10. Resiliency, Caching, and High Availability (HA)
- 11. Operational Best Practices & Git Branching Strategies
- 12. Troubleshooting & Common Failure Modes
- 13. Monitoring & Observability Metrics
- 14. Deep-Dive Interview Questions & Answers
- 15. Frequently Asked Questions (FAQ)
- 16. Summary & Next Steps
1. Introduction to Centralized Configuration
In a monolithic application, managing configuration is relatively straightforward. Properties are typically stored in a single application.properties or application.yml file packaged within the deployable artifact. However, as organizations transition to microservices architecturesβdeploying dozens, hundreds, or thousands of independent service instancesβthis traditional approach breaks down completely.
Managing configurations locally inside each microservice artifact introduces severe operational bottlenecks:
- Rebuild and Redeploy Cycles: Changing a simple configuration parameter (such as a database connection timeout or a feature flag) requires rebuilding the container image and redeploying the service. This introduces unnecessary downtime and risk.
- Environment Drift: Manually maintaining separate configuration files for Development, Testing, Staging, and Production environments often leads to discrepancies. A missing property in Production can cause catastrophic runtime failures.
- Security and Compliance Risks: Storing sensitive data, such as database passwords, API keys, and encryption tokens, in plaintext within Git repositories or packaged JARs violates basic security compliance standards (e.g., PCI-DSS, SOC2).
- Lack of Auditing: Without a centralized mechanism, tracking who changed a configuration value, when it was changed, and why becomes nearly impossible.
To solve these challenges, the 12-Factor App methodology mandates a strict separation of config from code. Configuration must be injected from the environment at runtime. Spring Cloud Config Server provides a highly scalable, centralized, and secure solution to manage externalized configurations across all environments in a distributed system.
2. What is Spring Cloud Config? (AEO Featured Snippet)
What is Spring Cloud Config Server?
Spring Cloud Config Server is a centralized configuration management tool for distributed systems. It provides a server-side and client-side resource model where configuration properties for all microservices are stored in a central backend (such as Git, HashiCorp Vault, JDBC database, or SVN) and served to microservices over HTTP. It supports dynamic configuration reloading at runtime without restarting service instances, environment-specific profiles (e.g., Dev, Test, Prod), and built-in encryption/decryption of sensitive properties.
By decoupling configuration from the application code, Spring Cloud Config establishes a single source of truth. The system allows developers and operations teams to manage configurations dynamically, enforce security controls, and audit changes seamlessly using standard Git workflows.
3. Architectural Blueprint & Workflows
An enterprise centralized configuration architecture consists of three primary components:
- Configuration Storage Backend: The physical repository where configuration files are stored. Common choices include Git (for version control and auditing), HashiCorp Vault (for secrets), and local file systems or databases.
- Spring Cloud Config Server: A Spring Boot application that acts as an intermediary. It fetches configurations from the backend, decrypts secured properties, and exposes them as a structured JSON API to clients.
- Spring Cloud Config Clients: The microservices themselves. At startup, they query the Config Server to retrieve their environment-specific properties and inject them into the Spring ApplicationContext.
Architectural Flow Diagram
The following ASCII diagram illustrates the lifecycle of configuration retrieval during microservice bootstrap, as well as the dynamic refresh workflow using a message broker:
+---------------------------------------------------------------------------------+ | | | [ Git Repository ] <--- (Fetches Config) ---+ | | (App & Env configs) | | | | | | [ HashiCorp Vault ] <-- (Fetches Secrets) --+ | | (Sensitive Keys) | | | v | | +-------------------------------+ | | | Spring Cloud Config Server | | | +-------------------------------+ | | ^ | | | | | (HTTP REST API JSON) | | | | | v | | +-------------------------------+ | | | Microservice Client Instance| | | | (e.g., Order Service) | | | +-------------------------------+ | | ^ | | | | | (Subscribes to Event) | | | | | v | | +-------------------------------+ | | | Apache Kafka Bus | | | +-------------------------------+ | | ^ | | | (Broadcasts Refresh) | | | | | [ Git Webhook / Ops ] ---------------------+ | | (Triggers /monitor endpoint) | +---------------------------------------------------------------------------------+
The Bootstrap and Configuration Loading Sequence
When a client microservice starts up, the following sequence occurs:
- The microservice starts its bootstrap phase, initializing a minimal Spring context.
- The microservice identifies the Config Server URL and its own application name and active profile (e.g.,
inventory-service,production). - The microservice sends an HTTP GET request to the Config Server:
GET /inventory-service/production. - The Config Server intercepts the request, connects to the configured backend (e.g., Git), clones or pulls the latest changes, merges the relevant properties, and decrypts any encrypted values.
- The Config Server returns a structured JSON payload containing the resolved properties to the client.
- The client microservice injects these properties into its
Environment, completes its context initialization, and starts serving traffic.
4. Designing the Git Configuration Repository
To ensure maintainability, scalability, and security, your configuration repository must follow a strict, logical directory and file-naming structure. Spring Cloud Config Server resolves properties based on the application name, active profiles, and Git labels (branches/tags).
File Naming Conventions
The Config Server maps properties using the following patterns, ordered from lowest to highest priority:
application.yml: Shared across all applications and all profiles.application-{profile}.yml: Shared across all applications running in a specific profile (e.g.,application-dev.yml).{application}.yml: Specific to a single microservice across all profiles (e.g.,order-service.yml).{application}-{profile}.yml: Specific to a single microservice running in a specific profile (e.g.,order-service-prod.yml). This file has the highest precedence and overrides all others.
Enterprise Git Repository Directory Structure
Below is a production-proven directory structure for a configuration repository:
config-repo/
βββ .gitignore
βββ application.yml
βββ application-dev.yml
βββ application-prod.yml
βββ order-service/
β βββ order-service.yml
β βββ order-service-dev.yml
β βββ order-service-prod.yml
βββ payment-service/
β βββ payment-service.yml
β βββ payment-service-dev.yml
β βββ payment-service-prod.yml
βββ security/
βββ global-security-rules.yml
Sample Configuration Files
Let's define a global application.yml containing common settings like timeout configurations and actuator exposure:
# application.yml (Global Defaults)
server:
shutdown: graceful
servlet:
context-path: /api/v1
spring:
jackson:
serialization:
write-dates-as-timestamps: false
default-property-inclusion: non_null
management:
endpoints:
web:
exposure:
include: "health,info,metrics,prometheus,refresh,busrefresh"
endpoint:
health:
show-details: always
Now, let's look at a service-specific configuration file, order-service-prod.yml, which overrides the database connection and configures production-specific performance tunings:
# order-service-prod.yml (Production Specifics)
spring:
datasource:
url: jdbc:postgresql://prod-db-cluster.internal:5432/order_db
username: order_app_user
password: "{cipher}AQB1A...[Encrypted Database Password]..."
hikari:
maximum-pool-size: 50
minimum-idle: 10
idle-timeout: 300000
connection-timeout: 20000
max-lifetime: 1800000
app:
payment-gateway:
endpoint: https://api.stripe.com/v3
timeout-ms: 5000
retry-attempts: 3
5. Step-by-Step Implementation: The Config Server
Let's construct a production-ready Spring Cloud Config Server using Spring Boot 3.x and Spring Cloud 2023.x (or current release train).
Step 1: Maven Dependencies
Create a new Spring Boot project and include the following dependencies in your pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<relativePath/>
</parent>
<groupId>com.enterprise.microservices</groupId>
<artifactId>config-server</artifactId>
<version>1.0.0</version>
<name>config-server</name>
<description>Enterprise Centralized Configuration Server</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2023.0.0</spring-cloud.version>
</properties>
<dependencies>
<!-- Spring Cloud Config Server Starter -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!-- Security Starter for securing the endpoints -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Actuator for monitoring and metrics -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- JGit for connecting to Git repositories via SSH -->
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>6.8.0.202311291450-r</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Step 2: Enable the Config Server
Annotate your main application class with @EnableConfigServer to activate the configuration server features:
package com.enterprise.microservices.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 3: Server Configuration (application.yml)
Now, let's configure the server to connect to an external Git repository using SSH keys, setting up caching paths, clone-on-startup, and security rules.
server:
port: 8888
spring:
application:
name: config-server
security:
user:
name: config_admin
password: ${CONFIG_SERVER_PASSWORD:SuperSecureAdminPass123!}
cloud:
config:
server:
git:
uri: git@github.com:enterprise-org/microservices-config-repo.git
ignore-local-ssh-settings: true
private-key: |
-----BEGIN OPENSSH PRIVATE KEY-----
MIIEpQIBAAKCAQEA0yG9v... [Your Private SSH Key Content] ...
-----END OPENSSH PRIVATE KEY-----
# Search paths within the repository
search-paths:
- '{application}'
- 'security'
# Clone the repository on startup to detect configuration errors early
clone-on-start: true
# Local directory to cache cloned configurations
basedir: /var/data/config-server-cache
# Set a connection timeout to prevent hanging threads
timeout: 10
# Allow fallback to local cache if Git repository is down
fail-on-required-property: true
# Secure the actuator endpoints
management:
endpoints:
web:
exposure:
include: "health,info,prometheus"
Step 4: Security Configuration Class
Secure the configuration endpoints from unauthorized access by requiring HTTP Basic Authentication:
package com.enterprise.microservices.configserver.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health/**", "/actuator/info").permitAll()
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults());
return http.build();
}
}
6. Step-by-Step Implementation: The Config Client (Spring Boot 3.x)
In Spring Boot 3.x, the bootstrap phase has been streamlined. The preferred method to import configuration from an external Config Server is using the spring.config.import property rather than the legacy bootstrap.yml file. Let's build a client microservice (e.g., order-service) to consume configurations.
Step 1: Maven Dependencies
Include the spring-cloud-starter-config dependency in the client's pom.xml:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Step 2: Client Configuration (application.yml)
Define the application name, active profile, and the import directive pointing to the Config Server in the client's application.yml:
spring:
application:
name: order-service
profiles:
active: prod
# Connect to Config Server using Spring Boot 3 config import
config:
import: "optional:configserver:http://config_admin:SuperSecureAdminPass123!@localhost:8888"
# If Config Server is down, should the application crash on startup?
# In production, setting fail-fast to true prevents half-configured instances from starting.
spring:
cloud:
config:
fail-fast: true
retry:
max-attempts: 6
initial-interval: 2000
multiplier: 1.5
Step 3: Consuming Properties with @RefreshScope
To support dynamic configuration reloading without application restarts, annotate your Spring Beans with @RefreshScope. When a configuration change occurs and a refresh is triggered, Spring will discard the existing bean instance and recreate it on the next access with the updated values.
package com.enterprise.microservices.orderservice.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/orders/config")
@RefreshScope // Enables dynamic reload of properties bound to this bean
public class ConfigurationTestController {
@Value("${app.payment-gateway.endpoint:https://fallback-gateway.com}")
private String paymentGatewayEndpoint;
@Value("${app.payment-gateway.timeout-ms:2000}")
private int timeoutMs;
@GetMapping
public Map<String, Object> getConfig() {
Map<String, Object> configMap = new HashMap<>();
configMap.put("endpoint", paymentGatewayEndpoint);
configMap.put("timeout", timeoutMs);
return configMap;
}
}
Alternative: Using @ConfigurationProperties
For complex configurations, binding properties to a structured class is highly recommended. @ConfigurationProperties classes are automatically refreshed when a config refresh occurs, without requiring @RefreshScope explicitly on the class.
package com.enterprise.microservices.orderservice.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.annotation.Validated;
import jakarta.validation.constraints.NotNull;
@Configuration
@ConfigurationProperties(prefix = "app.payment-gateway")
@Validated
public class PaymentGatewayProperties {
@NotNull
private String endpoint;
private int timeoutMs;
private int retryAttempts;
// Getters and Setters
public String getEndpoint() { return endpoint; }
public void setEndpoint(String endpoint) { this.endpoint = endpoint; }
public int getTimeoutMs() { return timeoutMs; }
public void setTimeoutMs(int timeoutMs) { this.timeoutMs = timeoutMs; }
public int getRetryAttempts() { return retryAttempts; }
public void setRetryAttempts(int retryAttempts) { this.retryAttempts = retryAttempts; }
}
7. Advanced Security: Symmetric & Asymmetric Encryption
Storing plaintext secrets in Git is a critical security vulnerability. Spring Cloud Config Server provides built-in mechanisms to encrypt sensitive values using either symmetric or asymmetric cryptography. Encrypted values are stored in the Git repository with a prefix of {cipher}, and the Config Server automatically decrypts them before serving them to client microservices.
Option A: Symmetric Encryption
Symmetric encryption uses a single shared secret key for both encryption and decryption. This is simple to configure but less secure than asymmetric encryption because anyone with access to the key can decrypt all secrets.
To enable symmetric encryption, define the ENCRYPT_KEY environment variable on your Config Server:
export ENCRYPT_KEY=MySuperSecretSymmetricKey123!
Option B: Asymmetric Encryption (Enterprise Standard)
Asymmetric encryption uses a public/private key pair. The operations team uses the public key to encrypt secrets, while the Config Server alone holds the private key (stored securely in a JKS keystore) to decrypt them at runtime.
Step 1: Generate a Keystore using Java Keytool
Execute the following command in your terminal to generate an RSA key pair inside a Java Keystore (JKS):
keytool -genkeypair -alias configserverkey \
-keyalg RSA -keysize 4096 -validity 3650 \
-keystore configserver.jks \
-storepass KeystorePassword123! \
-keypass KeyPassword123! \
-dname "CN=Enterprise Config Server, OU=Platform, O=Enterprise, L=Austin, S=Texas, C=US"
Step 2: Configure the Config Server with the Keystore
Place the configserver.jks file in the classpath (or mount it in your production container) and update application.yml:
encrypt:
key-store:
location: classpath:configserver.jks
password: KeystorePassword123!
alias: configserverkey
secret: KeyPassword123!
Step 3: Encrypting and Decrypting Values via REST API
The Config Server exposes endpoints to encrypt and decrypt values. Once asymmetric encryption is configured, you can call these endpoints:
To Encrypt a Secret:
curl -u config_admin:SuperSecureAdminPass123! \
http://localhost:8888/encrypt \
-d "my_postgres_db_password"
Response: AQA1B...[Base64 Encrypted String]...
To Decrypt a Secret (for verification):
curl -u config_admin:SuperSecureAdminPass123! \
http://localhost:8888/decrypt \
-d "AQA1B...[Base64 Encrypted String]..."
Response: my_postgres_db_password
Step 4: Storing the Encrypted Secret in Git
Copy the encrypted string returned by the server and place it in your configuration file, prefixing it with {cipher}. Do not include quotes inside the cipher block:
spring:
datasource:
password: "{cipher}AQA1B...[Base64 Encrypted String]..."
When the client microservice requests its configuration, the Config Server will decrypt this property on-the-fly and return the plaintext password directly to the client over HTTPS.
8. Enterprise Secrets Management with HashiCorp Vault
For high-security enterprise environments, storing encrypted secrets in Git is often disallowed by compliance. Instead, sensitive data should reside in a dedicated secrets manager like HashiCorp Vault. Spring Cloud Config Server supports a hybrid backend pattern: fetching non-sensitive properties from Git and secrets from Vault.
Architectural Flow of Hybrid Backend
When a client microservice requests configuration, the Config Server queries Git for properties, queries Vault for secrets based on the application name, merges the properties, and delivers a unified configuration payload to the client.
Step 1: Configure Config Server for Multiple Backends
Update the Config Server's application.yml to use both git and vault profiles:
spring:
profiles:
active: git, vault
cloud:
config:
server:
git:
uri: git@github.com:enterprise-org/microservices-config-repo.git
search-paths: '{application}'
vault:
host: 127.0.0.1
port: 8200
scheme: http
# Use KV secrets engine version 2 (recommended)
kv-version: 2
backend: secret
# Path to retrieve configurations
default-key: application
Step 2: Writing Secrets to HashiCorp Vault
In Vault, secrets are stored using paths that mirror the application name and profile. For example, to write secrets for order-service running in the prod profile, execute the following commands using the Vault CLI:
# Enable Key-Value secrets engine at path 'secret'
vault secrets enable -path=secret kv-v2
# Write secrets for order-service in production
vault kv put secret/order-service,prod \
spring.datasource.password="ProdSecretPassword987!" \
stripe.api.key="sk_live_51N...api_key..."
Step 3: Authenticating Config Server with Vault
The Config Server must authenticate with Vault using a secure token. This token can be passed to the Config Server at startup using the X-Config-Token header or the spring.cloud.config.server.vault.token property:
export SPRING_CLOUD_CONFIG_SERVER_VAULT_TOKEN="hvs.CAESIL...your_vault_token..."
With this architecture, developers can modify application configurations (like timeouts and log levels) in Git, while security administrators manage production credentials directly in Vault.
9. Dynamic Configurations with Spring Cloud Bus and Kafka
What happens when you update a configuration value in Git or Vault? By default, the microservices running in your cluster will not detect the change until they are restarted. While you can manually invoke the POST /actuator/refresh endpoint on each individual microservice instance, this approach is not feasible when running dozens of instances per service in a Kubernetes cluster.
Spring Cloud Bus solves this problem by linking all microservices through a lightweight message broker (such as Apache Kafka or RabbitMQ). When a configuration changes, a single HTTP POST request to the Config Server's /actuator/busrefresh endpoint broadcasts a refresh event to all instances via the message broker.
Dynamic Refresh Event Flow
+---------------------------------------------------------------------------------+ | | | 1. Developer pushes change to Git | | 2. Git Webhook triggers HTTP POST to Config Server's /actuator/busrefresh | | | | +-----------------------------+ | | | Spring Cloud Config Server | | | +-----------------------------+ | | | | | | (Publishes RefreshRemoteApplicationEvent) | | v | | +-----------------------------+ | | | Apache Kafka Broker | | | +-----------------------------+ | | / | \ | | / | \ (Broadcasts event to topic) | | v v v | | +-------------------------------+ | | | Order Svc | Order Svc | ... | | | | Instance 1 | Instance 2 | | | | +-------------------------------+ | | | | 3. All instances receive event, pull fresh config from Config Server, | | and rebuild beans annotated with @RefreshScope. | +---------------------------------------------------------------------------------+
Step-by-Step Implementation using Apache Kafka
Step 1: Add Spring Cloud Bus Kafka Dependencies to Client Services
Add the following starters to the pom.xml of both the Config Server and all Client Microservices:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
Step 2: Configure Kafka Bindings in application.yml
Add the Kafka broker connection details to the global application.yml in your Git repository so that all services automatically inherit the configuration:
spring:
cloud:
bus:
enabled: true
# Destination name (Kafka topic)
destination: config-refresh-topic
stream:
kafka:
binder:
brokers: kafka-broker-1.internal:9092,kafka-broker-2.internal:9092
auto-create-topics: true
Step 3: Triggering the Dynamic Refresh
When you update a property in Git (e.g., changing app.payment-gateway.timeout-ms from 5000 to 10000), commit and push the change. Then, execute a POST request to the Config Server's bus refresh endpoint:
curl -X POST -u config_admin:SuperSecureAdminPass123! \
http://localhost:8888/actuator/busrefresh
This triggers the following actions:
- The Config Server publishes a
RefreshRemoteApplicationEventto the Kafka topicconfig-refresh-topic. - Every microservice instance subscribed to this topic receives the event.
- Each instance queries the Config Server to fetch the updated configuration properties.
- The
ContextRefresherinside each microservice refreshes theEnvironmentand evicts all beans annotated with@RefreshScope. - On the next API request, the refreshed beans are reinitialized with the updated configurations, achieving zero-downtime hot-reloads.
10. Resiliency, Caching, and High Availability (HA)
Because the Config Server is a critical component in your microservices startup path, its failure can halt deployment pipelines and prevent auto-scaling groups from launching new instances. To prevent this, the Config Server must be designed for extreme resiliency and high availability.
1. Clustering and Load Balancing
In production, always run multiple instances of the Config Server behind a private load balancer (e.g., AWS ALB, NGINX, or Kubernetes Service ClusterIP). Since the Config Server is stateless, any instance can handle any incoming request.
2. Local File Cache (Git Base Directory)
Configure the local base directory (spring.cloud.config.server.git.basedir) to point to persistent storage (such as an AWS EBS volume or Kubernetes PersistentVolume). If the Git repository provider (e.g., GitHub, GitLab) goes down, the Config Server will fall back to serving configurations from its local disk cache.
3. Client Fail-Fast and Retry Policies
If the Config Server is temporarily unreachable during microservice startup, the microservice should not immediately fail. Instead, it should retry connecting several times before crashing. Configure this in the client's application.yml:
spring:
cloud:
config:
fail-fast: true # Crash startup if config cannot be loaded after retries
retry:
initial-interval: 1000 # Time (ms) to wait before first retry
max-interval: 10000 # Maximum wait time between retries
multiplier: 2.0 # Backoff multiplier
max-attempts: 5 # Total connection attempts
4. Fallback Configurations
For non-critical parameters, define sensible default values in the client microservice code using the standard Spring @Value fallback syntax. This ensures the application can run even if the property is missing from the remote server:
@Value("${app.payment-gateway.timeout-ms:5000}")
private int timeoutMs; // Defaults to 5000 if not served by Config Server
11. Operational Best Practices & Git Branching Strategies
Managing configurations for multiple environments requires strict release management. Treating your configuration repository with the same rigor as your source code is essential.
1. Git Branching Model for Configurations
There are two primary patterns for structuring environment configurations in Git:
Pattern A: Branch-Per-Environment (Recommended for strict isolation)
- main branch: Contains configurations deployed to Production.
- staging branch: Contains configurations deployed to Staging.
- develop branch: Contains configurations deployed to