Contactez-nous

Configuration centralisée avec Spring Cloud Config Server

Apprenez à gérer la configuration de vos microservices de manière centralisée et dynamique à l'aide de Spring Cloud Config Server, en utilisant Git ou d'autres backends.

Le défi de la configuration distribuée

Dans une architecture microservices, vous gérez de nombreux services indépendants. Chacun de ces services nécessite sa propre configuration (URL de base de données, clés API, paramètres métier, niveaux de log, etc.). De plus, cette configuration varie souvent en fonction de l'environnement de déploiement (développement, test, pré-production, production). Gérer ces configurations de manière dispersée dans les fichiers `application.properties` ou `yml` de chaque service devient rapidement ingérable :

  • Duplication : Des propriétés communes peuvent être répétées dans de nombreux services.
  • Incohérence : Il est facile d'introduire des erreurs ou des différences entre les environnements.
  • Gestion complexe : Mettre à jour une propriété partagée nécessite de modifier, tester et redéployer potentiellement plusieurs services.
  • Sécurité : Stocker des informations sensibles directement dans le code ou les artefacts de déploiement est une mauvaise pratique.

Pour résoudre ces problèmes, le pattern de la configuration externalisée et centralisée est essentiel. L'idée est de stocker toute la configuration des différents services et environnements dans un emplacement unique et de permettre aux services de récupérer leur configuration spécifique au démarrage.

Spring Cloud Config Server : La solution Spring

Spring Cloud Config Server est le composant de Spring Cloud dédié à la mise en oeuvre de ce pattern. C'est une simple application Spring Boot qui agit comme un serveur centralisé fournissant des propriétés de configuration à distance aux applications clientes (vos microservices).

Son fonctionnement est le suivant :

  1. Le Config Server est lié à un backend de configuration. Le plus souvent, il s'agit d'un dépôt Git (GitHub, GitLab, Bitbucket, local), mais d'autres options existent (système de fichiers local, HashiCorp Vault, JDBC, etc.). C'est dans ce backend que vous stockez vos fichiers de propriétés (`.properties` ou `.yml`).
  2. Les microservices clients sont configurés (via `bootstrap.properties`/`yml` ou `spring.config.import`) pour contacter le Config Server au démarrage.
  3. Le client indique au serveur son nom d'application (`spring.application.name`) et les profils actifs (`spring.profiles.active`).
  4. Le Config Server utilise ces informations pour récupérer les fichiers de configuration appropriés depuis le backend (ex: `mon-service.properties`, `mon-service-prod.properties`, `application.properties`).
  5. Le Config Server agrège ces propriétés et les renvoie au client via une API REST (généralement au format JSON).
  6. Le client intègre ces propriétés reçues dans son environnement Spring avec une priorité élevée, surchargeant ainsi les éventuelles propriétés définies localement dans ses propres fichiers `application.properties`.

Ce mécanisme permet de gérer toute la configuration de votre système distribué de manière centralisée, versionnée (grâce à Git) et dynamique.

Mise en place du Config Server

Créer un Config Server est simple :

  1. Créez un nouveau projet Spring Boot.
  2. Ajoutez la dépendance `spring-cloud-config-server` :
    
        org.springframework.cloud
        spring-cloud-config-server
    
  3. Activez la fonctionnalité dans votre classe d'application principale avec `@EnableConfigServer` :
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.config.server.EnableConfigServer;
    
    @SpringBootApplication
    @EnableConfigServer // Active le serveur de configuration
    public class ConfigServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ConfigServerApplication.class, args);
        }
    }
    
  4. Configurez le backend dans `application.properties` ou `application.yml`. Pour un backend Git :
    # Port sur lequel le Config Server écoute (par défaut 8888)
    server.port=8888
    
    # Configuration du backend Git
    spring.cloud.config.server.git.uri=https://github.com/votre-utilisateur/votre-repo-config
    # Optionnel: si le dépôt est privé
    # spring.cloud.config.server.git.username=votre_username_git
    # spring.cloud.config.server.git.password=votre_token_ou_motdepasse
    # Optionnel: sous-répertoire dans le dépôt où se trouvent les fichiers
    # spring.cloud.config.server.git.search-paths=config-files
    # Optionnel: branche à utiliser
    # spring.cloud.config.server.git.default-label=main 
    

Une fois démarré, le Config Server expose des endpoints REST (par défaut sur le port 8888) pour servir la configuration. Par exemple, `http://localhost:8888/{application}/{profile}`.

Organisation des fichiers de configuration (Backend Git)

Dans votre dépôt Git de configuration, vous organisez les fichiers de propriétés en suivant une convention de nommage spécifique :

  • `application.properties` (ou `application.yml`) : Contient les propriétés par défaut, partagées par toutes les applications et tous les profils.
  • `{application-name}.properties` (ou `.yml`) : Contient les propriétés spécifiques à une application donnée, applicables à tous ses profils. Surcharge les propriétés de `application.properties`.
  • `{application-name}-{profile}.properties` (ou `.yml`) : Contient les propriétés spécifiques à une application ET à un profil particulier (ex: `mon-service-prod.properties`, `mon-service-dev.yml`). Surcharge les deux niveaux précédents.

