
Vous savez décrire un état, le servir depuis Git et le durcir. Il manque la
dernière marche : supprimer l'étape manuelle. Ce projet final relie
Terraform, cloud-init et Salt pour qu'une VM tout juste provisionnée
s'enrôle seule, applique son highstate au premier démarrage, et naisse
déjà conforme. Sur le lab, il s'écoule 51 secondes entre terraform apply
et un serveur web opérationnel, sans qu'aucune commande ne soit tapée. Public
visé : avancés ayant suivi le parcours.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Enrôler automatiquement un minion avec
autosign. - Installer et configurer le minion depuis cloud-init.
- Déclencher un highstate au premier démarrage.
- Obtenir une VM conforme sans aucune intervention.
Prérequis
Section intitulée « Prérequis »- Avoir suivi le parcours, en particulier les bonnes pratiques (GitFS) et la production.
- Un outil de provisionnement, ici Terraform.
Le maillon manquant
Section intitulée « Le maillon manquant »Jusqu'ici, chaque nouvelle machine demandait des gestes : installer le minion, le pointer vers le master, accepter sa clé, puis lancer un highstate. Quatre occasions d'oublier quelque chose, et autant de machines qui dérivent dès leur naissance.
L'objectif est d'éliminer ces gestes en chaînant trois briques :
| Brique | Rôle dans la chaîne |
|---|---|
| Terraform | Crée la VM et lui injecte sa configuration cloud-init |
| cloud-init | Installe le minion, pose son identité, son rôle et son master |
| Salt | Accepte la clé (autosign) et applique le highstate au démarrage |
Chaque brique fait une chose, et le résultat est une machine qui se configure elle-même.
Accepter les clés automatiquement
Section intitulée « Accepter les clés automatiquement »Le premier verrou, c'est l'acceptation de clé : par défaut, un nouveau minion
attend qu'un humain valide sa clé sur le master. L'option autosign_file
lève ce verrou, mais sans ouvrir la porte à n'importe qui : seuls les
identifiants listés sont acceptés automatiquement.
autosign_file: /etc/salt/autosign.confLe fichier ne contient que les identifiants attendus, et Salt exige des permissions strictes, faute de quoi il ignore silencieusement le fichier :
echo 'web2' | sudo tee /etc/salt/autosign.confsudo chown salt:salt /etc/salt/autosign.confsudo chmod 0600 /etc/salt/autosign.confConfigurer le minion depuis cloud-init
Section intitulée « Configurer le minion depuis cloud-init »cloud-init s'exécute au premier démarrage de la VM. C'est là qu'on
installe le minion et qu'on lui donne son identité (minion_id), son rôle
(un grain) et son master. La ligne décisive est startup_states: highstate
: elle demande au minion d'appliquer tout ce que le top file lui assigne dès
qu'il démarre.
#cloud-configpackages: - gnupg - curl - ca-certificateswrite_files: - path: /etc/salt/minion_id content: web2 - path: /etc/salt/grains content: | role: web - path: /etc/salt/minion.d/capstone.conf content: | master: 192.168.10.40 startup_states: highstateruncmd: - install -d -m 0755 /etc/apt/keyrings - curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/SaltProjectKey/public | gpg --batch --yes --dearmor -o /etc/apt/keyrings/salt-archive-keyring.pgp - curl -fsSL https://github.com/saltstack/salt-install-guide/releases/latest/download/salt.sources -o /etc/apt/sources.list.d/salt.sources - apt-get update -qq - apt-get install -y salt-minion - systemctl enable --now salt-minionNotez que l'installation passe par le dépôt signé officiel, pas par un script téléchargé et exécuté à l'aveugle. La machine naît avec une chaîne de confiance vérifiable.
Côté Terraform, cette configuration est injectée comme user-data de la VM. Le provisionnement se résume alors à décrire la machine et à lui attacher ce fichier :
resource "proxmox_virtual_environment_vm" "capstone" { name = "saltminion4" # ... cpu, mémoire, disque, réseau ...
initialization { ip_config { ipv4 { address = "192.168.10.44/24" gateway = var.gateway } }
user_data_file_id = proxmox_virtual_environment_file.capstone_cloudinit.id }}Le top file doit vivre dans Git
Section intitulée « Le top file doit vivre dans Git »Un détail décide du succès ou de l'échec, et il coûte cher à découvrir. Si vous
servez vos states par GitFS (module précédent), c'est le top file du dépôt
Git qui fait autorité : il supplante celui posé dans /srv/salt. Une
machine qui démarre appliquera donc ce que Git lui assigne, pas ce qui traîne
sur le disque du master.
# top.sls, dans le dépôt Gitbase: '*': - motd 'role:web': - match: grain - nginxLa naissance, chronométrée
Section intitulée « La naissance, chronométrée »Tout est en place. On lance le provisionnement, puis on ne touche plus à rien :
terraform applyEn moins d'une minute, la machine s'enrôle et se configure. Le master l'a acceptée automatiquement :
sudo salt-key -LAccepted Keys:db1proxy1web1web2Le grain posé par cloud-init est bien là, et c'est lui qui a déclenché l'application du bon state :
sudo salt web2 grains.get roleweb2: webEt la machine est conforme : le paquet installé, la configuration gérée par Salt en place, et le site qui répond, sans qu'aucune commande n'ait été tapée sur cette VM.
sudo salt web2 cmd.run 'systemctl is-active nginx; tail -1 /etc/nginx/conf.d/tuning.conf; curl -s http://localhost/ | head -1'web2: active client_max_body_size 32m; <!DOCTYPE html>Le chronomètre s'arrête à 51 secondes entre le terraform apply et un serveur
web opérationnel et conforme. Le highstate rejoué ensuite ne change rien,
preuve que l'état est stable dès la naissance :
sudo salt web2 state.applySucceeded: 4Failed: 0Ce que cette chaîne change
Section intitulée « Ce que cette chaîne change »La machine n'est plus configurée après coup, elle naît conforme. La différence n'est pas cosmétique.
La dérive disparaît à la racine : il n'existe aucune fenêtre entre la création de la VM et son alignement, donc aucun serveur ne vit jamais dans un état non décrit. Le remplacement devient trivial : une machine douteuse se détruit et se recrée, au lieu de se réparer à la main. C'est le passage d'une infrastructure que l'on soigne à une infrastructure que l'on remplace, et Salt en est le garant à chaque démarrage.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
| La clé du minion reste en attente | autosign.conf ignoré | Vérifier chown salt:salt et chmod 0600 sur le fichier |
| Le minion s'enrôle mais rien ne s'applique | Le top file Git n'assigne rien à ce minion | salt <minion> state.show_top et corriger le top file dans Git |
| Le state attendu n'est pas appliqué | Le top file de GitFS supplante celui de /srv/salt | Déclarer le state dans le top file du dépôt Git |
| Le grain de rôle est absent | cloud-init n'a pas écrit /etc/salt/grains | Vérifier write_files et relancer saltutil.sync_grains |
| La VM démarre sans minion | Le dépôt Salt n'était pas joignable | Vérifier DNS et sortie réseau dans runcmd |
À retenir
Section intitulée « À retenir »autosign_fileenrôle les minions listés sans intervention ; le fichier doit appartenir àsaltet être en0600.- Un
autosign_filecontenant*accepterait n'importe quelle machine : listez des identifiants précis. - cloud-init installe le minion et pose son identité, son rôle et son master au premier démarrage.
startup_states: highstatefait converger la machine dès son démarrage, et la réaligne à chaque reboot.- Avec GitFS, le top file du dépôt Git supplante celui de
/srv/salt: c'est lui qui décide ce que reçoit la nouvelle machine. - Résultat : une VM née conforme en moins d'une minute, sans dérive possible entre sa création et son alignement.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Formation Terraform : approfondir le provisionnement qui déclenche cette chaîne.
- Cloud-init : tout ce que l'on peut préparer au premier démarrage d'une machine.