Aller au contenu
Infrastructure as Code medium

Templates et fichiers dans un cookbook Chef

9 min de lecture

logo chef

Une configuration qui varie selon la machine ne peut pas être un fichier figé : un template la génère à partir des attributs. Chef distingue deux ressources : cookbook_file dépose un fichier statique tel quel, template génère un fichier à partir d'un modèle ERB et de variables. Et grâce à notifies, on recharge le service uniquement quand sa configuration a changé. Ce guide construit une config nginx dynamique de bout en bout. Public visé : lecteur ayant compris les attributs Chef. Testé avec CINC Client 19.3.14 et kitchen-dokken sur Ubuntu 24.04.

  • Déposer un fichier statique avec cookbook_file.
  • Générer une configuration avec la ressource template et des variables.
  • Injecter des valeurs dans un template ERB.
  • Recharger le service uniquement quand la configuration change.
  • Les attributs Chef compris.
  • Le cookbook siteweb des guides précédents, avec ses attributs et sa configuration dokken.

Deux ressources déposent un contenu dans un fichier, pour deux besoins différents.

RessourceContenuCas d'usage
cookbook_fileUn fichier statique, copié tel quelUn robots.txt, un script, un certificat public
templateUn fichier généré depuis un modèle ERBUne config qui dépend d'attributs (port, chemins)

La règle : si le contenu est toujours le même, cookbook_file ; s'il dépend du node, template.

Les fichiers statiques se rangent dans le dossier files/ du cookbook. Créez files/robots.txt :

User-agent: *
Disallow:

Puis, dans recipes/default.rb, déposez-le avec cookbook_file. La propriété source désigne le fichier dans files/, le nom de la ressource est le chemin de destination :

cookbook_file "#{node['siteweb']['racine']}/robots.txt" do
source "robots.txt"
mode "0644"
end

Les modèles se rangent dans le dossier templates/. Créez templates/nginx-siteweb.conf.erb, une config nginx où le port et la racine sont des trous à remplir :

server {
listen <%= @port %>;
server_name _;
root <%= @racine %>;
index index.html;
}

<%= @port %> et <%= @racine %> sont de l'ERB : <%= ... %> insère la valeur d'une variable. Ces variables ne sont pas magiques, on les passe explicitement à la ressource template :

template "/etc/nginx/conf.d/siteweb.conf" do
source "nginx-siteweb.conf.erb"
variables(port: node['siteweb']['port'], racine: node['siteweb']['racine'])
notifies :reload, "service[nginx]", :delayed
end

La propriété variables transmet un couple clé-valeur ; dans le template, la clé port devient @port. On alimente donc le template avec les attributs vus au guide précédent.

La ligne clé est notifies :reload, "service[nginx]", :delayed. Elle dit : « quand cette ressource change, recharge le service nginx, à la fin du run ». Le :delayed regroupe les rechargements en une seule fois, après toutes les modifications. Déclarez la ressource service que le template notifie :

service "nginx" do
action [:enable, :start]
end

Appliquez la recette complète :

Fenêtre de terminal
kitchen converge
Converging 6 resources
Recipe: siteweb::default
* apt_package[nginx] action install
* directory[/var/www/siteweb] action create
* file[/var/www/siteweb/index.html] action create
* template[/etc/nginx/conf.d/siteweb.conf] action create
- create new file /etc/nginx/conf.d/siteweb.conf
+server {
+ listen 8080;
+ server_name _;
+ root /var/www/siteweb;
+ index index.html;
+}
* cookbook_file[/var/www/siteweb/robots.txt] action create
- create new file /var/www/siteweb/robots.txt
* service[nginx] action enable (up to date)
* service[nginx] action start
* service[nginx] action reload
- reload service service[nginx]
Infra Phase complete, 7/8 resources updated in 03 seconds

Le template a rendu les attributs (listen 8080, root /var/www/siteweb), le fichier statique est déposé, et le service a été rechargé parce que la config a changé. Vérifiez que la page répond sur le port généré :

Fenêtre de terminal
kitchen exec -c "curl -s localhost:8080"
Mon site

Relancez la convergence :

Fenêtre de terminal
kitchen converge
Infra Phase complete, 0 resources updated in 01 seconds

Aucune ressource mise à jour, et surtout aucun reload : le template n'a pas changé, donc notifies n'a rien déclenché. C'est tout l'intérêt de la notification : on ne redémarre un service que lorsque c'est réellement nécessaire, jamais à chaque exécution.

Chef sait où chercher grâce à deux dossiers conventionnels du cookbook.

siteweb/
├── attributes/
│ └── default.rb # les valeurs (port, racine...)
├── files/
│ └── robots.txt # source de cookbook_file
├── templates/
│ └── nginx-siteweb.conf.erb # source de template
└── recipes/
└── default.rb # les ressources

Exercice : changer le port et déclencher un reload

Section intitulée « Exercice : changer le port et déclencher un reload »

Prouvez que la notification fait bien son travail. Cherchez la solution avant d'ouvrir la réponse.

Faites passer le site sur le port 8090 sans toucher au template ni à la recette. Convergez : le template doit être réécrit et le service rechargé.

Indice : le port est un attribut ; surchargez-le comme au guide précédent.

  • cookbook_file dépose un fichier statique (dans files/) ; template génère un fichier depuis un modèle ERB (dans templates/).
  • En ERB, <%= valeur %> affiche, <% code %> exécute sans afficher.
  • La propriété variables passe les valeurs au template ; la clé port devient @port dans le modèle.
  • notifies :reload, "service[nginx]", :delayed recharge le service seulement quand la ressource change.
  • L'idempotence tient : un second passage ne recharge pas un service dont la config n'a pas bougé.

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