Quelle est la différence entre les valeurs par défaut et les variables dans un rôle Ansible?

151

Lors de la création d'un nouveau rôle Ansible, le modèle crée à la fois un varset un defaultsrépertoire avec un main.ymlfichier vide . Lors de la définition de mon rôle, je peux placer des définitions de variables dans l'un ou l'autre de ces éléments, et elles seront disponibles dans mes tâches.

Quelle est la différence entre mettre les définitions dans defaultset vars? Qu'est-ce qui devrait entrer defaultset que devrait entrer vars? Est-il judicieux d'utiliser les deux pour les mêmes données?

Je sais qu'il y a une différence de priorité / priorité entre les deux, mais j'aimerais comprendre ce qui devrait aller où.

Disons que mon rôle créerait une liste de répertoires sur le système cible. Je voudrais fournir une liste de répertoires par défaut à créer, mais je voudrais permettre à l'utilisateur de les remplacer lors de l'utilisation du rôle.

Voici à quoi cela ressemblerait:

---
- directories:
  - foo
  - bar
  - baz

Je pourrais placer cela dans le defaults/main.ymlou dans le vars/main.yml, du point de vue de l'exécution, cela ne ferait aucune différence - mais où devrait-il aller?

nwinkler
la source

Réponses:

113

La documentation Ansible sur la priorité des variables résume ce joli:

Si plusieurs variables du même nom sont définies à des endroits différents, elles gagnent dans un certain ordre, qui est:

  • les variables supplémentaires (-e dans la ligne de commande) gagnent toujours
  • puis vient les variables de connexion définies dans l'inventaire (ansible_ssh_user, etc)
  • puis vient "presque tout le reste" (commutateurs de ligne de commande, vars en jeu, vars inclus, variables de rôle, etc.)
  • puis vient le reste des variables définies dans l'inventaire
  • puis viennent les faits découverts sur un système
  • puis les "role defaults", qui sont les plus "defaulty" et perdent en priorité à tout.

Supposons donc vous avez un rôle de « tomcat » que vous utilisez pour installer Tomcat sur un tas de webhosts, mais vous devez les différentes versions de tomcat sur un hôte couple, ont besoin de fonctionner comme des utilisateurs différents dans d' autres cas, etc. Le defaults/main.ymlfichier pourrait ressembler quelque chose comme ça:

tomcat_version: 7.0.56
tomcat_user: tomcat

Comme ce ne sont que des valeurs par défaut, cela signifie qu'elles seront utilisées si ces variables ne sont définies nulle part ailleurs pour l'hôte en question. Vous pouvez les remplacer via extra-vars, via des faits dans votre fichier d'inventaire, etc. pour spécifier des valeurs différentes pour ces variables.

Edit: Notez que la liste ci-dessus concerne Ansible 1.x. Dans Ansible 2.x, la liste a été développée. Comme toujours, la documentation Ansible fournit une description détaillée de la priorité des variables pour 2.x.

Bruce P
la source
4
Merci, c'est une excellente page - c'est ce que je cherchais. Je vais beaucoup plus en détail sur ce qu'il faut mettre defaultset ce qu'il y a varsplus bas.
nwinkler
42
cela vaut la peine de souligner: les variables de rôle ont une priorité maléfique . d'après mon expérience, ils sont plus élevés que jouer aux vars, ce qui est vraiment ennuyeux.
tedder42
5 ans plus tard, mais ... j'ai tendance à regarder les choses de cette façon: les valeurs par défaut des rôles sont des choses que je m'attends à ce qu'un utilisateur du rôle écrase quelque part dans leur vars. Les variables de rôle, OTOH, me permettent d'éviter le codage en dur des informations dans une tâche, mais ne seront probablement remplacées que pour les tests et modifiées par un responsable de rôle. Par exemple, un nom d'utilisateur d'administrateur initial serait dans les valeurs par défaut, mais les versions de dépendance seraient dans vars.
ntwrkguru
41

