Відповідь: Умовно визначте змінні у файлі vars, якщо виконується певна умова


19

Залежно від значення (True / False) змінної, визначеної у group_vars, я намагаюся визначити деякі змінні у файлі vars. Їх значення залежить від значення групи вар.

Мій поточний файл var виглядає так:

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

Для кожної з моїх ролей я використовую змінну, визначену в цьому файлі.

Мій тестовий зошит виглядає нижче:

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

Помилка, яку я отримую після запуску книги, така:

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

Я роблю тут щось дурне або це навіть не підтримується? Я намагався знайти інший спосіб визначення цих варіантів (у мене їх дуже багато), але мені не вдалося отримати щось функціональне. Будь-які пропозиції?


Де в кінцевому підсумку вони використовуються? Це може бути зайвим, якщо все, для чого ви збираєтесь їх використовувати, є частиною templateмодульного дзвінка.
84104

Якщо testгрупа залежить від групи, вона повинна бути розміщена у group_vars.
Костянтин Суворов

На жаль, тест не залежить від групи. Як зазначено в описі, тест залежить від значення змінної group_var.
pandoJohn

Відповіді:


11

Я не думаю, що ви можете, я зазвичай створюю окремі файли для зберігання умовних колекцій змінних і використовую whenпункт для включення їх у певну умову:

- 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
Це те, чого я намагався уникати. Я не хочу використовувати include vars або визначати 2 додаткові файли var для своїх завдань.
pandoJohn

Я не розумію, коли можна використовувати enable_vars з умовою, чому не можна визначити змінну із умовою?
GP92

10

Ansible дозволяє одній з наступних форм умовно визначити змінну:

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

Поєднавши вище синтаксис з пошуком vars, ми можемо завантажити складні vars (список у цьому випадку):

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

Існує ще один спосіб виконати умовне завантаження дерев за допомогою пошуку vars. Цей спосіб зручний, коли вам потрібно застосувати логіку випадку (тобто змінна умова має більше двох можливих значень):

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

Попри це було б добре, я боюся, що ваш шлях не можливий (або я не знаю правильного шляху).

Я б запропонував спершу підготувати файл vars із шаблону jinja, а потім включити його з include_vars. Дивіться приклад ігрової книги:

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

Зміст прикладу шаблону jinja /tmp/vars.yaml.j2:

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

Мені це подобається, але проблема полягає в тому, що після генерації .yml-файлу з шаблону jinja це не доступно для наступних завдань з моєї книги.
pandoJohn

Чому? Коли я спробував розширити тестову книжку із завданням налагодження, - debug: var=testя можу побачити, що є визначені test.var1і test.var2з очікуваними значеннями. Отже, ви повинні мати можливість використовувати ці змінні в інших завданнях ігрової книги.
Ярослав Кучера

0

AFAIK, це {} те, що ви намагаєтеся, - це для шаблонів Jinja2, а не для файлів yml. З документації :

ansible дозволяє цикли і умовні умови Jinja2 у шаблонах, але в ігрових книгах ми їх не використовуємо.

Ви можете підготувати окремий .yml-файл із п’єсою, яка встановлює потрібні змінні під час пропозицій, а потім імпортувати (або включати) їх у свою основну програму. Таким чином, ви можете умовно визначити всі параметри в одному файлі.

АБО: Використовуйте ролі. Я думаю, що ролі є найбільш адекватним підходом до вирішення вашої проблеми.


0

Зрештою, я створив 2 окремих var-файли - назвемо їх type_a.ymlі type_b.yml- і я визначив групову змінну, яка вказує, який файл використовувати - щось подібне type_of_file: a. Ось так виглядає моя книжка для гри:

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

Дякую за всі відповіді. Я вважаю їх дуже корисними.


0

Я сподіваюсь, що наступний фрагмент (взятий з відповідної документації ) може стати вагомим доповненням до корисних внесків інших вище.

- name: Show value of 'variablename'
  debug: msg="{{ lookup('vars', 'variabl' + myvar)}}"
  vars:
    variablename: hello
    myvar: ename
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.