Contrôler les Feature Flags sans Redéploiement

Imaginez la situation : votre équipe vient de livrer un nouveau tunnel d'achat derrière un feature flag. Tout semble bon en staging. Mais une heure après le déploiement en production, votre monitoring affiche un pic d'abandons de panier. Vous devez désactiver immédiatement la nouvelle fonctionnalité.

Si désactiver cette fonctionnalité implique de préparer une nouvelle release, d'attendre le pipeline de build et de redéployer en production, vous avez un problème. Le temps que l'ancien code soit de nouveau en ligne, vous avez déjà perdu du chiffre d'affaires et frustré vos utilisateurs.

C'est pourquoi les feature flags doivent pouvoir être contrôlés à l'exécution, sans toucher au pipeline de déploiement. La capacité de modifier la valeur d'un flag pendant que l'application tourne est ce qui distingue un véritable feature flag d'une simple configuration qu'on a nommée « flag ».

L'approche la plus simple : les fichiers de configuration

La méthode la plus directe pour contrôler les flags consiste à utiliser des fichiers de configuration sur le serveur. Votre application lit les valeurs des flags depuis un fichier au démarrage, et vous pouvez déclencher un rechargement sans redémarrer le processus.

Par exemple, un fichier flags.json simple pourrait ressembler à ceci :

{
  "new-checkout": {
    "enabled": true,
    "description": "Nouveau tunnel d'achat avec étapes simplifiées"
  },
  "dark-mode": {
    "enabled": false,
    "description": "Basculement de l'interface en mode sombre"
  },
  "recommendation-engine": {
    "enabled": true,
    "rollout-percentage": 25,
    "description": "Déploiement progressif des recommandations personnalisées"
  }
}

Cette approche fonctionne bien quand vous avez un ou deux serveurs. Vous modifiez le fichier, envoyez un signal SIGHUP ou attendez l'intervalle de rechargement périodique, et l'application prend en compte la nouvelle valeur.

Mais cette méthode montre rapidement ses limites. Si votre application tourne sur dix serveurs, vous devez modifier dix fichiers. Si un serveur rate la mise à jour, certains utilisateurs voient la nouvelle fonctionnalité et d'autres non. Et il faut que quelqu'un ait un accès shell aux serveurs de production pour effectuer la modification, ce qui crée un goulot d'étranglement et un problème de traçabilité.

Variables d'environnement : mieux, mais encore limité

Les variables d'environnement sont un cran au-dessus. Vous définissez NEW_CHECKOUT_ENABLED=true au démarrage de l'application, et la valeur du flag est disponible pendant tout le cycle de vie du processus. C'est particulièrement utile pour différencier les environnements : staging reçoit true, production reçoit false.

La limitation est évidente : vous ne pouvez pas modifier une variable d'environnement sans redémarrer le processus. Si vous devez désactiver une fonctionnalité en pleine journée, vous devez redémarrer l'application avec une nouvelle valeur de variable. Ce redémarrage peut prendre quelques secondes ou minutes, selon le temps de démarrage de votre application et le préchauffage des pools de connexions.

Dans les environnements conteneurisés comme Kubernetes, vous pouvez mettre à jour les variables d'environnement via des ConfigMaps sans reconstruire l'image du conteneur. Mais le pod doit toujours redémarrer pour prendre en compte le changement. Certains orchestrateurs gèrent les redémarrages progressifs automatiquement, mais il y a toujours une courte fenêtre où l'ancienne valeur est active.

La vraie solution : un tableau de bord centralisé pour les flags

Quand votre équipe a besoin d'un contrôle en temps réel sur de nombreux services, vous avez besoin d'un système dédié de gestion des flags. Celui-ci vous offre une interface web ou une API pour modifier les valeurs des flags, et l'application lit ces valeurs depuis un service central.

Voici comment cela fonctionne en pratique :

  1. Votre application intègre un petit SDK provenant de la plateforme de gestion des flags
  2. À l'exécution, l'application demande à la plateforme : « Le flag new-checkout est-il activé pour l'utilisateur ID 12345 ? »
  3. La plateforme répond en fonction des règles que vous avez configurées via le tableau de bord
  4. Lorsque vous modifiez une valeur de flag dans le tableau de bord, toutes les instances de l'application la prennent en compte en quelques secondes

