Forum général.général [Ansible] : changement conditionnel de la valeur d'une variable

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
0
7
avr.
2017

Je dispose dans un fichier group_vars/all.yml de deux variables ainsi que d'un booleen :

var_a
var_b
booleen

Je voudrais faire un truc du genre :

var_a: "{{ var_b if booleen|default(true)|bool == false}}"

ansible n'aime pas cette syntaxe:

the inline if-expression on line 1 evaluated to false and no else section was defined.

Cependant, lorsque j'essaie de faire
var_a: "{{ var_b if booleen|default(true)|bool == false else var_a}}"

voici ce qu'il me dit:

recursive loop detected in template string:

j'ai essayé de faire un truc du style toto=var_a et mettre toto à la place de var_a dans le test mais je ne peux rien faire.

A noter que je n'ai pas la main sur les roles/tasks qui seront exécutés derrière, je dois absolument modifier la valeur au niveau du playbook.

Une solution ?

  • # ne pas faire référence à soi-même

    Posté par  . Évalué à 4.

    Sans avoir vérifié dans le code d'ansible, je suppose que c'est un effet de bord de la façon dont sont implémentés les facts d'ansible.
    Il ne faut probablement pas voir ça comme une affectation de variable, qui ferait appel à son ancienne valeur, mais à une re-définition de la valeur, l'ancienne valeur n'étant plus disponible tu te retrouve avec une définition récursive qu'il ne peut pas résoudre.

    Mais tu ne dis pas à quel endroit tu essaie de re-définir cette variable.
    Est-ce dans une action set_facts?
    Ou peut-être dans une section vars d'une action, ou d'un block?

    Au passage, si ta variable booleen est déjà un … booléen, tu peux résumé ton test à "not booleen" (avec quand même de filtre default si la variable n'est pas définie pour tous les hosts), et en inversant le if on évite la négation.

    Au pire, si tu as vraiment besoin de re-définir la variable var_a, ça peut probablement se faire en deux temps:

    - set_fact:
        var_a_bis: "{{var_a if booleen|default(true) else var_b}}"
    - set_fact:
        var_a: "{{var_a_bis}}"

    Je n'ai pas testé, mais comme les actions s'exécutent séquentiellement, ça devrait le faire.

    • [^] # Re: ne pas faire référence à soi-même

      Posté par  . Évalué à 2. Dernière modification le 08 avril 2017 à 21:07.

      je suppose que c'est un effet de bord de la façon dont sont implémentés les facts d'ansible.
      Il ne faut probablement pas voir ça comme une affectation de variable, qui ferait appel à son ancienne valeur, mais à une re-définition de la valeur, l'ancienne valeur n'étant plus disponible tu te retrouve avec une définition récursive qu'il ne peut pas résoudre.

      C'est aussi ce que je me suis dit : au moins ça me rassure sur le diagnostic.

      Mais tu ne dis pas à quel endroit tu essaie de re-définir cette variable.

      Je croyais que si :

      Je dispose dans un fichier group_vars/all.yml de deux variables ainsi que d'un booleen :

      en gros j'ai un truc du genre :
      + plabook_dir
      | + group_vars
      | + all.yml
      + playbookA.yml
      + playbookB.yml

      Est-ce dans une action set_facts?

      Non

      Ou peut-être dans une section vars d'une action, ou d'un block?

      Voir au dessus. Je ne sais pas si c'est sufisamment précis …

      les playbooks A B etc … font appel à des rôles sur lesquels je n'ai pas la main, et mes playbooks sont appelés par un processus sur lequel je n'ai pas la main. Je dois juste insérer mon changement de variable entre les deux.

      Sinon pour ta solution je ne suis pas sur de pouvoir faire un set_facts au niveau du fichier group_var (je ne peux pas faire ce que je veux à ce niveau).

      En tout cas merci pour l'aide.

      • [^] # Re: ne pas faire référence à soi-même

        Posté par  . Évalué à 3.

        Ah, j'avais compris à l'envers, je croyais que tu ne pouvais pas modifier les variables des hosts et était obligé de les re-définir dans le playbook.
        Alors je ne vois pas bien le problème, met directement la bonne valeur puisque tu controlle la définition 'origine des variables.

        • [^] # Re: ne pas faire référence à soi-même

          Posté par  . Évalué à 2.

          Alors je ne vois pas bien le problème, met directement la bonne valeur puisque tu controlle la définition 'origine des variables.

          Le contexte de mon problème est difficile à expliquer, ou c'est moi qui me complique la vie.

          je ne controle pas la définition "origine" : ce sont des variables définies lors de l'appel à mon playbook (extra_vaers dont je ne contrôle pas l'appel).

          var_a m'est passée par un appel à mon playbook, var_b également, ainsi que le booléen.
          le rôle que j'appelle dans mon playbook ne connait que var_a; var_b lui est inconnu : le but est de positionner var_a à var_b si le booléen est à l'état false, et ensuite d'appeler le rôle.

          Celà dit j'ai peutêtre trouvé un contournement …

  • # Essais

    Posté par  (site web personnel) . Évalué à 4.

      vars:
        var_a: "a"
        var_b: "b"
    
      tasks:
      - debug: msg="{{ var_b if (booleen|default(true)|bool == false) else var_a }}"
      - debug: msg="{% if (booleen|default(true)|bool == false) %}{{ var_b }}{% else %}{{ var_a }}{% endif %}"

    les deux marchent, testé avec "-e booleen=true", "-e booleen=false" et sans avoir défini la variable, avec Ansible 2.2.1

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.