Introduction
📅 Date de réalisation : 10 June 2025
Contexte
Ce projet a été réalisé pour accompagner un étudiant en Bac+5 dans le cadre de son projet de fin d’année en DevOps. L’objectif était de mettre en place une chaîne complète d’intégration et de déploiement continu (CI/CD) en exploitant les outils modernes du Cloud et de l’automatisation.
Objectif
Prendre une application existante et construire une infrastructure DevOps permettant :
- Le déploiement automatique sur Azure
- L’automatisation des tests et du build
- L’utilisation de conteneurs pour assurer portabilité et rapidité de déploiement
Environnement utilisé
- Cloud : Azure
- IaC : Terraform
- CI/CD : Jenkins
- Conteneurisation : Docker & Docker Compose
- Versioning : Git & GitHub
- Application : App JavaScript (Node.js + MySQL)
Architecture globale
Description
- Une VM Ubuntu Spot déployée sur Azure via Terraform
- Réseau : VNet public (NSG ouvert sur tous les ports, car projet de test uniquement)
- Logiciels installés automatiquement (cloud-init) : Docker, Apache2, Jenkins
- Pipeline Jenkins déclenché via webhook GitHub → build + tests + déploiement de l’application dans des conteneurs Docker
- Application exposée sur le port 3000 (frontend + backend + MySQL en conteneurs)
- Jenkins accessible sur le port 8080
- Apache2 sur le port 80 (utilisé pour récupérer le mot de passe Jenkins sans SSH)
Schéma d’architecture (vue simplifiée)
Prérequis
Techniques
- Azure Subscription + Resource Group
- VM Ubuntu 22.04 LTS (image gen2)
- Terraform > v3.0
- Docker & Docker Compose
- Jenkins
- GitHub repository avec fichiers :
Dockerfiledocker-compose.ymlJenkinsfilecloud-init.yaml(installation auto : Docker, Jenkins, Apache2)
Accès
- Rôle Contributor ou Owner sur Azure
- Accès au repo GitHub
Infrastructure as Code (Terraform)
Objectif
Créer automatiquement l’infrastructure sur Azure.
Fichiers
main.tf: définition des ressources Azure (VM, VNet, NSG)variables.tf: paramètres (VM size, mots de passe, etc.)cloud-init.yaml: script d’initialisation de la VM (Docker, Jenkins, Apache2)
Procédure
az login
terraform init
terraform plan
terraform apply
Jenkins (CI/CD)
Installation / Configuration
- Accéder à Jenkins via
http://<public_ip>:8080 - Récupérer le mot de passe admin (affiché par Apache sur port 80)
- Installer les plugins recommandés + Git Server
- Créer un compte admin
- Ajouter les credentials GitHub (via un token PAT)
- Configurer le Webhook GitHub →
http://<public_ip>:8080/github-webhook/
Pipeline (extrait du Jenkinsfile)
pipeline {
agent any
environment {
APP_PORT = "3000"
VM_IP = "xx.xx.xx.xx"
}
stages {
stage('Checkout & Setup') { steps { git url: 'https://github.com/stanilpaul/docker-getting-started-devops-enhanced.git', branch: 'main' } }
stage('Build & Test') { steps { sh 'docker-compose up -d && sleep 15 && docker-compose exec app yarn test || true && docker-compose down' } }
stage('Deploy') { steps { sh 'docker-compose up -d && sleep 5 && curl -I http://localhost:${APP_PORT} || true' } }
}
post {
success { echo "✅ Application déployée sur http://${VM_IP}:${APP_PORT}" }
failure { echo "❌ Échec - vérifier logs" }
}
}
Docker
Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile --production
COPY . .
CMD ["node", "src/index.js", "--host", "0.0.0.0"]
EXPOSE 3000
Docker Compose
services:
app:
build: .
ports:
- "3000:3000"
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: secret
MYSQL_DB: todos
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: todos
volumes:
- todo-mysql-data:/var/lib/mysql
volumes:
todo-mysql-data:
Application
- Repo : docker/getting-started-app
- Techno : JavaScript (Node.js) – 92.8%, HTML 4.4%, CSS 2.8%
- Ports : 3000 (app), 8080 (Jenkins), 80 (Apache2 helper)
- Tests : lancer
docker ps→ 2 conteneurs actifs (app + MySQL). Vérifier via navigateur :http://<public_ip>:3000
Sécurité
⚠️ Ce projet est une démo/test, mais pour une vraie production :
- Restreindre les règles NSG (ne pas laisser tous les ports ouverts)
- Ne pas stocker de mots de passe dans
variables.tf→ utiliserterraform.tfvarsou Azure Key Vault - Déplacer le state file Terraform vers un backend sécurisé (Azure Storage)
Procédures opérationnelles
- Déploiement manuel : si Jenkins tombe →
terraform destroypuisterraform apply - Relancer Docker :
docker-compose down && docker-compose up -d - Rollback : revenir à une version antérieure via GitHub
- Supervision : Azure Monitor / Log Analytics. Optionnellement exporter vers Grafana