
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.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- 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.
Prérequis
Section intitulée « Prérequis »- Structurer un cookbook lu, et les attributs et templates maîtrisés.
- La VM
web1et le dépôt~/chef-parcavec son.chef/config.rb(du guide de déploiement).
Pourquoi une ressource personnalisée
Section intitulée « Pourquoi une ressource personnalisée »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.
Définir la ressource : propriétés et action
Section intitulée « Définir la ressource : propriétés et action »Les ressources personnalisées vivent dans le dossier resources/ du cookbook. Créez resources/site_web.rb :
property :racine, String, required: trueproperty :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 endendDeux 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;}Utiliser sa ressource dans une recette
Section intitulée « Utiliser sa ressource dans une recette »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 :updateend
package 'nginx'
monparc_site_web 'blog' do racine '/var/www/blog' port 8080end
monparc_site_web 'docs' do racine '/var/www/docs' port 8081end
service 'nginx' do action [:enable, :start]endOn déploie sur la VM web1 : le cookbook monparc dans ~/chef-parc/cookbooks/, le run list pointé dessus, puis on converge :
knife node run_list set web1 'recipe[monparc::default]' -c .chef/config.rbknife zero converge 'name:web1' -c .chef/config.rbLa 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 reloadInfra Phase complete, 12/17 resources updated in 03 secondsLes 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 :
curl http://192.168.122.167:8080/curl http://192.168.122.167:8081/Site blog sur le port 8080Site docs sur le port 8081Un 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.
Ressource personnalisée ou recette ?
Section intitulée « Ressource personnalisée ou recette ? »Les deux contiennent des ressources, mais ne jouent pas le même rôle.
| Recette | Ressource personnalisée | |
|---|---|---|
| Rôle | Décrire une machine (un serveur web) | Un bloc réutilisable paramétrable |
| Appel | Une fois, via le run list | Plusieurs fois, avec des propriétés |
| Paramètres | Attributs de nœud | Proprié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.
Exercice : ajouter un titre
Section intitulée « Exercice : ajouter un titre »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.
On déclare la propriété et on l'utilise dans le contenu :
property :titre, String, default: 'Bienvenue'
# ... dans l'action :createfile "#{new_resource.racine}/index.html" do content "#{new_resource.titre}\n" mode '0644'endPuis on passe un titre à l'appel :
monparc_site_web 'blog' do racine '/var/www/blog' port 8080 titre 'Mon blog'endLa page de blog affiche désormais Mon blog. Une propriété de plus, et la ressource gagne en souplesse sans que la recette se complique.
À retenir
Section intitulée « À retenir »- Une ressource personnalisée encapsule un motif récurrent de ressources, réutilisable comme une ressource native.
- Elle vit dans
resources/; le fichierresources/site_web.rbdu cookbookmonparcdonne la ressourcemonparc_site_web. - Les
propertydéclarent les paramètres (type,required,default) ; l'actiondécrit le travail, en lisantnew_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.