
On répète partout que Chef s'adapte à la machine. C'est vrai, mais à moitié :
Chef choisit tout seul le bon gestionnaire de paquets, il ne devinera jamais
que le serveur web s'appelle apache2 chez Debian et httpd chez Red Hat.
Ce module écrit une recette réellement portable grâce à Ohai et à
platform_family, et la prouve : la même recette, le même test,
convergés sur Debian et sur RHEL, tous les deux au vert. Public visé :
intermédiaires ayant écrit des recettes.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre ce qu'Ohai collecte avant la convergence.
- Distinguer
platformetplatform_family. - Écrire une recette portable avec
value_for_platform_family. - Valider la même recette sur deux familles.
Prérequis
Section intitulée « Prérequis »- Savoir écrire une recette et utiliser Test Kitchen.
Ohai : ce que Chef sait de la machine
Section intitulée « Ohai : ce que Chef sait de la machine »Avant toute convergence, Chef lance Ohai, qui interroge la machine et
remplit l'objet node : distribution, version, noyau, mémoire, réseau, disques.
Ces valeurs s'appellent les attributs automatiques, et vous n'avez rien à
faire pour les obtenir.
Le plus simple pour les explorer est cinc-shell, qui charge le nœud sans rien
converger :
cinc-shellnode['platform']node['platform_family']node['kernel']['release'] => "ubuntu" => "debian" => "6.8.0-134-generic"platform ou platform_family : la distinction qui change tout
Section intitulée « platform ou platform_family : la distinction qui change tout »Regardez bien les deux premières valeurs : platform vaut ubuntu, mais
platform_family vaut debian. Ce n'est pas une redondance, c'est la
notion clé de la portabilité.
| Attribut | Ce qu'il donne | Exemples |
|---|---|---|
platform | La distribution précise | ubuntu, debian, rocky, almalinux, fedora |
platform_family | La famille, qui partage les mêmes outils | debian, rhel, suse, windows |
Écrire une condition sur platform vous condamne à l'énumérer sans fin :
ubuntu, puis debian, puis Ubuntu 22 mais pas 24, puis quelqu'un déploie sur
Rocky, puis sur AlmaLinux... Chaque nouvelle distribution casse votre
recette.
Écrire une condition sur platform_family couvre toute la famille d'un coup :
debian prend Ubuntu et Debian ; rhel prend Rocky, AlmaLinux, CentOS Stream et
RHEL.
Ce que Chef fait déjà tout seul
Section intitulée « Ce que Chef fait déjà tout seul »Une bonne nouvelle avant le travail : la ressource package est déjà
portable. Vous écrivez package, et Chef choisit le fournisseur adapté à la
machine. La preuve, dans la sortie de convergence :
* apt_package[apache2] action install ← sur Ubuntu* dnf_package[httpd] action install ← sur Rocky LinuxVous n'avez jamais écrit apt ni dnf. Chef a traduit votre intention. Il en
va de même pour service, user, group : l'outil est choisi pour
vous.
Ce que Chef ne devinera jamais
Section intitulée « Ce que Chef ne devinera jamais »En revanche, Chef ne peut pas savoir que votre serveur web s'appelle
apache2 ici et httpd là. Ce n'est pas un outil, c'est une donnée, et
elle change d'une famille à l'autre.
C'est exactement le rôle de value_for_platform_family : une table de
correspondance entre la famille et la valeur.
# La famille décide du nom du paquetpaquet = value_for_platform_family( 'debian' => 'apache2', 'rhel' => 'httpd')
package paquet
file '/var/www/html/index.html' do content "Servi par #{paquet} sur #{node['platform']} (famille #{node['platform_family']})\n" mode '0644'endLe nom du service suivrait la même variable, puisqu'il porte le même nom que le paquet dans les deux familles.
La preuve : même recette, deux familles
Section intitulée « La preuve : même recette, deux familles »Test Kitchen sait converger plusieurs plateformes à partir du même cookbook. Il suffit de les déclarer :
platforms: - name: ubuntu-24.04 driver: image: dokken/ubuntu-24.04 - name: rockylinux-9 driver: image: dokken/rockylinux-9Le même fichier de test vérifie l'intention, pas le nom du paquet :
paquet = os.debian? ? 'apache2' : 'httpd'
describe package(paquet) do it { should be_installed }end
describe file('/var/www/html/index.html') do its('content') { should match(/Servi par #{paquet}/) }endSur Ubuntu :
* apt_package[apache2] action install ✔ is expected to be installed ✔ content is expected to match /Servi par apache2/
Test Summary: 2 successful, 0 failures, 0 skippedSur Rocky Linux, sans changer une seule ligne de la recette :
* dnf_package[httpd] action install ✔ is expected to be installed ✔ content is expected to match /Servi par httpd/
Test Summary: 2 successful, 0 failures, 0 skippedDeux familles, deux gestionnaires de paquets, deux noms de paquets, une seule recette. C'est la portabilité que Chef promet, à condition de lui donner la table de correspondance qu'il ne peut pas deviner.
Les attributs qu'on utilise vraiment
Section intitulée « Les attributs qu'on utilise vraiment »Ohai en collecte des centaines, mais une poignée suffit au quotidien.
| Attribut | Ce qu'il donne |
|---|---|
node['platform_family'] | La famille : le premier réflexe de portabilité |
node['platform'] | La distribution précise |
node['platform_version'] | Sa version (24.04, 9.4) |
node['os'] | linux, windows, darwin |
node['kernel']['release'] | La version du noyau |
node['ipaddress'] | L'adresse principale |
node['memory']['total'] | La mémoire, pour dimensionner |
Le dernier est souvent sous-estimé : il permet de calculer une valeur de configuration au lieu de la coder en dur, par exemple le nombre de processus d'un serveur web selon la mémoire réellement disponible.
Dépannage
Section intitulée « Dépannage »Les erreurs de portabilité se ressemblent toutes : Chef a fait son travail, mais la donnée ne correspondait pas à la machine.
| Symptôme | Cause probable | Solution |
|---|---|---|
No candidate version available for apache2 | Nom de paquet en dur, machine RHEL | value_for_platform_family |
| La recette casse sur une nouvelle distribution | Condition écrite sur platform | Passer à platform_family |
undefined method '[]' for nil sur un attribut Ohai | L'attribut n'existe pas sur cette plateforme | Vérifier avec cinc-shell, prévoir un repli |
| Le chemin de configuration est faux | Il diffère selon la famille | Le sortir dans une table comme le nom du paquet |
| Le service échoue en conteneur | Pas d'init, symptôme variable selon la famille | Valider les services sur une VM |
À retenir
Section intitulée « À retenir »- Ohai interroge la machine avant la convergence et remplit
node: vous n'avez rien à faire pour l'obtenir. platformest la distribution (ubuntu),platform_familyest la famille (debian). Testez la famille.- Chef choisit déjà le bon outil :
packagedevientapt_packageoudnf_packagesans que vous l'écriviez. - Mais il ne devinera jamais vos données :
apache2chez Debian,httpdchez RHEL. value_for_platform_familyest la table de correspondance qui rend la recette portable.- Un nom de paquet en dur est une bombe à retardement : invisible tant qu'on ne déploie qu'une famille.
- Prouvez la portabilité en convergeant les deux familles dans Test Kitchen : même recette, même test, deux verts.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Panorama des outils de gestion de configuration : comment Ansible et Salt traitent la même question.