TP Bonus - Automatisation du déploiement avec Gitlab CI
Versionner le projet et utiliser la CI Gitlab avec Ansible pour automatiser le déploiement
Créez un compte sur la forge logicielle
gitlab.comet créez un projet (dépôt) public.Affichez et copiez
cat ~/.ssh/id_ed25519.pub.Dans
(User) Settings > SSH Keys, collez votre clé publique copiée dans la quesiton précédente.Suivez les instructions pour pousser le code du projet Ansible sur ce dépôt.
Dans le menu à gauche sur la page de votre projet Gitlab, cliquez sur
Build > Pipeline Editor. Cet éditeur permet d'éditer directement dans le navigateur le fichier.gitlab-ci.ymlet de commiter vos modification directement dans des branches sur le serveur.Ajoutez à la racine du projet un fichier
.gitlab-ci.ymlavec à l'intérieur:
image:
# This linux container (docker) we will be used for our pipeline : ubuntu bionic with ansible preinstalled in it
name: williamyeh/ansible:ubuntu18.04
variables:
ANSIBLE_CONFIG: $CI_PROJECT_DIR/ansible.cfg
deploy:
# The 3 lines after this are used activate the pipeline only when the master branch changes
only:
refs:
- master
script:
- ansible --version
En poussant du nouveau code dans master ou en mergant dans master les jobs sont automatiquement lancés via une nouvelle pipeline : c'est le principe de la CI/CD Gitlab. only: refs: master sert justement à indiquer de limiter l'exécution des pipelines à la branche master.
Cliquez sur
commitdans le web IDE et cochezmerge to master branch. Une fois validé votre code déclenche donc directement une exécution du pipeline.Vous pouvez retrouver tout l'historique de l'exécution des pipelines dans la Section
CI / CD > Jobsrendez vous dans cette section pour observer le résultat de la dernière exécution.Notre pipeline nous permet uniquement de vérifier la bonne disponibilité d'ansible.
Elle est basée sur une (vieille) image docker contenant Ansible pour ensuite executer notre projet d'Iinfra as Code.
Alternative 1 : se connecter directement depuis le runner aux serveurs cible
Créons un runner Gitlab de type
shellet installons-le dans notre lab.Faisons en sorte que c'est ce runner qui se chargera de l'exécution des jobs grâce aux tags.
Remplacez
ansible --versionpar un ping de toutes les machines.Relancez la pipeline en committant (et en poussant) vos modifications dans
master.Allez observer le job en cours d'exécution.
Enfin lançons notre playbook principal en remplaçant la commande ansible précédente dans la pipeline et committant
Alternative 2 : un déploiement léger et sécurisé avec ansible-pull
https://blog.octo.com/ansible-pull-killer-feature/
- Avec l'aide de cet article et de l'option
--url, mettre en place un déploiement "inversé" avecansible-pull. Il va falloir exécuter un playbook qui s'applique sur localhost ou sur notre hostname (vnc-votreprenom) - En mettant en place un
cron(ou untimersystemd), lancez ce déploiement toutes les 5min, et observez dans les logs.
Alternative 3 : un déploiement plus sécurisé avec un webhook
Création du script d'exécution et logs dans Ansible
- à la racine du dépôt Ansible, créez un script Bash nommé
ansible-run.sh, copiez et collez le contenu suivant dans le fichieransible-run.shet remplacez la commande par un vrai playbook situé dans le même dossier :
#!/bin/bash
ansible-playbook site.yml --diff
- rendez le script exécutable avec
chmod +x ansible-run.sh
Pour suivre ce qu'il se passe, ajoutez la ligne suivante dans votre fichier ansible.cfg pour spécifier le chemin du fichier de logs (ansible_log.txt en l'occurrence) :
log_path=./ansible_log.txt
- dans un terminal, faites
./ansible-run.shet observez les logs pour tester votre script de déploiement.
Installation et configuration du Webhook
Sur votre serveur de déploiement (celui avec le projet Ansible), installez le paquet webhook en utilisant la commande suivante :
sudo apt install webhook
Ensuite, créons un fichier de configuration pour le webhook.
- Avec
nanoouvipar exemple, faitessudo nano /etc/webhook.confpour créer le fichier puis modifions-le avec le contenu suivant en adaptant la partie/home/formateur/projet-ansibleavec le chemin de votre projet, puis enregistrez et quittez le fichier (pournano, en appuyant surCtrl + X, suivi deY, puis appuyez surEntrée) :
[
{
"id": "redeploy-webhook",
"command-working-directory": "/home/formateur/projet-ansible",
"execute-command": "/home/formateur/projet-ansible/ansible-run.sh",
"include-command-output-in-response": true,
}
]
Lancement et test du webhook
Lancez le webhook en utilisant la commande suivante dans un nouveau terminal (si le terminal se ferme, le webhook s'arrêtera) :
/usr/bin/webhook -nopanic -hooks /etc/webhook.conf -port 9999 -verbose
Pour tester le webhook, ouvrez simplement un navigateur web et accédez à l'URL suivante, en remplaçant localhost par le nom de votre domaine ou l'adresse IP de votre serveur si nécessaire :
http://localhost:9999/hooks/redeploy-webhook
Le webhook exécutera le script ansible-run.sh, qui lancera votre playbook Ansible.
Le webhook attend que le playbook finisse, laissons la page se charger dans le navigateur, ce qui peut prendre du temps. Ensuite, il affichera le retour de la sortie standard (ou une erreur).
Faites un tail -f ansible_log.txt pour suivre le playbook le temps qu'il se termine, puis observer le retour de la requête HTTP dans votre navigateur.
Intégration à Gitlab CI
Dans un fichier .gitlab-ci.yml vous n'avez plus qu'à appeler curl http://votredomaine:9999/hooks/redeploy-webhook pour déclencher l'exécution de votre playbook Ansible en réponse à une requête depuis les serveurs de Gitlab.
deploy:
# The 3 lines after this are used activate the pipeline only when the master branch changes
only:
refs:
- master
script:
- curl --fail http://hadrien.lab.doxx.fr:9999/hooks/redeploy-webhook
Cette configuration est bien plus sécurisée, même si en production nous protégerions le webhook avec un mot de passe (token) pour éviter que le webhook soit déclenché abusivement si quelqu'un en découvrait l'URL.
--fail permet de convertir une erreur HTTP (500) en code de sortie d'erreur Bash pour la CI.
On pourrait aussi variabiliser le webhook pour faire passer des paramètres à notre script ansible-run.sh.
Bonus : Créez une planification pour le rolling upgrade de notre application
- Dans
Build > Pipeline schedulesajoutez un job planifié toutes les heures (fréquence maximum sur gitlab.com) (en production toutes les nuits serait plus adapté) :* * * * * * - Observez le résultat.
- Supprimez le job
Pour Codeberg / ForgeJo
- Ajouter une clé SSH (éventuellement la générer avec ssh-keygen) publique à Gitlab ou Codeberg
Enregistrer un "runner" : https://docs.codeberg.org/ci/actions/#running-on-host-machine
Actions > Exécuteurs > et copier le token
wget -O forgejo-runner https://code.forgejo.org/forgejo/runner/releases/download/v3.3.0/forgejo-runner-3.3.0-linux-amd64
chmod +x forgejo-runner
./forgejo-runner register --instance https://codeberg.org et compléter
- Installer Docker :
curl https://get.docker.com | sh
sudo usermod -a -G docker $USER
et rebooter : sudo reboot
Lancer le runner dans un terminal :
./forgejo-runner daemonPour Codeberg : activer les Actions ForgeJo dans les paramètres du dépôt : Fonctionnalité des dépôts > Vue générale
Adapter le fichier de CI pour que Ansible lance nos playbooks
B. Pour Codeberg / Forgejo, repartir de ce template à mettre dans
.forgejo/workflows/ansible.yml
on: [push]
jobs:
test:
runs-on: docker
container:
image: nikolaik/python-nodejs
steps:
- uses: actions/checkout@v4
- run: pip install ansible
- run: ansible-playbook site.yml