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)

Utilisez Terraform pour vos projets Docker

Magazine
Marque
GNU/Linux Magazine
Numéro
240
Mois de parution
septembre 2020
Spécialité(s)
Résumé

Terraform est un outil populaire pour déployer de l’infrastructure en particulier à destination des Clouds publics. Cependant, il possède de nombreux providers pour dialoguer avec différents hyperviseurs, bases de données ou solutions d’infrastructures en Software Defined. Voyons dans cet article son utilisation avec Docker.

Tirez le meilleur parti de votre gestionnaire de configuration Puppet

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

Puppet [1], outil de gestion de configuration et d’automatisation, a été présenté précédemment dans les colonnes de Linux Pratique [2]. Je vous propose de découvrir certaines fonctionnalités du logiciel qui ont évolué ou qui méritent de s’y attarder pour exploiter au mieux cet outil.

Développez vos photos numériques avec darktable

Magazine
Marque
Linux Pratique
Numéro
117
Mois de parution
janvier 2020
Spécialité(s)
Résumé

Après une séance photo, il faut travailler et développer un nombre important d’images avec des outils dédiés à la photo. Dans ce domaine, un outil comme GIMP est inadapté. Je vous propose de voir comment darktable peut résoudre tous vos besoins pour gérer un vrai workflow dans le développement des photos numériques.

Les derniers articles Premiums

Les derniers articles Premium

Cryptographie : débuter par la pratique grâce à picoCTF

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

L’apprentissage de la cryptographie n’est pas toujours évident lorsqu’on souhaite le faire par la pratique. Lorsque l’on débute, il existe cependant des challenges accessibles qui permettent de découvrir ce monde passionnant sans avoir de connaissances mathématiques approfondies en la matière. C’est le cas de picoCTF, qui propose une série d’épreuves en cryptographie avec une difficulté progressive et à destination des débutants !

Game & Watch : utilisons judicieusement la mémoire

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

Au terme de l'article précédent [1] concernant la transformation de la console Nintendo Game & Watch en plateforme de développement, nous nous sommes heurtés à un problème : les 128 Ko de flash intégrés au microcontrôleur STM32 sont une ressource précieuse, car en quantité réduite. Mais heureusement pour nous, le STM32H7B0 dispose d'une mémoire vive de taille conséquente (~ 1,2 Mo) et se trouve être connecté à une flash externe QSPI offrant autant d'espace. Pour pouvoir développer des codes plus étoffés, nous devons apprendre à utiliser ces deux ressources.

Raspberry Pi Pico : PIO, DMA et mémoire flash

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

Le microcontrôleur RP2040 équipant la Pico est une petite merveille et malgré l'absence de connectivité wifi ou Bluetooth, l'étendue des fonctionnalités intégrées reste très impressionnante. Nous avons abordé le sujet du sous-système PIO dans un précédent article [1], mais celui-ci n'était qu'une découverte de la fonctionnalité. Il est temps à présent de pousser plus loin nos expérimentations en mêlant plusieurs ressources à notre disposition : PIO, DMA et accès à la flash QSPI.

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 49 listes de lecture

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous