Aujourd’hui, on va partir à la découverte ou re découverte de Jenkins, l’outil très populaire d’intégration continue. Ce type d’article part d’une volonté de m’intéresser à certains sujets du monde informatique, d’autres articles viendront sur ce blog si je trouve des sujets que je trouve pertinent de partager. J’ai utilisé l’outil dans un environnement professionnel pour réaliser des tâches basiques comme du build et du test unitaire et ai découvert la suite de plugin Blue Ocean lors d’une phase de veille technologique. Je vous propose dans ce billet de faire un petit tour de ce que propose cette suite de plugin et à quel besoin elle répond.
Jenkins en quelques mots
Jenkins est un outil d’intégration continue, utilisé par un million de personne chaque jour sur environ 500 000 serveurs. L’outil dispose de plus de 1000 plugins permettant a chaque utilisateur de connecter Jenkins à beaucoup d’autres logiciels et outils.
Des flux de déploiements simples
Le terme « intégration continue » revient souvent, mais il n’est pas le seul.
L’intégration continue par définition est la construction des livrables et l’exécution de tests unitaires.
Le delivery continue rajoute deux étapes qui sont le déploiement et l’exécution de tests sur le livrable déployé
Si l’on ajoute à cela la mise en production de ce livrable, on parle alors de déploiement continu.
Bien entendu, ces termes peuvent signifier autre chose pour chaque entreprise, ici il s’agit d’une définition grossière qui permet d’introduire ces termes et les définir d’une façon simple.
Et d’autres plus complexes
Les schémas ci-dessus laissent penser qu’un flux de déploiement est un enchainement simple d’étape, mais en réalité, c’est bien plus complexe que cela de décrire un flux qui permet de déployer sur toute une chaine de production.
En témoigne l’exemple de cloudbees.com, une plateforme fournissant des solutions de Delivery Continu. Plusieurs choses intéressantes sur ce flux de déploiement :
- Multiples phases
- Plusieurs sorties possibles sur certaines étapes
- Des étapes exécutées sur des serveurs différents (Jaune pour les serveurs de tests, bleu pour les serveurs de production)
On se retrouve rapidement avec des flux de plus en plus complexes, selon l’infrastructure choisie par une entreprise et mettre en oeuvre un flux de ce genre sur un Jenkins « classique » se révèle complexe voire impossible.
Besoin de changement
Plusieurs éléments ont poussé la plateforme Jenkins à évoluer pour répondre aux nouveaux besoin de ses utilisateurs.
Décentralisation des jobs
Aujourd’hui, dans beaucoup d’entreprise, le développement d’une application est confié à une équipe et le déploiement à une autre. Les jobs configurés pour déployer une application ne sont généralement pas disponibles pour les développeurs, car leur mission s’arrête une fois les tests terminés. Mais selon les modifications apportées à l’application, la phase de déploiement peut être vouée à évoluer aussi ce qui implique une synchronisation des Dev et des Ops.
De plus, selon comment sont configuré les jobs, un projet peut avoir plusieurs jobs et en cas d’évolution les équipes environnement peuvent être amenées à en modifier beaucoup.
La maintenance s’avère rapidement complexe et couteuse.
Utilisation des méthodes agiles
Les méthodes Agiles sont de plus en plus utilisées dans les projets. En agile, les équipes sont autonomes et pluridisciplinaires et devraient donc être en capacité de traiter cette phase de déploiement. Les livrables sont livrés lors de cycles itératifs permettant d’avoir en théorie un logiciel pouvant aller en production à la fin de chaque cycle. De plus, la tendance DevOps se développe permettant a une même équipe de s’occuper du développement et du déploiement.
Experience utilisateur de l’outil
Aujourd’hui, la modification d’un job passe par une interface graphique ce qui rend lourd la modification de plusieurs jobs. Une phase d’apprentissage est nécessaire pour qu’une personne puisse utiliser l’outil et comprendre ce qu’il fait. Cet apprentissage est spécifique à Jenkins et ne peut être mis à contribution sur d’autres outils d’intégration continue.
Pipeline Project
La réponse à tous ces nouveaux besoin : les projets Pipeline. Ce type de projet n’est pas nouveau dans Jenkins cependant, ils ont gagné en facilité de mise en oeuvre suite à la sortie d’une suite de plugins « Blue Ocean » qui met à disposition une nouvelle interface pour créer son Pipeline de déploiement.
Les apports
Concrètement, quels sont les apports de ce type de projet Pipeline ?
Tout d’abord, la logique de déploiement n’est plus stockée dans Jenkins, elle est déportée dans un fichier « Jenkinsfile » (un fichier texte classique) dans lequel cette logique est codée soit via une syntaxe « Déclarative », la plus récente, à partir de mot clés mis à disposition pour réaliser des actions, soit via une syntaxe « Scriptée » grâce à un sous ensemble du langage Groovy Script. On peut mixer les deux façons de faire au sein d’un même fichier Jenkinsfile.
Deuxièmement, ce Jenkinsfile est stocké dans votre gestionnaire de source ! Plus besoin d’ouvrir Jenkins et de regarder la configuration d’un job pour voir ce qu’il fait, cette logique est maintenant accessible à toute personne ayant accès au gestionnaire de source, ce qui permet :
- L’audit du fichier pour savoir exactement ce qu’il se passe au déploiement
- Pouvoir faire des évolutions sur ce flux de déploiement en créant une nouvelle branche comme on en ajoute pour réaliser des évolutions sur une application
- Tester l’évolution de son flux de déploiement sans casser l’ancien et faire un rollback si nécessaire
Il reste nécessaire de faire prendre connaissance à Jenkins de votre projet. Ce qui change avec les projets Pipeline, c’est que Jenkins va scanner votre repository de source et scanner l’ensemble des branches et pull request à la recherche de fichier Jenkinsfile. Pour chaque branche qui en possède un, Jenkins va automatiquement créer un Job. Combiné à la configuration d’un Webhook sur votre gestionnaire de source, cela permet de créer à la volée des job pour vos branches, vérifier immédiatement si tout est OK ou non avant de fusionner vos modifications.
Intégration de Docker
Avec Blue Ocean, on peut désormais invoquer des images Docker à la volée lors de la configuration du flux de développement. Cela permet donc de déporter les outils vers des images docker, faciliter la gestion de multiple version d’outil dans différents projets et de reproduire un environnement de production. Les projets pipeline supportent les fichiers Dockerfile permettant de créer à la volée un conteneur basé sur une description personnalisée.
A quoi cela ressemble ?
Un fichier Jenkinsfile débute toujours par la balise pipeline. Ensuite, sur cet exemple, nous voyons une balise agent. Cette balise permet d’indiquer à Jenkins a quel endroit doivent être exécutés l’ensemble des stages qui suivent. Plusieurs choix sont possibles :
- none : On définira l’agent sur chacun des stages plutôt qu’en global
- node avec un label : On indique à Jenkins sur quel noeud qu’il connait exécuter les stages. Cela peut être utile si vous avez une application Java par exemple, d’indiquer à Jenkins d’exécuter les stages sur un noeud qui possède Maven
- docker : Permet d’indiquer une image, des arguments, un repository privé
- dockerfile : Permet d’utiliser un docker file pour instancier une image
Suit la balise « stages » qui décrit l’ensemble des phases de notre déploiement. Chaque stage possède un nom ainsi qu’une suite de « steps » ou étapes. Une étape peut être l’invocation d’un plugin Jenkins existant. Ici, il s’agit simplement d’exécuter des commandes shells, mais vous pouvez invoquer des commandes Bash pour windows, exécuter des commandes git, utiliser le plugin maven, faire de la temporisation etc….
Au sein d’un stage, les steps peuvent être exécutés de manière parallèle. Utilisé par exemple pour lancer les tests unitaires jUnit, DBUnit, Jasmine… en parallèle avant de passer à l’étape qui suit.
Le mot clé « post » est disponible pour déclencher des étapes à la fin de l’exécution de l’ensemble des steps parallèles d’un stage.
Par où commencer ?
Initialiser un Jenkinsfile peut être compliqué si on n’est pas familier avec le concept de projet Pipeline. C’est pourquoi Blue Ocean intègre un éditeur graphique pour configurer son pipeline.
Je préviens d’entrée : Cet éditeur vous servira pour initialiser ce fichier, mais une fois que vous aurez compris le fonctionnement, vous irez plus vite à le modifier à la main et de plus, plus vous l’enrichirez, moins l’outil graphique vous aidera. Si vous mixez du déclaratif et du script, l’outil ne fonctionnera plus puisqu’il ne supporte que les pipelines déclaratifs.
La première page de l’assistant vous demande sur quel gestionnaire vous hébergez votre code source et de sélectionner votre repository.
Vous arrivez ensuite sur ce canevas vierge où vous pourrez ajouter des stages et des étapes. Les étapes disponibles sont listées dans l’outil et lorsque vous en choisissez une, les options pour les utiliser apparaissent.
A quoi cela ressemble une fois terminé ?
Cette image montre le Pipeline que j’ai créé pour un projet Angular. Il est relativement simple (60 lignes de code dans le Jenkinsfile) et permet de builder, tester, déployer et analyser la qualité de code du livrable.
Des flux plus complexes
Sur ces deux exemples vous pouvez voir comment se matérialise des étapes parallèles.
D’autres possibilités offertes
En plus de ce que nous venons de voir, les projets Pipeline permettent de
- Conditionner des traitements, selon des branches
- Deployer en production uniquement s’il s’agit de la branche master
- Passer l’analyse de code uniquement sur develop
- Executer des contrôles sur les branches d’évolution dont le pattern est feature/* etc…
- Demander la validation d’un humain avant de passer au prochain stage
- La directive « input » permet de bloquer le traitement du flux en demandant à un humain de cliquer sur un bouton. Utilisé par exemple lors de la dernière phase pour re contrôler que tout va bien avant d’envoyer en production
- Interaction avec l’ensemble des plugins disponibles dans Jenkins
- Un générateur de syntaxe est disponible dans Jenkins. Vous utilisez un plugin comme pour un projet « freestyle » et Jenkins vous donne la syntaxe à utiliser dans votre Jenkinsfile
- Récupération de crédential stocké dans Jenkins
- Evite de mettre en clair vos mots de passe
- Instructions poussées via l’utilisation du Groovy script
- Utilisation possible de if/else, try/catch
- Utilisation des variables d’environnement proposées par Jenkins
Pour aller plus loin
Si vous êtes arrivés jusqu’ici, félicitations. Pour aller plus loin, je ne peux que vous conseiller d’aller visiter le site officiel qui regorge de documentation sur le sujet.
https://jenkins.io/doc/book/pipeline/syntax/
https://jenkins.io/doc/book/pipeline/jenkinsfile/
https://github.com/jenkinsci/pipeline-examples/tree/master/declarative-examples/simple-examples
Très bon article. Je connais Jenkins mais il permet de voir plus loin qu’un simple CI.
De plus, super bien rédigé !
Super article,
Déjà connu et mis en place de mon coté, mais très très bien écrit pour les profanes!
Good Job Mr Fabien!