Dans la majorité des projets de développement, la partie backend repose sur une architecture en microservices. Du point de vue "DevOps", cela signifie la création d’un "Jenkinsfile" par "microservice" en gardant principalement les mêmes stages des pipelines avec des modifications sur les paramètres relatifs à chaque microservice, à savoir le nom du projet, la version, etc.
Dans l’optique de réduire la redondance des tâches similaires exécutées par les pipelines du projet, Jenkins propose les “shared libraries” pour externaliser un script commun entre tous les pipelines des microservices.
Cet article vous montre comment cette fonctionnalité clé simplifie la gestion de vos projets backend et industrialise vos processus de déploiement.
Notre objectif sera donc de concevoir un pipeline dynamique qui ne nécessite aucun changement au niveau du script pour qu’il soit réutilisé à chaque microservice du projet. L’aspect dynamique réside dans sa capacité à récupérer les paramètres du projet dynamiquement depuis les fichiers de configuration du microservice à travers des plugins Jenkins (exemple du fichier "pom.xml" pour un microservice à base de java/spring boot).
Une instance Jenkins avec l’accès à l’interface graphique.
Notre environnement du travail s’appuie sur les technologies suivantes (pour un socle java/spring boot) :
Vous pouvez adapter l’architecture ainsi que le script du pipeline conformément à votre environnement et vos besoins.
Dans un répertoire git, créer un dossier “vars” dans lequel le script groovy sera ajouté (créer un fichier vide pour le moment).
Accéder à Tableau de bord > Administrer Jenkins > Configure system .
Puis chercher la section “Global Pipeline Libraries” et appuyer sur “ajouter”.
remplir les champs en spécifiant un nom pour la librairie qui sera son identifiant (ce nom sera utilisé pour faire l’appel à la librairie), ainsi que l’url du répertoire git du projet, puis enregistrer.
Au niveau de Tableau de bord > Administrer Jenkins > Gestion des plugins. Assurer que le plugin “pipeline-utility-steps” est installé.
Ce plugin sera utilisé par la suite dans le script pour récupérer des valeurs depuis le fichier "pom.xml" du projet.
Revenons à notre répertoire git. modifier le fichier testBackendLib.groovy pour ajouter le script suivant :
def call() {
pipeline {
environment {
// La fonction readMavenPom est disponible dans le plugin Jenkins: Pipeline Utility Steps
pom = readMavenPom file: 'pom.xml'
VERSION = "${pom.version}"
PROJECT_NAME = "${pom.artifactId}"
DOMAIN = "${pom.properties.domain}"
// TODO: a renseigner l'url de base du répository des conteneurs
REGISTRY_URL = "l'url de votre registry"
IMAGE_NAME = "$REGISTRY_URL/$DOMAIN/$PROJECT_NAME"
}
stages {
stage("Build") {
steps {
script {
sh "chmod +x ./mvnw && ./mvnw -s settings.xml clean install -U"
}
}
}
stage("Code Analysis") {
environment {
scannerHome = tool 'SonarQubeScanner'
}
steps {
// Jenkins possède un plugin pour l'intégration avec SonarQube
withSonarQubeEnv('SonarQubeScanner') {
sh "${scannerHome}/bin/sonar-scanner -Dsonar.java.binaries=target/classes \
-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml \
-Dsonar.projectKey=$PROJECT_NAME \
-Dsonar.coverage.exclusions=**/config/**/*"
}
}
}
stage("Quality gate") {
steps {
timeout(time: 10, unit: 'MINUTES') {
// Usage du même plugin de SonarQube pour Jenkins
waitForQualityGate abortPipeline: true
}
}
}
stage('Dependency-check') {
when {
expression { true }
}
steps {
sh """
chmod +x ./mvnw
./mvnw -s ./settings.xml dependency-check:purge dependency-check:update-only dependency-check:check
"""
}
post {
always {
// Usage du même plugin de DependencyCheck pour Jenkins
dependencyCheckPublisher pattern: 'target/dependency-check-report.xml'
}
}
}
stage("Build image") {
steps {
script {
sh "podman build -t ${IMAGE_NAME}:${VERSION} . "
}
}
}
stage("Push image") {
steps {
script {
withCredentials([usernamePassword(credentialsId: "registry-creds", usernameVariable: "USERNAME", passwordVariable: 'PASSWORD')]) {
script {
sh "echo $PASSWORD | podman login $REGISTRY_URL -u $USERNAME --password-stdin"
sh "podman push ${IMAGE_NAME}:${VERSION}"
}
}
}
}
}
}
post {
always {
node('master') {
sh "podman rmi -f ${IMAGE_NAME}:${VERSION}"
}
}
}
}
}
Afin de mettre cette “shared library” en action, au niveau du répertoire git de chaque microservice, ajouter un fichier jenkinsfile. Ce fichier sera chargé d’appeler la libraire et de l’appliquer sur le microservice.
Dans cet article, nous avons exploré le concept des “shared libraries” et examiné comment il est possible d’externaliser et de partager l’intégralité d’un script d’intégration continue entre tous les microservices d’un projet backend.
Cette approche offre une perspective précieuse sur la manière dont les “shared libraries” peuvent être mises en œuvre pour favoriser la cohérence et l’efficacité dans le développement de projets à microservices.
Il est important de noter que la mise en place dépend principalement du contexte et de l'environnement de travail, et ainsi, elle doit être ajustée en fonction du cas d'usage.