- Blogue
Déployer des infrastructures Web à la fois complexes et maintenables grâce à l’Infrastructure as Code
29 avril — 2020
Chez Mirego, nous concevons, développons et déployons des applications Web depuis plus de 10 ans. Cela nous a permis d’expérimenter toute une variété de plateformes, fournisseurs, techniques et principes de déploiement.
Dernièrement, c’est le désir de minimiser les risques d’erreurs humaines, améliorer la visibilité sur l’infrastructure et augmenter la validité de la documentation de nos projets qui nous a amené à remettre en question nos processus DevOps.
Depuis quelques années, nous nous appuyons sur les principes Infrastructure as Code pour bâtir et déployer des infrastructures Web fiables, maintenables et documentées.
Évolution
Tout d’abord, en 2008, c’était la montée du cloud computing avec l’arrivée du service EC2 d’Amazon Web Services (AWS), qui nous permettait de lancer manuellement des machines sur lesquelles nous installions des serveurs Web. Provisionnements manuels et déploiements contrôlés par des scripts personnalisés étaient sources de problèmes fréquents.
Ensuite est arrivée Heroku qui éliminait la gestion de machines et rendait obsolètes les scripts personnalisés pour effectuer des manipulations liées au déploiement d’une application Web. Ajustement du nombre d’instances, mises à jour de sécurité automatiques du système d’exploitation, provisionnement rapide de composantes externes via des addons, etc. Toute cette complexité était abstraite et gérée de façon transparente par Heroku.
Avec la croissance de Mirego et l’envergure de nos nouveaux clients, Heroku s’avérait souvent être un choix mis de côté, puisque ces clients venaient avec des contraintes de fournisseurs spécifiques. Ces contraintes, combinées avec les frais onéreux de gestion d’Heroku, nous ont fait pivoter vers des services comme AWS Elastic Beanstalk, Google App Engine et Azure App Services. Ces services sont de bons compromis entre un service complet comme Heroku et des services Do it yourself comme AWS EC2 et Google Compute Engine, qui offrent plus de contrôle et de flexibilité, mais demandent plus de maintenance et de configuration des services internes à provisionner (p. ex. base de données, réseau de distribution de contenu, etc.). Tout était encore géré avec des manipulations manuelles et des scripts personnalisés utilisant les outils CLI mis à notre disposition par ces fournisseurs.
Bref, peu importe le choix du fournisseur (AWS, Google Cloud, Azure, Heroku, etc.) et son type de service (do it yourself, fully-managed, semi-managed, etc.), nos principes de déploiement d’infrastructure étaient toujours les mêmes et donc, comportaient les mêmes enjeux potentiels.
Enjeu n°1 : Risque d’erreurs humaines
Personne n’est parfait, tout le monde fait parfois des erreurs. En nous fiant à des manipulations humaines pour effectuer des changements dans une infrastructure, nous introduisions un risque de plus dans l’équation, puisque celles-ci sont souvent loin d’être triviales. On risquait donc de se retrouver avec des infrastructures mal ou différemment configurées selon l’environnement.
Enjeu n°2 : Manque de visibilité
Nous avions depuis très longtemps mis en place des processus de code review pour nous assurer de la haute qualité du code que nous intégrons dans nos projets. Nous ne pouvions pas en dire autant des changements d’infrastructure et des déploiements, qui sont tout aussi, sinon plus importants que des changements de code applicatif. Pas de traçabilité non plus sur qui a effectué quel changement ou déclenché quel déploiement.
Enjeu n°3 : Documentation à titre indicatif seulement
La documentation est souvent présentée comme la bête noire des développeurs. Malgré son importance cruciale dans la maintenabilité d’un projet, celle-ci a bien souvent autant de valeur que le maximum d’effort mis par l’équipe à la rédiger et à la maintenir. S’il n’y a pas d’incitatif direct à maintenir la documentation, elle sera laissée pour compte et deviendra obsolète ou pire, nuisible. C’est ce qui arrivait souvent avec une infrastructure documentée de cette manière; on ne pouvait plus se fier à la documentation pour connaître la vérité.
Infrastructure as Code
C’est pour éliminer ces problèmes que nous nous sommes tournés vers les principes Infrastructure as Code (IaC).
Dans un système IaC, l’état de l’infrastructure est représenté de façon déclarative plutôt qu’impérative, sous forme de code dans le projet. Cet état comprend les composantes de base de l’infrastructure : serveurs, services internes, applications déployées, configurations, etc.
Un outil est alors en charge d’appliquer cet état dans un environnement donné, en s’occupant de faire les ajouts, modifications et suppressions nécessaires pour refléter l’état décrit dans le code, par rapport à l’état actuellement en place dans cet environnement.
Avantage n°1 : Processus s’appliquant au code
Étant donné que l’état de l’infrastructure est stocké de façon déclarative dans les fichiers du projet, il est donc traité comme une partie du code du projet. Il est alors soumis aux mêmes processus que le reste du code :
- Versioning — on peut visualiser son historique et son évolution depuis le début du projet;
- Code Review — les changements qu’on lui porte doivent être approuvés par les membres de l’équipe avant d’être intégrés;
- Linting et formatting — sa syntaxe et son format sont primordiaux dans la maintenabilité de celui-ci, il faut en prendre soin.
Avantage n°2 : Pas de manipulations humaines, donc pas d’erreurs humaines
Se fier sur un outil automatisé pour déployer des infrastructures et des applications Web nous assure :
- Tranquillité d’esprit — aucun facteur humain n’entre en ligne de compte dans l’application de modifications. La seule intervention humaine agit sur la représentation déclarative de l’infrastructure et non pas sur l’infrastructure en tant que telle. Le risque d’erreur humaine est donc minimisé;
- Traçabilité — tout changement et déploiement dans l’infrastructure est documenté, traçable et attribuable;
- Symétrie multienvironnement — une symétrie parfaite entre les infrastructures déployées sur plusieurs environnements différents (p. ex. développement et production) nous permet de réduire le nombre de bogues potentiels que pourraient causer des différences, même mineures.
Avantage n°3 : Sécurité et ownership
Il est important pour Mirego que les développeurs cultivent un maximum d’ownership dans le produit qu’ils bâtissent. Une fonctionnalité doit pouvoir être portée par une même personne du début (code) jusqu’à la fin (déploiement). La sécurité d’une infrastructure est critique et il est tout aussi important pour nous qu’un minimum de personnes y ait accès.
Un système automatisé de déploiement d’infrastructure nous permet d’atteindre le bon équilibre entre culture d’ownership et sécurité. Tout le monde peut déployer des changements dans l’infrastructure, mais personne n’y a accès directement puisque c’est le rôle du système automatisé de les appliquer.
Avantage n°4 : Disaster recovery
En cas d’incident majeur, il est très facile de provisionner un nouvel environnement à partir de zéro, puisqu’il suffit de suivre le même processus qu’un déploiement ou un simple changement : l’outil automatisé applique l’état décrit par rapport à l’état en place. L’état en place est vide; toutes les composantes seront alors créées automatiquement.
Avantage n°5 : Documentation implicite
En décrivant l’infrastructure et ses composantes, nous nous trouvons également à la documenter. Il devient alors pratiquement impossible de se retrouver avec une documentation d’infrastructure incomplète ou erronée, puisque l'infrastructure elle-même est la source de vérité qui sert à appliquer les changements.
Dès le début du développement du projet de refonte complète de l’écosystème numérique TV5 Unis, nous avons mis en place les principes d’Infrastructure as Code au sein de son processus de déploiement. Puisque nous travaillons avec la méthodologie agile, les différentes composantes de l’infrastructure se sont intégrées graduellement au fur et à mesure que le projet prenait forme. Cela nous a permis de suivre l’évolution de cette infrastructure pièce par pièce en la soumettant à notre processus de code review et de validation en équipe.
La liste des composantes du projet est variée et comprend entre autres applications Web, bases de données relationnelles, moteurs de recherche de contenu, réseaux de distribution de contenu statique, systèmes de synchronisation de contenu externe, planificateurs de tâches asynchrones, etc. Même si ces composantes sont complexes et interreliées, le fait qu’elles soient représentées en « format code » les rend simples à visualiser, à raisonner et donc à maintenir.
Il n’y a ainsi pas de possibilité d’angle mort ni de composante obscure ou non documentée. Tout est visible et connu pour l’équipe, peu importe si cela fait huit mois ou huit jours qu’une personne est impliquée dans le projet.
Bref, c’est pour gagner de la visibilité, éviter les erreurs humaines, cultiver l’équilibre entre sécurité et ownership, prévoir les désastres et toujours pouvoir se référer à une documentation exacte que nous nous appuyons sur les principes Infrastructure as Code dans nos processus DevOps. Ils nous permettent de bâtir et déployer des infrastructures Web fiables, maintenables et documentées.