Aller au contenu
Infrastructure as Code medium

Les grains Salt : faits système et grains personnalisés

6 min de lecture

Un parc n'est jamais homogène : distributions différentes, rôles variés. Les grains sont la réponse de Salt : des faits collectés côté minion qui décrivent chaque machine, exploitables pour cibler et brancher vos déploiements. Ce module apprend à déployer automatiquement selon le système d'exploitation et le rôle. Public visé : intermédiaires ayant pratiqué states et pillars.

  • Lire les grains système d'un minion.
  • Définir des grains personnalisés (rôle, environnement).
  • Cibler et brancher des states selon les grains.
  • Savoir écrire des states et connaître le ciblage.

Au démarrage, chaque minion collecte des dizaines de faits : os, os_family, osrelease, cpuarch, mem_total, fqdn, adresses IP. Ces grains système sont disponibles partout, dans le ciblage comme dans les states. La fonction grains.item en lit une sélection :

Fenêtre de terminal
salt 'web1' grains.item os os_family osrelease cpuarch
web1:
----------
cpuarch:
x86_64
os:
Debian
os_family:
Debian
osrelease:
13

grains.items affiche tout, grains.get os_family renvoie une seule valeur. Ces faits pilotent ensuite les décisions : grains['os_family'] dans un state permet de choisir le bon paquet ou le bon chemin selon la distribution.

Les grains système décrivent la machine, mais pas son rôle métier. On ajoute alors des grains personnalisés : role: web, environnement: prod. Ils se définissent dans le fichier /etc/salt/grains du minion, dans sa configuration, ou dynamiquement. Ce sont eux qui rendent un top file lisible et un ciblage stable.

# /etc/salt/grains sur le minion
role: web
environnement: prod

Après modification, un salt 'web1' saltutil.sync_grains ou un redémarrage du minion recharge les grains. On les relit comme les autres :

Fenêtre de terminal
salt 'web1' grains.get role
web1:
web

Le drapeau -G sélectionne les minions par grain. Un grain de rôle vise une fonction métier ; un grain système vise une famille de machines. Sur un parc où seul un serveur porte le rôle web :

Fenêtre de terminal
salt -G 'role:web' test.ping
web1:
True

Le même mécanisme avec un grain système rassemble toute une famille d'OS, ici trois machines Debian :

Fenêtre de terminal
salt -G 'os_family:Debian' test.ping
proxy1:
True
web1:
True
db1:
True

C'est ce ciblage qui remplace les exceptions machine par machine : vous décrivez une intention (« les serveurs web », « les hôtes Debian »), pas une liste.

Assemblons les deux idées. Un state unique installe le bon serveur web selon la famille d'OS du minion, grâce à grains['os_family'] évalué en Jinja. Sur une machine Debian il posera apache2, sur une machine RedHat httpd, sans que vous ayez à écrire une exception.

{# le paquet du serveur web dépend de la famille d'OS du minion #}
{% set pkg = "apache2" if grains["os_family"] == "Debian" else "httpd" %}
serveur_web:
pkg.installed:
- name: {{ pkg }}
service.running:
- name: {{ pkg }}
- enable: true
- require:
- pkg: serveur_web

À l'application sur une cible Debian, Salt résout pkg en apache2, installe le paquet et démarre le service :

Fenêtre de terminal
salt db1 state.apply webserver
ID: serveur_web
Function: pkg.installed
Name: apache2
Result: True
Changes: ...
----------
ID: serveur_web
Function: service.running
Name: apache2
Result: True
Summary for db1
------------
Succeeded: 2 (changed=1)
Failed: 0

Un state correct ne change rien s'il est rejoué sur un système déjà conforme. Le second passage le vérifie :

Fenêtre de terminal
salt db1 state.apply webserver
Name: apache2
Comment: All specified packages are already installed
Name: apache2
Comment: The service apache2 is already running
Succeeded: 2
Failed: 0

changed=1 au premier passage, aucun changement au second : le state est idempotent. La preuve côté machine confirme le résultat :

Fenêtre de terminal
salt db1 cmd.run 'systemctl is-active apache2'
db1:
active
SymptômeCause probableSolution
Un grain personnalisé n'apparaît pasGrains non rechargéssalt '<minion>' saltutil.sync_grains ou redémarrer le minion
-G 'role:web' ne cible personneGrain absent ou mal orthographiéVérifier /etc/salt/grains et grains.get role
grains['os_family'] lève une erreur en JinjaGrain inexistant sur la cibleUtiliser grains.get('os_family', 'Debian') avec repli
  1. Les grains sont des faits du minion, collectés à son démarrage.
  2. Les grains système (os_family, osrelease) adaptent le déploiement à la machine.
  3. Les grains personnalisés (role, environnement) rendent ciblage et top file lisibles.
  4. Le drapeau -G cible les minions par grain, système ou personnalisé.
  5. Fait non secret pour le ciblage : grain. Donnée sensible : pillar.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn