229 Membres 1087 Contributions

Open Community

Simplifiez-vous l'admin grâce à Ansible

Publiée par Xavier P. - Stormshield dans technique

Sans même être administrateur système, il n'est pas rare de devoir effectuer des tâches de maintenance ou d'administration sur une ou plusieurs machines. Afin de limiter le temps que l'on y consacre ainsi que des erreurs humaines, l'automatisation de ces tâches s'impose généralement assez vite. Le premier outil de cette automatisation est le plus fréquemment un ensemble de scripts shell, exécutant les commandes nécessaires sur les machines ciblées via SSH. Mais il est également possible de se tourner vers des outils de configuration d'infrastructure dédiés à ce problème, telsPuppet ou Chef. Malheureusement ces outils nécessitent souvent un temps apprentissage conséquent, ce qui en rebute beaucoup et les relègue à l'administration des systèmes les plus complexes.

Je vous propose dans cet article de découvrir Ansible, un outil de configuration qui n'a pas oublié de rester simple, à travers un petit exemple.

 

Le scénario

On veut s'assurer qu'un ensemble de machines est proprement configuré :

  • ntp et rsyslog sont installés et démarrés
  • ntp doit être démarré à chaque démarrage de la machine
  • une configuration spécifique est copiée pour rsyslog, qui doit la prendre en compte

Ce scénario est bien entendu simpliste mais suffira à la démonstration, sans trop en faire.

Note: les exemples suivants sont lancés sous Debian, mais ils seraient parfaitement valables sous RedHat par exemple, en remplaçant apt par yum.

 

Script shell

Voici un script possible (et un peu naïf) pour implémenter notre scénario :

 

 

 

Exécution :

./example.sh user1@machine1 user2@machine2

Quelques remarques :

  • Lancer des commandes "à distance" n'est ni pratique ni lisible.
  • On pourrait bien entendu copier le script à distance et l'exécuter sur place, en inversant le sens de la copie de fichier (scp), mais :
    • cela oblige la machine distante à avoir accès à la machine qui contrôle l'exécution ;
    • pour des opérations plus compliquées, il est souvent nécessaire d'intercaler les interactions entre les différents hôtes.
  • Un certain nombre de vérifications et d'options a été omis, rendant ce script peu robuste ou pas optimal (Peut-être APT était-il déjà à jour. Que se passe-t-il si ntp n'est plus installé mais l'a été par le passé ? etc.).

 

Ansible

Ansible est un outil exécutant lui aussi des commandes via SSH, mais avec les avantages suivants :

  • la syntaxe est concise ;
  • les scripts sont rejouables sans crainte de casser le système : seules les modifications nécessaires sont exécutées ;
  • plus besoin de gérer les erreurs, Ansible s'arrête à la première erreur avec un message clair ;
  • les connexions sont optimisées afin que le tout s'exécute plus rapidement ;
  • des tâches peuvent être exécutées en parallèle sur les différentes machines concernées si souhaité ;
  • contrairement à la plupart de ses concurrents, il ne nécessite pas l'installation d'agent sur les machines administrées.

Ansible prend en entrée des fichiers YAML (.yml). Ceux-ci permettent de définir des structures de données simples ou complexes tout en restant lisibles. Dans le cas des scripts Ansible, il suffit de retenir que l'indentation est importante pour départager les sections et leur contenu, et que les différents éléments d'une liste sont précédés d'un tiret (-). Enfin, un fichier YAML doit toujours commencer par trois tirets "---".

Sans plus attendre, voici notre exemple réécrit pour Ansible, avec quelques fonctionnalités supplémentaires, et suivi d'une version commentée :

Et la version commentée :

On notera la syntaxe concise mais néanmoins claire. La version non-commentée fait 30 lignes ! Les champs "name" sont optionnels mais permettent de commenter à la fois le script et son exécution (comme nous allons le voir) ils sont donc plutôt conseillés.

Ce qui peut surprendre et qu'il faut bien comprendre est que les "tâches" définies dans un script Ansible (que l'on appelle un "playbook") sont en fait une description de l'état cible du système, et non une liste de commandes à exécuter à chaque lancement. Ainsi, Ansible ne lancera pas les tâches pour lesquelles le système est déjà dans l'état désiré. C'est pour cela que l'on définit ici deux tâches relatives au service rsyslog :

  • On désire que le service soit démarré, Ansible le démarrera donc s'il ne l'est pas.
  • Par ailleurs, on désire que le service soit redémarré si le fichier de configuration change, afin de le prendre en compte. Là encore, le redémarrage n'aura donc pas lieu si le fichier ne change pas (Ansible fait une comparaison du contenu du fichier pour savoir s'il faut le remplacer).
  • Le seul moyen de n'écrire qu'une tâche relative au service rsyslog, tout en étant sûr que nos deux souhaits soient respectés, serait de demander un redémarrage systématique du service quand le script est lancé, ce qui serait souvent inefficace.

Avant de pouvoir exécuter ce playbook, il nous reste à spécifier l'inventaire des machines constituant notre environnement cible. Appelons-le tout simplement "inventaire" pour l'exemple :

 

Pour la suite, si vous avez une machine à base de apt ou yum sous la main, vous pouvez l'utiliser en lieu et place de "machine1" pour essayer le script.

Note : le script est ici exécuté avec l'utilisateur root, mais il est évidemment possible de spécifier un autre utilisateur dans le script ou dans l'inventaire (si l'utilisateur dépend de la machine). On peut alors demander à Ansible d'exécuter certaines tâches avec sudo, via à la clause : "sudo: yes".

Exécution !

$ ansible-playbook -i inventaire example.yml

 

Ansible nous indique clairement les étapes où un changement est survenu, et celles où tout était déjà en place. En l'occurrence, ntp et rsyslog ont été démarrés lors de leur installation, et il n'y a donc pas eu lieu de le faire une deuxième fois.

Observons à présent ce qui se produit si on relance le script, après avoir modifié rsyslog.conf (un espace suffira) : 

 

Le script s'est exécuté plus vite car il n'a pas eu besoin de mettre à jour APT, ni d'installer des paquets. On observe par ailleurs que puisque rsyslog.conf a été modifié, le service a bien été redémarré.

Et une dernière fois, sans rien modifier :


 

Tout étant déjà en ordre, Ansible n'a rien fait.

Conclusion

Voilà pour l'exemple de base. Les tâches d'administration les plus courantes se feront ainsi sans problème grâce à l'ensemble conséquent de modules disponibles : ajouter des utilisateurs, changer les droits de fichiers, gérer des clés SSH, configurer MySQL, etc.

Étant un outil d'automatisation complet, Ansible est capable de bien plus encore. On citera pour l'exemple :

  • la possibilité de créer des templates de configuration, de manière à adapter les fichiers copiés sur les machines distantes en fonction de certaines paramètres ;
  • la possibilité d'organiser variables, tâches, fichiers et templates en une hiérarchie de fichiers claire et maintenable, notamment via un concept très simple de rôles ;
  • la possibilité de catégoriser les tâches de manière à ne lancer que certaines d'entre elles.

Je vous invite à aller faire un tour sur le site d'Ansible pour voir l'étendue de ses capacités. Quoiqu'il en soit : qui peut le plus peut le moins, et j'espère vous avoir donné avec ce petit article quelques pistes pour vos futurs scripts.

Nicolas D., ingénieur R&D

Pour publier un commentaire, merci de vous authentifier.

Messages d'alerte