Fabric, le couteau suisse de l’automatisation

Magazine
Marque
Linux Pratique
Numéro
122
Mois de parution
novembre 2020
Spécialité(s)


Résumé

Fabric est une bibliothèque Python et une interface en ligne de commandes facilitant l’utilisation de SSH, que ce soit pour des applications ou dans le but d’automatiser certaines tâches répétitives d’administration système. La grande force de Fabric est d’être particulièrement simple à utiliser.


Body

1. Fabric, késako ?

Fabric, c’est tout le contraire des outils DevOps modernes tels que Salt ou Ansible pour ne citer que ceux qui opèrent au-dessus du protocole SSH. Ce n’est pas un langage de haut niveau avec de nombreux modules faisant abstraction des couches système inférieures. Point d’idempotence, de templates ou toutes les fonctionnalités qui font des outils de gestion de configuration le saint Graal de l’orchestration et pourtant je suis un fervent partisan de Puppet.

Pour autant, lorsqu’il s’agit d’interagir rapidement sur un grand nombre de serveurs, Puppet n’est pas la solution la plus efficace et un cluster SSH encore moins. L’adoption de Fabric dans mon entreprise lorsque le produit est devenu mature a radicalement changé notre façon d’administrer nos nombreux systèmes en parallèle de l’utilisation de Puppet. Il m’est ainsi arrivé fréquemment d’utiliser Fabric pour bootstraper des agents Puppet.

Lorsque l’on écrit du code Fabric, on travaille avec les primitives natives de SSH et le shell et on fait moins qu’effleurer du Python. C’est cette simplicité qui fait de Fabric un véritable couteau suisse, utilisable par n’importe qui.

Comme Ansible donc, il se base sur SSH. Il n’y a donc aucun agent particulier à installer. L’authentification est gérée par SSH, on peut donc se logger par login/mot de passe ou par clé SSH. Sudo est géré pour la délégation de droits ainsi que les primitives de transfert de fichiers.

2. On en est à quelle version déjà ?

Fabric première version est la version historique, disponible dans les dépôts Ubuntu 14.04 et 16.04 qui a comme grand défaut de n’être compatible que jusqu’à Python 2.7 qui n’est plus supporté par la fondation Python depuis un an, mais peut-être encore par votre distribution.

Fabric2 est une réécriture majeure qui supporte Python 3, dont le but avoué des développeurs est d’être plus facilement maintenable. Cependant, cette nouvelle version apporte une syntaxe largement modifiée et dont il manque encore de nombreuses fonctionnalités pour un sysadmin comme les groupes de machines. Mais pour un développeur qui cherche une surcouche à plus haut niveau que le shell pour déployer une application ou qui a besoin d’une intégration SSH avec Django au-dessus de ce que fourni le framework paramiko, le produit est tout à fait adapté.

Enfin, ma version de prédilection est Fabric3. C’est un fork amical de Fabric1 conçu pour fonctionner avec Python > 3.4. L’installation passe par le système de packages Python pip, tout ce qu’il y a de plus classique :

pip3 install Fabric3

3. Tout commence par un fabfile

Le lancement de fabric se fait par la commande fab qui cherche ses instructions dans un fichier fabfile.py dans le répertoire courant. Malgré l’extension du fichier, les connaissances requises en Python sont très faibles pour écrire un fabfile.

Voyons donc un premier fabfile avec une seule fonction :

from fabric.api import abort, cd, env, get, hide, hosts, local, prompt, \
    put, require, roles, run, runs_once, settings, show, sudo, warn, open_shell
 
def host_details():
    run('lsb_release -a')

Et allons exécuter notre fonction sur l’un de nos serveurs :

fab -H ldap1 host_details
 
[ldap1] Executing task 'host_details'
[ldap1] run: lsb_release -a
[ldap1] Login password for 'julien':
[ldap1] out: No LSB modules are available.
[ldap1] out: Distributor ID:   Ubuntu
[ldap1] out: Description:      Ubuntu 20.04 LTS
[ldap1] out: Release: 20.04
[ldap1] out: Codename: focal
[ldap1] out:
 

