Puppet : portée des variables (scope and Puppet)



  • Si vous utilisez une version récente de Puppet (> 2.7) ou si vous envisagez de mettre à jour, il est peut-être temps de faire du ménage dans vos variables et dans la façon dont vous les déclarez. A partir de la version 2.7, vous risquez de voir apparaître un certain nombre de message pour vous encourager à ne plus utiliser des “variables dynamiques” (dynamic lookup) et d’utiliser des variables qualifiées. Dans les prochaines versions, si vous ne faites rien, vos variables auront “undefined” pour valeur ! Basé sur le grand ménage du lundi dans mes modules, voici les warnings sur lesquels je suis tombé et les corrections que j’ai dû apporter.

    Warning !

    Les erreurs que vous pouvez rencontrer dans vos logs :

    Jun  4 01:23:24 1.2.3.4 puppet-master[9767]: Currently $fqdn is "my.host"
    Jun  4 01:23:24 1.2.3.4 puppet-master[9767]: In the future $fqdn will be undefined
    Jun  4 02:05:51 1.2.3.4 puppet-master[20719]: Dynamic lookup of $fqdn at /etc/puppet/modules/common/manifests/config.pp:24 is deprecated. For more information, see http://docs.puppetlabs.com/guides/scope_and_puppet.html. To see the change in behavior, use the --debug flag.
    

    Quand une variable n’est pas correctement définie dans un manifest, vous avez la ligne à corriger directement dans le log (ligne 24 du config.pp). C’est plus délicat pour retrouver les variables à corriger dans les templates…

    Corrigez vos manifests

    Dans vos manifests, on va retrouver principalement deux types de variables : celles que vous définissez et les facts. Les facts sont des variables “globales” : des top-scope variables. Pour ces variables c’est simple, elles sont toujours précédées de “::”.

    Exemples :

    • $fqdn, que nous avons vu en warning dans mon log plus haut, devient $::fqdn
    • $ipaddress deviendra $::ipaddress

    En clair, tous les facts que vous retrouverez via la commande facter devront être appelés via $::fact dans vos manifests.

    Dans les autres cas, si vous souhaitez utiliser une variable définie dans une autre classe, un autre module, indiquez explicitement son chemin complet. Par exemple, vous avez un module common avec une classe config dans laquelle est définie la variable myvar : plutôt que d’y accéder via $myvar, utilisez $common::config::myvar. Utilisez la syntaxe $myvar uniquement pour les variables locales (par exemple une variable d’une classe paramétrée).

    Corrigez vos templates

    Dans un template, la syntaxe suivante était utilisée :

    Ma variable myvar définie dans le manifeste qui appelle ce template a pour valeur <%= myvar %>.
    Si je veux utiliser un fact, c'est le même principe : <%= fqdn %>
    
    • Pour les facts, c’est simple, il faut préfixer la variable par un “@”. Par exemple <%= fqdn %> devient <%= @fqdn %>.
    • Pour vos variables, si elle est déclarée dans le manifest qui appelle le template, utilisez également le “@”.
    • Dans le cas ou vous souhaitez accéder à une variable définie en dehors du manifest actuel, en dehors du scope local, utilisez la fonction scope.lookupvar :
    <%= scope.lookupvar('common::config::myvar') %>
    
    • Vous pouvez valider votre template via :
    erb -P -x -T '-' mytemplate.erb | ruby -c
    

    Vous êtes prêt pour les prochaines versions de Puppet. Voici les articles qui m’ont aidé à faire le ménage dans mes modules :
    http://docs.puppetlabs.com/guides/scope_and_puppet.html
    http://docs.puppetlabs.com/guides/templating.html