Solution Challenge CI/CD et Observabilité des Données

mer. 15 janvier 2025 - 6 min read -

Solution Challenge CI/CD et Observabilité des Données

Cette solution présente une stack d’observabilité complète intégrant PostgreSQL, Prometheus et Grafana, avec un déploiement automatisé via GitLab CI/CD.

📋 Vue d’ensemble

Cette architecture permet de monitorer en temps réel les métriques d’une base de données PostgreSQL, visualisées via Grafana, avec un déploiement entièrement automatisé.

Table des matières


Structure du Projet

Voici l’organisation des fichiers du projet :

cicd-observability-challenge/
├── .gitlab-ci.yml              # Pipeline CI/CD
├── docker-compose.yml          # Orchestration des services
├── prometheus/
│   └── prometheus.yml          # Configuration Prometheus
├── grafana/
│   ├── dashboards/
│   │   └── postgres-dashboard.json
│   └── provisioning/
│       ├── dashboards/
│       │   └── dashboard.yml
│       └── datasources/
│           └── datasource.yml
├── postgres/
│   └── init.sql                # Script d'initialisation DB
└── README.md

Configuration Docker Compose

Le fichier docker-compose.yml orchestre l’ensemble de la stack :

Services Déployés

  1. PostgreSQL - Base de données principale
  2. Postgres Exporter - Collecte des métriques
  3. Prometheus - Stockage et agrégation des métriques
  4. Grafana - Visualisation
version: '3.8'
 
services:
  postgres:
    image: postgres:15
    container_name: postgres-db
    environment:
      POSTGRES_DB: monitoring_db
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres123
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - monitoring
 
  postgres-exporter:
    image: prometheuscommunity/postgres-exporter:latest
    container_name: postgres-exporter
    environment:
      DATA_SOURCE_NAME: "postgresql://postgres:postgres123@postgres:5432/monitoring_db?sslmode=disable"
    ports:
      - "9187:9187"
    depends_on:
      - postgres
    networks:
      - monitoring
 
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--storage.tsdb.retention.time=200h'
      - '--web.enable-lifecycle'
    depends_on:
      - postgres-exporter
    networks:
      - monitoring
 
  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_PASSWORD: admin123
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
      - ./grafana/dashboards:/var/lib/grafana/dashboards
    depends_on:
      - prometheus
    networks:
      - monitoring
 
volumes:
  postgres_data:
  prometheus_data:
  grafana_data:
 
networks:
  monitoring:
    driver: bridge

✅ Bonnes pratiques

  • Utilisation de volumes nommés pour la persistance des données
  • Réseau dédié pour l’isolation des services
  • Variables d’environnement pour la configuration

Configuration Prometheus

Le fichier prometheus/prometheus.yml définit les cibles de collecte :

global:
  scrape_interval: 15s
  evaluation_interval: 15s
 
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"
 
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
 
  - job_name: 'postgres-exporter'
    static_configs:
      - targets: ['postgres-exporter:9187']
    scrape_interval: 5s
    metrics_path: /metrics

Métriques Collectées

  • pg_up - Statut de PostgreSQL
  • pg_stat_database_numbackends - Connexions actives
  • pg_stat_database_xact_commit - Transactions validées
  • pg_stat_database_xact_rollback - Transactions annulées

Pipeline CI/CD GitLab

Le fichier .gitlab-ci.yml automatise le déploiement :

Stages du Pipeline

stages:
  - build
  - deploy
  - test
 
variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: "/certs"
 
services:
  - docker:20.10.16-dind
 
before_script:
  - docker info
  - docker-compose --version

Stage BUILD

build:
  stage: build
  image: docker:20.10.16
  script:
    - echo "Building custom postgres exporter image..."
    - docker build -t custom-postgres-exporter .
    - echo "Build completed successfully"
  only:
    - main
    - develop

Stage DEPLOY

deploy:
  stage: deploy
  image: docker/compose:latest
  script:
    - echo "Starting deployment..."
    - docker-compose up -d
    - echo "Waiting for services to be ready..."
    - sleep 30
    - docker-compose ps
    - echo "Checking service health..."
    - docker-compose logs postgres
    - docker-compose logs postgres-exporter
    - docker-compose logs prometheus
    - docker-compose logs grafana
  after_script:
    - docker-compose down
  only:
    - main

Stage TEST

test:
  stage: test
  image: alpine:latest
  before_script:
    - apk add --no-cache curl
  script:
    - echo "Testing Prometheus metrics collection..."
    - sleep 10
    - curl -f http://prometheus:9090/-/ready || exit 1
    - echo "Testing PostgreSQL exporter metrics..."
    - curl -f http://postgres-exporter:9187/metrics | grep -q "pg_up" || exit 1
    - echo "Testing Grafana availability..."
    - curl -f http://grafana:3000/api/health || exit 1
    - echo "All tests passed!"
  dependencies:
    - deploy
  only:
    - main

⚠️ Points d’attention

  • Les tests nécessitent que les services soient accessibles depuis le runner
  • Un délai de 30 secondes est nécessaire pour que tous les services démarrent
  • Les logs sont consultables pour le débogage