Quand il s’agit de simplement lancer une commande à usage unique, il est possible d’appeler directement fabric avec en paramètre notre commande sans avoir besoin de modifier le fabfile.

fab -H ldap2,ldap1 -- lsb_release -a
[ldap2] Executing task '<remainder>'
[ldap2] run: lsb_release -a
[ldap2] Login password for 'julien':
[ldap2] out: No LSB modules are available.
[ldap2] out: Distributor ID:    Ubuntu
[ldap2] out: Description:       Ubuntu 18.04.4 LTS
[ldap2] out: Release:   18.04
[ldap2] out: Codename: bionic
 
[ldap1] Executing task '<remainder>'
[ldap1] run: lsb_release -a
[ldap1] out: No LSB modules are available.
[ldap1] out: Distributor ID:   Ubuntu
[ldap1] out: Description:      Ubuntu 20.04 LTS
[ldap1] out: Release: 20.04
[ldap1] out: Codename: focal

4. On mutualise avec les rôles

Je parlais d’administration d’un parc de serveurs donc ma commande fabric elle est jolie, elle me permet de spécifier plusieurs serveurs en utilisant fab -H ldap1,ldap2, mais ce n’est pas très pratique à utiliser. Et puis surtout je n’ai pas besoin de connaître et saisir le nom de tous les serveurs lorsque je déploie une nouvelle configuration SNMP, en particulier lorsque le parc est mouvant.

Pour cela, Fabric expose une variable d’environnements env.roledefs, en pratique un dictionnaire permettant d’organiser nos serveurs par rôles. Bien entendu, un serveur peut se retrouver dans plusieurs rôles, mais il n’est pas possible d’utiliser nos définitions de rôles sous la forme imbriquée, d’union ou d’intersection.

env.roledefs = {
    'dns': ['ns1', 'ns2'],
    'ldap': ['ldap1', 'ldap2'],
    'world': ['ldap1', 'ldap2', 'ns1', 'ns2'],
}

Comme pour les hôtes, on peut au besoin lancer une commande sur plusieurs rôles en les séparant par une virgule. Et quand le nombre de machines devient trop grand, il est même possible de paralléliser l’exécution avec -P.

fab -R ldap host_details
 
[ldap1] Executing task 'host_details'
[ldap1] run: lsb_release -a
[ldap1] Login password for 'julien':
[ldap1] out: No LSB modules are available.
[ldap1] out: Distributor ID:   Ubuntu
[ldap1] out: Description:      Ubuntu 20.04 LTS
[ldap1] out: Release: 20.04
[ldap1] out: Codename: focal
[ldap1] out:
[ldap2] Executing task 'host_details'
[ldap2] run: lsb_release -a
[ldap2] out: No LSB modules are available.
[ldap2] out: Distributor ID:    Ubuntu
[ldap2] out: Description:       Ubuntu 18.04.4 LTS
[ldap2] out: Release:   18.04
[ldap2] out: Codename: bionic

Personnellement, j’ai tendance à découper mes rôles par profil de serveur (DB, LDAP, SMTP, etc.), par environnement (recette, production…) et créer un rôle qui contient l’ensemble des serveurs.

5. Tout SSH dans un fabfile

