40 votes

Ansible : Définir conditionnellement des variables dans le fichier vars si une certaine condition est remplie

En fonction de la valeur (Vrai/Faux) d'une variable définie dans le groupe_vars J'essaie de définir certaines variables dans un fichier vars. Leur valeur dépend de la valeur de la variable group_vars.

Mon fichier var actuel ressemble à ceci :

{% if my_group_var %}
test:
   var1: value
   var2: value
   ...
   varn: value
{% else %}
test:
   var1: other_value
   var2: other_value
   ...
   varn: other_value
{% endif %}

Pour chacun de mes rôles, j'utilise une variable définie dans ce fichier.

Mon playbook de test ressemble à ce qui suit :

- name: blabla
  hosts: blabla
  vars_files:
     - <path>/test_vars.yml
  roles: blabla 

L'erreur que je reçois après avoir exécuté le playbook est la suivante :

{% if my_group_var %}
 ^ here

exception type: <class 'yaml.scanner.ScannerError'>
exception: while scanning for the next token
found character that cannot start any token
  in "<unicode string>"

Est-ce que je fais quelque chose de stupide ici ou est-ce que ce n'est même pas supporté ? J'ai essayé de trouver une autre façon de définir ces variables (j'en ai beaucoup) mais je n'ai pas réussi à obtenir quelque chose de fonctionnel ici. Avez-vous des suggestions ?

0 votes

Où ces variables finissent-elles par être utilisées ? Cela n'est peut-être pas nécessaire si vous ne les utilisez que dans le cadre d'un projet de template appel du module.

0 votes

Si test est dépendant du groupe, il doit être placé dans group_vars.

0 votes

Malheureusement, le test ne dépend pas du groupe. Comme mentionné dans la description, le test dépend de la valeur d'une variable group_var.

38voto

Vladimir Points 446

Ansible permet l'une des formes suivantes pour définir une variable de manière conditionnelle :

    test:
      var1: "{% if my_group_var %}value{% else %}other_value{% endif %}"
      var2: "{{'value' if (my_group_var) else 'other_value'}}"

En combinant la syntaxe ci-dessus avec la recherche de variables, nous pouvons charger des variables complexes (map dans ce cas) :

test_value_when_my_group_var_is_true:
   var1: value
   var2: value

test_value_when_my_group_var_is_false:
   var1: other_value
   var2: other_value

test: "{{ lookup('vars','test_value_when_my_group_var_is_true') if (my_group_var) else lookup('vars','test_value_when_my_group_var_is_false')}}"

Il existe une autre façon de procéder au chargement conditionnel de l'arbre avec la recherche de variables. Cette méthode est pratique lorsque vous devez mettre en œuvre une logique de cas (c'est-à-dire que la variable de condition a plus de deux valeurs possibles) :

test_value_when_my_group_var_is_foo:
   var1: value
   var2: value

test_value_when_my_group_var_is_bar:
   var1: other_value
   var2: other_value

test_value_when_my_group_var_is_baz:
   var1: yet_another_value
   var2: yet_another_value

test: "{{ lookup('vars','test_value_when_my_group_var_is_' + my_group_var) }}"

18voto

snowdude Points 2790

Je ne pense pas que vous puissiez le faire. En général, je crée des fichiers séparés pour contenir les collections de variables conditionnelles et j'utilise un fichier de type when pour les inclure dans une condition spécifique :

- include_vars: test_environment_vars.yml
  when: global_platform == "test"

- include_vars: staging_environment_vars.yml
  when: global_platform == "staging"

- include_vars: prod_environment_vars.yml
  when: 
    - global_platform != "test" 
    - global_platform != "staging"

3 votes

C'est quelque chose que j'essayais d'éviter. Je ne veux pas utiliser les include vars ou définir deux fichiers var supplémentaires pour mes tâches.

0 votes

Je ne comprends pas alors qu'il est possible d'utiliser include_vars avec condition, pourquoi ne peut-on pas définir une variable avec condition ?

0 votes

C'est à mes yeux la meilleure solution : diviser pour mieux régner.

2voto

Jaroslav Kucera Points 1395

Bien que ce serait bien, j'ai peur que votre façon de faire ne soit pas possible (ou que je ne connaisse pas la bonne façon).

Je suggère de préparer d'abord le fichier vars à partir du modèle jinja et de l'inclure ensuite avec include_vars. Voir le playbook d'exemple :

---
- name: -Test-
  hosts: local
  vars:
    my_group_var: False
#    my_group_var: True

  tasks:

  - name: Prepare vars file from template.
    template: src=/tmp/vars.yaml.j2
              dest=/tmp/vars.yaml

  - name: Include vars
    include_vars: "/tmp/vars.yaml"

Le contenu de l'exemple de modèle jinja /tmp/vars.yaml.j2 est :

{% if my_group_var %}                                                                                                                                                                                             
test:                                                                                                                                                                                                             
   var1: value                                                                                                                                                                                                    
   var2: value                                                                                                                                                                                                    
{% else %}                                                                                                                                                                                                        
test:                                                                                                                                                                                                             
   var1: other_value                                                                                                                                                                                              
   var2: other_value                                                                                                                                                                                              
{% endif %}

0 votes

J'aime cette méthode mais le problème est qu'après avoir généré le fichier .yml à partir du modèle jinja, il n'est pas disponible pour les tâches suivantes de mon livre de jeu.

0 votes

Pourquoi ? Lorsque j'ai essayé d'étendre le playbook de test avec la tâche de débogage - debug: var=test Je peux voir, qu'il y a défini à la fois test.var1 y test.var2 avec les valeurs attendues. Vous devriez donc être en mesure d'utiliser ces variables dans d'autres tâches du playbook.

2voto

Chen Du Points 11

Pourquoi personne ne le mentionne ?

_dist: "{{ ansible_lsb.id|lower if ansible_lsb.id == 'Raspbian' else ansible_distribution|lower }}"

1voto

pandoJohn Points 365

Ce que j'ai fait en fin de compte, c'est de créer 2 fichiers var séparés - appelons-les type_a.yml y type_b.yml - et j'ai défini une variable de groupe qui indique quel fichier utiliser - quelque chose comme type_of_file: a . Voici à quoi ressemble mon livre de jeu maintenant :

- name: blabla
  hosts: blabla
  vars_files:
     - <path>/type_{{ type_of_file }}.yml
  roles: blabla

Merci pour toutes les réponses. Je les trouve vraiment utiles.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X