DEVOXX 2015 : « Livrer chaque jour ce qui est prêt »

Du 8 au 10 avril 2015 se déroulait le Devoxx, LA conférence pour Développeurs à Paris. En tant que nouvel arrivant dans la capitale, je me devais d’y faire un tour ! Une conférence a particulièrement retenu mon attention : « Livrer chaque jour ce qui est prêt », présentée par Dimitri BAELI (@dbaeli) et Benjamin DEGERBAIX (@benbaix) de chez LesFurets.com. Je commencerai par vous résumer cette présentation. Nous approfondirons ensuite le sujet en nous penchant sur une pratique de plus en plus adoptée : le Continuous Delivery.

CONTEXTE 

La problématique est posée dès le début : comment passer d’une organisation de type « éditeur logiciel » (cycle Plan/Dev/Recette/Prod) avec une release par mois, à une organisation non moins solide de type « Continuous Delivery » avec une mise en production par jour de « ce qui est prêt » ?

1. Quels avantages ?

  • Une réactivité accrue vis à vis du business ;
  • L’accélération du Go-To-Market ;
  • Une productivité et efficacité améliorées ;
  • Un produit de meilleure qualité ;
  • Une satisfaction client accrue.

2. Quelles difficultés ?

  • Le coût initial ;
  • L’investissement de chaque partie (de la conception à l’exploitation).

Déployer en production plusieurs fois par jour sans que l’utilisateur n’y voit quelque chose, ça vous rappelle personne ? Facebook, Google, Etsy, Netflix et j’en passe… ont déjà franchi le cap depuis plusieurs années ! Avant toute chose, veillez à ne pas confondre Continuous Delivery et Continuous Deployment. Dans le cadre du premier, la décision de mettre en production n’est pas systématique et reste une étape manuelle. A chacun de déterminer quelle solution lui convient le mieux selon ses besoins.

continuous delivery

Vous l’avez compris, c’est un cheminement. Il est donc impossible de faire du Continuous Deployment sans Continuous Delivery, comme du Continuous Delivery sans Continuous Integration. Pour des équipes qui démarrent de zéro, l’investissement risque de s’avérer conséquent. Chaque partie prenante peut émettre des objections quant à la valeur ajoutée du changement. Il faut donc y aller étape par étape !

MAIS ALORS, PAR OU COMMENCER ?

L’équipe des Furets nous explique l’approche qu’ils ont choisie afin d’implémenter le Continuous Delivery : améliorer par la fin ! Ils se sont tout d’abord concentrés sur l’exploitation avant de remonter progressivement jusqu’à la conception.

1. Exploitation

  • Monitoring / Measure 

Pour livrer tous les jours,- plus précisément à J+2, c’est à dire que les livraisons contiennent ce qui a été développé l’avant-veille – il ne faut pas négliger la qualité. On pense alors tests unitaires et tests d’intégration. Mais avant cela, il y a toute une partie outillage. En effet, Les Furets ont mis en place des outils de monitoring qui leur permettent de s’appuyer sur de multiples métriques et pour le coup, ce sont des métriques fonctionnelles (taux de conversion par exemple) à l’aide de sondes Zabbix.

> Conseil n°1 : ajouter des métriques métiers sur les applications et habituer l’équipe à s’en servir.

  • Logs 

Réagir vite est un des facteurs clés. Encore faut-il être au courant et à l’écoute de la moindre perturbation au sein du système. Les logs sont une source d’information importante et doivent être suivies notamment après la mise en production. Pour cela, il faut maintenir un niveau de remontée d’exception visible afin de ne pas noyer l’information. D’autre part, dans le cas des Furets, la page d’accueil est une application single-page, ce qui induit beaucoup de code Javascript. Les erreurs levées par ce code doivent être également lisibles dans les logs. Dernier point : si les logs sont bien visibles, elles doivent être bien sûr lues. Ils ont fait le choix d’envoyer la trace de chaque erreur par email. Et pas que les logs de production.

A chacun d’adapter par la suite la fréquence en envoyant un email toutes les heures ou tous les jours.

