Ansible - використовуйте значення за замовчуванням, якщо змінна не визначена


98

Я налаштовую usersстворення Linux всередині своєї ролі. Мені потрібно , щоб користувачі моєї ролі підганяє home_directory, group_name, name, password.

Мені було цікаво, чи існує більш гнучкий спосіб впоратися зі значеннями за замовчуванням.

Я знаю, що наведений нижче код можливий:

- name: Create default
  user:
    name: "default_name"
  when: my_variable is not defined

 - name: Create custom
  user:
    name: "{{my_variable}}"
  when: my_variable is defined

Але, як я вже згадував, є багато необов’язкових змінних, і це створює багато можливостей.

Чи є щось на зразок коду вище?

user:
  name: "default_name", "{{my_variable}}"

Код повинен встановлюватися, name="default_name"коли my_variableвін не визначений.

Я міг би встановити всі змінні defaults/main.ymlта створити користувача таким чином:

- name: Create user
  user:
    name: "{{my_variable}}"

Але ці змінні знаходяться всередині справді великого хешу, і всередині цього хешу є деякі хеші, які не можуть бути типовими.


Відповіді:


190

Ви можете використовувати Jinja's default:

- name: Create user
  user:
    name: "{{ my_variable | default('default_value') }}"

10
І якщо змінна за замовчуванням залежить від іншої змінної. Наприклад default('/home/' {{ anothervar }}), чи є спосіб об’єднати ці значення?
Бернардо Вале

8
Просто видаліть 'навколо, default_valueі він буде використовувати змінну з назвою default_value
dagonza

7
Не працює, якщо змінна вкладена як {{ dict.key | default(5) }}. Це не вдасться, якщо dictне визначено.
Джордан Стюарт

1
FYI, тепер це призведе до помилки:[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}.
Брайан Кеннеді,

1
@JordanStewart У мене був той самий випадок - із вкладеними змінними. Я розмістив відповідь із можливими рішеннями нижче.
Роман Круглов

11

Не повністю пов’язаний, але ви також можете перевірити наявність обох змінних undefinedІ empty(наприклад, my_variable:). (ПРИМІТКА: працює лише з версією ansible> 1.9, див .: посилання )

- name: Create user
  user:
    name: "{{ ((my_variable == None) | ternary('default_value', my_variable)) \
    if my_variable is defined else 'default_value' }}"

2
Це чудово, дуже корисно.
eagle33322

5

Якщо хтось шукає варіант, який обробляє вкладені змінні, у цій проблемі github є кілька таких опцій .

Коротше кажучи, вам потрібно використовувати фільтр "за замовчуванням" для кожного рівня вкладених vars. Для змінної "a.nested.var" це буде виглядати так:

- hosts: 'localhost'
  tasks:
    - debug:
        msg: "{{ ((a | default({})).nested | default({}) ).var | default('bar') }}"

або ви можете встановити значення пустих значень за замовчуванням для кожного рівня vars, можливо, використовуючи фільтр "об'єднати". Або скористайтеся фільтром "json_query". Але обраний мною варіант здається мені простішим, якщо у вас є лише один рівень вкладеності.


4

Якщо у вас є одна гра, яку ви хочете прокрутити по елементах, визначте цей список у group_vars / all або десь ще, що має сенс:

all_items:
  - first
  - second
  - third
  - fourth

Тоді ваше завдання може виглядати так:

  - name: List items or default list
    debug:
      var: item
    with_items: "{{ varlist | default(all_items) }}"

Передайте varlist як масив JSON:

ansible-playbook <playbook_name> --extra-vars='{"varlist": [first,third]}'

До цього вам також може знадобитися завдання, яке перевіряє, чи кожен елемент у списку varlist також є в all_items :

  - name: Ensure passed variables are in all_items
    fail:
      msg: "{{ item }} not  in all_items list"
    when: item not in all_items
    with_items: "{{ varlist | default(all_items) }}"

3

Якщо ви використовуєте пошук для встановлення типового зчитування із середовища, ви також встановили для другого параметра за замовчуванням значення true:

- set_facts:
    ansible_ssh_user: "{{ lookup('env', 'SSH_USER') | default('foo', true) }}"

Ви також можете об'єднати кілька визначень за замовчуванням:

- set_facts:
    ansible_ssh_user: "{{ some_var.split('-')[1] | default(lookup('env','USER'), true) | default('foo') }}"

1

Питання досить давнє, але як щодо:

- hosts: 'localhost'
  tasks:
    - debug:
        msg: "{{ ( a | default({})).get('nested', {}).get('var','bar') }}"

Мені це здається менш громіздким ...


1

Якщо ви призначаєте значення за замовчуванням для логічного факту, переконайтесь, що всередині default () не використовуються лапки.

- name: create bool default
  set_fact:
    name: "{{ my_bool | default(true) }}"

Для інших змінних використовували той самий метод, що вказаний у підтвердженій відповіді.

- name: Create user
  user:
    name: "{{ my_variable | default('default_value') }}"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.