Aller au contenu

TP : SonarQube self-hosted, Quality Gate et Quality Profile

Objectifs pédagogiques

À la fin de ce TP, vous devez être capables de :

  • déployer un SonarQube self-hosted en local
  • créer un projet et lancer une première analyse avec sonar-scanner
  • lire les résultats d'une analyse dans l'interface SonarQube
  • créer un Quality Profile personnalisé à partir de Sonar way
  • créer un Quality Gate personnalisé et l'associer à un projet
  • faire échouer une analyse quand le Quality Gate n'est pas respecté

Fil conducteur

Dans ce TP, vous allez partir d'une instance SonarQube locale, analyser un projet simple, puis durcir progressivement les contrôles de qualité :

  1. déployer SonarQube
  2. analyser un projet
  3. personnaliser les règles via un Quality Profile
  4. définir la politique de validation via un Quality Gate
  5. faire échouer l'analyse si le projet ne respecte pas cette politique

Choix recommandés pour le TP

Pour éviter de perdre du temps sur l'application elle-même, prenez un petit projet facile à scanner :

  • une API Flask ou FastAPI
  • un projet Node.js simple
  • un mini projet Java Maven

Le plus simple pour un TP rapide reste souvent un petit projet Python ou Node.js

Partie 1 : Déployer SonarQube en local

Objectif

Mettre à disposition une instance SonarQube self-hosted avec une base PostgreSQL

Travail demandé

Créez un fichier docker-compose.yml contenant au minimum :

  • un service sonarqube
  • un service postgres
  • des volumes persistants

Exemple minimal :

services:
  sonarqube:
    image: sonarqube:community
    container_name: sonarqube
    depends_on:
      - postgres
    ports:
      - "9000:9000"
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://postgres:5432/sonarqube
      SONAR_JDBC_USERNAME: sonarqube
      SONAR_JDBC_PASSWORD: sonarqube
    volumes:
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_logs:/opt/sonarqube/logs
      - sonarqube_extensions:/opt/sonarqube/extensions

  postgres:
    image: postgres:16
    container_name: sonarqube-postgres
    environment:
      POSTGRES_USER: sonarqube
      POSTGRES_PASSWORD: sonarqube
      POSTGRES_DB: sonarqube
    volumes:
      - postgresql:/var/lib/postgresql
      - postgresql_data:/var/lib/postgresql/data

volumes:
  sonarqube_data:
  sonarqube_logs:
  sonarqube_extensions:
  postgresql:
  postgresql_data:

Commandes utiles

docker compose up -d
docker compose ps
docker compose logs -f sonarqube

Vérifications attendues

  • l'interface est accessible sur http://localhost:9000
  • vous pouvez vous connecter avec les identifiants par défaut puis changer le mot de passe administrateur
  • les conteneurs restent en état Up

Questions de synthèse

  • Pourquoi PostgreSQL est-il préférable à la base embarquée pour un usage réel
  • À quoi servent les volumes persistants
  • Pourquoi un outil d'analyse comme SonarQube doit-il être traité comme un service d'équipe et non comme un simple binaire local

Partie 2 : Créer un projet et lancer une première analyse

Objectif

Créer un projet SonarQube et comprendre le cycle minimal d'analyse

Travail demandé

  1. Connectez-vous à SonarQube
  2. Créez un projet local
  3. Générez un token d'analyse
  4. Ajoutez un fichier sonar-project.properties dans votre projet

Exemple minimal :

sonar.projectKey=tp-sonarqube-local
sonar.projectName=tp-sonarqube-local
sonar.sources=.
sonar.sourceEncoding=UTF-8
sonar.host.url=http://localhost:9000
  1. Lancez une première analyse avec sonar-scanner

Exemple :

sonar-scanner -Dsonar.token=VOTRE_TOKEN

Vérifications attendues

  • le projet apparaît dans SonarQube
  • une analyse est visible dans l'historique
  • vous voyez au moins quelques métriques et quelques issues

Questions de synthèse

  • Quel est le rôle de sonar.host.url
  • Pourquoi le token ne doit-il pas être commité dans Git
  • Quelle différence faites-vous entre lancer une analyse en local et intégrer l'analyse dans une CI

Partie 3 : Produire des résultats exploitables

Objectif

Disposer d'un projet avec assez de matière pour manipuler des règles de qualité

Travail demandé

