freedzhost.cloud

DevOps module 1 : la culture, Linux, le shell et Git

Niveau DébutantTemps estimé 14 hÀ lire avant Parcours DevOps : 59 jours du commit à la productionUn mot inconnu ? Lexique

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 ?

  1. San Francisco
  2. Gand
  3. Berlin
Réponse

Gand, en Belgique, en octobre 2009, organisés par Patrick Debois.

Qu'a montré la conférence de Flickr en 2009 ?

  1. Que dev et ops coopérant pouvaient déployer plus de dix fois par jour
  2. Que l'exploitation doit valider chaque version à la main
  3. 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 ?

  1. Oui, l'outil est le cœur
  2. 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)

  1. 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.
  2. Installez Git et un éditeur : sudo apt install git, puis vérifiez git --version.
  3. Créez le dossier de votre carnet : mkdir -p ~/devops-notes && cd ~/devops-notes, et un premier fichier day-01.md avec l'histoire du DevOps en cinq phrases, avec vos mots.
  4. É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 ?

  1. La vitesse de frappe
  2. Les serveurs
  3. 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…

  1. la fréquence de déploiement
  2. le délai des changements
  3. 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 ?

  1. 15 %
  2. 3 %
  3. 85 %
Réponse

3 / 20 = 15 %.

D'après la recherche DORA, aller plus vite…

  1. fait toujours baisser la stabilité
  2. 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)

  1. 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.
  2. Calculez la part de l'attente dans le total. Entourez la file la plus longue.
  3. 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 ?

  1. /lib
  2. /var/lib
  3. /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)

  1. Visitez /, /etc, /var/log avec cd et ls -la ; notez ce que vous trouvez dans chacun.
  2. Lisez /etc/os-release avec cat : quelle distribution, quelle version ?
  3. Ouvrez man ls, trouvez avec / ce que fait -h, puis lancez ls -lh /var/log.
  4. Trouvez tous les fichiers .conf directement sous /etc : find /etc -maxdepth 1 -name "*.conf".
  5. Créez ~/lab/day03 avec mkdir -p, copiez-y /etc/hostname avec cp, renommez-le avec mv, supprimez-le avec rm.

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 ?

  1. 755
  2. 700
  3. 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 ?

  1. Pour limiter ce qu'obtient un attaquant s'il est compromis
  2. Parce que root est plus lent
Réponse

Moindre privilège : une intrusion reste dans les droits de cet utilisateur.

Pratique (30 min)

  1. Créez un utilisateur pour un service fictif : sudo useradd --system --no-create-home app, puis id app.
  2. sudo mkdir -p /srv/app, puis donnez-le à app : sudo chown app:app /srv/app et sudo chmod 750 /srv/app.
  3. En tant que vous, essayez ls /srv/app : pourquoi est-ce refusé ? Lisez ls -ld /srv/app.
  4. Créez ~/lab/hello.sh contenant echo hello. Lancez ./hello.sh : refusé. Ajoutez le droit d'exécution, relancez.
  5. 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 ?

  1. SIGKILL (9)
  2. 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)

  1. Listez les processus avec ps aux | head, puis ouvrez top et trouvez celui qui utilise le plus de mémoire (M), q pour sortir.
  2. Lancez sleep 600 &, trouvez son PID avec pgrep sleep, arrêtez-le avec kill.
  3. É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
  4. sudo systemctl daemon-reload && sudo systemctl enable --now tick, puis journalctl -u tick -f. Arrêtez-la avec sudo 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 ?

  1. Écrase out.log avec les seules erreurs
  2. Ajoute la sortie et les erreurs à la fin de out.log
  3. 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 ?

  1. Pour aller plus vite
  2. Pour une sortie alphabétique
  3. Parce que uniq ne fusionne que les lignes identiques qui se suivent
Réponse

uniq compare chaque ligne à la précédente seulement.