Les variables de rôle définies dans varont une priorité très élevée - elles ne peuvent être écrasées qu'en les passant sur la ligne de commande, dans la tâche spécifique ou dans un bloc. Par conséquent, presque toutes vos variables doivent être définies dans defaults.

Dans l'article " Priorité variable - Où mettre votre rôle Vars ", l'auteur donne un exemple de ce qu'il faut mettrevars : des constantes spécifiques au système qui ne changent pas beaucoup. Ainsi, vous pouvez avoir vars/debian.ymlet vars/centos.ymlavec les mêmes noms de variables mais des valeurs différentes et les inclure conditionnellement.

Chiborg
la source
4

À mon humble avis , il est peu pratique et pas raisonnable que les lieux Ansible comme priorité la configuration dans vars des rôles . Configuration dans vars/main.ymletdefaults/main.yml devrait être faible et probablement la même priorité.

Existe-t-il des exemples concrets de cas où nous voulons ce type de comportement?

Il y a des exemples que nous ne voulons pas de cela.

Le point à souligner ici est que la configuration dans defaults/main.ymlne peut pas être dynamique. Configuration en vars/main.ymlcan. Ainsi, par exemple, vous pouvez inclure la configuration pour un système d'exploitation et une version spécifiques de manière dynamique, comme indiqué dans geerlingguy.postgresql

Mais parce que la priorité est si étrange et peu pratique dans Ansible, geerlingguy doit introduire des pseudo variables comme on peut le voir dans variables.yml

- name: Define postgresql_packages.
  set_fact:
    postgresql_packages: "{{ __postgresql_packages | list }}"
  when: postgresql_packages is not defined

Il s'agit d'un exemple concret de la vie réelle qui démontre que la préséance n'est pas pratique.

Un autre point à souligner ici est que nous voulons que les rôles soient configurables. Les rôles peuvent être externes, gérés par quelqu'un d'autre. En règle générale, vous ne voulez pas que la configuration des rôles ait une priorité élevée.

on sait
la source
Cela devrait être un commentaire, pas une réponse.
ntwrkguru
3

Fondamentalement, tout ce qui entre dans les «valeurs par défaut du rôle» (le dossier des valeurs par défaut à l'intérieur du rôle) est le plus malléable et le plus facile à remplacer. Tout ce qui se trouve dans le répertoire vars du rôle remplace les versions précédentes de cette variable dans l'espace de noms. L'idée ici à suivre est que plus vous obtenez explicite dans la portée, plus cela prend de priorité avec la ligne de commande -e extra vars toujours gagnante. Les variables d'hôte et / ou d'inventaire peuvent l'emporter sur les valeurs par défaut des rôles, mais pas sur les inclusions explicites comme le répertoire vars ou une tâche include_vars. doc

Pauljolsen
la source
-4

Les variables et les valeurs par défaut vont de pair. voici un exemple

-name: install package
 yum: name=xyz{{package_version}} state=present

dans votre fichier par défaut, vous auriez quelque chose comme:

package_version: 123

Ce que ansible fera, c'est qu'il prendra la valeur de package_versionet le placera à côté du nom du paquet pour qu'il se lise quelque part comme suit:

-name: install package
 yum: name=xyz123 state=present

De cette façon, il s'installera xyz123et non xyz123.4ou quoi que ce soit dans le grand référentiel de xyz.

A la fin ça fera yum install -y xyz123

Donc, fondamentalement, les valeurs par défaut sont les valeurs présentes, si vous ne définissez pas de valeur spécifique pour les variables, car cet espace ne peut pas rester vide.

qubsup
la source
Évalué car il ne répond pas à la question. Évidemment, ils defaultssont utilisés lorsqu'il n'y a pas de varsdéfinition, mais la réponse n'explique pas, pourquoi vous définiriez une valeur comme l'une ou l'autre, ce que le PO a demandé. Comparez avec l'explication ci-dessous.
Thomas Hirsch