Les commandes distantes sont pratiques mais éphémères. Les states font le saut décisif : décrire une fois l'état voulu d'un serveur, puis laisser Salt le faire converger de façon idempotente. Ce guide construit un serveur web déclaratif de bout en bout, du premier fichier SLS au highstate rejoué sans dérive, avec les requisites qui rechargent le service quand sa configuration change. Public visé : administrateurs à l'aise avec les commandes distantes de Salt.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Écrire un fichier SLS déclaratif (paquet, service, fichiers).
- Associer des states aux minions avec le top file.
- Appliquer un highstate et prouver son idempotence.
- Ordonner les états avec les requisites (
require,watch). - Simuler un changement avec
test=Trueavant de l'appliquer.
Prérequis
Section intitulée « Prérequis »- Un master et au moins un minion de rôle
web, opérationnels. Sinon, commencez par Découvrir Salt puis Les commandes distantes. - L'exemple cible un minion
web1portant le grainrole: web.
Qu'est-ce qu'un state
Section intitulée « Qu'est-ce qu'un state »Un state décrit un résultat, pas une suite d'étapes. Au lieu d'ordonner
« lance apt install nginx », vous déclarez : « le paquet nginx est
présent, le service est démarré et activé, ce fichier a ce contenu ».
À chaque application, Salt compare l'état réel à l'état voulu et n'agit
que sur les écarts.
C'est le principe d'idempotence : rejouer le même state deux fois ne change rien la seconde fois. Cette propriété est ce qui distingue la gestion de configuration d'un simple script shell, qui réexécute tout à chaque passage. La même logique déclarative existe chez Ansible, Chef ou Puppet ; Salt l'exprime en YAML rendu par Jinja.
Les states vivent dans des fichiers SLS (SaLt State), rangés sous le
répertoire /srv/salt du master. Voici l'arborescence que nous allons
construire pour un serveur web :
Répertoiresrv/salt/
- top.sls
Répertoirenginx/
- init.sls
- tuning.conf
- index.html
Anatomie d'un fichier SLS
Section intitulée « Anatomie d'un fichier SLS »Le cœur du serveur web tient dans nginx/init.sls. Chaque bloc porte un
identifiant, appelle une fonction d'état (pkg.installed,
service.running, file.managed) et liste ses arguments. Le fichier ci-dessous
installe nginx, garde son service démarré, déploie un fichier de
réglage et une page d'accueil.
nginx: pkg.installed: [] service.running: - enable: true - require: - pkg: nginx
/etc/nginx/conf.d/tuning.conf: file.managed: - source: salt://nginx/tuning.conf - user: root - group: root - mode: "0644" - require: - pkg: nginx - watch_in: - service: nginx
/var/www/html/index.html: file.managed: - source: salt://nginx/index.html - user: root - group: root - mode: "0644" - require: - pkg: nginxTrois détails méritent l'attention. Le mode est toujours quoté
("0644") : sans les guillemets, YAML l'interpréterait comme un nombre décimal.
Le propriétaire et le groupe sont explicites plutôt qu'hérités du
compte d'exécution. Enfin, la source salt://nginx/tuning.conf désigne un
fichier servi par le master, depuis /srv/salt/nginx/.
Le fichier de réglage et la page sont volontairement simples :
client_max_body_size 32m;Ici, tout tient dans un seul init.sls, ce qui reste lisible pour un service
simple. Dès qu'un service se complexifie, la bonne pratique est de découper :
l'installation dans init.sls, la configuration dans un conf.sls
dédié, et les valeurs spécifiques à l'OS (nom de paquet, chemins) dans un
map.jinja. On garde le cas simple pour l'instant.
Le top file : qui reçoit quoi
Section intitulée « Le top file : qui reçoit quoi »Un state ne s'applique pas tout seul : le top file (top.sls) fait le lien
entre les minions et les states à leur appliquer. Il réutilise le même
ciblage que les commandes distantes, ici par grain role.
base: 'role:web': - match: grain - nginxLa ligne base désigne l'environnement par défaut. Tout minion dont le grain
role vaut web recevra le state nginx. C'est la carte d'assignation de
votre parc : un seul endroit décrit qui doit être quoi.
Appliquer le highstate
Section intitulée « Appliquer le highstate »Le highstate applique à chaque minion l'ensemble des states que le top file lui assigne. C'est la commande centrale de Salt en configuration.
sudo salt 'web1' state.applyweb1:---------- ID: nginx Function: pkg.installed Result: True Comment: All specified packages are already installed Changes:---------- ID: /etc/nginx/conf.d/tuning.conf Function: file.managed Result: True Comment: File /etc/nginx/conf.d/tuning.conf updated Changes: ---------- diff: New file mode: 0644---------- ID: nginx Function: service.running Result: True Comment: Service nginx is already enabled, and is running Changes: ---------- nginx: True---------- ID: /var/www/html/index.html Function: file.managed Result: True Comment: File /var/www/html/index.html updated
Summary for web1------------Succeeded: 4 (changed=2)Failed: 0------------Lisez le résumé de bas en haut : 4 états exécutés, 2 modifiés, aucun échec. Salt n'a rien fait sur le paquet (déjà présent), a créé le fichier de réglage et la page, et a rechargé le service. Chaque bloc indique son résultat, un commentaire lisible et les changements appliqués.
Prouver l'idempotence
Section intitulée « Prouver l'idempotence »Relançons exactement la même commande. C'est le test qui valide un state correct.
sudo salt 'web1' state.applySummary for web1------------Succeeded: 4Failed: 0------------Le résumé ne mentionne plus changed : zéro modification. Chaque état est
déjà « in the correct state ». Un state qui reviendrait avec des changements à
chaque passage aurait une dérive à corriger : c'est le signal d'alarme
numéro un en gestion de configuration.
Ordonner les états : les requisites
Section intitulée « Ordonner les états : les requisites »Par défaut, Salt exécute les états dans l'ordre du fichier, mais les requisites rendent les dépendances explicites et robustes. Vous en avez déjà utilisé deux dans le state nginx.
require garantit qu'un état ne s'exécute qu'après un autre : le service
et les fichiers dépendent tous du paquet (require: pkg: nginx), donc nginx est
installé avant qu'on tente de le démarrer ou d'écrire sa configuration.
watch (et son miroir watch_in) déclenche une réaction sur
changement. Ici, tuning.conf porte watch_in: service: nginx : dès que le
fichier change, Salt recharge nginx, et seulement dans ce cas. Vérifions-le
en modifiant la valeur du réglage puis en réappliquant :
sudo salt 'web1' state.apply ID: /etc/nginx/conf.d/tuning.conf Function: file.managed Result: True Comment: File /etc/nginx/conf.d/tuning.conf updated---------- ID: nginx Function: service.running Result: True Comment: Service restartedLe Service restarted prouve que la modification du fichier a entraîné le
rechargement, sans que vous ayez à l'ordonner manuellement. D'autres requisites
complètent la palette : onchanges agit seulement si un autre état a changé,
unless et onlyif conditionnent l'exécution à une commande. Pour
réutiliser des states entre eux, include importe un autre fichier SLS et
extend en ajuste un bloc.
# Réutiliser un state existantinclude: - nginx
extend: nginx: service.running: - reload: trueSimuler avant d'appliquer : test=True
Section intitulée « Simuler avant d'appliquer : test=True »Avant tout changement sensible, Salt sait simuler un highstate : il montre ce qui changerait sans rien modifier. C'est le filet de sécurité à adopter systématiquement.
sudo salt 'web1' state.apply test=True ID: /etc/nginx/conf.d/tuning.conf Function: file.managed Result: None Comment: The file /etc/nginx/conf.d/tuning.conf is set to be changedLe Result: None et le commentaire « set to be changed » signalent une
modification prévue. Le fichier réel sur le minion reste intact : test=True
n'écrit rien. Vous validez ainsi l'impact d'un changement avant de
l'appliquer, exactement comme un plan avec Terraform.
Vérifier le résultat
Section intitulée « Vérifier le résultat »Un state n'a de valeur que si le résultat est observable. Interrogeons le serveur web depuis le minion :
sudo salt 'web1' cmd.run 'curl -s http://localhost/ | grep -o "<title>.*</title>"'web1: <title>Serveur web géré par Salt</title>Le serveur répond et sert bien notre page : le paquet, le service, la configuration et le contenu sont tous conformes à ce que le state décrit.
Sécurité et bonnes pratiques
Section intitulée « Sécurité et bonnes pratiques »Trois réflexes rendent vos states fiables en production.
Simuler systématiquement. Un state.apply test=True avant chaque application
sensible vous montre l'impact sans risque. C'est gratuit et cela évite les
mauvaises surprises.
Valider les configurations. Un fichier qui casse un service bloque son
rechargement. Faites précéder les configs critiques d'une validation
(nginx -t, sshd -t) via un état de vérification, et gardez les modes
stricts et les propriétaires explicites, comme dans l'exemple.
Aucun secret dans les states. Mots de passe, clés et jetons n'ont rien à faire dans un fichier SLS versionné. Ils vivent dans les pillars, sujet d'un prochain module.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
No Top file found | top.sls absent ou minion non ciblé | Vérifier /srv/salt/top.sls et le grain de ciblage |
| Le state revient « changed » à chaque passage | Dérive ou state non idempotent | Identifier le bloc fautif, souvent un cmd.run non gardé |
Job for <service> failed | Config déployée invalide | Corriger le fichier, valider avec test=True puis <service> -t |
Rendering SLS ... failed | Erreur de syntaxe YAML ou Jinja | Vérifier l'indentation et le mode quoté |
Le watch ne recharge pas | Requisite mal orienté | Utiliser watch_in côté fichier ou watch côté service |
À retenir
Section intitulée « À retenir »- Un state décrit un résultat ; Salt le fait converger de façon idempotente.
- Les states vivent dans des fichiers SLS (YAML + Jinja) sous
/srv/salt. - Le top file assigne les states aux minions par ciblage (ici un grain).
- Le highstate applique tout ; le second passage sans changement prouve l'idempotence.
- Les requisites (
require,watch) ordonnent les états et déclenchent les rechargements ;test=Truesimule avant d'appliquer.
Prochaines étapes
Section intitulée « Prochaines étapes »Le prochain module, Les modules Salt, détaille les briques d'état
(pkg, service, file, user, cron, git) pour déployer une application
complète. En attendant sa publication, ces ressources prolongent ce guide.