Cette approche résout le problème de coordination. Vous modifiez une valeur à un seul endroit, et chaque instance de chaque service voit la mise à jour presque immédiatement. Pas d'accès SSH aux serveurs. Pas de redémarrages progressifs. Pas de risque de valeurs incohérentes entre les instances.

Des plateformes comme LaunchDarkly, Split ou Flagsmith offrent cette capacité directement. Elles gèrent les parties complexes : distribution fiable des valeurs des flags, mise en cache pour éviter les surcoûts de performance, et règles de ciblage granulaires.

Choisir ce qui convient à votre équipe

La bonne approche dépend de là où se trouve votre équipe aujourd'hui et de là où elle se dirige.

Le diagramme suivant peut vous aider à décider quelle approche correspond à votre situation :

flowchart TD A[Combien de serveurs ?] -->|Peu| B[Fichiers de config] A -->|Beaucoup| C[Besoins de contrôle temps réel ?] C -->|Oui| D[Tableau de bord centralisé] C -->|Non| E[Variables d'environnement] B --> F[Avantages : Simple, pas de nouvel outil] B --> G[Inconvénients : Manuel par serveur, pas de traçabilité] E --> H[Avantages : Centralisé via l'orchestrateur] E --> I[Inconvénients : Nécessite un redémarrage, léger délai] D --> J[Avantages : Instantané, traçable, par utilisateur] D --> K[Inconvénients : Dépendance externe, coût]

Les fichiers de configuration conviennent aux petites équipes avec un ou deux serveurs. La charge opérationnelle est minimale et vous n'avez pas besoin d'apprendre une nouvelle plateforme. Assurez-vous simplement que votre application peut recharger la configuration sans redémarrage complet.

Les variables d'environnement fonctionnent bien lorsque vous utilisez déjà Kubernetes ou un orchestration similaire. Vous pouvez gérer les valeurs des flags via des ConfigMaps et laisser l'orchestrateur gérer le redémarrage. C'est un bon compromis avant d'investir dans une plateforme dédiée.

Les tableaux de bord centralisés deviennent nécessaires lorsque vous avez plusieurs services, que vous avez besoin d'un contrôle en temps réel, ou que vous souhaitez que des non-ingénieurs puissent gérer les flags. Les chefs de produit peuvent activer des fonctionnalités pour des segments d'utilisateurs spécifiques. Les ingénieurs peuvent désactiver une fonctionnalité problématique depuis leur téléphone. Les équipes d'exploitation peuvent auditer qui a modifié quoi et quand.

Une checklist pratique pour le contrôle des flags

Avant de choisir un mécanisme, vérifiez ces points :

  • Pouvez-vous modifier la valeur d'un flag sans déployer de code ?
  • La modification prend-elle effet dans un délai acceptable (secondes, pas des heures) ?
  • Plusieurs membres de l'équipe (ingénieurs, chefs de produit, opérations) peuvent-ils modifier les flags sans partager d'identifiants ?
  • Existe-t-il une piste d'audit de qui a modifié quoi et quand ?
  • Pouvez-vous modifier les flags pour des utilisateurs ou segments spécifiques, et pas seulement globalement ?
  • Le mécanisme fonctionne-t-il dans tous vos environnements (staging, production, canary) ?

Si vous répondez « non » à l'un de ces points, votre mécanisme de contrôle des flags doit être amélioré.

Ce qui compte le plus

Le principe de base est simple : si modifier un flag nécessite un déploiement, vous n'utilisez pas de feature flags. Vous utilisez une configuration qui s'appelle « flag » par hasard.

Le mécanisme que vous choisissez doit correspondre à la taille de votre équipe et à sa maturité opérationnelle. Commencez simplement, mais prévoyez le jour où vous devrez désactiver une fonctionnalité sur cinquante microservices sans toucher à un seul serveur. Ce jour viendra, et quand il arrivera, vous serez content d'avoir mis en place un contrôle centralisé des flags correctement.

L'objectif n'est pas de construire un système de flags parfait dès le premier jour. L'objectif est de garantir que lorsque quelque chose tourne mal en production, votre première action soit de modifier la valeur d'un flag, et non de lancer un pipeline de déploiement.