Votre pipeline contient désormais les étapes de build et de test.
Dans ce dernier chapitre de la partie CI, nous allons voir les deux dernières étapes du pipeline d’intégration continue : la qualité de code et la gestion des artéfacts de livraison (le package).
Mesurez la qualité de votre code
Commençons par l’analyse de code statique, afin de contrôler la qualité du code.
Pour cela, je vous invite à suivre les manipulations de la vidéo ci-dessous.
Durant la phase de mesure de la qualité, il est également important de tester son code pour avoir une vision de la sécurité de ce dernier. Il existe trois types différents de tests de sécurité dans le code :
le SAST(Static Application Security Testing) ou test de sécurité statique de l'application. Ce test consiste à tester le code source de l’application contre des vulnérabilités connues de l’application. Il n’est pas nécessaire d’avoir compilé l’application ;
le DAST(Dynamic Application Security Testing) ou test de sécurité dynamique de l'application. Ce test consiste à tester dynamiquement une application déployée. Il intervient généralement durant la phase de déploiement continue de l’application, car ce test nécessite d’avoir une application déployée pour fonctionner. La fondation OWASP met à disposition des outils permettant de détecter des failles de sécurité dans des applications déployées. Ce type de test fonctionne en mode boite noire, c’est-à-dire que le test s’exécute sans avoir accès au code source, ni au binaire, mais directement par un point d’entrée de l’application comme une page web ou la page principale de l’application ;
le IAST(Interactive Application Security Testing) ou test de sécurité interactif de l’application. Ce test consiste à tester l’application depuis l’intérieur de celle-ci. Contrairement au DAST, le IAST a accès au binaire de l’application et au code source. Il permet d’avoir une portée plus importante pour l’analyse des failles de sécurité de l’application.
Le SAST peut être lancé juste après la compilation du code, en même temps que les tests unitaires. Comme expliqué juste avant, le but est de tester le code source de l’application à la recherche de vulnérabilités connues du langage.
Ça y est, l’étape de qualité est implémentée !
Packagez votre application pour la déployer
La dernière étape après la mesure de la qualité du code est le packaging de l’application, afin de pouvoir la déployer plus facilement.
Pour ce projet, nous avons choisi Docker comme programme de packaging.
GitLab vient avec une registry Docker incluse, ce qui nous permet de stocker nos images au sein de GitLab. Pour pouvoir packager nos images Docker, il est nécessaire d’ajouter une nouvelle étape à notre pipeline d’intégration continue. Nous allons une nouvelle fois modifier le fichier.gitlab-ci.yml
pour ajouter cette nouvelle étape. Le fichier final ressemblera alors à ceci :
stages:
- build
- test
- quality
- package
cache:
paths:
- .m2/repository
key: "$CI_JOB_NAME"
build_job:
stage: build
image: eclipse-temurin:17-jdk-alpine
script:
- ./mvnw compile
-Dhttps.protocols=TLSv1.2
-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN
-Dorg.slf4j.simpleLogger.showDateTime=true
-Djava.awt.headless=true
--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true
test_job:
stage: test
image: eclipse-temurin:17-jdk-alpine
script:
- ./mvnw test
-Dhttps.protocols=TLSv1.2
-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN
-Dorg.slf4j.simpleLogger.showDateTime=true
-Djava.awt.headless=true
--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true
code_quality_job:
stage: quality
allow_failure: true
image: docker:stable
services:
- docker:dind
script:
- mkdir codequality-results
- docker run
--env CODECLIMATE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
--volume /tmp/cc:/tmp/cc
codeclimate/codeclimate analyze -f html > ./codequality-results/index.html
artifacts:
paths:
- codequality-results/
package_job:
stage: package
image: eclipse-temurin:17-jdk-alpine
services:
- docker:dind
variables:
DOCKER_HOST: tcp://docker:2375
script:
- apk add --no-cache docker-cli-compose
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- ./mvnw install -PbuildDocker -DskipTests=true -DpushImage
-Dhttps.protocols=TLSv1.2
-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository
-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN
-Dorg.slf4j.simpleLogger.showDateTime=true
-Djava.awt.headless=true
--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true
- docker compose build
- docker compose push
Ce job supplémentaire compile le projet et l’encapsule dans un conteneur. Il est ensuite poussé sur la registry de GitLab. Nous retrouvons toutes les lignes que nous avons vues précédemment. La partiescript
lance cependant quelques commandes supplémentaires :
Tout d’abord, nous installons le client Docker dans l’image
eclipse-temurin:17-jdk-alpine
afin de pouvoir lancer les commandes propres à Docker.Ensuite, nous nous connectons sur la registry interne de GitLab afin de pouvoir pousser les images Docker de façon sécurisée.
Enfin, nous lançons la commande Maven de création de l’image Docker.
Ce processus nous permettra, dans la livraison continue, de déployer facilement le même code sur différents environnements. Il sert aussi à figer le code compilé dans un package immuable. De ce fait, nous pouvons facilement redéployer le même code compilé sur n’importe quel autre environnement. Cela assure que le code ne soit pas modifié entre deux environnements et qu’un code testé soit déployé partout de la même façon. Les images Docker ainsi packagées se retrouvent sur la page de la registry :
Sur la plateforme SaaS Gitlab, il existe une fonctionnalité d’analyse des artéfacts de livraison comme les images Docker qui détecte automatiquement toutes les Common Vulnerabilities and Exposures(CVE) d’une image donnée. Ainsi, lors de la phase de déploiement, l’équipe d’exploitation peut prendre une décision éclairée basée sur le nombre de failles présentes dans cette image applicative.
Il existe aussi d’autres types d’analyses disponibles dans Gitlab, comme l’analyse de dépendance, qui ne se base pas sur une image Docker, mais analyse les dépendances de vos applications (paquets Java, NodeJS, etc.) pour avoir une vision générale des failles de sécurité de toute l’application.
Nous avons maintenant toutes les étapes nécessaires pour l’intégration continue. Comme prévu, notre code est compilé en continu, testé, analysé puis packagé, prêt à être déployé sur de nouveaux environnements.
Découvrez les autres outils de l’intégration continue
Vous avez donc vu tout au long de cette partie comment mettre en place l’intégration continue avec GitLab. Mais sachez qu’il existe d’autres outils reprenant les mêmes concepts. Le plus connu et le plus utilisé d’entre eux est Jenkins. Avec cet outil, vous pouvez implémenter toutes les étapes précédemment vues. De plus, Jenkins utilise maintenant un fichier de description comme GitLab, qui s’appelle Jenkinsfile.
Le principe est strictement le même que GitLab : il s’agit d’un fichier de description du pipeline d’intégration continue qui va contenir toutes les étapes à lancer, afin de garantir que le code compile et qu’il est de qualité à tout moment. Cependant, il est nécessaire d’installer Jenkins dans votre entreprise, de le configurer, de le maintenir et de le mettre à jour, ce qui peut s’avérer long et fastidieux.
Pour ceux qui ne voudraient pas passer leur temps à maintenir ce genre d’outils, il existe aussi d’autres outils en mode Software-as-a-Service (SaaS), où la maintenance et l’évolution sont garanties par le fournisseur. Ces outils peuvent être plus adaptés pour mettre en place rapidement et sans effort un pipeline d’intégration continue. Les outils les plus connus dans cet écosystème sont Travis CI et CircleCI.
Le gros avantage de ces outils est que la maintenance n’est pas à la charge de l’équipe, mais du fournisseur. De plus, ces outils peuvent se connecter automatiquement sur Github.com pour la plupart, ce qui évite aussi les configurations longues et fastidieuses des différents outils.
Enfin, GitHub a sorti un nouveau service à destination des développeurs, afin de pouvoir implémenter rapidement des pipelines d’intégration continue : GitHub Actions. Le principe est toujours le même : un fichier .workflow permet de créer un pipeline afin de compiler et déployer du code sur n’importe quelle plateforme. L’avantage principal de GitHub Actions est que ce dernier est directement intégré dans GitHub.
En résumé
Il existe plusieurs tests de sécurité du code : le SAST, le DAST et l’IAST.
Il est possible de packager facilement une application dans un conteneur Docker.
Le packaging d’une application permet de sauvegarder les artéfacts prêts à être déployés.
Il existe de nombreux outils pour la mise en place de l’intégration continue.
Maintenant que nous avons réalisé ensemble l’intégration continue, je vous invite à tester vos connaissances avec un quiz. Ensuite, dans la deuxième partie du cours, nous allons mettre en place la livraison continue, du déploiement à la supervision, en passant par les tests en production.