Process de déploiement automatique
30/09/2021 par Fred.
Le déploiement d’une application complexe sur une production en haute disponibilité est souvent une opération compliquée et parfois risquée, où chaque minute hors ligne coûte cher. Chez i-Run nous effectuons en moyenne de 2 à 3 déploiements en production par semaine. Il est donc primordial pour nous que cette opération soit la plus banale et anodine possible. Voilà le process qui a été mis en place par l’équipe pour automatiser et fiabiliser le processus de mise en production.
Un peu de contexte
Nos applications sont à base de JavaScript, de HTML et de Java. Donc nos artéfacts sont produits à partir de NPM ou de Maven déployés sur des serveurs d’application Java. Le code est versionné sous Git et le CI est effectué par GitLab.
Les Origines
On est parti de loin …
Il y a quelques années de ça, les déploiements se faisaient de manière assez manuelle. Un des développeurs, vaillant et volontaire, prenait en charge la release et le déploiement. Il commençait alors un ultra-trail semé d’embûches.
Il devait s’assurer que tous les développements étaient fusionnés, puis il buildait les artefacts sur son poste avant de les versionner dans le dépôt Git. Il devait aussi vérifier que toutes les configurations étaient bien mises aux valeurs de production et pas aux valeurs de développement, car les fichiers de configuration font partie de l’application.
Ensuite, il notait le hash de commit et lançait un script shell que l’administrateur système avait développé et dont il ne comprend pas le contenu. Ce script se connecte à la production et tire le commit depuis le hash précédemment noté.
Bien sûr, ce processus impliquait que sur le serveur de production, tout le nécessaire de prérequis et de configuration était déjà fait, sans besoin de modification. Si une configuration était à ajouter ou modifier, une intervention de l’administrateur système était requise.
… bref, on a eu plusieurs fois des ratés dans le processus qui nous ont amenés à revoir notre système de déploiement.
Les problèmes que l’on souhaite résoudre
Plusieurs problèmes se posent avec le processus historique :
- Possibilité d’erreur humaine à plusieurs étapes. En effet, il y a beaucoup trop de manipulations humaines à faire et chaque manipulation amène de possibles erreurs.
- Builds effectués sur le poste de développement. Il est toujours préférable de produire les artéfacts sur des environnements maitrisés et le plus proche possible de la configuration de la production.
- Processus fastidieux. Le processus est long, complexe et demande des connaissances techniques pour être effectué.
- Problèmes de sécurité. Le processus nécessitant des compétences de développement, cela impose que les développeurs aient, indirectement, accès aux machines de production.
Description du processus actuel
Après plusieurs mois de travail et quelques années de stabilisation et de maintenance, un processus de déploiement a été mis en place pour résoudre ces problématiques.
Workflow de travail
Avant d’automatiser, il a fallu rendre notre workflow de travail automatisable. C’est-à-dire faire en sorte que chaque développement ayant vocation à atterrir sur la production, se présente de manière uniforme à la validation.
Équipe de dev
Chaque développement quel qu’il soit débute donc par un ticket. On utilise Gitlab en interne pour notre gestion de tickets. Le développeur crée une branche au format 4242-description-du-dev
sur tous les projets impliqués dans la fonctionnalité ou la correction, et fait ses modifications sur cette branche.
Une fois le développement effectué, la branche est poussée en revue. Deux développeurs doivent alors la revoir et approuver les modifications. GitLab permet de lister les revues de code en attente pour faciliter l’organisation des développeurs.
Une fois le code revu, le ticket est mis au statut Validation en attente
.
Équipe fonctionnelle
Nous utilisons le concept de “Milestone” ou “Jalon” présent dans GitLab pour matérialiser un déploiement ou une MEP.
L’équipe fonctionnelle crée une milestone dans GitLab. Cette milestone est remplie avec un ensemble de tickets au statut Validation en attente
. L’équipe fonctionnelle choisit comment les tickets sont regroupés. Plusieurs milestones peuvent être validées en même temps par différents consultants.
Quand la milestone est constituée, chaque consultant est capable de déployer un environnement de validation pour sa milestone.
Une fois la milestone validée, les consultants habilités sont en mesure de déployer eux même les développements vers la plateforme de préproduction puis de production. Le déploiement se fait en déclenchant un pipeline manuellement dans GitLab. C’est simple et impossible de se tromper. Les étapes du pipeline ne sont accessibles que quand les prérequis de l’étape précédente sont satisfait. Il est ainsi impossible de lancer les déploiements si, par exemple, les artefacts ne se sont pas générés correctement, ou si les tests ne sont pas validés.
Automatisation
Pour les développeurs
Comme les développements se passent souvent sur plusieurs dépôts Git et qu’il est important de bien respecter les formats de nom de branche, les développeurs disposent d’outils pour switcher facilement d’un ticket à l’autre (et donc d’une branche à l’autre) sur tous les dépôts. L’outil permet aussi de créer automatiquement les merge requests pour tous les projets concernés par un ticket. Ce genre de traitement est facile à automatiser du moment que toutes les branches sur tous les dépôts ont le même format et le même nom.
Un dernier outil permet de synthétiser l’état d’un ticket en récupérant l’état de chaque branche et chaque merge request sur l’ensemble des dépôts.
Pour les fonctionnels
Du côté des consultants fonctionnels, une commande permet de lancer le déploiement des milestones précédemment constituées, sur un environnement de validation. Cette commande, qui se joue sur le PC du consultant, effectue les actions suivantes :
- Récupère, depuis GitLab, la liste des tickets de la milestone
- Pour chaque projet, crée une branche Git au format
staging/nom_de_l_environnement
- Pour chaque projet, fusionne dans cette branche les développements correspondant aux tickets de la milestone
- Pousse la branche de staging sur GitLab
Un pipeline prend alors le relais pour les opérations suivantes :
- Construit tous les artefacts nécessaires
- Crée l’environnement de validation
- Déploie l’environnement à partir des artefacts précédemment construits
- Une fois le processus terminé, un message prévient de la disponibilité de l’environnement dans le chat
Une fois la validation effectuée, le même script permet de lancer une release.
Pour chaque projet concerné par un ticket de la milestone, le script va créer une branche de release à partir de la branche de staging. Toutes les branches de release sont poussées sur GitLab ce qui déclenche un pipeline de construction de la release.
Ce pipeline va détecter les projets concernés par les modifications de la milestone. Pour chaque projet, il va compiler, tester et packager les artefacts. Une fois tous les artefacts nécessaires empaquetés et archivés sur le Nexus, un message prévient que la release est terminée.
Déploiement en production
À ce stade, le consultant fonctionnel possède une liste des composants et des versions à déployer sur la production. Seul les composants ayant été modifiés sont présent dans cette liste.
Le déploiement est scripté via Ansible dans un projet GitLab dédié. Il permet aux consultants de choisir et de tagger les versions à déployer sur les serveurs de préproduction et de production.
Le push du tag déclenche un pipeline qui va vérifier que tous les prérequis à une mise en production sont satisfait. Seules les personnes habilitées à faire des mises en production ont accès au projet GitLab de déploiement. En revanche, ils n’ont pas accès aux identifiants de connexion à la production, ces identifiants sont dans des variables accessibles seulement par les administrateurs.
Une fois le pipeline terminé, un bouton donne accès au déploiement sur la préproduction. Une fois que la préproduction est correctement déployée et validée, une nouvelle étape permet le déploiement vers la production. Ces deux étapes se lancent en un simple clic.
Conclusion
Pour résumer, ce processus est en place depuis plus d’une année et nous a permis de résoudre les problèmes précédemment cités. L’automatisation a drastiquement limité les interactions utilisateur. Et les interactions restantes sont simples et peu sujettes à erreur.
Les problèmes de sécurité et de distribution des accès à la production sont résolu via GitLab et des variables masquées dans les CI/CD.
Tous les builds sont effectués à l’intérieur de conteneurs docker préconfigurés et identiques à la production. Plus besoin de configuration spécifique ou d’outils de développement pour lancer une release ou un déploiement.
Le processus est devenu simple et ne demande pas de compétence en développement pour être exécuté. Il faut seulement être capable de lancer une ligne de commande et cliquer sur un bouton.
De plus l’isolation des environnements de validation permet à l’équipe fonctionnelle de traiter plusieurs sujets en parallèle et d’enchainer les projets de manière plus fluide.
Cette automatisation nous permet, depuis sa mise en place, de faire jusqu’à 3 mises en production par jour (si nécessaire) avec une moyenne de deux ou trois mises en production par semaine.