Ajoutez volontairement quelques problèmes simples dans votre projet. L'objectif n'est pas de faire un exercice de sécurité complet mais d'avoir des résultats visibles dans SonarQube.

Exemples possibles :

  • duplication de code
  • fonction trop longue
  • variable inutilisée
  • complexité trop élevée
  • mot de passe codé en dur
  • usage d'une pratique peu sûre détectée par votre langage

Vérifications attendues

  • l'analyse remonte plusieurs issues
  • les issues appartiennent à plusieurs catégories utiles pour le TP
  • vous pouvez identifier au moins une règle activée qui a déclenché un résultat

Questions de synthèse

  • Toutes les mauvaises pratiques sont-elles détectées par SonarQube
  • Pourquoi faut-il éviter de transformer SonarQube en outil de "correction automatique" sans réflexion

Partie 4 : Créer un Quality Profile personnalisé

Objectif

Comprendre que le Quality Profile définit quelles règles sont actives pour un langage

Point de repère

SonarQube fournit par défaut le profil Sonar way, marqué comme profil intégré et utilisé par défaut si aucun autre profil n'est choisi

Travail demandé

  1. Ouvrez Quality Profiles
  2. Sélectionnez le langage principal de votre projet
  3. Créez un profil personnalisé à partir de Sonar way
  4. Nommez-le par exemple Master Custom Profile
  5. Activez ou désactivez quelques règles pour observer l'impact
  6. Associez ce profil à votre projet
  7. Relancez une analyse

Recommandation pédagogique

Choisissez 2 à 4 ajustements maximum pour garder un lien clair entre la modification du profil et le résultat observé

Exemples d'ajustements pertinents :

  • activer une règle plus stricte sur les mots de passe codés en dur
  • activer une règle sur la complexité
  • désactiver une règle jugée trop bruyante pour le TP
  • comparer le résultat avant et après changement du profil

Ce que vous devez observer

  • le Quality Profile agit sur les règles de détection
  • un changement de profil modifie les issues remontées au prochain scan
  • un profil personnalisé permet d'adapter SonarQube au contexte d'une équipe

Questions de synthèse

  • Quelle différence faites-vous entre un Quality Profile et un Quality Gate
  • Pourquoi partir de Sonar way est-il plus raisonnable que repartir de zéro
  • Dans quels cas une équipe voudrait-elle désactiver une règle pourtant valide techniquement

Partie 5 : Créer un Quality Gate personnalisé

Objectif

Comprendre que le Quality Gate définit les critères de validation d'un projet

Travail demandé

  1. Ouvrez Quality Gates
  2. Créez un nouveau gate, par exemple Master Gate
  3. Ajoutez quelques conditions simples et explicites
  4. Associez ce gate à votre projet
  5. Relancez une analyse et observez le statut

Proposition de gate simple pour le TP

Créez un gate centré sur le New Code avec 3 ou 4 conditions maximum :

  • New issues doit être égal à 0
  • New Security Rating doit être A
  • New Reliability Rating doit être A
  • New Duplicated Lines (%) doit être inférieur à un seuil raisonnable

L'objectif n'est pas d'avoir le gate le plus sévère possible mais un gate compréhensible et démontrable

Ce que vous devez observer

  • le Quality Gate ne décide pas quelles règles tournent
  • il décide si le résultat final est acceptable ou non
  • un projet peut avoir le même profile mais des gates différents selon le contexte

Questions de synthèse

  • Pourquoi est-il préférable de raisonner sur le New Code
  • Pourquoi un gate trop strict peut-il être contre-productif au début
  • Quel serait un bon compromis entre exigence et adoption pour une équipe qui démarre

Partie 6 : Faire échouer l'analyse quand le gate échoue

Objectif

Passer d'un simple dashboard à un vrai contrôle bloquant

Travail demandé

Relancez l'analyse avec l'attente du statut du Quality Gate

Commande :

sonar-scanner \
  -Dsonar.token=VOTRE_TOKEN \
  -Dsonar.qualitygate.wait=true

Vous pouvez aussi ajuster le délai d'attente :

sonar-scanner \
  -Dsonar.token=VOTRE_TOKEN \
  -Dsonar.qualitygate.wait=true \
  -Dsonar.qualitygate.timeout=300