> Conseil n°2 : ne laisser pas les erreurs Javascript pourrir le navigateur des utilisateurs.

2. Mise en production

  • Infrastructure as Code 

Le code est versionné, testé, intégré, validé et soumis à des tests de charge, mais qu’en est-il de l’infrastructure ? Avec l’utilisation progressive des services de Cloud, on a grand besoin de pouvoir faire de même avec les environnements. C’est là qu’intervient un principe issu de la culture DevOps : l’Infrastructure As Code. De la configuration de l’applicatif à celle des serveurs de chaque environnement, tout est inclus dans un livrable dédié. C’est uniquement lors de l’installation de l’application à l’aide de scripts de déploiement par exemple, que la bonne configuration sera chargée et utilisée en détectant sur quel environnement on se trouve. C’est tout aussi faisable pour les modifications sur le schéma de données et ainsi automatiser la migration des bases de données. Si vous avez besoin de changer des paramètres de configuration directement sur un environnement sans passer par le process de Continuous Delivery, vous pouvez utiliser une solution plus dynamique en stockant cette partie en base de données. On peut encore aller plus loin en ajoutant des tests unitaires sur l’infrastructure et l’analyse de qualité.

  • Zero Downtime Deployment 

Livrer tous les jours c’est bien, mais sans éteindre et redémarrer la production, c’est mieux. C’est ce qu’on appelle le Zero Downtime Deployment. Plusieurs solutions existent pour cela :

    • Blue/Green Deployment : c’est la solution mise en œuvre chez les Furets. L’équipe a créé un deuxième environnement de production, afin d’y déployer la nouvelle version de l’application. Par exemple, supposons que le blue contienne la version courante et le green la nouvelle : il suffit de rediriger les utilisateurs du blue vers le green et cela grâce au routage. Ce pattern est aussi utilisé pour faire de l’A/B Testing en ne redirigeant qu’une partie des utilisateurs sur la nouvelle version et de surveiller l’adoption de la nouvelle fonctionnalité à l’aide de métriques. Concernant les sessions HTTP, il est possible d’utiliser des sessions partagées en utilisant un cache de session commun entre les serveurs.
    • Canary Release : lorsque la nouvelle version de l’application est prête, il suffit de la déployer sur votre infrastructure et de la rendre accessible seulement à un sous-ensemble de vos utilisateurs. Similaire au Blue/Green Deployment, vous pouvez à tout moment revenir sur la version précédente en cas de problèmes rencontrés avec la nouvelle.

       canary release

    • Dark Launch : les tests de charge sont très utiles lorsqu’on souhaite simuler l’impact d’un nombre important d’utilisateurs. Mais quand vous êtes une société telle que Facebook, simuler plusieurs millions de personnes tentant d’accéder à une nouvelle fonctionnalité n’est pas chose simple. Dans le cadre du lancement du chat de Facebook, les développeurs ont choisi de lancer une période de “Dark Launch”, pendant laquelle les pages Facebook feraient des connexions aux serveurs de chat. Des requêtes simulaient alors l’envoi de messages mais sans que la partie UI ne soit visible. Le but était de surveiller si le site pouvait supporter la charge engendrée par la nouvelle fonctionnalité. Une fois les bugs corrigés, il ne restait plus qu’à activer l’interface utilisateur.

3. Validation 

La validation de la release s’effectue à l’aide d’outils manuels et automatiques :

  • Tests unitaires et d’intégration ;
  • Code review ;
  • Validation fonctionnelle ;
  • Grid Selenium ;
  • Zeno Pixel.
  • Grid Selenium

Les tests Selenium sont très souvent intégrés au build de l’application, notamment à l’aide de Maven. Dans le cas des Furets, les tests sont exécutés après build sur un serveur. Leurs 200 tests mettant six heures en exécution classique. Ils ont choisi de mettre en place une grille afin de les paralléliser et ainsi accélérer leur exécution. Résultat : une heure ! C’est mieux mais pas encore assez lorsque l’on souhaite livrer tous les jours. En utilisant un système de virtualisation tel que LXC (LinuX Container) en s’appuyant sur la mémoire au lieu du disque, dix minutes suffisent pour exécuter les 200 tests Selenium.

  • Zeno Pixel