Configuration Grafana

Datasource Prometheus

Fichier : grafana/provisioning/datasources/datasource.yml

apiVersion: 1
 
datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
    editable: true

Provisioning des Dashboards

Fichier : grafana/provisioning/dashboards/dashboard.yml

apiVersion: 1
 
providers:
  - name: 'default'
    orgId: 1
    folder: ''
    type: file
    disableDeletion: false
    updateIntervalSeconds: 10
    allowUiUpdates: true
    options:
      path: /var/lib/grafana/dashboards

Dashboard PostgreSQL

Le dashboard postgres-dashboard.json comprend :

  • Panel 1 : Connexions actives en temps réel
  • Panel 2 : Statut de la base de données (up/down)
{
  "title": "PostgreSQL Monitoring Dashboard",
  "panels": [
    {
      "title": "PostgreSQL Active Connections",
      "type": "timeseries",
      "targets": [
        {
          "expr": "pg_stat_database_numbackends{datname=\"monitoring_db\"}",
          "legendFormat": "Active Connections"
        }
      ]
    },
    {
      "title": "PostgreSQL Status",
      "type": "stat",
      "targets": [
        {
          "expr": "pg_up",
          "legendFormat": "PostgreSQL Status"
        }
      ]
    }
  ]
}

Script d’initialisation PostgreSQL

Fichier : postgres/init.sql

-- Création d'une base de données de test
CREATE DATABASE monitoring_db;
 
-- Connexion à la base
\c monitoring_db;
 
-- Table de test pour générer des métriques
CREATE TABLE IF NOT EXISTS user_sessions (
    id SERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL,
    session_start TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    session_end TIMESTAMP,
    active BOOLEAN DEFAULT TRUE
);
 
-- Données de test
INSERT INTO user_sessions (user_id, active)
VALUES
    (1, true),
    (2, true),
    (3, false),
    (4, true),
    (5, false);
 
-- Utilisateur pour les métriques
CREATE USER monitoring WITH PASSWORD 'monitoring123';
GRANT CONNECT ON DATABASE monitoring_db TO monitoring;
GRANT USAGE ON SCHEMA public TO monitoring;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO monitoring;

Tests et Validation

Script de Test Automatisé

Fichier : test-stack.sh

#!/bin/bash
 
echo "=== Test de la Stack d'Observabilité ==="
 
# Test 1: Vérification des services
echo "1. Vérification des services..."
docker-compose ps
 
# Test 2: Test Prometheus
echo "2. Test de Prometheus..."
curl -f http://localhost:9090/-/ready || { echo "Prometheus non disponible"; exit 1; }
 
# Test 3: Test des métriques PostgreSQL
echo "3. Test des métriques PostgreSQL..."
curl -s http://localhost:9187/metrics | grep -q "pg_up" || { echo "Métriques PostgreSQL manquantes"; exit 1; }
 
# Test 4: Test Grafana
echo "4. Test de Grafana..."
curl -f http://localhost:3000/api/health || { echo "Grafana non disponible"; exit 1; }
 
# Test 5: Test de la base de données
echo "5. Test de la base de données..."
docker exec postgres-db psql -U postgres -d monitoring_db -c "SELECT COUNT(*) FROM user_sessions;" || { echo "Base de données non accessible"; exit 1; }
 
echo "✅ Tous les tests sont passés avec succès!"

Accès aux Services

Une fois déployé, accédez aux services via :

ServiceURLCredentials
Grafanahttp://localhost:3000admin / admin123
Prometheushttp://localhost:9090-
PostgreSQLlocalhost:5432postgres / postgres123
Exporterhttp://localhost:9187/metrics-

Vérification des Métriques

# Vérifier que Prometheus collecte les métriques
curl http://localhost:9090/api/v1/query?query=pg_up
 
# Vérifier les métriques de l'exporter
curl http://localhost:9187/metrics | grep pg_up

Déploiement Local

Démarrage

# Cloner le repository
git clone <repository-url>
cd cicd-observability-challenge
 
# Lancer la stack
docker-compose up -d
 
# Vérifier le statut
docker-compose ps

Nettoyage

# Arrêter et supprimer les volumes
docker-compose down -v
 
# Nettoyer le système Docker
docker system prune -f

Résultats Attendus

✅ Stack Fonctionnelle

  • ✓ PostgreSQL opérationnel avec données de test
  • ✓ Exporter collectant les métriques toutes les 5 secondes
  • ✓ Prometheus scrappant et stockant les données
  • ✓ Grafana affichant les dashboards en temps réel
  • ✓ Pipeline CI/CD validant automatiquement le déploiement

Métriques Disponibles

  • Statut : PostgreSQL up/down
  • Connexions : Nombre de connexions actives
  • Transactions : Commits et rollbacks
  • Performance : Métriques de performance DB

Cette solution répond complètement aux exigences du challenge en déployant une stack d’observabilité fonctionnelle avec un pipeline CI/CD automatisé et testé.