Manipulation attendue

  1. Faites une analyse qui passe
  2. Introduisez volontairement un changement qui doit faire échouer votre gate
  3. Relancez l'analyse
  4. Corrigez le problème
  5. Vérifiez que l'analyse repasse au vert

Ce que vous devez observer

  • l'analyse attend le résultat du Quality Gate
  • si le gate échoue, la commande échoue aussi
  • vous pouvez utiliser ce comportement dans une pipeline CI/CD

Questions de synthèse

  • Pourquoi sonar.qualitygate.wait=true est-il important en CI
  • En quoi un Quality Gate rend la qualité "actionnable"
  • Pourquoi faut-il distinguer un dashboard d'observation d'un contrôle bloquant

Partie 7 : Intégration CI minimale

Objectif

Transposer la même logique dans une pipeline

Point d'attention réseau

Le job CI qui exécute sonar-scanner doit pouvoir joindre SONAR_HOST_URL

Cela veut dire que http://localhost:9000 fonctionne pour un scan local sur votre machine, mais pas pour un runner GitLab SaaS

Deux architectures sont possibles :

  • Option A : GitLab SaaS + tunnel SonarQube tourne sur votre machine ou sur un serveur local, puis vous l'exposez temporairement avec ngrok ou cloudflared
  • Option B : runner self-hosted Le runner GitLab est installé dans le même réseau que SonarQube et peut joindre l'instance directement sans tunnel

Pour un TP, l'option A est souvent la plus simple si vous utilisez GitLab.com

Pour un contexte plus réaliste en entreprise, l'option B est généralement préférable

Option A : GitLab SaaS avec tunnel

Si vous utilisez les runners partagés GitLab.com, vous devez exposer votre SonarQube local avec une URL accessible depuis Internet

Exemples d'outils :

  • ngrok
  • cloudflared

Exemple avec ngrok :

ngrok http 9000

Vous obtenez alors une URL publique de type :

https://abcd-12-34-56-78.ngrok-free.app

Dans ce cas :

  • SONAR_HOST_URL doit pointer vers l'URL publique du tunnel
  • SONAR_TOKEN reste le token généré dans votre SonarQube local
  • si le tunnel tombe, la pipeline échoue

Option B : runner self-hosted sans tunnel

Si votre runner GitLab est dans le même réseau que SonarQube, vous pouvez utiliser une URL privée ou interne

Exemples :

http://sonarqube:9000
http://192.168.1.20:9000

Dans ce cas :

  • pas besoin d'exposer SonarQube sur Internet
  • la connectivité est plus stable
  • l'architecture est plus propre pour un usage durable

Recommandation pour ce TP

Choisissez l'une des deux approches suivantes :

  1. GitLab.com et runners SaaS : utilisez un tunnel ngrok ou cloudflared
  2. GitLab avec runner self-hosted : utilisez un accès réseau direct sans tunnel

Exemple minimal GitLab CI/CD

stages:
  - quality

sonarqube-check:
  stage: quality
  image:
    name: sonarsource/sonar-scanner-cli:latest
    entrypoint: [""]
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
    GIT_DEPTH: "0"
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script:
    - sonar-scanner -Dsonar.qualitygate.wait=true
  only:
    - main
    - merge_requests

Variables attendues

  • SONAR_HOST_URL
  • SONAR_TOKEN

Questions de synthèse

  • Pourquoi localhost ne peut-il pas être utilisé depuis un runner GitLab SaaS
  • Dans quel cas un tunnel est-il nécessaire
  • Pourquoi un runner self-hosted évite-t-il ce besoin
  • Pourquoi GIT_DEPTH: "0" est-il recommandé
  • Pourquoi le cache .sonar/cache améliore-t-il l'expérience CI
  • À quel moment activeriez-vous ce contrôle sur main seulement, puis sur toutes les merge requests

Critères de réussite du TP

Le TP est réussi si vous pouvez démontrer :

  • une instance SonarQube self-hosted opérationnelle
  • une première analyse visible dans l'interface
  • un Quality Profile personnalisé associé au projet
  • un Quality Gate personnalisé associé au projet
  • une analyse qui échoue lorsque le gate n'est pas respecté

Pour aller plus loin

  • comparer deux profils pour un même projet
  • tester un gate très souple puis un gate plus strict
  • séparer les règles utiles en apprentissage de celles utiles en production
  • discuter en groupe de ce qui doit être bloquant ou non dans une vraie équipe