Zeno Pixel est un outil Open Source développé en interne chez LesFurets qui permet de faire de la non-régression sur la partie frontend du site. Pour cela, l’outil prend des screenshots des pages de l’application et les compare à la version précédente ou à un autre environnement. Il est développé en NodeJS et PhantomJS et permet également de tester plusieurs résolutions (mobile, tablette, desktop). Vous pouvez retrouver Zeno Pixel sur le Github des Furets : https://github.com/lesfurets/zeno-pixel

4. Développement

  • Feature Branch

Le principe de la Feature Branch est que tout développement de fonctionnalités doit avoir sa propre branche, tirée depuis la branche principale. Elle est donc parfaitement isolée des autres développements.

Feature Branch

Lorsque le développement de celle-ci est terminé, le développeur émet une Pull Request afin que ses modifications soient prises en compte et intégrées.

 

  • Continuous Merge

Le Feature Branching soulève des difficultés quant à l’intégration continue. Afin de pallier ce problème, LesFurets se sont appuyés sur le merge octopus de git et ont même développé une commande pour simplifier son utilisation : git-octopus. Après chaque commit, le serveur d’intégration continue va essayer de merger les n branches de features avec le master et le résultat est commité dans une branche jetable appelée octopus. La sélection des branches à prendre en compte lors du merge se fait sur nommage de celles-ci (exemple : features/*). Enfin, c’est sur branche jetable que sont effectués tous les tests. Concernant la gestion des conflits, il n’y a aucune résolution donc s’il existe un conflit, le merge échoue automatiquement. Et si une feature branche empêche le build de l’application, il suffit de renommer la branche afin qu’elle ne soit pas prise en compte lors du prochain merge. Ce n’est pas du feature toggle mais ça s’en approche.

5. Conception

  • Fonctionnalités indépendantes

Pour livrer ce qui est prêt le plus tôt possible, les fonctionnalités développées doivent être indépendantes les unes des autres. Si l’une est terminée mais qu’elle dépend d’une autre en cours de réalisation, elle ne pourra pas être livrée en production comme il se doit. Le découplage des fonctionnalités est primordial. Si vous êtes dans l’incapacité de faire cela, fusionnez les évolutions entre elles.

  • Fast feedback

Le fast feedback est une partie importante du Continuous Delivery. En déployant tous les jours, il est possible de tester une nouvelle fonctionnalité et prendre rapidement en compte le retour des utilisateurs. Mais l’avis de l’utilisateur n’est pas le seul, le feedback intervient à chaque étape du delivery, que ce soit après le commit, les tests d’intégration ou la phase de validation. Et cela grâce notamment aux logs et monitoring mis en place tout au long du processus. La décision de stopper ou de continuer intervient plus tôt, la réactivé de l’équipe est plus accrue et l’amélioration du produit est continue.

Conclusion

Le Continuous Delivery est l’une des composantes du manifeste Agile. Pourtant, peu d’entreprises le mettent en place pour plusieurs raisons, notamment l’investissement qui peut être conséquent sur des projets d’envergure. Mais son adoption devrait devenir de plus en plus courante grâce à l’aide d’outils qui simplifient sa mise en œuvre. On peut évoquer notamment Docker qui permet de déployer son application sur n’importe quel environnement au sein d’un conteneur logiciel. Ou encore Chef ou Puppet, des outils de gestion automatisée de configuration. Et bien sûr l’intégration continue avec un des serveurs les plus connus : Jenkins. Cette liste est loin d’être exhaustive, il existe pléthore d’outils pour cela, qu’ils soient Open Source ou bien sous licence propriétaire.

Retrouvez la présentation slideshare : ici !

Share
Kevin ALDEBERT
Kevin ALDEBERT

1884

Leave a Reply

Your email address will not be published. Required fields are marked *