J'enseigne le développement web. Chaque étudiant reçoit un espace d'hébergement LAMP personnel où il publie ses productions, en ligne, sous son propre sous-domaine. C'est le cœur du dispositif pédagogique : on n'apprend pas le web en local, on l'apprend en publiant. Reste que chaque rentrée, ce dispositif me coûtait une demi-journée de clics.
Le problème
Un étudiant, ce n'est pas un compte. C'est cinq choses à créer, dans le bon ordre, avec les bonnes conventions :
- Un dossier - rangé par promotion, avec les bonnes permissions
- Un sous-domaine -
prenom.mondomaine.be, pointant sur ce dossier - Un certificat SSL - parce qu'un site en HTTP simple en 2026, non
- Une base MySQL - avec son utilisateur dédié et ses droits
- Un compte FTP - restreint à son propre dossier
Mon hébergement est un mutualisé classique avec cPanel, l'interface qu'on retrouve chez une bonne partie des hébergeurs. Elle fait le travail. Mais elle le fait à la souris : chaque opération demande de naviguer dans un menu, remplir un formulaire, valider, revenir en arrière. Comptez cinq à dix minutes par étudiant si tout se passe bien.
Quinze étudiants, ça fait entre une heure et demie et deux heures et demie. Deux fois par an. A répéter exactement de la même façon, sans se tromper d'un caractère dans un nom de base de données.
Et c'est là que ça coince vraiment : ce n'est pas long, c'est abrutissant. Le genre de tâche où l'attention décroche au septième étudiant et où l'on découvre trois semaines plus tard que le compte FTP de quelqu'un pointe sur le mauvais dossier.
Ce que j'avais déjà sous la main
Un accès SSH. Il est fourni par à peu près tous les hébergeurs mutualisés sérieux, et je ne m'en servais que pour du dépannage ponctuel.
Or cPanel expose une API en ligne de commande, uapi, accessible depuis cette session SSH. Tout ce que l'interface web fait avec des formulaires, cette API le fait avec une commande. Je le savais vaguement. Je ne l'avais jamais exploré, parce que le coût d'entrée (lire la documentation, tester, se tromper) dépassait toujours le coût de la soirée de clics.
C'est exactement le calcul que l'IA change.
L'exploration
J'ai demandé à Claude Code d'explorer le serveur et de me dire ce qui était pilotable depuis SSH. Pas d'écrire quoi que ce soit : juste regarder, lister les fonctions disponibles, comprendre les conventions déjà en place sur mes anciennes promotions.
Le résultat en quelques minutes :
| Opération | Commande | Statut |
|---|---|---|
| Créer un sous-domaine | SubDomain addsubdomain | OK |
| Créer une base | Mysql create_database | OK |
| Créer un utilisateur SQL | Mysql create_user | OK |
| Créer un compte FTP | Ftp add_ftp | OK |
| Supprimer un sous-domaine | delsubdomain | Indisponible |
Quatre opérations sur cinq automatisables immédiatement. La cinquième, la suppression de sous-domaine, n'existe que dans une version plus ancienne de l'API, dont le binaire est masqué par l'isolation du mutualisé. Elle reste manuelle. Ce n'est pas grave : on crée quinze comptes par an, on en supprime beaucoup moins souvent.
Le SSL, lui, résiste. Le renouvellement automatique n'est pas activé sur mon compte, et le plugin qui émet les certificats ne s'expose que dans l'interface web. À la création d'un sous-domaine, le certificat installé est auto-signé : le navigateur affiche une alerte tant qu'on n'a pas émis le vrai. C'est la seule étape que je continue de faire à la main, mais l'interface permet de cocher tous les sous-domaines d'un coup : une minute pour la promo entière, contre cinq à dix minutes par étudiant auparavant.
Ne pas s'arrêter au script
À ce stade, j'avais de quoi écrire un script shell et passer à autre chose. C'est ce que j'aurais fait il y a deux ans, et le script aurait fini oublié dans un dossier, sans documentation, inexploitable à la rentrée suivante.
La vraie unité de réutilisation aujourd'hui, ce n'est pas le script. C'est le skill : un dossier qui contient à la fois le script et le mode d'emploi écrit pour une IA. La différence est concrète. À la prochaine rentrée, je n'aurai pas à retrouver le script ni à me souvenir de sa syntaxe. J'écrirai :
Crée les comptes pour la promo 3tiweb2028 :
martin, leila, kwame, sofia, ...
Et le skill se charge du reste, y compris de me rappeler les conventions que j'aurai oubliées.
Écrire le skill comme on écrit du code testé
Un skill mal écrit est pire qu'un script : il donne l'illusion que la connaissance est capturée alors qu'elle est incomplète. J'ai donc appliqué la méthode inverse de l'intuition : observer l'échec avant d'écrire la solution.
J'ai lancé un agent sans aucune documentation, avec la consigne de ne rien modifier, et je lui ai demandé comment il s'y prendrait. Ses lacunes sont devenues mon plan :
- Il a oublié le compte FTP - il ne l'avait pas deviné, alors que c'est indispensable pour que l'étudiant dépose ses fichiers
- Il a hésité sur les conventions de nommage - deux schémas coexistaient sur mes anciennes promos
- Il n'a pas su si le dossier parent devait exister - cas exact de la première promotion de l'année
Une fois le skill écrit, j'ai refait passer le test à un autre agent, en lui demandant d'être critique. Verdict : 6,5 sur 10, avec une liste de défauts précise. Pas de commande de connexion, pas de boucle pour traiter une liste, sécurité documentée mais absente de la procédure, mots de passe générés puis perdus faute de les capturer.
Cette note m'a fait gagner plus de temps que n'importe quelle relecture de ma part. Je connais trop le sujet pour voir ce qui manque.
Les deux bugs que seule l'exécution réelle a révélés
Le skill corrigé, je l'ai testé sur un compte jetable. Deux bugs sont apparus, invisibles a la relecture.
Une plage de caractères au lieu d'une liste
Le générateur de mot de passe utilisait cette classe de caractères :
tr -dc 'A-Za-z0-9!#%*+-=?@'
Le premier mot de passe généré contenait un chevron : lKlA=JTo<w1VtfpUiWtJ. Or le chevron n'est pas dans ma liste.
Explication : dans une classe de caractères, +-= n'est pas trois caractères mais une plage, de + a = dans la table ASCII. Elle inclut le chevron, la barre oblique, la virgule. Exactement les caractères qui cassent une chaîne shell ou une URL de connexion. Le tiret doit être placé en dernier pour être pris au sens littéral.
Un paramètre facultatif qui ne l'est pas
La création du compte FTP renvoyait un succès franc. Mais le login réellement créé n'était pas prenom@mondomaine.be : c'était prenom@nomdecompte.hebergeur.fr, rattaché au domaine principal.
Sans paramètre domain= explicite, cPanel choisit le domaine principal du compte. Le piège est vicieux : la commande réussit, rien n'alerte, et l'erreur ne se manifeste qu'au moment ou l'étudiant essaie de se connecter avec le login qu'on lui a communiqué. Pire, la suppression échoue ensuite avec « ce compte n'existe pas », puisqu'on lui passe le domaine attendu et non le domaine réellement enregistré.
Ce que ça donne
Le skill fait 232 lignes de documentation et 146 lignes de script. Une commande, une liste de pseudos :
bash provision.sh 3tiweb2027 martin leila kwame
Sortie par étudiant :
--- martin ---
[1/5] sous-domaine OK martin.mondomaine.be
[2/5] permissions OK 750 nobody
[3/5] base OK compte_martin
user mysql OK compte_martin
droits OK
[4/5] ftp OK martin@mondomaine.be
[5/5] sécurité OK .htaccess dans img/ uploads/ files/
Et sur la sortie standard, une ligne CSV par étudiant, prête a devenir le tableau que je leur distribue : identifiants, URL, base, login FTP, mot de passe unique. Les diagnostics partent sur la sortie d'erreur, ce qui permet de rediriger le CSV vers un fichier sans le polluer.
| Avant | Apres | |
|---|---|---|
| Par étudiant | 5 a 10 minutes | quelques secondes |
| Pour 15 étudiants | 1h30 a 2h30 | une commande |
| Risque d'erreur | élevé, croissant avec la fatigue | nul, et vérifié a chaque étape |
| Tableau d'identifiants | recopié a la main | généré |
Les limites
Une automatisation honnête annonce ce qu'elle ne fait pas.
- Le certificat SSL reste manuel - le plugin qui l'émet n'existe que dans l'interface web, mais une minute suffit pour toute la promo
- La suppression de sous-domaine reste manuelle - la fonction n'est pas exposée dans l'API accessible depuis le mutualisé
- Un échec en cours de route laisse un état partiel - le script s'arrête net et le signale, mais ne défait pas ce qui a déjà ete créé
- Le script refuse d'écraser un compte existant - c'est voulu, mais cela veut dire qu'une reprise après échec demande un nettoyage manuel
- Rien ne remplace la vérification - je regarde toujours le premier compte créé avant de lancer les quatorze autres
Le bilan
Ce qui me frappe, ce n'est pas le gain de temps brut. C'est que cette automatisation était a ma portée depuis des années. L'API existait, l'accès SSH existait, mes compétences existaient. Ce qui manquait, c'était la volonté de passer une soirée a lire de la documentation d'API pour économiser une soirée de clics. Le calcul ne penchait jamais du bon cote.
L'IA n'a rien inventé ici. Elle a fait s'effondrer le coût d'exploration. Lire la documentation, tester les commandes, découvrir qu'un paramètre est obligatoire alors qu'il semble facultatif : ce travail de défrichage, qui me coûtait une soirée, prend maintenant quelques minutes.
Ce n'est pas magique pour autant. Le premier jet du skill valait 6,5 sur 10. Les deux bugs les plus pénibles ne sont apparus qu'a l'exécution réelle, sur un vrai serveur. C'est moi qui savais quelles conventions respecter, quel était le bon nom de base de données, pourquoi les permissions devaient être alignées sur les anciennes promotions.
L'IA est excellente sur les tâches répétitives et pénibles. Pas parce qu'elle les fait mieux que moi, mais parce qu'elle rend rentable le fait de les automatiser une bonne fois.
Ce que j'en retiens
- Le skill, pas le script. Un script sans mode d'emploi est perdu a la rentrée suivante
- Observer l'échec avant d'écrire. Les lacunes d'un agent non documente sont le meilleur plan de rédaction
- Faire noter son propre travail. Un 6,5 sur 10 argumenté vaut mieux qu'une relecture complaisante
- Tester en réel, sur du jetable. Les bugs les plus coûteux ne se voient pas a la lecture
- Automatiser ce qui est pénible, pas ce qui est difficile. Les tâches abrutissantes sont celles ou l'humain se trompe