Trop de shell pour l'administration système: une mauvaise idée ?
Sous ce titre que certains pourront trouver provocateur se cache selon moi une vraie question: est ce qu’il n’est pas plus intéressant d’utiliser un langage de programmation (comme Python ou Golang) à la place du shell pour faire de l’administration système ?
EDIT: une nouvelle version de cette article est sortie, je vous conseille de le lire. J’ai également participé à un podcast sur le sujet.
Avoir des bases en Shell est important
Maitriser le shell est toujours intéressant. J’utilise d’ailleurs régulièrement sur ma machine des commandes comme find, grep, ou awk, et j’ai quelques scripts qui me permettent de changer certains réglages.
Pour pas mal de petits besoins d’administration système, un script shell peut être suffisant. Pourquoi s’embêter à utiliser autre chose alors qu’un petit script avec quelques conditions et quelques commandes fait le job ?
Malheureusement, je pense que les "petits besoins" peuvent grossir rapidement, et pour moi des scripts shell trop longs sont vite un problème. Je vais essayer d’expliquer pourquoi avec un exemple.
Réaliser un backup
Prenons comme exemple un grand classique de l’administration système: vous voulez écrire un script réalisant un backup d’une base de données quelconque.
A première vue, le besoin est simple et pourrait être réalisé par un script shell:
-
On crée le backup
-
On le déplace quelque part
On pourrait très bien écrire un script shell réalisant ces deux actions.
Mais quand on réfléchit un peu plus à ce script, et à comment le rendre "prod ready", on se rend compte finalement qu’on veut aussi:
-
Des logs pertinents, si possible structurés en json.
-
Une façon propre de gérer les erreurs: envoi des erreurs à des outils de type Sentry par exemple, envoi d’alertes pertinentes à son outil de monitoring, slack…
-
Des métriques, comme par exemple le temps d’exécution du script.
On peut ensuite imaginer plein d’autres trucs, comme un système de retry en cas d’échec par exemple. Peut être aussi qu’on aura également besoin d’un client S3 pour stocker le backup sur un object store, ou d’interagir avec des services cloud (pour les logs et les métriques).
Mon petit script est finalement en train de se complexifier, et devient de plus en plus un programme à part entière. De plus, chaque interaction avec un système externe apporte son lot de complexité (client spécifique nécessaire, authentification, mTLS…) qui peut être difficile à réaliser en shell.
Je veux également que ce script (ou programme) ne soit pas gêré de façon différente par rapport aux autres programmes développés dans l’entreprise:
-
Tests unitaires et tests d’intégrations.
-
Code dans Git, intégration continue, avec creation de releases lors de modifications.
-
Déploiement automatisé, avec rollbacks possibles etc…
Scripts et programmes
Je pense qu’il faut éviter de faire une distinction entre les scripts écrits par les ops et les programmes écrits par les développeurs.
Le cycle de vie de ces base de codes doit être selon moi identique, et utiliser un langage de programmation comme Go pour réaliser ce genre de tâche amène son lot d’avantages, comme par exemple :
-
L’énorme écosystème du langage. Je n’ai pas à me demander si ce sera la galère d’envoyer mes logs, métriques, alertes ou événements à des systèmes externes car j’aurai des libs clientes dans le langage.
Vous allez me dire que tout cela est aussi faisable en shell. Il est en effet possible d’installer des paquets pour obtenir certains clients (kafkacat, s3cmd…), d’utiliser curl ou autre, mais le confort de développement sera toujours en dessous de ce que l’on trouve dans des langages de programmation complets. -
Le tooling: outils de tests, formatter, analyse statique du code, gestion des dépendances… Cela est éventuellement possible en shell, mais on est reste selon moi loin de ce qu’on trouve ailleurs.
-
Possibilité de produire un binaire statique dans le cas de Go, et donc d’éviter d’avoir à polluer la machine en installant des tonnes de packages.
-
Je trouve qu’écrire du shell correctement est difficile (la syntaxe est une chose, mais ça on peut s’y habituer). On se retrouve vite limité d’un point de vue architecture logicielle avec le shell, et se tirer une balle dans le pied est très rapide (sur la gestion des erreurs par exemple).
Ayant hérité dans une précédente expérience de scripts shell de plus de 10000 lignes, ou de "programmes" shell complexes où çasource
dans tout les sens pour avoir une sorte de système de modules, c’est juste l’enfer à maintenir.
Bref, du code c’est du code, que ce soit écrit par un dev ou par un ops. Les deux mondes doivent avoir les mêmes exigences sur le code produit. D’ailleurs, cela permet à tout le monde de travailler sur les différents programmes de l’entreprise de la même façon, et donc les développeurs peuvent aussi contribuer à l’outillage ops de façon standardisée.
Je ne dis pas qu’on ne doit jamais faire de shell, pour de petites tâches cela marche très bien, mais dès qu’on commence à avoir des centaines de lignes de shell, avec de la logique dans le script, c’est le signe qu’il est temps selon moi de passer à autre chose.
On me dit aussi parfois que coder en shell est plus rapide que dans un autre langage. C’est vrai que le shell se prête très bien à certaines choses, comme la rechercher et manipulation de fichiers par exemple. Si votre script ne fait que ça vous pouvez continuer comme je l’ai dit précédemment à faire du shell. Mais je ne pense pas que cet argument tient quand le script se complexifie, je dirai même que c’est l’inverse car le script sera plus maintenable dans un autre langage de programmation.
Conclusion
je pense que l’abus de shell est dangereux pour la santé. Un certain nombre de scripts seraient plus maintenables et plus fiables dans un langage comme Golang (je cite beaucoup Go ici car je pense que c’est un très bon langage pour ce genre de tâches. Mais rassurez vous, le langage a aussi ses défauts).
Les développeurs et les ops doivent travailler de la même façon sur leurs programmes, et le shell apporte trop de désanvantages pour être utilisé pour des programmes complexes.
Add a comment
If you have a bug/issue with the commenting system, please send me an email (my email is in the "About" section).