DevOps module 1 : la culture, Linux, le shell et Git
Quatorze séances pour poser le sol sur lequel tous les outils suivants s'appuient : la culture qui a donné son nom au DevOps, un terminal Linux où vous êtes à l'aise, des scripts qui échouent bruyamment au lieu de se taire, et Git utilisé comme outil d'équipe, avec des revues. Le module se termine par votre premier dépôt public.
Toutes les adresses des exemples viennent des plages réservées à la documentation (RFC 5737 : 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24) et tous les domaines sont example.com ou example.org.
Jour 1 · 03/11 — Ce qu'est le DevOps, et d'où il vient
Objectif : raconter l'histoire du DevOps en cinq phrases et nommer ses cinq piliers.
Théorie 1/2 : le mur entre deux équipes
Pendant des décennies, les développeurs (« dev ») étaient jugés sur la vitesse à livrer des changements, et l'exploitation (« ops ») sur la stabilité de la production. Une équipe lançait les versions par-dessus le mur, l'autre freinait. En juin 2009, à la conférence Velocity d'O'Reilly, John Allspaw et Paul Hammond, de Flickr, donnent la conférence « 10+ Deploys per Day: Dev and Ops Cooperation at Flickr », à une époque où une mise en production par mois passait pour ambitieuse. Patrick Debois, consultant belge qui n'a pu la suivre qu'à distance, organise les premiers DevOpsDays à Gand en octobre 2009 ; le mot-dièse raccourci en #DevOps a nommé le mouvement.
Le DevOps puise dans l'Agile (2001) et dans le Lean industriel (le système de production de Toyota) : le travail avance par petits lots, les problèmes se voient tôt, et ceux qui construisent un service s'occupent aussi de le faire tourner.
Où se sont tenus les premiers DevOpsDays, en 2009 ?
- San Francisco
- Gand
- Berlin
Réponse
Gand, en Belgique, en octobre 2009, organisés par Patrick Debois.
Qu'a montré la conférence de Flickr en 2009 ?
- Que dev et ops coopérant pouvaient déployer plus de dix fois par jour
- Que l'exploitation doit valider chaque version à la main
- Que les conteneurs remplacent les machines virtuelles
Réponse
Des déploiements fréquents, petits et sûrs, rendus possibles par la coopération dev/ops et l'automatisation.
Théorie 2/2 : CALMS, cinq piliers
Une façon courante de décrire le DevOps est CALMS : Culture (responsabilité partagée, sans reproche), Automatisation (ce qui se répète est scripté), Lean (petits lots, supprimer l'attente), Mesure (décider sur des données), Share, le partage (connaissances et outils sont partagés). L'acronyme était d'abord CAMS (Damon Edwards et John Willis, 2010) ; Jez Humble a ajouté le L. La première lettre est la culture : acheter un outil ne rend pas une équipe DevOps.
Dans CALMS, que veut dire le C ?
Réponse
Culture. Suivent l'automatisation, le Lean, la mesure et le partage.
Une entreprise achète un outil de CI et renomme son équipe d'exploitation « équipe DevOps », rien d'autre ne change. Est-ce du DevOps ?
- Oui, l'outil est le cœur
- Non : sans responsabilité partagée ni façons de travailler changées, c'est un changement de nom
Réponse
Non. Les outils servent une culture ; ils ne la créent pas.
Pratique (30 min)
- Installez votre machine Linux (voir la page du parcours) : une VM Debian ou Ubuntu, ou WSL 2. Mettez-la à jour :
sudo apt update && sudo apt upgrade. - Installez Git et un éditeur :
sudo apt install git, puis vérifiezgit --version. - Créez le dossier de votre carnet :
mkdir -p ~/devops-notes && cd ~/devops-notes, et un premier fichierday-01.mdavec l'histoire du DevOps en cinq phrases, avec vos mots. - Écrivez les cinq lettres de CALMS et, pour chacune, un exemple tiré d'un métier que vous connaissez (même hors informatique).
Avec votre IA : « Tu es un tuteur DevOps exigeant. Pose-moi cinq questions courtes, une par une, sur les origines du DevOps (Flickr 2009, DevOpsDays à Gand, CALMS). Attends ma réponse à chaque fois, dis-moi si elle est juste et corrige-moi en une phrase. Ne donne pas les réponses à l'avance. »
Synthèse (10 min)
Trois lignes : le problème auquel répond le DevOps, qui l'a nommé et quand, ce que veut dire CALMS. Puis refaites les deux QCM sans notes.
Jour 2 · 04/11 — Mesurer la livraison : le flux et les métriques DORA
Objectif : nommer les métriques DORA et dire ce que mesure chacune.
Théorie 1/2 : les trois voies
Le roman de Gene Kim The Phoenix Project (2013) et The DevOps Handbook (2016) décrivent trois voies : le flux (le travail va vite de l'idée à la production, par petits lots), le retour d'information (les problèmes se voient vite, là où ils naissent) et l'apprentissage continu (expérimenter, tirer les leçons des échecs). Une cartographie de la chaîne de valeur dessine chaque étape d'une idée jusqu'à la production avec son temps d'attente : l'essentiel du délai est en général de l'attente, pas du travail.
Un changement demande 2 heures de travail et 9 jours d'attente de validations. Que faut-il améliorer d'abord ?
- La vitesse de frappe
- Les serveurs
- L'attente entre les étapes
Réponse
L'attente : le flux est limité par les files, pas par le temps de travail.
Théorie 2/2 : les métriques DORA
Le programme de recherche DORA (DevOps Research and Assessment ; le livre Accelerate de Nicole Forsgren, Jez Humble et Gene Kim, 2018) a relié quelques mesures de livraison à la performance des entreprises. Les quatre clés d'origine : fréquence de déploiement, délai de mise en production des changements, taux d'échec des changements, temps de rétablissement. DORA les a depuis renommées et complétées ; il en décrit aujourd'hui cinq :
- Débit : délai des changements (du commit à la production), fréquence de déploiement, temps de rétablissement après un déploiement raté ;
- Instabilité : taux d'échec des changements (part des déploiements qui demandent une correction immédiate) et taux de reprise (déploiements non prévus causés par un incident).
La leçon de la recherche : vitesse et stabilité ne s'opposent pas ; les meilleures équipes ont les deux.
« Le temps entre un commit et ce commit en production », c'est…
- la fréquence de déploiement
- le délai des changements
- le temps de rétablissement
Réponse
Le délai des changements (change lead time).
Sur 20 déploiements, 3 ont demandé un retour arrière ou un correctif immédiat. Quel est le taux d'échec des changements ?
- 15 %
- 3 %
- 85 %
Réponse
3 / 20 = 15 %.
D'après la recherche DORA, aller plus vite…
- fait toujours baisser la stabilité
- va de pair avec la stabilité chez les équipes les plus performantes
Réponse
Les plus performants sont à la fois plus rapides et plus stables.
Pratique (30 min)
- Prenez un processus que vous connaissez (commander un repas, s'inscrire dans une école, publier une vidéo). Dessinez sa chaîne de valeur dans votre carnet : chaque étape, son temps de travail, son temps d'attente.
- Calculez la part de l'attente dans le total. Entourez la file la plus longue.
- Lisez la page de DORA sur les métriques, sur dora.dev, et recopiez dans votre carnet, avec vos mots, la définition de chacune des cinq.
Avec votre IA : « Voici une chaîne de valeur que j'ai dessinée : [collez vos étapes avec temps de travail et d'attente]. Joue un coach Lean. Ne la redessine pas pour moi : pose-moi trois questions qui me font trouver moi-même le plus gros gaspillage, puis dis-moi si ma réponse est cohérente avec les chiffres. »
Synthèse (10 min)
Trois lignes : les trois voies, les cinq métriques DORA en deux groupes, pourquoi l'attente compte plus que le travail. Puis calculez un taux d'échec pour 4 échecs sur 50 déploiements (8 %).
Jour 3 · 05/11 — La ligne de commande Linux
Objectif : se déplacer dans l'arborescence, lire des fichiers et trouver de l'aide sans moteur de recherche.
Théorie 1/2 : l'arborescence et les chemins
Linux a une seule arborescence qui part de /. Quelques dossiers servent tous les jours : /etc (configuration), /var/log (journaux), /home (dossiers des utilisateurs), /usr/bin (programmes), /tmp (fichiers temporaires). Un chemin absolu commence par / ; un chemin relatif part de là où vous êtes (pwd) ; ~ est votre dossier personnel, . le dossier courant, .. le parent.
pwd # où suis-je
ls -la # lister, avec fichiers cachés et détails
cd /var/log # aller à un chemin absolu
cd .. # remonter d'un niveau
cd ~ # retour à la maison
Dans quel dossier de premier niveau cherche-t-on la configuration d'un service ?
Réponse
/etc.
Vous êtes dans /var/log. Où vous mène cd ../lib ?
/lib/var/lib/var/log/lib
Réponse
.. est /var, donc /var/lib.
Théorie 2/2 : lire et trouver
cat affiche un fichier, less le parcourt page par page (q pour sortir, / pour chercher), head et tail montrent son début ou sa fin, tail -f suit un journal qui grossit. find /etc -name "*.conf" trouve des fichiers par leur nom. L'aide est sur la machine : man ls, ls --help. La philosophie Unix, formulée par Doug McIlroy aux Bell Labs : des programmes qui font une chose et la font bien, et qui travaillent ensemble.
Quelle commande suit un fichier journal à mesure que des lignes arrivent ?
Réponse
tail -f fichier (-F survit aussi à la rotation du fichier).
Quelle commande ouvre la page de manuel d'un programme ?
Réponse
man, par exemple man find.
Pratique (30 min)
- Visitez
/,/etc,/var/logaveccdetls -la; notez ce que vous trouvez dans chacun. - Lisez
/etc/os-releaseaveccat: quelle distribution, quelle version ? - Ouvrez
man ls, trouvez avec / ce que fait-h, puis lancezls -lh /var/log. - Trouvez tous les fichiers
.confdirectement sous/etc:find /etc -maxdepth 1 -name "*.conf". - Créez
~/lab/day03avecmkdir -p, copiez-y/etc/hostnameaveccp, renommez-le avecmv, supprimez-le avecrm.
Avec votre IA : « J'apprends la ligne de commande Linux sur Debian. Donne-moi dix petites tâches de difficulté croissante en n'utilisant que pwd, cd, ls, cat, less, head, tail, find, cp, mv, rm et mkdir. Seulement les tâches, numérotées, sans solutions. Quand je colle mes commandes, vérifie chacune et explique toute erreur. »
Synthèse (10 min)
Trois lignes : chemin absolu ou relatif, cinq dossiers importants, où trouver de l'aide. Puis refaites la commande find sans notes.
Jour 4 · 06/11 — Utilisateurs et droits
Objectif : lire et poser des droits en lettres et en chiffres, et savoir pourquoi un service tourne sous son propre utilisateur.
Théorie 1/2 : propriétaire, groupe, autres
Chaque fichier appartient à un utilisateur et à un groupe. ls -l affiche dix caractères : le type (- fichier, d dossier), puis trois triplets pour le propriétaire, le groupe et les autres : r lire, w écrire, x exécuter (pour un dossier : y entrer). En chiffres, r = 4, w = 2, x = 1, additionnés par triplet : rwxr-x--- vaut 750.
chmod 640 app.conf # rw- r-- ---
chmod u+x deploy.sh # ajouter l'exécution au propriétaire
sudo chown app:app /srv/app # changer propriétaire et groupe
Combien vaut rw-r--r-- en chiffres ?
Réponse
6 (4+2), 4, 4 : 644.
Exercice généré sans fin (JavaScript requis) : convertir des droits.
Théorie 2/2 : root, sudo et moindre privilège
root peut tout ; sudo lance une commande en root et laisse une trace dans les journaux. Un service (un serveur web, une base de données) reçoit son propre utilisateur, avec les seuls droits dont il a besoin : s'il est compromis, l'attaquant obtient cet utilisateur, pas la machine. C'est le principe du moindre privilège, et il revient partout dans ce parcours (conteneurs, jetons de CI, Kubernetes).
Un script ne doit être lancé que par son propriétaire, lu par personne d'autre. Quel mode ?
- 755
- 700
- 777
Réponse
700 : rwx pour le propriétaire, rien pour le groupe et les autres. 777 n'est presque jamais la réponse.
Pourquoi faire tourner un serveur web sous un utilisateur dédié plutôt qu'en root ?
- Pour limiter ce qu'obtient un attaquant s'il est compromis
- Parce que root est plus lent
Réponse
Moindre privilège : une intrusion reste dans les droits de cet utilisateur.
Pratique (30 min)
- Créez un utilisateur pour un service fictif :
sudo useradd --system --no-create-home app, puisid app. sudo mkdir -p /srv/app, puis donnez-le àapp:sudo chown app:app /srv/appetsudo chmod 750 /srv/app.- En tant que vous, essayez
ls /srv/app: pourquoi est-ce refusé ? Lisezls -ld /srv/app. - Créez
~/lab/hello.shcontenantecho hello. Lancez./hello.sh: refusé. Ajoutez le droit d'exécution, relancez. - Faites cinq tours de l'exercice généré ci-dessus.
Avec votre IA : « Interroge-moi sur les droits Linux : donne-moi huit cas, un par un, en mélangeant "écris ce mode en chiffres" (par exemple rwxr-x---) et "quel mode pour ce besoin" (par exemple une clé SSH privée). Attends chaque réponse, corrige-la, et explique la raison de sécurité quand ma réponse est trop ouverte. »
Synthèse (10 min)
Trois lignes : les trois triplets, r/w/x = 4/2/1, pourquoi le moindre privilège. Puis refaites la conversion de rwxr-x--- (750) sans notes.
Jour 5 · 07/11 — Processus, services, systemd
Objectif : voir ce qui tourne, démarrer et arrêter un service, et lire ses journaux.
Théorie 1/2 : processus et signaux
Un programme en cours d'exécution est un processus avec un numéro (PID). ps aux les liste, top (ou htop) les montre en direct. On envoie à un processus un signal : kill PID envoie SIGTERM (arrête-toi proprement), kill -9 PID envoie SIGKILL (arrête-toi tout de suite, sans ménage). Essayez TERM d'abord ; KILL peut laisser des fichiers à moitié écrits.
Quel signal laisse un programme se terminer proprement ?
- SIGKILL (9)
- SIGTERM (15)
Réponse
SIGTERM, le signal par défaut de kill. SIGKILL ne peut pas être intercepté.
Théorie 2/2 : systemd et journald
Sur la plupart des distributions, le premier processus (PID 1) est systemd (Lennart Poettering et Kay Sievers, 2010). Il démarre les services décrits par des fichiers d'unité et les relance si besoin. Son collecteur de journaux, journald, se lit avec journalctl.
systemctl status ssh # état, PID, dernières lignes du journal
sudo systemctl restart ssh # redémarrer
sudo systemctl enable --now ssh # démarrer maintenant et à chaque boot
journalctl -u ssh --since "1 hour ago"
journalctl -u ssh -f # suivre
Quelle commande fait démarrer un service à chaque démarrage ?
Réponse
systemctl enable (avec --now, il le démarre aussi tout de suite).
Écrivez la commande qui affiche les journaux de l'unité nginx.
Réponse
journalctl -u nginx.
Pratique (30 min)
- Listez les processus avec
ps aux | head, puis ouvreztopet trouvez celui qui utilise le plus de mémoire (M), q pour sortir. - Lancez
sleep 600 &, trouvez son PID avecpgrep sleep, arrêtez-le aveckill. - Écrivez une unité minimale
/etc/systemd/system/tick.service:[Unit] Description=Write the date every 10 seconds [Service] ExecStart=/bin/sh -c 'while true; do date; sleep 10; done' Restart=on-failure [Install] WantedBy=multi-user.target sudo systemctl daemon-reload && sudo systemctl enable --now tick, puisjournalctl -u tick -f. Arrêtez-la avecsudo systemctl disable --now tick.
Avec votre IA : « Voici la sortie de systemctl status d'un service qui échoue : [collez-la]. Ne me donne pas la solution. Explique chaque ligne de cette sortie en une phrase, puis demande-moi quelle ligne, selon moi, désigne la cause. »
Le faire faire par un agent : maintenant que vous avez écrit une unité à la main, un agent peut rédiger la suivante. Consigne : « Écris une unité systemd pour /usr/local/bin/backup.sh qui tourne sous l'utilisateur backup, redémarre en cas d'échec et journalise dans le journal ; ne donne que le fichier. » Vous vérifiez encore à la main : l'utilisateur existe, le chemin est juste, systemd-analyze verify passe, et le service démarre.
Synthèse (10 min)
Trois lignes : PID et signaux, ce que fait systemd, comment lire les journaux d'un service. Puis refaites les commandes enable --now et journalctl -u sans notes.
Jour 6 · 08/11 — Tubes, redirections, outils texte
Objectif : répondre à une question sur un fichier journal avec une seule ligne de commandes enchaînées.
Théorie 1/2 : les flux standard
Chaque programme a trois flux : stdin (0, entrée), stdout (1, sortie normale), stderr (2, erreurs). On les redirige : > écrit stdout dans un fichier (en l'écrasant), >> ajoute à la fin, 2> redirige les erreurs, 2>&1 envoie les erreurs au même endroit que stdout. Le tube |, imaginé par Doug McIlroy et ajouté à Unix en 1973, envoie la sortie d'un programme sur l'entrée du suivant.
Que fait cmd >> out.log 2>&1 ?
- Écrase out.log avec les seules erreurs
- Ajoute la sortie et les erreurs à la fin de out.log
- Jette tout
Réponse
>> ajoute stdout, 2>&1 envoie stderr au même endroit.
Théorie 2/2 : grep, cut, sort, uniq, wc
grep " 500 " access.log # lignes contenant " 500 "
grep -c "ERROR" app.log # compter les lignes qui correspondent
cut -d' ' -f1 access.log # premier champ (le client)
sort | uniq -c | sort -rn | head -5 # les 5 plus fréquents
wc -l fichier # nombre de lignes
sed et awk vont plus loin (remplacer, calculer par colonne) ; apprenez-les quand vous en avez besoin.
Écrivez la commande qui compte les lignes contenant ERROR dans app.log.
Réponse
grep -c ERROR app.log.
Pourquoi sort avant uniq -c ?
- Pour aller plus vite
- Pour une sortie alphabétique
- Parce que
uniqne fusionne que les lignes identiques qui se suivent
Réponse
uniq compare chaque ligne à la précédente seulement.
Pratique (30 min)
- Créez un faux journal d'accès :
for i in $(seq 1 200); do echo "198.51.100.$((RANDOM % 5)) GET /page$((RANDOM % 3)) $(shuf -n1 -e 200 200 200 404 500)" done > ~/lab/access.log - Combien d'erreurs 500 ?
grep -c " 500$" ~/lab/access.log. - Quel client fait le plus de requêtes ? Enchaînez
cut,sort,uniq -c,sort -rn,head -1. - Quelle page renvoie le plus de 404 ? Commencez par
grep " 404$", puis coupez le troisième champ (-f3). - Gardez chaque réponse avec
>> ~/devops-notes/day-06.md.
Avec votre IA : « Voici une ligne de commande que j'ai écrite pour trouver les 5 adresses clientes les plus fréquentes d'un journal d'accès : [collez-la]. Explique ce que chaque commande du tube reçoit et produit, puis donne-moi une ligne d'entrée pour laquelle ma commande donnerait un résultat faux, s'il en existe une. »
Le faire faire par un agent : un agent avec accès au shell peut répondre seul à « quelle page renvoie le plus de 404 dans access.log ». Demandez-lui la commande lancée, pas seulement le résultat. Vous vérifiez encore : relancez sa commande et comparez avec un comptage grep sur une valeur.
Synthèse (10 min)
Trois lignes : les trois flux, > ou >>, ce que fait un tube. Puis refaites la ligne du client le plus actif sans notes.
Jour 7 · 09/11 — Scripts bash 1 : variables, tests, codes de sortie
Objectif : écrire un script qui s'arrête à la première erreur et dit pourquoi.
Théorie 1/2 : un script et son code de sortie
Un script est un fichier texte qui commence par un shebang, #!/usr/bin/env bash, rendu exécutable. Chaque commande renvoie un code de sortie : 0 pour un succès, tout autre nombre pour un échec ; $? contient le dernier. Les chaînes CI, systemd et Ansible décident toutes « réussi ou échoué » sur ce nombre.
#!/usr/bin/env bash
set -euo pipefail # arrêt sur erreur, sur variable non définie, sur tube raté
name="${1:-world}" # premier argument, "world" par défaut
if [[ -f /etc/os-release ]]; then
echo "Hello $name, this is $(. /etc/os-release; echo "$PRETTY_NAME")"
else
echo "no os-release" >&2
exit 1
fi
Quel code de sortie signifie le succès ?
Réponse
0. Tout le reste est un échec.
Sans set -e, une commande échoue au milieu d'un script. Que se passe-t-il ?
- Le script s'arrête
- Le script continue comme si de rien n'était
Réponse
Il continue, souvent en faisant des dégâts avec des données manquantes. set -e l'arrête.
Théorie 2/2 : guillemets et tests
Mettez toujours les variables entre guillemets : "$file", sinon un nom avec une espace devient deux arguments. [[ -f x ]] teste un fichier, -d un dossier, -z "$v" une chaîne vide, "$a" == "$b" l'égalité. cmd1 && cmd2 lance cmd2 seulement si cmd1 a réussi ; cmd1 || cmd2 seulement si elle a échoué.
file="my notes.txt"; rm $file : que reçoit rm ?
- Deux arguments,
myetnotes.txt - Un argument,
my notes.txt
Réponse
Deux : sans guillemets, le shell coupe à l'espace. Écrivez rm "$file".
Écrivez la ligne qui fait s'arrêter un script bash sur les erreurs, les variables non définies et les tubes ratés.
Réponse
set -euo pipefail.
Pratique (30 min)
- Écrivez
~/lab/check-disk.sh: il prend un seuil en pourcentage (80 par défaut), lit l'occupation de/avecdf --output=pcent / | tail -1 | tr -dc '0-9', affiche OK ou ALERT, et sort avec 0 ou 1. - Rendez-le exécutable, lancez-le avec 80, puis avec 1 pour forcer l'alerte, et vérifiez
echo $?à chaque fois. - Retirez
set -euo pipefail, faites une faute de frappe dans une commande au milieu, lancez : il continue. Remettez la ligne.
Avec votre IA : « Relis ce script bash comme un administrateur système confirmé : [collez check-disk.sh]. Liste les problèmes par gravité (bogue, robustesse, style), cite la ligne exacte pour chacun, et ne réécris pas tout le script : je le corrigerai moi-même. »
Synthèse (10 min)
Trois lignes : le shebang, le code de sortie, pourquoi set -euo pipefail et les guillemets. Puis réécrivez les cinq premières lignes du script sans notes.
Jour 8 · 10/11 — Scripts bash 2 : boucles, fonctions, ShellCheck, prompter pour un script
Objectif : écrire un script réutilisable qui passe ShellCheck, et écrire un prompt qui obtient d'une IA un script utilisable.
Théorie 1/3 : boucles, fonctions, arguments
check() { # une fonction, appelée avec : check example.com
local host="$1"
if curl -fsS -o /dev/null --max-time 5 "https://$host"; then
echo "OK $host"
else
echo "FAIL $host"; return 1
fi
}
failed=0
for host in "$@"; do # chaque argument passé au script
check "$host" || failed=$((failed + 1))
done
exit "$failed"
"$@" désigne tous les arguments, chacun gardé entier ; local garde une variable dans sa fonction.
Qu'est-ce que "$@" ?
- Le nom du script
- Tous les arguments, chacun gardé comme un mot
- Le dernier code de sortie
Réponse
Tous les arguments. $0 est le nom, $? le dernier code de sortie.
Théorie 2/3 : ShellCheck
ShellCheck (Vidar Holen, libre) lit un script et signale les variables sans guillemets, les tests faux et beaucoup de pièges classiques, chacun avec un code (SC2086 pour un guillemet manquant) et une page qui l'explique. Installez-le avec sudo apt install shellcheck ; au module 2, il tourne dans votre chaîne CI.
Quel outil analyse les scripts bash ?
Réponse
ShellCheck : shellcheck script.sh.
Théorie 3/3 : prompter pour un script
Un prompt faible : « écris-moi un script de sauvegarde ». Ce qui ne va pas : ni système, ni source, ni destination, aucune règle en cas d'échec, aucun format, aucun moyen de vérifier. Le modèle va deviner et inventer.
Le prompt retravaillé :
Rôle : tu es un administrateur Linux prudent.
Contexte : Debian 13, bash 5, pas de root ; rsync est installé.
Tâche : écris backup.sh qui copie ~/projects vers /mnt/backup/projects.
Contraintes : set -euo pipefail ; chaque variable entre guillemets ;
sortie 1 avec un message sur stderr si la destination n'est pas montée ;
pas de rm, pas de sudo.
Entrées : aucune, les deux chemins en constantes en tête de fichier.
Sortie : le script seul, dans un bloc de code, un commentaire par étape.
Vérification : je lancerai shellcheck et un test disque démonté.
Chaque ligne supprime une devinette : le rôle donne le ton, le contexte les versions, les contraintes les dangers, le format de sortie ce que vous recevrez, la vérification ce à quoi la réponse doit résister.
Quel prompt est meilleur ? A : « Écris un script pour nettoyer les logs, fais-le bien. » B : « Bash 5 sous Debian : supprime les fichiers *.log de plus de 14 jours dans /var/log/myapp uniquement, affiche chaque fichier supprimé, simulation par défaut, --apply pour supprimer ; ne donne que le script ; je le testerai avec shellcheck. »
- A, il laisse le modèle libre
- B : périmètre, sécurité, format et vérification sont donnés
Réponse
B. « Fais-le bien » n'est pas une contrainte ; une simulation par défaut et un dossier précis, si.
« Corrige mon script, il marche pas. » Que manque-t-il en premier ?
- La politesse
- Un rôle
- Le script et le message d'erreur exact
Réponse
Les entrées : sans le vrai script et la vraie erreur, le modèle ne peut que deviner.
Pratique (30 min)
- Tapez le script
checkci-dessus dans~/lab/check-sites.shet lancez-le avecexample.com example.org, puis avec un nom qui n'existe pas. - Passez
shellcheckdessus et sur lecheck-disk.shd'hier ; corrigez chaque avertissement en lisant la page SC correspondante. - Ajoutez une option
-hqui affiche une ligne d'usage.
Avec votre IA : envoyez le prompt de sauvegarde retravaillé ci-dessus, tel quel. Puis passez shellcheck sur sa réponse et testez-la sans la destination. Notez dans votre carnet ce qu'elle a eu juste et faux.
Le faire faire par un agent : un agent dans votre dépôt peut passer ShellCheck sur tous les scripts et proposer des corrections. Consigne : « Lance shellcheck sur chaque fichier .sh, corrige les avertissements sans changer le comportement, montre-moi le diff. » Vous vérifiez encore : lisez chaque ligne modifiée, relancez les tests des scripts, et refusez toute correction qui fait taire un avertissement par un commentaire disable sans raison.
Synthèse (10 min)
Trois lignes : "$@" et local, ce qu'attrape ShellCheck, les sept parties d'un bon prompt. Puis réécrivez le prompt de sauvegarde de mémoire.
Jour 9 · 11/11 — Le réseau depuis le terminal : DNS, HTTP, SSH
Objectif : savoir depuis un terminal si un service répond, par son nom, son port et son code HTTP.
Théorie 1/2 : noms, ports, HTTP
Une machine a une adresse IP ; le DNS traduit un nom en cette adresse (dig example.com). Un service écoute sur un port : 22 SSH, 80 HTTP, 443 HTTPS, 5432 PostgreSQL. ss -tlnp liste les ports sur lesquels votre machine écoute. HTTP répond par un code d'état : 2xx succès, 3xx redirection, 4xx erreur du client, 5xx erreur du serveur. curl -I https://example.com montre le code et les en-têtes.
Sur quel port HTTPS écoute-t-il par défaut ?
Réponse
443.
Exercice généré sans fin (JavaScript requis) : les codes d'état HTTP.
Théorie 2/2 : SSH et les clés
SSH (Tatu Ylönen, 1995) ouvre un shell chiffré sur une machine distante. Plutôt qu'un mot de passe, on utilise une paire de clés : la clé privée reste sur votre machine (mode 600), la clé publique va dans ~/.ssh/authorized_keys sur le serveur. Ansible, les dépôts Git distants et les déploiements reposent dessus.
ssh-keygen -t ed25519 -C "laptop" # créer une paire de clés
ssh-copy-id deploy@203.0.113.10 # installer la clé publique sur le serveur
ssh deploy@203.0.113.10
Quelle clé copie-t-on sur le serveur ?
- La clé privée
- La clé publique (
.pub)
Réponse
La clé publique. La clé privée ne quitte jamais votre machine.
curl renvoie 502 depuis un site derrière un proxy inverse. Où regardez-vous d'abord ?
- L'application derrière le proxy (arrêtée ou injoignable)
- Votre propre navigateur
Réponse
502 Bad Gateway : le proxy n'a pas reçu de réponse valable du serveur derrière lui.
Pratique (30 min)
dig +short example.com, puisdig example.com MX: notez l'adresse et le type d'enregistrement.curl -I https://example.cometcurl -I https://example.com/nothing-here: notez les deux codes.ss -tlnp: sur quels ports votre machine écoute-t-elle ? Lancezpython3 -m http.server 8000dans un autre terminal et regardez à nouveau, puiscurl -I http://127.0.0.1:8000.- Créez une paire de clés ed25519 avec
ssh-keygen, vérifiez que~/.ssh/id_ed25519est en mode 600. Si vous avez une deuxième VM, installez-y la clé et connectez-vous sans mot de passe.
Avec votre IA : « Je lance curl -v https://example.com et je colle la sortie ci-dessous. Explique, dans l'ordre, chaque étape que tu y vois (DNS, TCP, TLS, requête HTTP, réponse), en citant la ligne qui la montre, en moins de 15 lignes : [collez la sortie]. »
Le faire faire par un agent : un agent peut désormais faire toute la vérification « est-ce que ça répond ? » sur une liste d'URL et rendre nom, port et code pour chacune. Demandez-lui les commandes utilisées. Vous vérifiez encore un résultat à la main avec dig et curl -I, pour savoir que le rapport est réel.
Synthèse (10 min)
Trois lignes : ce que fait le DNS, les familles de codes HTTP, clé publique et clé privée. Puis refaites cinq tours de l'exercice des codes HTTP.
Jour 10 · 12/11 — Git 1 : le modèle, les premiers commits
Objectif : comprendre ce qu'est un commit, et versionner votre carnet.
Théorie 1/2 : pourquoi Git, et comment il pense
Linus Torvalds a écrit Git en avril 2005, quand le noyau Linux a perdu l'usage gratuit de son outil précédent, BitKeeper. Git est distribué : chaque clone contient tout l'historique. Un commit est un instantané de tout le projet, avec un auteur, un message et un pointeur vers son parent ; il est nommé par une empreinte (hash) de son contenu, si bien que l'historique ne peut pas être modifié en douce. Trois endroits : le répertoire de travail (vos fichiers), la zone d'index (staging area, ce que contiendra le prochain commit, remplie par git add) et le dépôt (les commits).
Que fait git add ?
- Crée un commit
- Place des changements dans la zone d'index pour le prochain commit
- Envoie le code au serveur
Réponse
Il indexe. git commit enregistre, git push envoie.
Un commit stocke…
- un instantané du projet, nommé par une empreinte
- seulement les lignes modifiées, nommées par un numéro
Réponse
Un instantané (Git compresse et partage les contenus identiques), nommé par son empreinte.
Théorie 2/2 : les commandes de tous les jours
git init # créer un dépôt
git status # ce qui a changé, ce qui est indexé
git add day-10.md # indexer un fichier
git commit -m "Add day 10" # enregistrer
git log --oneline --graph # historique
git diff # changements non indexés ; git diff --staged pour l'index
git restore fichier # jeter un changement non indexé
Un fichier .gitignore liste ce que Git ne doit jamais versionner : produits de compilation, réglages locaux, et surtout les secrets.
Quelle commande dit ce qui a changé et ce qui est indexé ?
Réponse
git status, la commande que vous lancerez le plus.
Quelle commande montre ce que contiendra le prochain commit ?
Réponse
git diff --staged (ou --cached).
Pratique (30 min)
- Réglez votre identité :
git config --global user.name "Votre Nom"etgit config --global user.email "vous@example.org"(votre vraie adresse va là, pas sur une page publique). - Dans
~/devops-notes:git init,git add .,git commit -m "Add notes for days 1 to 9". - Modifiez un fichier, regardez
git diff, indexez-le, regardezgit diff --staged, faites le commit. - Créez un
.gitignoreavec*.tmp, créezx.tmp, vérifiez quegit statusl'ignore. - Lisez l'historique avec
git log --oneline.
Avec votre IA : « Explique les trois zones de Git (répertoire de travail, index, dépôt) avec une analogie, puis donne-moi six commandes dans le désordre et demande-moi, pour chacune, de quelle zone vers quelle zone elle déplace les données. Corrige mes réponses. »
Synthèse (10 min)
Trois lignes : ce qu'est un commit, les trois zones, à quoi sert .gitignore. Puis refaites la suite add / commit / log sans notes.
Jour 11 · 13/11 — Git 2 : branches, merge, rebase, conflits
Objectif : travailler sur une branche, la ramener, et résoudre un conflit sans paniquer.
Théorie 1/2 : une branche est une étiquette
Une branche n'est qu'une étiquette mobile qui pointe vers un commit ; HEAD dit sur quelle branche vous êtes. En créer une ne coûte rien.
git switch -c feature/greeting # créer une branche et s'y placer
# ... commits ...
git switch main
git merge feature/greeting # ramener le travail
Si main n'a pas bougé, la fusion est une avance rapide (fast-forward) : l'étiquette avance. Sinon, Git crée un commit de fusion à deux parents. git rebase main, lancé sur la branche, rejoue plutôt ses commits par-dessus main : un historique droit, mais des commits réécrits ; ne rebasez jamais des commits que d'autres ont déjà récupérés.
Qu'est-ce qu'une branche Git ?
- Une copie de chaque fichier
- Un pointeur mobile vers un commit
Réponse
Un pointeur ; c'est pour cela que les branches ne coûtent rien.
Pourquoi ne pas rebaser une branche que vos collègues ont déjà récupérée ?
- Le rebase réécrit ses commits, et leurs copies ne correspondent plus
- Le rebase supprime la branche
Réponse
Les commits changent d'empreinte ; l'historique des autres diverge.
Théorie 2/2 : les conflits
Un conflit survient quand deux branches ont modifié les mêmes lignes. Git s'arrête et marque le fichier :
<<<<<<< HEAD
greeting="Hello"
=======
greeting="Bonjour"
>>>>>>> feature/greeting
Vous corrigez le fichier pour qu'il ait le bon contenu, retirez les marqueurs, faites git add, puis git commit (ou git rebase --continue). git merge --abort revient à l'état d'avant.
Quelle commande annule une fusion en cours ?
Réponse
git merge --abort.
Vous avez corrigé le fichier en conflit. Étape suivante ?
git push --forcegit reset --hardgit adddu fichier, puis commit
Réponse
Indexer le fichier dit à Git que le conflit est résolu.
Pratique (30 min)
- Jouez les premiers niveaux de Learn Git Branching (« Séquence d'introduction »).
- Dans un nouveau dépôt
~/lab/conflict: commitez surmainun fichiergreet.shavecgreeting="Hello". - Créez
feature/fr, changez la ligne en"Bonjour", commitez. Revenez surmain, changez-la en"Hi", commitez. git merge feature/fr: résolvez le conflit, commitez, lisezgit log --oneline --graph.- Recommencez avec
git rebaseau lieu de merge, et comparez les graphes.
Avec votre IA : « Voici la sortie de git status et le fichier en conflit pendant une fusion : [collez les deux]. Ne le résous pas pour moi. Explique quelle partie vient de quelle branche, et demande-moi quelle version le fichier final doit garder et pourquoi. »
Le faire faire par un agent : les agents résolvent bien les conflits simples une fois l'intention donnée. Consigne : « Rebase cette branche sur main ; pour chaque conflit, garde le comportement de main plus la nouvelle fonctionnalité de cette branche, et liste chaque conflit et ton choix. » Vous vérifiez encore : lisez la liste, lancez les tests, et comparez git diff main avec ce que la branche devait changer.
Synthèse (10 min)
Trois lignes : branche = pointeur, merge ou rebase, comment résoudre un conflit. Puis redessinez de mémoire le graphe d'un commit de fusion.
Jour 12 · 14/11 — Git 3 : dépôts distants et modèles de branches
Objectif : pousser sur une forge, ouvrir une pull request, et choisir un modèle de branches.
Théorie 1/2 : dépôts distants et pull requests
Un dépôt distant (remote) est une autre copie du dépôt, en général sur une forge (GitHub, Forgejo, GitLab). git push envoie vos commits, git fetch rapatrie les siens sans toucher à votre travail, git pull rapatrie et fusionne. Une pull request (merge request sur GitLab) propose de fusionner une branche : c'est là que le code est discuté, relu et testé avant d'atteindre main.
git remote add origin git@github.com:you/ops-scripts.git
git push -u origin main
git switch -c fix/typo && git commit -am "Fix typo" && git push -u origin fix/typo
Quelle commande télécharge les nouveaux commits du dépôt distant sans changer votre branche ?
Réponse
git fetch. git pull fusionne en plus.
Théorie 2/2 : trois modèles de branches
- Git Flow (Vincent Driessen, janvier 2010) : des branches
develop,feature/*,release/*,hotfix/*autour demain. Dans une note ajoutée en mars 2020, son auteur dit qu'il convient aux logiciels versionnés, et que les applications web livrées en continu sont mieux servies par plus simple. - GitHub Flow (Scott Chacon, 2011) :
mainest toujours déployable ; chaque changement est une branche courte, une pull request, une revue, une fusion, un déploiement. - Le développement sur le tronc (trunk-based development) : tout le monde intègre dans le tronc (
main) au moins une fois par jour, avec des branches très courtes et des drapeaux de fonctionnalité (feature flags) pour le travail inachevé. La recherche DORA l'associe à la haute performance.
Vous déployez une appli web plusieurs fois par jour. Quel modèle l'auteur même de Git Flow vous déconseille-t-il ?
- Le développement sur le tronc
- Git Flow
- GitHub Flow
Réponse
Git Flow : son auteur oriente les applis web livrées en continu vers plus simple.
En développement sur le tronc, comment fusionne-t-on une fonctionnalité inachevée ?
- Derrière un drapeau de fonctionnalité, éteint
- On la garde trois mois sur une branche
Réponse
Derrière un drapeau : le code est intégré, la fonctionnalité cachée.
Pratique (30 min)
- Créez un compte sur GitHub ou sur une instance Forgejo, ajoutez votre clé publique SSH dans ses réglages.
- Créez un dépôt public vide
ops-scripts; en local, mettez-y voscheck-disk.shetcheck-sites.sh, commitez, ajoutez le distant, poussez. - Créez une branche
docs/readme, ajoutez unREADME.mdqui dit ce que fait chaque script, poussez-la, ouvrez une pull request, lisez son diff sur la forge, fusionnez-la. - En local :
git switch main && git pull, et vérifiez que le README est là.
Avec votre IA : « Mon équipe compte deux personnes, nous déployons une petite appli web à chaque fusion, et nous n'avons pas de versions numérotées. Compare Git Flow, GitHub Flow et le développement sur le tronc pour ce cas dans un tableau (branches, fréquence de fusion, risques), puis demande-moi lequel je choisirais et conteste mon choix une fois. »
Synthèse (10 min)
Trois lignes : push / fetch / pull, à quoi sert une pull request, les trois modèles en une phrase chacun. Puis refaites la suite branche, push et pull request sans notes.
Jour 13 · 15/11 — Revue de code et hygiène des commits
Objectif : écrire des commits lisibles par un relecteur, et relire une pull request utilement.
Théorie 1/2 : petits commits, messages clairs
Un bon commit fait une seule chose, et son message dit pourquoi. Une convention répandue, Conventional Commits 1.0.0, préfixe le sujet par un type : feat:, fix:, docs:, ci:, refactor:… Des outils peuvent alors calculer un numéro de version (gestion sémantique de version : MAJEUR.MINEUR.CORRECTIF) et un journal des changements à partir de l'historique. Le sujet reste court, à l'impératif ; le corps explique la raison. (Ce site écrit ses messages de commit en anglais, comme la plupart des projets libres.)
fix: stop check-disk from passing when df fails
df returns nothing on an unmounted path, and the empty value was read
as 0 %, so the script printed OK. Exit 2 when df gives no number.
Quel sujet suit Conventional Commits ?
- « changes »
- « fix: handle an empty df output »
- « Fixed stuff in the script!! »
Réponse
Type, deux-points, sujet court à l'impératif.
Une nouvelle fonctionnalité qui ne casse rien fait monter quelle partie de la version sémantique 1.4.2 ?
- MINEUR : 1.5.0
- MAJEUR : 2.0.0
- CORRECTIF : 1.4.3
Réponse
MINEUR. CORRECTIF pour les corrections, MAJEUR pour les changements incompatibles.
Théorie 2/2 : relire
Google publie ses règles de revue de code. Leur critère : approuver un changement dès qu'il améliore la santé générale du code, même s'il n'est pas parfait. Un relecteur regarde la conception, le comportement, les tests, les noms, les commentaires, et garde les pull requests petites (quelques centaines de lignes au plus se relisent bien). Les commentaires portent sur le code, jamais sur la personne, et disent ce qui bloque et ce qui est une suggestion (« nit: »).
Une pull request de 3 000 lignes qui mélange une refonte et une fonctionnalité. Meilleure réponse ?
- Approuver sans lire, c'est trop long
- Demander de la découper en pull requests plus petites
Réponse
Découper : les petits changements sont bien relus et fusionnés plus vite.
Quel commentaire est le meilleur commentaire de revue ?
- « Cette boucle relit le fichier pour chaque hôte ; pourrait-on le lire une fois avant la boucle ? »
- « Tu as au moins testé ? »
Réponse
Précis, sur le code, avec une suggestion.
Pratique (30 min)
- Dans
ops-scripts, ouvrez une branche qui corrige les remarques ShellCheck d'avant-hier ou ajoute l'option-h, en deux commits séparés avec des messages Conventional Commits et un corps. - Ouvrez la pull request avec une description : quoi, pourquoi, comment tester.
- Relisez-la vous-même le lendemain matin, comme un inconnu : laissez au moins deux commentaires sur la forge, un bloquant, un « nit: ».
- Si vous connaissez un autre apprenant, échangez une revue.
Avec votre IA : « Relis ce diff en suivant les règles de revue de code de Google : [collez git diff main]. Donne au plus cinq commentaires, chacun avec fichier et ligne, marqués BLOQUANT ou NIT, et une phrase pour dire si le changement améliore le code dans l'ensemble. Ne réécris pas le code. »
Le faire faire par un agent : les agents savent écrire messages de commit et descriptions de pull request à partir d'un diff. Consigne : « Écris un message Conventional Commits pour le diff indexé : sujet de moins de 60 caractères, corps qui explique pourquoi. » Vous vérifiez encore que le « pourquoi » est vrai : l'agent ne voit que le diff, pas votre raison.
Synthèse (10 min)
Trois lignes : ce qu'est un bon commit, MAJEUR.MINEUR.CORRECTIF, le critère de revue de Google. Puis réécrivez correctement un de vos anciens messages de commit.
Jour 14 · 16/11 — Livrable du module 1 : votre dépôt ops-scripts
Objectif : publier un dépôt propre de deux ou trois scripts documentés, et vérifier vos acquis.
Théorie 1/2 : ce qui rend un dépôt lisible
Un inconnu, un recruteur ou vous dans six mois ouvre le dépôt : le README.md dit ce qu'il fait, comment l'installer, le lancer, le tester ; un fichier LICENSE dit ce que les autres ont le droit d'en faire (par exemple MIT) ; l'historique raconte une histoire en petits commits ; rien de secret n'y figure, pas même dans un vieux commit.
Vous avez commité un mot de passe la semaine dernière, puis l'avez supprimé dans un nouveau commit. A-t-il disparu ?
- Oui
- Non, il est toujours dans l'historique : changez le mot de passe
Réponse
Chaque ancien commit le contient encore. Changez d'abord le secret ; nettoyer l'historique vient ensuite.
Théorie 2/2 : révision du module
Laquelle n'est pas une métrique DORA ?
- La fréquence de déploiement
- Le taux d'échec des changements
- Les lignes de code par jour
Réponse
Les lignes de code mesurent l'activité, pas la livraison.
rwxr-x--- en chiffres ?
Réponse
750.
Un script se termine par exit 3. Pour une chaîne CI, l'étape…
- a échoué
- a réussi avec un avertissement
Réponse
Tout code non nul est un échec.
Exercice généré sans fin (JavaScript requis) : révision des droits.
Pratique (30 min)
- Terminez
ops-scripts:check-disk.sh,check-sites.sh, et un troisième de votre choix (par exemple un résumé de journal construit au jour 6). Chacun passeshellcheck, a-h, sort en non nul en cas d'échec. - Écrivez le README : but, prérequis, usage avec un exemple, comment tester. Ajoutez une
LICENSE. - Vérifiez l'historique :
git log --onelinese lit comme une histoire ; rien de secret dedans (git log -p | grep -i pass). - Poussez, et ajoutez le lien du dépôt dans votre carnet : c'est le livrable 1 de votre portfolio.
Avec votre IA : « Joue un responsable de recrutement pour un poste DevOps junior. Voici le README et la liste des fichiers de mon dépôt : [collez-les]. Dis-moi en cinq puces ce que tu me demanderais en entretien à son sujet, et une chose qui te ferait arrêter de lire. Pas de compliments. »
Le faire faire par un agent : un agent peut rédiger un README à partir du code des scripts et de leur sortie -h. Vous vérifiez encore chaque commande qu'il contient en la lançant, et vous réécrivez le « pourquoi » avec vos mots : c'est à vous que le recruteur posera la question, pas à l'agent.
Synthèse (10 min)
Comptez votre score à la révision. Les sujets manqués reviennent au jour 54, quand vous concevez votre projet final.
Sources
- John Allspaw et Paul Hammond — 10+ Deploys per Day: Dev and Ops Cooperation at Flickr (Velocity 2009)
- devopsdays — à propos
- DORA — les métriques de performance de livraison
- systemd et ShellCheck
- Manuel de GNU Bash
- Pro Git et la référence Git
- Vincent Driessen — A successful Git branching model, GitHub Flow, trunkbaseddevelopment.com
- Conventional Commits 1.0.0 et gestion sémantique de version
- Google — guide de revue de code
Utile ? Dites-nous ce qu'il faut mesurer ensuite.