Exemple de structure de fichiers dans le dépôt Git :

config-repo/
├── application.properties      # Propriétés communes à tous
├── service-a.properties        # Propriétés spécifiques à service-a (tous profils)
├── service-a-prod.properties   # Propriétés pour service-a en profil 'prod'
├── service-a-dev.properties    # Propriétés pour service-a en profil 'dev'
├── service-b.yml               # Propriétés spécifiques à service-b (format YAML)
└── service-b-prod.yml          # Propriétés pour service-b en profil 'prod'

Lorsqu'un client nommé `service-a` avec le profil `prod` actif contacte le Config Server, celui-ci va récupérer et agréger dans l'ordre (le dernier gagne) :

  1. `application.properties`
  2. `service-a.properties`
  3. `application-prod.properties` (s'il existe)
  4. `service-a-prod.properties`

Cette hiérarchie permet une gestion fine et flexible de la configuration.

Configuration du client (Microservice)

Pour qu'un microservice utilise le Config Server, il doit :

  1. Ajouter la dépendance `spring-cloud-starter-config` (ou s'assurer qu'elle est apportée par `spring-cloud-starter-bootstrap` dans les anciennes versions) :
    
        org.springframework.cloud
        spring-cloud-starter-config
    
  2. Configurer la connexion au Config Server. La méthode moderne (depuis Spring Boot 2.4) utilise la propriété `spring.config.import` dans `application.properties` ou `application.yml`. Cette configuration doit être traitée très tôt dans le cycle de démarrage.
    # Nom de cette application (doit correspondre aux noms de fichiers dans le repo Git)
    spring.application.name=service-a
    
    # Profils actifs (peuvent aussi être définis via variable d'environnement, etc.)
    spring.profiles.active=prod
    
    # Importer la configuration depuis le Config Server (remplace bootstrap.properties)
    # La clause "optional:" évite une erreur si le serveur n'est pas joignable au démarrage (utile pour le dev)
    spring.config.import=optional:configserver:http://localhost:8888
    
    # Optionnel: Configuration si le Config Server nécessite une authentification
    # spring.cloud.config.username=user
    # spring.cloud.config.password=password
    
    # Optionnel: Activer les tentatives de connexion au Config Server
    # spring.cloud.config.fail-fast=true 
    # spring.cloud.config.retry.max-attempts=6
    
  3. (Méthode historique/alternative) Utiliser un fichier `src/main/resources/bootstrap.properties` ou `bootstrap.yml` pour définir les propriétés `spring.application.name` et `spring.cloud.config.uri`. La configuration dans `bootstrap.*` est chargée avant `application.*`.
    # Contenu de bootstrap.properties (moins recommandé maintenant)
    spring.application.name=service-a
    spring.cloud.config.uri=http://localhost:8888
    # spring.profiles.active=prod # Peut aussi être ici
    

Au démarrage, le client contactera `http://localhost:8888`, demandera la configuration pour `service-a` avec le profil `prod`, et intégrera les propriétés reçues dans son environnement.

Avantages et considérations

Avantages :

  • Centralisation : Un seul endroit pour gérer toute la configuration.
  • Cohérence : Réduit les risques d'erreurs et de dérive entre environnements.
  • Gestion des environnements : Facilement gérée par les profils Spring et la structure des fichiers.
  • Dynamicité : Possibilité de rafraîchir la configuration sans redémarrer tous les services (via `/actuator/refresh` et potentiellement Spring Cloud Bus).
  • Auditabilité et versioning : L'utilisation de Git permet de suivre l'historique des modifications de configuration.
  • Sécurité : Permet de sortir les configurations (y compris les secrets si la fonctionnalité de chiffrement est utilisée) du code et des artefacts de déploiement.

Considérations :

  • Dépendance au démarrage : Les microservices dépendent du Config Server pour démarrer (sauf si `optional:` est utilisé ou si une configuration locale de secours est présente). Il faut donc assurer la haute disponibilité du Config Server en production (ex: plusieurs instances derrière un load balancer).
  • Sécurité du Config Server : Les endpoints du Config Server doivent être sécurisés pour éviter l'exposition non autorisée de la configuration.
  • Gestion des secrets : Bien que Config Server propose un chiffrement, pour une gestion plus robuste des secrets, l'intégration avec des outils comme HashiCorp Vault (qui peut être un backend pour Config Server) est souvent recommandée.
  • Rafraîchissement : Le rafraîchissement dynamique de la configuration nécessite une configuration supplémentaire (`@RefreshScope` sur les beans concernés, et potentiellement Spring Cloud Bus pour notifier plusieurs instances).

Spring Cloud Config Server est un pilier fondamental de la construction d'architectures microservices robustes et gérables avec l'écosystème Spring Cloud.