Aller au contenu

Feature Flags

Découpler le déploiement du code de l'activation des fonctionnalités pour livrer en continu sans exposer de code incomplet.


Découpler déploiement et activation

Déployer et publier sont deux opérations distinctes.

Déployer : mettre le code en production. Le code est en place, mais peut être inactif.

Publier (release) : activer la fonctionnalité pour les utilisateurs. C'est une décision métier, pas technique.

Sans feature flags, déploiement et publication sont synchrones : chaque déploiement est une release. Avec des feature flags, on peut déployer 10 fois par jour en silence, puis activer la fonctionnalité un vendredi matin avec le service marketing.

graph LR
    A["Code mergé\nsur main"] --> B["Deploiement\nCI/CD automatique"]
    B --> C["Flag OFF\nCode inactif"]
    C -->|"Decision metier"| D["Flag ON\nActivation"]
    D -->|"Probleme detecte"| C
    style D fill:#2ecc71,color:#fff
    style C fill:#95a5a6,color:#fff

Le déploiement devient ennuyeux

L'objectif des feature flags est de rendre les déploiements aussi ennuyeux que possible. Pas de stress, pas de coupure planifiee, pas de tout-ou-rien. On deploie du code comme on fusionne des branches : tranquillement.


Types de flags

Type Rôle Durée de vie Exemple
Release flag Cache une fonctionnalité non terminee Court (semaines) FEATURE_NEW_CHECKOUT=false
Experiment flag A/B testing, mesure d'impact Court (jours) EXPERIMENT_BUTTON_COLOR=red
Ops flag Coupe-circuit pour une fonctionnalité en charge Long (permanent) ENABLE_HEAVY_ANALYTICS=false
Permission flag Activation par segment d'utilisateurs Long BETA_ACCESS=true pour utilisateurs beta

Cycle de vie d'un flag

Un flag a un cycle de vie défini. Il nait, il sert, et il doit mourir. Un flag qui ne meurt pas devient de la dette.

graph LR
    A["Creation\ndu flag"] --> B["Deploiement\nflag OFF"]
    B --> C["Activation canary\n10% des users"]
    C -->|"Metriques OK"| D["Activation\n100% des users"]
    C -->|"Probleme detecte"| B
    D --> E["Cleanup\nretrait du code"]
    E --> F["Suppression\ndu flag"]
    style F fill:#e74c3c,color:#fff
    style D fill:#2ecc71,color:#fff

Le cleanup est aussi important que la création. Un flag qu'on oublie de supprimer :

  • complique le code avec des branches conditionnelles mortes
  • crée de la confusion pour les nouveaux développeurs
  • peut interagir de façon inattendue avec d'autres flags

Trunk-based development + feature flags

Les feature flags sont le complement naturel du trunk-based development. On commite directement sur main sans branches de feature longues, le code incomplet etant protégé par un flag.

gitGraph
    commit id: "feat: debut nouveau checkout"
    commit id: "feat: etape 1 checkout (flag OFF)"
    commit id: "fix: correction API"
    commit id: "feat: etape 2 checkout (flag OFF)"
    commit id: "feat: etape 3 checkout (flag OFF)"
    commit id: "ops: activer checkout en staging"
    commit id: "ops: activer checkout en prod"

Tous les commits vont sur main. La fonctionnalité est cachee derriere un flag jusqu'à ce qu'elle soit prete. Pas de merge de branche longue, pas de conflits d'intégration.

Pour la stratégie de branching associee, voir Workflows Git.

Trunk-based + flags = intégration continue réelle

L'intégration continue au sens strict signifie que tout le monde intégré son code dans la branche principale au moins une fois par jour. Les feature flags rendent cela possible même pour des fonctionnalités qui prennent des semaines a développer.


Bonnes pratiques

Conventions de nommage

# Format recommande : DOMAINE_FONCTIONNALITE
FEATURE_NEW_CHECKOUT          # release flag
EXPERIMENT_HOMEPAGE_LAYOUT    # A/B test
OPS_DISABLE_RECOMMENDATIONS   # coupe-circuit
BETA_ADVANCED_ANALYTICS       # acces par segment

TTL et cleanup

Définir un TTL (Time To Live) à la création du flag. Ajouter un ticket de cleanup au backlog au même moment.

Type de flag TTL recommande
Release flag 2 sprints
Experiment flag 1 sprint
Ops flag Permanent, reviewe chaque trimestre
Permission flag Permanent, documenté

Éviter la dette de flags

# Mauvais : flag jamais retire
if feature_flags.is_enabled("OLD_PAYMENT_FLOW"):
    # code de 2023 que tout le monde a oublie
    process_old_payment()
else:
    process_payment()

# Bon : apres activation a 100% et validation
# Supprimer le flag ET l'ancien code
process_payment()

La dette de flags est une dette technique

Un projet avec 50 flags actifs dont personne ne connait le rôle est un projet en danger. Etablissez un registre de flags, assignez un propriétaire a chacun, et reviewez-les chaque trimestre.


Outils

Outil Description Lien
Unleash Plateforme open-source de feature flags, self-hosted getunleash.io
LaunchDarkly SaaS avance, ciblage granulaire, A/B testing intégré launchdarkly.com
Flipt Alternative open-source légère a Unleash flipt.io
Variables d'env Solution minimaliste sans service externe pour débuter