Pour le premier exemple nous avons simplement utilisé la primitive run, mais fabric en dispose d’une multitude d’autres pour couvrir l’essentiel des cas d’usages d’un sysadmin :

  • sudo : forcément lorsqu’on parle d’administration système se pose la question des droits. Pas question de tout faire en root, d’ailleurs le compte est probablement désactivé à la connexion SSH. L’utilisation se fait de la même façon que la commande run :
  • sudo('systemctl restart snmpd.service')
  • Et il est aussi possible de préciser l’utilisateur sous lequel exécuter la commande en sudo :
  • sudo('/opt/zimbra/bin/zmlocalconfig ldap_host',user="zimbra")
  • Transférer des fichiers avec get et put :
  • put('snmpd.conf','/etc/snmp/snmpd.conf',use_sudo=True,mirror_local_mode=True)
  • ou à l’inverse :
  • get('/etc/resolv.conf','resolv.conf')
  • mirror_local_mode, optionnel, est bien pratique pour répliquer les permissions locales sur la machine distante. Il est tout autant possible de spécifier les permissions avec mode=’0640’ ou ne rien indiquer.
  • Redémarrer un serveur : reboot(), par défaut avec un timer de 120 secondes.
  • Interaction avec le sysadmin avec prompt :
  • def installpkg():
  •     pkg = prompt('Lequel monseigneur?')
  •     sudo('apt -y install '+pkg)
  • Les contextes : ils permettent de redéfinir une partie de l’environnement pour fournir un contexte d’exécution aux commandes qui seront lancées.
  • def run_commande():
  •     with shell_env(PATH='/opt/zimbra/bin:$PATH'):
  •                 run("commande")
  • lcd modifie le chemin de la machine sur laquelle le fabfile est exécuté et cd la machine sur laquelle on se connecte.   
  • def update_git() :
  •         with cd("/srv/project"):
  •             run("git pull")

6. Environnement

Fabric propose également certaines dispositions pour interagir avec les variables d’environnement. De manière absolument pas sécurisée, les variables env.user et env.password permettent d’indiquer les identifiants de connexion de manière globale dans le fabfile, la dernière chose à montrer à son RSSI donc.

Néanmoins, d’autres aspects de l’environnement ont toute leur place sur un grand parc. Notamment, si je veux collecter tous les fichiers /etc/resolv.conf de mes serveurs pour les auditer, je peux facilement les récupérer localement nommés de manière appropriée :

