Aller au contenu
Infrastructure as Code medium

CI/CD des cookbooks Chef : lint, tests et pipeline durci

10 min de lecture

Logo Chef

Sur votre poste, vous pensez à lancer Cookstyle et ChefSpec. En équipe, un jour, quelqu'un oubliera, et le cookbook fautif partira en production. Ce module transforme ces contrôles en barrière automatique : un pipeline GitHub Actions qui lint et teste chaque modification, et bloque la fusion en cas d'échec. Vous durcirez aussi le pipeline lui-même, car un workflow mal écrit est une porte d'entrée dans votre chaîne de livraison. Public visé : intermédiaires ayant pratiqué Cookstyle et ChefSpec.

  • Faire tourner Cookstyle et ChefSpec en intégration continue.
  • Bloquer la fusion quand un contrôle échoue.
  • Durcir le pipeline lui-même.
  • Situer les tests d'intégration dans la chaîne.

Un contrôle automatique n'a d'intérêt que s'il échoue quand il le doit. Vérifions d'abord que nos deux outils bloquent vraiment.

Cookstyle ne se contente pas de compter les espaces : il détecte aussi les dépréciations. Sur un cookbook non nettoyé, il sort avec un code d'erreur :

Fenêtre de terminal
cookstyle .
echo "code de sortie : $?"
10 files inspected, 34 offenses detected, 34 offenses autocorrectable
code de sortie : 1

Parmi ces remontées, une vraie faute de fond :

spec/spec_helper.rb:7:1: W: Chef/Deprecations/ChefSpecCoverageReport:
Don't use the deprecated ChefSpec coverage report functionality in your specs.

C'est exactement ce qu'on attend d'une CI : elle attrape ce que l'oeil laisse passer. La correction automatique règle le gros du lot :

Fenêtre de terminal
cookstyle -a .
cookstyle .
10 files inspected, 35 offenses detected, 35 offenses corrected
10 files inspected, no offenses detected

Code 0 : le pipeline peut passer au vert. ChefSpec, lui, valide la logique des recettes en une fraction de seconde, sans machine :

webstack::install
met a jour le cache apt
installe le paquet nginx
Finished in 0.12 seconds
8 examples, 0 failures

Le workflow tient en deux jobs indépendants : le lint et les tests unitaires. Tous deux tournent dans l'image CINC Workstation, qui embarque déjà cookstyle et chef exec rspec : rien à installer, et l'environnement de CI est identique à celui du poste.

.github/workflows/cookbook.yml
name: Cookbook
on:
push:
branches: [main]
pull_request:
permissions: {}
jobs:
lint:
name: Cookstyle
runs-on: ubuntu-latest
container:
image: cincproject/workstation@sha256:aefb66a55c5651ae8e1aae4ed21c8c8416a880d0b2e8d9b0deb5695d0bd0f6ad
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Analyser le style et les depreciations
run: cookstyle .
unit:
name: ChefSpec
runs-on: ubuntu-latest
container:
image: cincproject/workstation@sha256:aefb66a55c5651ae8e1aae4ed21c8c8416a880d0b2e8d9b0deb5695d0bd0f6ad
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Tests unitaires des recettes
run: chef exec rspec --format documentation

Chaque outil sortant en code non nul quand il échoue, aucune configuration supplémentaire n'est nécessaire : GitHub marque le job en rouge, et la règle de protection de branche empêche alors la fusion. La barrière est là.

Un pipeline exécute du code avec des droits sur votre dépôt. C'est une cible. Quatre décisions, visibles dans le workflow ci-dessus, le rendent difficile à détourner.

permissions: {} retire tous les droits par défaut du jeton, et on ne réaccorde ensuite que le strict nécessaire. Un workflow compromis ne peut alors rien écrire.

Les actions sont épinglées par SHA de commit, pas par tag. Un tag comme v7 peut être redéplacé par son auteur ou un attaquant : le SHA, lui, désigne un contenu immuable. Le commentaire # v7.0.0 garde la lisibilité.

persist-credentials: false empêche checkout de laisser le jeton Git sur le disque du runner, où une dépendance malveillante pourrait le récupérer.

L'image du conteneur est épinglée par digest (@sha256:...), et non par latest. Une image latest peut changer sous vos pieds : le digest garantit que la CI d'aujourd'hui exécute exactement ce qu'elle exécutait hier.

On ne se relit pas soi-même. Quatre outils analysent un workflow et trouvent ce qu'on ne voit plus. Ils sont complémentaires : chacun attrape ce que les autres laissent passer.

OutilCe qu'il vérifie
actionlintLa syntaxe du workflow et des expressions
zizmorLes failles de sécurité GitHub Actions (injections, droits)
poutineLes risques de chaîne de livraison (exécution non fiable, secrets)
plumberLa confiance dans les composants tiers : actions et images
Fenêtre de terminal
actionlint .github/workflows/cookbook.yml
zizmor .github/workflows/cookbook.yml
poutine analyze_local .
plumber analyze

Sur le workflow ci-dessus, les quatre passent, et plumber résume la posture :

Plumber Score : 100 / 100 pts
Critical 0 High 0 Medium 0 Low 0

Il manque une marche, et il faut être honnête sur ce point. ChefSpec valide ce que la recette déclare ; il ne prouve pas que la machine finit dans le bon état. Cette preuve, c'est le rôle d'InSpec, et elle exige une vraie machine convergée.

Deux stratégies s'offrent à vous, selon vos moyens.

La CI peut monter elle-même une machine jetable (Test Kitchen), converger, puis lancer InSpec. C'est la boucle la plus complète, mais elle est lente (des minutes) et suppose un runner capable de lancer des conteneurs ou des VM. On la réserve souvent à une exécution nocturne, pas à chaque commit.

Plus simplement, InSpec s'exécute après le déploiement, contre la machine réellement convergée. Le pipeline valide alors la cohérence du cookbook (rapide, à chaque commit), et le déploiement valide le résultat (une fois, sur la vraie cible).

Retenez la répartition : Cookstyle et ChefSpec en CI, à chaque changement ; InSpec après convergence, là où l'état réel existe.

Un pipeline qui échoue vous apprend quelque chose ; encore faut-il traduire le message. Les cas les plus fréquents :

SymptômeCause probableSolution
La CI est verte mais le cookbook casse en prodSeul ChefSpec tourne, il ne teste pas l'état réelAjouter InSpec après la convergence
cookstyle échoue sur des broutilles de styleComportement attenducookstyle -a corrige automatiquement
Chef/Deprecations/... en CILe cookbook utilise une fonctionnalité dépréciéeLa retirer : elle disparaîtra dans une version future
Le job ne trouve pas chef ou cookstyleL'image du conteneur n'est pas CINC WorkstationVérifier l'image: du job
La CI passe soudain au rouge sans changement du codeUne action ou une image non épinglée a bougéÉpingler par SHA et digest

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  1. Un contrôle n'est une barrière que s'il échoue : cookstyle sort en code 1, ce qui bloque le job.
  2. Cookstyle attrape aussi les dépréciations, pas seulement le style.
  3. L'image CINC Workstation donne en CI le même environnement que sur le poste, sans rien installer.
  4. permissions: {}, actions épinglées par SHA, persist-credentials: false et image par digest : quatre décisions qui durcissent le pipeline.
  5. Un tag (v7, latest) n'est pas une version : il peut être redéplacé.
  6. Faites tourner actionlint, zizmor, poutine et plumber : chacun voit ce que les autres ratent.
  7. ChefSpec en CI, InSpec après convergence : ils ne répondent pas à la même question.

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