LAB : Livraison continue d’image Docker sur Harbor avec Jenkins#
Présentation#
Dans ce lab, on va aller un peu plus loin que le lab précèdent et essayer d'intégrer un pipeline de déploiement continu. Ce pipeline nous permettra de déployer notre application de façon automatisé de bout en bout sans intervention humaine.
Dans ce lab, on va utiliser la stratégie de branche appelée Trunk-Based Development qui s'adapte le mieux à du déploiement continu. Dans cette stratégie, on va garder une branch main contenant le code principal de notre application et chaque nouvelle modifiation sera effectuée via des branches de features
Ci-dessous les étapes principales de notre procesus de déploiement continu :
1. Création d'une branche de feature depuis la main et ajout des modifications
2. Déclenchement automatisé (via webhook) du pipeline pour executer l'integration continue ainsi que le déploiement vers l'environnement de DEV
- Checkout : Récupération du code source depuis GitHub.
- Build Docker Image : Construction de l'image Docker avec le tag dev-SNAPSHOT
- Push to Harbor : Push de l'image Docker vers le registre Harbor avec authentification.
- Deploy to Dev : Déploiement de l'image en environnement de développement.
- Health Check : Vérification de la santé de l'application en développement.
3. Déclenchement automatisé des actions de livraison vers la production
- Création automatisée d'une Pull Request de la branche de feature vers la branche de main
- Merge de la Pull Request vers la branche main (fusion automatique).
- Create Git Tag : Création d'un tag Git avec auto-incrémentation de la version.
- Trigger Deployment from Tag : Déclenchement du job Jenkins de déploiement en production basé sur le tag.
- Deploy to Prod : Déploiement de l'image en environnement de production.
4. Envoi notifications vers canal Slack
Objectifs:#
- Déploiement continu d'une application flask-app avec Github, Harbor, SonarQube, Slack et Jenkins
- Mise en place pipeline de déploiement continu pour une application flask (build, test, push, run)
Prérequis#
- Connaissance de Docker et GIT
- Instance docker fonctionnel
- Editeur de code
- Utilitaire installé sur la machine: git
- Avoir un proxy nginx fonctionnel (voir lab deploy reverse proxy sur la section 03-conteneurisation)
- Avoir un jenkins de fonctionnel voir lab du stage 6
Jenkins sur Docker - Avoir Slack de fonctionnel et pret à accueillir des notifications depuis jenkins (voir lab du stage 6
Integration Jenkins & slack) - Avoir ngrok d'activé pour pouvoir déclencher des pipelines via webhook Github, voir lab du stage 6
Jenkins Webhook - Avoir un harbor fonctionnel, voir lab précèdent dans ce meme stage
- Avoir un sonarqube de fonctionnel, voir labs stage 07
- Avoir fait le lab précèdent sur la livraison continue
Déroulement du Lab#
Etape 1 : Lancement du tunnel ngrok pour exposer notre jenkins sur une url publique#
(voir lab du stage 6 Jenkins Webhook)
- Lancer le tunnel ngrok
ngrok http 80

