Aller au contenu
Infrastructure as Code medium

Créer des ressources personnalisées Chef

9 min de lecture

logo chef

Quand le même bloc de ressources revient dans plusieurs recettes, on le transforme en ressource réutilisable. Une ressource personnalisée (custom resource) encapsule un motif (créer un répertoire, générer une config, ...) derrière un nom et des propriétés, exactement comme les ressources natives package ou file. Ce guide construit une ressource site_web et l'utilise deux fois pour déployer deux sites sur la vraie VM web1 via knife-zero. Public visé : lecteur ayant lu structurer un cookbook. Testé avec CINC Client 19.3.14 et knife-zero 2.6.0 sur une VM Debian 13.

  • Définir une ressource personnalisée avec des propriétés et une action.
  • Encapsuler un motif récurrent de ressources.
  • Utiliser votre ressource dans une recette, plusieurs fois.
  • Distinguer une ressource personnalisée d'une recette.

Imaginez déployer trois sites web. Chacun demande un répertoire, une page, un fichier de configuration nginx. Sans ressource personnalisée, vous copiez-collez le même trio trois fois, en changeant juste le nom et le port. Le jour où le motif évolue, il faut corriger partout.

Une ressource personnalisée résout ça : vous décrivez le motif une fois, avec des trous à remplir (les propriétés), puis vous l'appelez autant de fois que nécessaire. C'est le même principe que les ressources natives, appliqué à votre logique métier.

Les ressources personnalisées vivent dans le dossier resources/ du cookbook. Créez resources/site_web.rb :

property :racine, String, required: true
property :port, Integer, default: 80
action :create do
directory new_resource.racine do
recursive true
mode '0755'
end
file "#{new_resource.racine}/index.html" do
content "Site #{new_resource.name} sur le port #{new_resource.port}\n"
mode '0644'
end
template "/etc/nginx/conf.d/#{new_resource.name}.conf" do
source 'site.conf.erb'
variables(port: new_resource.port, racine: new_resource.racine)
notifies :reload, 'service[nginx]', :delayed
end
end

Deux notions structurent ce fichier. Les property déclarent les paramètres : racine est une chaîne obligatoire (required: true), port un entier avec une valeur par défaut (default: 80). L'action :create décrit ce que fait la ressource : elle enchaîne des ressources natives, en lisant les propriétés via new_resource (new_resource.racine, new_resource.port). Le new_resource.name reprend le nom donné à l'appel. Le notifies :reload recharge nginx quand un vhost change : indispensable sur une vraie VM, où nginx tourne déjà avant que la config n'existe.

Le template templates/site.conf.erb génère le vhost à partir des propriétés :

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

Dans recipes/default.rb, on appelle la ressource comme n'importe quelle ressource native, deux fois, avec des propriétés différentes :

apt_update 'mise a jour du cache' do
action :update
end
package 'nginx'
monparc_site_web 'blog' do
racine '/var/www/blog'
port 8080
end
monparc_site_web 'docs' do
racine '/var/www/docs'
port 8081
end
service 'nginx' do
action [:enable, :start]
end

On déploie sur la VM web1 : le cookbook monparc dans ~/chef-parc/cookbooks/, le run list pointé dessus, puis on converge :

Fenêtre de terminal
knife node run_list set web1 'recipe[monparc::default]' -c .chef/config.rb
knife zero converge 'name:web1' -c .chef/config.rb

La sortie montre la ressource personnalisée qui déploie ses ressources internes, une fois pour blog, une fois pour docs :

Recipe: monparc::default
* apt_package[nginx] action install
* monparc_site_web[blog] action create
* directory[/var/www/blog] action create
* file[/var/www/blog/index.html] action create
* template[/etc/nginx/conf.d/blog.conf] action create
* monparc_site_web[docs] action create
* directory[/var/www/docs] action create
* file[/var/www/docs/index.html] action create
* template[/etc/nginx/conf.d/docs.conf] action create
* service[nginx] action enable (up to date)
* service[nginx] action start
* service[nginx] action reload
Infra Phase complete, 12/17 resources updated in 03 seconds

Les ressources internes sont indentées sous chaque appel : c'est l'encapsulation en action, et le reload en fin de run applique les deux vhosts. Vérifiez que les deux sites répondent, chacun sur son port :

Fenêtre de terminal
curl http://192.168.122.167:8080/
curl http://192.168.122.167:8081/
Site blog sur le port 8080
Site docs sur le port 8081

Un second knife zero converge 'name:web1' -c .chef/config.rb ne recrée rien : la ressource personnalisée est idempotente, car les ressources natives qu'elle contient le sont.

Les deux contiennent des ressources, mais ne jouent pas le même rôle.

RecetteRessource personnalisée
RôleDécrire une machine (un serveur web)Un bloc réutilisable paramétrable
AppelUne fois, via le run listPlusieurs fois, avec des propriétés
ParamètresAttributs de nœudPropriétés typées

La règle : dès qu'un motif de ressources se répète avec des variantes, c'est une ressource personnalisée. Elle remplace les anciens mécanismes LWRP et definitions, qu'on ne rencontre plus que dans de vieux cookbooks.

Enrichissez la ressource. Cherchez la solution avant d'ouvrir la réponse.

Ajoutez une propriété titre (chaîne, avec une valeur par défaut) à la ressource site_web, et servez-vous-en pour le contenu de la page. Appelez ensuite un site avec un titre personnalisé.

Indice : une property de plus, lue via new_resource.titre.

  • Une ressource personnalisée encapsule un motif récurrent de ressources, réutilisable comme une ressource native.
  • Elle vit dans resources/ ; le fichier resources/site_web.rb du cookbook monparc donne la ressource monparc_site_web.
  • Les property déclarent les paramètres (type, required, default) ; l'action décrit le travail, en lisant new_resource.
  • On l'appelle plusieurs fois avec des propriétés différentes ; elle reste idempotente.
  • Une recette décrit une machine ; une ressource personnalisée est un bloc réutilisable. Elle remplace les vieux LWRP et definitions.

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