Pratique (30 min)

  1. 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
  2. Combien d'erreurs 500 ? grep -c " 500$" ~/lab/access.log.
  3. Quel client fait le plus de requêtes ? Enchaînez cut, sort, uniq -c, sort -rn, head -1.
  4. Quelle page renvoie le plus de 404 ? Commencez par grep " 404$", puis coupez le troisième champ (-f3).
  5. 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 ?

  1. Le script s'arrête
  2. 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 ?

  1. Deux arguments, my et notes.txt
  2. 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)

  1. Écrivez ~/lab/check-disk.sh : il prend un seuil en pourcentage (80 par défaut), lit l'occupation de / avec df --output=pcent / | tail -1 | tr -dc '0-9', affiche OK ou ALERT, et sort avec 0 ou 1.
  2. Rendez-le exécutable, lancez-le avec 80, puis avec 1 pour forcer l'alerte, et vérifiez echo $? à chaque fois.
  3. 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 "$@" ?

  1. Le nom du script
  2. Tous les arguments, chacun gardé comme un mot
  3. 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. »

  1. A, il laisse le modèle libre
  2. 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 ?

  1. La politesse
  2. Un rôle
  3. 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)

  1. Tapez le script check ci-dessus dans ~/lab/check-sites.sh et lancez-le avec example.com example.org, puis avec un nom qui n'existe pas.
  2. Passez shellcheck dessus et sur le check-disk.sh d'hier ; corrigez chaque avertissement en lisant la page SC correspondante.
  3. Ajoutez une option -h qui 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 ?

  1. La clé privée
  2. 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 ?

  1. L'application derrière le proxy (arrêtée ou injoignable)
  2. 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)

  1. dig +short example.com, puis dig example.com MX : notez l'adresse et le type d'enregistrement.
  2. curl -I https://example.com et curl -I https://example.com/nothing-here : notez les deux codes.
  3. ss -tlnp : sur quels ports votre machine écoute-t-elle ? Lancez python3 -m http.server 8000 dans un autre terminal et regardez à nouveau, puis curl -I http://127.0.0.1:8000.
  4. Créez une paire de clés ed25519 avec ssh-keygen, vérifiez que ~/.ssh/id_ed25519 est 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 ?

  1. Crée un commit
  2. Place des changements dans la zone d'index pour le prochain commit
  3. Envoie le code au serveur
Réponse

Il indexe. git commit enregistre, git push envoie.

Un commit stocke…

  1. un instantané du projet, nommé par une empreinte
  2. 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)

  1. Réglez votre identité : git config --global user.name "Votre Nom" et git config --global user.email "vous@example.org" (votre vraie adresse va là, pas sur une page publique).
  2. Dans ~/devops-notes : git init, git add ., git commit -m "Add notes for days 1 to 9".
  3. Modifiez un fichier, regardez git diff, indexez-le, regardez git diff --staged, faites le commit.
  4. Créez un .gitignore avec *.tmp, créez x.tmp, vérifiez que git status l'ignore.
  5. 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 ?

  1. Une copie de chaque fichier
  2. 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 ?

  1. Le rebase réécrit ses commits, et leurs copies ne correspondent plus
  2. 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 ?

  1. git push --force
  2. git reset --hard
  3. git add du fichier, puis commit
Réponse

Indexer le fichier dit à Git que le conflit est résolu.

Pratique (30 min)

  1. Jouez les premiers niveaux de Learn Git Branching (« Séquence d'introduction »).
  2. Dans un nouveau dépôt ~/lab/conflict : commitez sur main un fichier greet.sh avec greeting="Hello".
  3. Créez feature/fr, changez la ligne en "Bonjour", commitez. Revenez sur main, changez-la en "Hi", commitez.
  4. git merge feature/fr : résolvez le conflit, commitez, lisez git log --oneline --graph.
  5. Recommencez avec git rebase au 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 de main. 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) : main est 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 ?

  1. Le développement sur le tronc
  2. Git Flow
  3. 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 ?

  1. Derrière un drapeau de fonctionnalité, éteint
  2. 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)

  1. Créez un compte sur GitHub ou sur une instance Forgejo, ajoutez votre clé publique SSH dans ses réglages.
  2. Créez un dépôt public vide ops-scripts ; en local, mettez-y vos check-disk.sh et check-sites.sh, commitez, ajoutez le distant, poussez.
  3. Créez une branche docs/readme, ajoutez un README.md qui dit ce que fait chaque script, poussez-la, ouvrez une pull request, lisez son diff sur la forge, fusionnez-la.
  4. 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 ?

  1. « changes »
  2. « fix: handle an empty df output »
  3. « 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 ?

  1. MINEUR : 1.5.0
  2. MAJEUR : 2.0.0
  3. 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 ?

  1. Approuver sans lire, c'est trop long
  2. 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 ?

  1. « Cette boucle relit le fichier pour chaque hôte ; pourrait-on le lire une fois avant la boucle ? »
  2. « Tu as au moins testé ? »
Réponse

Précis, sur le code, avec une suggestion.

Pratique (30 min)

  1. 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.
  2. Ouvrez la pull request avec une description : quoi, pourquoi, comment tester.
  3. Relisez-la vous-même le lendemain matin, comme un inconnu : laissez au moins deux commentaires sur la forge, un bloquant, un « nit: ».
  4. 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 ?

  1. Oui
  2. 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 ?

  1. La fréquence de déploiement
  2. Le taux d'échec des changements
  3. 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…

  1. a échoué
  2. 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)

  1. 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 passe shellcheck, a -h, sort en non nul en cas d'échec.
  2. Écrivez le README : but, prérequis, usage avec un exemple, comment tester. Ajoutez une LICENSE.
  3. Vérifiez l'historique : git log --oneline se lit comme une histoire ; rien de secret dedans (git log -p | grep -i pass).
  4. 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

Utile ? Dites-nous ce qu'il faut mesurer ensuite.