- Récupérer l'url génèrée et le renseigner dans le proxy nginx présent dans le fichier
lecloudfacile-devops-labs/ginx-proxy/conf.d/jenkins.conf
Il suffira juste de modifier la ligne contenant server_name jenkins.lcf.io en rajoutant l'url de ngrok génèrée précèdemment. Dans notre exemple, cela donnera ce contenu ci-dessous
server {
listen 80;
server_name jenkins.lcf.io ea1e-3-248-49-188.ngrok-free.app;
location / {
proxy_pass http://jenkins:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
- Recharger la conf du proxy avec la commande
docker exec -ti proxy nginx -s reload
- Se rendre sur l'url ngrok et confirmer qu'il redirige bien sur jenkins
Etape 2 : Création d'un repo Github privé pour hébergement de l'application flask-app#
Dans cette étape, on a va partir d'un nouveau repo qu'on va créer comme fait lors du lab précèdent. Ce repo contiendra la meme application flask-app ainsi qu'un seul jenkinsfile pour le déploiement continu.
- Créer un nouveau repo Github privé avec comme nom
flask-app-cd
(voir lab précèdent pour création repo privé flask-app)
- Récupèration du code source
Depuis votre terminal, récupèrer le code source de flask-app-cd
git clone https://github.com/wingufactory/lecloudfacile-devops-labs.git
Si vous souhaitez travailler dans le meme dossier lecloudfacile-devops-labs que vous avez déjà, faire ces manip :
cd lecloudfacile-devops-labs
git stash
git pull --rebase
git stash pop
- Se rendre dans le dossier flask-app-cd
cd lecloudfacile-devops-labs/flask-app-cd
- Ouvrir le fichier
Jenkinsfile, se rendre à la ligne numéro 129 et remplacer<user github>par votre nom utilisateur de github
vi Jenkinsfile
def repo = "<user github>/flask-app-cd"
- Pousser le contenu dans le repo Github privé
flask-app-cdcréé
git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/<nom utilisateur>/flask-app-cd.git
git push -u origin main
- Se rendre sur Github et vérifier que les fichiers sont bien présents et que les deux branches (
mainetdev) sont bien présentes

Etape 3 : Création du pipeline Jenkins de type multibranch#
- Installer le plugin
Multibranch Scan Webhook Triggerpour permettre de déclencher le job depuis un push sur Github

-
Puis depuis la page principale de Jenkins, se rendre dans le dossier
flask-apppour créer le pipeline de déploiement continu de notre application. -
Créer un nouveau job de type
Multibranch Pipelinenomméflask-app-cd

- Cliquer sur
configureà gauche pour le configuer
--> Display Name : flask-app-cd
--> Description : Deploiement continu flask-app
--> Cliquer sur Add souce et selectionner Github

--> Renseigner l'url du repo github flask-app-cd et le credential de connexion

--> dans la section behaviour, cliquer sur Add et selectionner Discover tags


--> Cliquer encore sur Add et sélectionner Filter by name (with wildcards)

--> Renseigner dans ce champs feature/* refs/tags/v* v*

--> Dans la section Scan Multibranch Pipeline Triggers , cocher Scan by webhook et mettre la valeur flask-app dans le champ Trigger token

--> Enfin cliquer sur Save
Etape 4 : Création du credential de Jenkins API token#
Dans cette étape on va génèrer un token pour l'utilisateur lecloudfacile sur Jenkins pour rendre possible le déclenchement automatique des étapes de livraison de notre application vers la prod depuis un tag (stage Trigger Deployment from Tag du Jenkinsfile)
- Cliquer sur le profil de l'utilisateur lecloudfacile, puis sur
Security

- Cliquer sur
Add new Token, lui donner le nomtoken-jenkinset cliquer surGenerate

-
Copier le token génèré et le sauvegarder quelque part
-
Cliquer sur
Save -
Ensuite créer un nouveau credential de type
Username withPasswordpour y stocker le token jenkins
--> Username : lecloudfacile
--> Password : <token génèré>
--> ID : jenkins-api-token
--> Description : `token de connexion à jenkins``

Etape 5 : Mise en place du webhook sur Github#
Dans cette étape on va mettre en place un webhook sur notre repo Github pour pouvoir déclencher le pipeline depuis un push sur Github
- Se rendre sur le repo Github
flask-app-cd-->Settings-->Webhooks-->Add webhook
--> Payload url : https://<url ngrok>/multibranch-webhook-trigger/invoke?token=flask-app
--> Content type : application/json
--> Dans la section events, cocher Send me everything
--> Enfin cliquer sur Add Webhook

Etape 6 : Execution du pipeline#
Maintenant on va lancer notre pipeline de déploiement continu en rajoutant une modification dans la branche de feature
- Depuis le terminal, toujours dans le dossier
flask-app-cd, créer une nouvelle branchefeature/new
git checkout -b feature/readme
- Rajouter un nouveau fichier
README.mdavec comme contenutest push
echo 'test push' > README.md
- Pousser les modifs sur Github
git add .
git commit -m "add readme"
git push origin feature/readme
Etape 7 : Vérifications#
- Vérifier qu'un job du nom de
feature/readmeest visible depuis le pipeline multibranch et est bien en succès. Il constitue nos étapes d'intégration continue et de livraison vers l'environnement de DEV.

- Vérifier qu'un job s'est lancé dans l'onglet
Tagsavec le nom de notre release généré dynamiquement depuis Gihub. Ce job consitue notre déploiement vers la production

- Vérifier en ligne de terminal qu'on a nos deux conteneurs de dev et prod qui tournent avec les bonnes images Docker
docker ps -a --filter name=flask-app

- Sur Github, vérifier qu'on a bien le tag de créé en cliquant sur
tags

- Vérifier sur Github également qu'on a bien le pull request de créé et mergé avec le main
Se rendre dans l'onglet Pull requests, cliquez sur Closed


- Vérifier la réception de notifications sur Slack

- Accèder à la DEV via l'url -->
flask-app.dev.lcf.io

- Accèder à la PROD via l'url -->
flask-app.lcf.io
