web-dev-qa-db-fra.com

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

En fonction de la valeur (True/False) d'une variable définie dans le group_vars, j'essaie de définir certaines variables dans un fichier vars. Leur valeur dépend de la valeur du groupe var.

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 à ci-dessous:

- 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:

{% 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>"

Suis-je en train de faire quelque chose de stupide ici ou ce n'est même pas supporté? J'ai essayé de trouver une autre façon de définir ces vars (j'en ai beaucoup) mais je n'ai pas réussi à obtenir quelque chose de fonctionnel ici. Aucune suggestion?

20
pandoJohn

Ce que j'ai fait à la fin était de créer 2 fichiers var séparés - appelons-les type_a.yml et 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 playbook 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.

0
pandoJohn

Je ne pense pas que vous puissiez, je crée généralement des fichiers séparés pour contenir les collections de variables conditionnelles et j'utilise une clause when pour les inclure à 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" 
12
HBruijn

Ansible permet à l'une des formes suivantes de 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 (liste 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 d'effectuer un chargement d'arbre conditionnel avec la recherche vars. Cette méthode est pratique lorsque vous avez besoin d'implémenter 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) }}"
11
Vladimir

Malgré que ce soit sympa, je crains que votre chemin ne soit pas possible (ou je ne suis pas au courant de la bonne façon).

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

---
- 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 %}
2
Jaroslav Kucera

J'espère que le snip suivant (tiré de Documentation Ansible ) pourra apporter un complément utile aux contributions utiles des autres ci-dessus.

- name: Show value of 'variablename'
  debug: msg="{{ lookup('vars', 'variabl' + myvar)}}"
  vars:
    variablename: hello
    myvar: ename
0
Peter Smallwood

AFAIK, cette {} chose que vous essayez est pour les modèles Jinja2 et non pour les fichiers yml. De la documentation :

ansible autorise les boucles et les conditions Jinja2 dans les modèles, mais dans les playbooks, nous ne les utilisons pas.

Vous pouvez préparer un fichier .yml séparé avec un jeu qui configure les variables dont vous avez besoin en utilisant des clauses when, puis en les important (ou en les incluant) dans votre livre de jeu principal. De cette façon, vous pouvez avoir toutes les variables définies conditionnellement dans un seul fichier.

OU: utilisez des rôles. Je pense que les rôles sont l'approche la plus adéquate pour résoudre votre problème.

0
niglesias