def get_resolvconf():
  get('/etc/resolv.conf','/tmp/resolv.conf-+env.host)

7. Un exemple dans le monde réel

Pour ne pas finir sur une bête liste de commandes, voici ce que nous donnerait un script fabric pour déployer un service SNMP avec un fichier de configuration local. Il y a de fortes chances que du SNMP soit standardisé sur un parc de machines et l’utilisation d’un outil d’automatisation tel que Fabric a toute sa place.

from fabric.api import abort, cd, env, get, hide, hosts, local, prompt, \
    put, require, roles, run, runs_once, settings, show, sudo, warn, open_shell
 
 
env.roledefs = {
    'dns': ['ns1', 'ns2'],
    'ldap': ['master', 'slave'],
    'world': ['ldap1', 'ldap2', 'ns1', 'ns2'],
}
 
def yumcleanup():
    sudo('yum clean all')
 
def inst_snmp():
    sudo('yum install net-snmp')
    sudo('systemctl enable snmpd.service')
 
def conf_snmp():
    put('snmpd.conf','/etc/snmp/snmpd.conf',use_sudo=True,mode=’0600’)
    sudo('systemctl restart snmpd.service')
 
def deploy_snmp():
    yumcleanup()
    inst_snmp()
    conf_snmp()

Il suffit ensuite d’appeler la commande deploy_snmp pour déclencher la configuration du SNMP sur les serveurs désirés. Et en quelques lignes de Python de plus, il est possible de rendre les commandes neutres sur le système de packages utilisé par la distribution.

Conclusion

Fabric n’est plus tout jeune dans le monde Linux et open source désormais. Bien qu'il soit largement dépassé par d’autres solutions autour de SSH comme Salt ou Ansible sur le terrain des fonctionnalités, ces logiciels ne doivent pas être opposés.

Je considère qu’un outil simple garde son intérêt pour sa souplesse et sa facilité d’utilisation. Il est en effet bien plus simple d’écrire une fonction de quelques lignes à exécuter sur plusieurs machines que l’équivalent Ansible, surtout quand c’est du code jetable.



Article rédigé par

Par le(s) même(s) auteur(s)

Galera, la solution pour des bases de données hautement disponibles

Magazine
Marque
Linux Pratique
Numéro
137
Mois de parution
mai 2023
Spécialité(s)
Résumé

Lorsqu’une application ne peut tolérer d’indisponibilités ou quand il devient nécessaire de fournir de la redondance au service de bases de données, il convient de mettre en place une architecture limitant les risques d’interruption de service. De même, le besoin de performance peut se faire sentir avec la croissance du nombre d’utilisateurs. Galera est une extension pour MariaDB aidant à résoudre ces deux situations.

Gérez votre stockage avec Stratis

Magazine
Marque
Linux Pratique
Numéro
128
Mois de parution
novembre 2021
Spécialité(s)
Résumé

Quand on parle de gestion du stockage local à un administrateur système Linux, il est généralement question de LVM et de filesystem XFS ou ext4. À un niveau plus évolué, on trouvera ZFS qui n'est pas libre ou bien Btrfs qui tarde à tenir ses promesses. Stratis a pour vocation de proposer quelque chose de neuf avec l’existant !

Déployer des environnements de développement avec Vagrant

Magazine
Marque
Linux Pratique
Numéro
127
Mois de parution
septembre 2021
Spécialité(s)
Résumé

Vagrant est un logiciel libre permettant de déployer rapidement des machines virtuelles. C'est un logiciel développé par la société Hashicorp, déjà connue pour d'autres logiciels comme Terraform, Packer ou Vault. Historiquement lié à VirtualBox, Vagrant s'est désormais largement ouvert à d'autres solutions de virtualisation comme Libvirt ou de conteneurisation comme Docker.

Les derniers articles Premiums

Les derniers articles Premium

Bénéficiez de statistiques de fréquentations web légères et respectueuses avec Plausible Analytics

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Pour être visible sur le Web, un site est indispensable, cela va de soi. Mais il est impossible d’en évaluer le succès, ni celui de ses améliorations, sans établir de statistiques de fréquentation : combien de visiteurs ? Combien de pages consultées ? Quel temps passé ? Comment savoir si le nouveau design plaît réellement ? Autant de questions auxquelles Plausible se propose de répondre.

Quarkus : applications Java pour conteneurs

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Initié par Red Hat, il y a quelques années le projet Quarkus a pris son envol et en est désormais à sa troisième version majeure. Il propose un cadre d’exécution pour une application de Java radicalement différente, où son exécution ultra optimisée en fait un parfait candidat pour le déploiement sur des conteneurs tels que ceux de Docker ou Podman. Quarkus va même encore plus loin, en permettant de transformer l’application Java en un exécutable natif ! Voici une rapide introduction, par la pratique, à cet incroyable framework, qui nous offrira l’opportunité d’illustrer également sa facilité de prise en main.

De la scytale au bit quantique : l’avenir de la cryptographie

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Imaginez un monde où nos données seraient aussi insaisissables que le célèbre chat de Schrödinger : à la fois sécurisées et non sécurisées jusqu'à ce qu'un cryptographe quantique décide d’y jeter un œil. Cet article nous emmène dans les méandres de la cryptographie quantique, où la physique quantique n'est pas seulement une affaire de laboratoires, mais la clé d'un futur numérique très sécurisé. Entre principes quantiques mystérieux, défis techniques, et applications pratiques, nous allons découvrir comment cette technologie s'apprête à encoder nos données dans une dimension où même les meilleurs cryptographes n’y pourraient rien faire.

Les listes de lecture

8 article(s) - ajoutée le 01/07/2020
Découvrez notre sélection d'articles pour faire vos premiers pas avec les conteneurs, apprendre à les configurer et les utiliser au quotidien.
11 article(s) - ajoutée le 02/07/2020
Si vous recherchez quels sont les outils du DevOps et comment les utiliser, cette liste est faite pour vous.
8 article(s) - ajoutée le 02/07/2020
Il est essentiel d'effectuer des sauvegardes régulières de son travail pour éviter de perdre toutes ses données bêtement. De nombreux outils sont disponibles pour nous assister dans cette tâche.
Voir les 58 listes de lecture

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous