Aller au contenu
Infrastructure as Code medium

Déboguer Chef : lire une erreur, simuler, inspecter un nœud

11 min de lecture

Logo Chef

Une convergence qui échoue crache des dizaines de lignes rouges, une stacktrace et un message demandant d'ouvrir un rapport de bug. Le réflexe du débutant est de paniquer, ou de tout relire. C'est inutile : Chef vous dit déjà exactement quelle ligne a échoué, à condition de savoir où regarder. Ce module apprend à lire une erreur en trente secondes, à simuler avant d'appliquer, et à inspecter un nœud sans rien exécuter. Public visé : débutants ayant déjà convergé un cookbook.

  • Lire une erreur de convergence et trouver la ligne fautive.
  • Distinguer erreur de compilation et erreur d'exécution.
  • Simuler une convergence avec why-run.
  • Inspecter les attributs d'un nœud avec cinc-shell.

Prenons une faute que tout le monde commet : lire un attribut qui n'existe pas.

port = node['appli']['port'] # cet attribut n'existe pas
file '/tmp/appli.conf' do
content "port=#{port}\n"
end

La convergence échoue, et Chef affiche un pavé. Ignorez la fin, qui vous demande d'ouvrir un rapport de bug : la réponse est au début.

Recipe Compile Error in .../cookbooks/casse/recipes/default.rb
================================================================================
NoMethodError
-------------
undefined method '[]' for nil
Cookbook Trace: (most recent call first)
----------------------------------------
.../cookbooks/casse/recipes/default.rb:1:in 'Chef::Mixin::FromFile#from_file'
Relevant File Content:
----------------------
1>> port = node['appli']['port'] # cet attribut n'existe pas
2:
3: file '/tmp/appli.conf' do

Trois blocs vous suffisent, et dans cet ordre.

Le type d'erreur (NoMethodError: undefined method '[]' for nil) dit quoi : vous avez appelé quelque chose sur nil. Puisque node['appli'] n'existe pas, il vaut nil, et demander ['port'] à nil explose.

La Cookbook Trace dit , et c'est le bloc le plus précieux : elle ne liste que vos fichiers, pas les entrailles de Chef. Ici, ligne 1 de votre recette.

Le Relevant File Content vous montre la ligne, marquée d'un 1>>. Vous n'avez même pas besoin d'ouvrir votre éditeur.

Compilation ou exécution : deux erreurs très différentes

Section intitulée « Compilation ou exécution : deux erreurs très différentes »

Le message dit Recipe Compile Error, et ce détail change tout. Chef travaille en deux phases, et savoir laquelle a échoué oriente la recherche.

PhaseCe qui s'y passeMessage d'erreur typique
CompilationChef lit vos recettes et construit la liste des ressourcesRecipe Compile Error
ExécutionChef applique les ressources une par uneError executing action ... on resource

Une erreur de compilation signifie que Chef a buté en lisant votre code : attribut absent, faute de Ruby, cookbook introuvable. Aucune ressource n'a été appliquée, la machine est intacte.

Une erreur d'exécution signifie que le code était valide mais que l'action a échoué sur la machine : paquet inexistant, service qui refuse de démarrer, permission refusée. Là, des ressources précédentes ont pu s'appliquer, et la machine est dans un état intermédiaire.

Avec cette correction, la convergence passe :

Infra Phase complete, 1/1 resources updated in 00 seconds
port=8080

Avant de lancer une convergence sur une machine qui compte, on veut savoir ce qui va changer. Le mode --why-run exécute la recette sans rien modifier et annonce ses intentions.

Fenêtre de terminal
sudo cinc-client -z --why-run -o 'recipe[webstack]'
- Would force update new lists of packages
- Would install version 1.24.0-2ubuntu7.13 of package nginx
- Would create new directory /var/www/webstack
- Would change mode from '' to '0755'
- Would create new file /etc/nginx/conf.d/webstack.conf

Le conditionnel (« Would ») est explicite : rien n'a été touché. Vous savez maintenant que ce cookbook installerait nginx dans une version précise et créerait ces fichiers.

why-run a une limite structurelle qu'il faut absolument connaître : comme il n'applique rien, les ressources suivantes raisonnent sur une machine inchangée. Une garde (only_if, not_if) qui dépend d'une ressource précédente est donc évaluée à tort.

Prenons une recette qui installe un paquet, puis utilise le binaire qu'il apporte :

package 'tree'
execute 'utiliser le binaire installé' do
command 'tree --version > /tmp/tree-version.txt'
only_if { ::File.exist?('/usr/bin/tree') }
end

Sur une machine où tree n'est pas installé, voici ce que why-run annonce :

* apt_package[tree] action install
- Would install version 2.2.1-1 of package tree
* execute[utiliser le binaire installé] action run (skipped due to only_if)
Infra Phase complete, 1/2 resources would have been updated

Il prétend que l'execute sera ignoré. Voici ce que fait la convergence réelle :

* apt_package[tree] action install
- install version 2.2.1-1 of package tree
* execute[utiliser le binaire installé] action run
- execute tree --version > /tmp/tree-version.txt
Infra Phase complete, 2/2 resources updated in 01 seconds

1/2 annoncé, 2/2 en réalité. Le paquet ayant été vraiment installé, la garde devient vraie et la commande s'exécute.

Inspecter un nœud sans rien exécuter : cinc-shell

Section intitulée « Inspecter un nœud sans rien exécuter : cinc-shell »

Vous voulez savoir ce que Chef voit de la machine : quelle plateforme, quelle famille, combien de mémoire. Nul besoin de converger : cinc-shell ouvre un interpréteur avec le nœud déjà chargé.

Fenêtre de terminal
cinc-shell
node['platform']
node['platform_family']
node['kernel']['release']
=> "ubuntu"
=> "debian"
=> "6.8.0-134-generic"

C'est l'outil idéal pour vérifier un attribut avant de l'utiliser, plutôt que de découvrir en pleine convergence qu'il valait nil. Notez au passage la distinction entre platform (ubuntu) et platform_family (debian) : c'est presque toujours la famille qu'il faut tester dans une recette.

Quand rien de tout cela ne suffit, -l debug montre tout ce que Chef fait : chargement d'Ohai, résolution des cookbooks, décision de chaque ressource.

Fenêtre de terminal
sudo cinc-client -z -l debug -o 'recipe[webstack]'
DEBUG: Running Ohai with the following configuration: {logger: Chef::Log}
DEBUG: The plugin path /etc/chef/ohai/plugins does not exist. Skipping...
DEBUG: Plugin Network: Parsing ethtool output: Features for enp1s0:

Le volume est considérable, et c'est précisément pourquoi il ne faut pas commencer par là. Réservez-le aux cas où le comportement est inexplicable : une ressource qui se rejoue sans raison, un attribut écrasé par on ne sait quoi.

Voici les erreurs les plus fréquentes, et le réflexe qui va avec.

SymptômeCause probableRéflexe
NoMethodError: undefined method '[]' for nilUn attribut absent vaut nilnode.dig(...) avec une valeur de repli
Recipe Compile ErrorChef a buté en lisant le codeLa machine est intacte : lire la Cookbook Trace
Error executing action ... on resourceL'action a échoué sur la machineDes ressources précédentes ont pu s'appliquer
Un mur rouge illisibleOn lit au mauvais endroitLire le début : type d'erreur, Cookbook Trace, 1>>
why-run annonce moins que la réalitéLes gardes sont évaluées sur une machine inchangéeAttendu : il sous-estime, ne concluez pas « rien à faire »
Un attribut ne vaut pas ce qu'on croitPriorité ou nom différentcinc-shell et lire la valeur réelle
  1. La réponse est au début du message d'erreur, pas à la fin : type d'erreur, Cookbook Trace, puis la ligne marquée 1>>.
  2. La Cookbook Trace ne liste que vos fichiers : c'est le bloc le plus utile.
  3. La stacktrace n'apprend rien de plus : sa première ligne est déjà à l'écran.
  4. Recipe Compile Error : la machine est intacte. Error executing action : elle est dans un état intermédiaire.
  5. Un attribut absent vaut nil sans prévenir : utilisez node.dig avec une valeur de repli.
  6. why-run sous-estime : une garde dépendant d'une ressource précédente est évaluée à tort (1/2 annoncé, 2/2 en réalité). C'est un indicateur, pas une preuve.
  7. cinc-shell inspecte les attributs sans rien exécuter ; -l debug est le dernier recours.

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