Ansible: definire condizionalmente le variabili nel file var se viene soddisfatta una determinata condizione


19

A seconda del valore (Vero / Falso) di una variabile definita in group_vars, sto cercando di definire alcune variabili in un file VAR. Il loro valore dipende dal valore del var del gruppo.

Il mio file var attuale è simile al seguente:

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

Per ognuno dei miei ruoli sto usando una variabile definita in questo file.

Il mio playbook di prova è simile al seguente:

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

L'errore che sto ricevendo dopo aver eseguito il playbook è:

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

Sto facendo qualcosa di stupido qui o questo non è nemmeno supportato? Ho provato a trovare un altro modo per definire questi vari (ne ho molti) ma non sono riuscito a ottenere qualcosa di funzionale qui. Eventuali suggerimenti?


Dove finiscono per essere usati questi VAR? Questo potrebbe non essere necessario se tutto ciò per cui li utilizzerai è parte di una templatechiamata al modulo.
84104

Se testdipende dal gruppo, deve essere inserito in group_vars.
Konstantin Suvorov,

Sfortunatamente, il test non dipende dal gruppo. Come menzionato nella descrizione, il test dipende dal valore di una variabile group_var.
pando John,

Risposte:


11

Non credo che tu possa, di solito creo file separati per contenere raccolte variabili condizionali e uso una whenclausola per includerli in una condizione specifica:

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

2
Questo è qualcosa che stavo cercando di evitare. Non voglio usare include var o definire 2 file var aggiuntivi per i miei compiti.
pando John,

Non capisco..quando è possibile usare include_vars con condizione, perché non è possibile definire una variabile con condizione?
GP92

10

Ansible consente a una delle seguenti forme di definire la variabile in modo condizionale:

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

Combinando la sintassi sopra e la ricerca di Vars possiamo caricare Vars complessi (elencare in questo caso):

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')}}"

Esiste un altro modo per eseguire il caricamento condizionale dell'albero con la ricerca var. In questo modo è utile quando è necessaria la logica del caso dell'attrezzo (ovvero la variabile di condizione ha più di due valori possibili):

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) }}"

2

Nonostante sarebbe bello, temo che la tua strada non sia possibile (o non sono consapevole nel modo giusto).

Suggerirei prima di preparare il file var dal modello jinja e quindi includerlo con include_vars. Vedi il playbook di esempio:

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

Il contenuto dell'esempio jinja template /tmp/vars.yaml.j2 è:

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

Mi piace questo, ma il problema è che dopo aver generato il file .yml dal modello jinja questo non è disponibile per le attività successive dal mio playbook.
pando John,

Perché? Quando ho cercato di estendere il playbook test con task debug - debug: var=testposso vedere, che sono definite sia test.var1e test.var2con i valori attesi. Quindi dovresti essere in grado di usare queste variabili in altre attività del playbook.
Jaroslav Kucera,

0

AFAIK, questa {} cosa che stai provando è per i modelli Jinja2 e non per i file yml. Dalla documentazione :

ansible consente loop e condizionali Jinja2 nei template, ma nei playbook non li usiamo.

Puoi preparare un file .yml separato con un gioco che imposta le variabili che devi usare quando clausole e quindi importarle (o includerle) nel tuo playbook principale. In questo modo è possibile avere tutti i var definiti in modo condizionale in un singolo file.

OPPURE: utilizzare i ruoli. Penso che i ruoli siano l'approccio più adeguato per risolvere il tuo problema.


0

Quello che ho fatto alla fine è stato creare 2 file var separati - chiamiamoli type_a.ymle type_b.yml- e ho definito una variabile di gruppo che indica quale file usare - qualcosa del genere type_of_file: a. Ecco come appare il mio playbook ora:

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

Grazie per tutte le risposte Li trovo davvero utili.


0

Spero che il seguente taglio (tratto da Ansible Documentation ) possa apportare una valida aggiunta ai contributi utili degli altri precedenti.

- name: Show value of 'variablename'
  debug: msg="{{ lookup('vars', 'variabl' + myvar)}}"
  vars:
    variablename: hello
    myvar: ename
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.