Яка різниця між include_tasks та import_tasks?


62

У відповіді 2.4 includeмодуль застарілий. Замість цього він поставляється з двома модулями заміни import_tasksта include_tasks. Але вони мають дуже подібні описи:

  • include_tasks: Включає файл із переліком завдань, які потрібно виконати в поточній книзі.
  • import_tasks: Імпортує список завдань, які потрібно додати до поточної книги для подальшого виконання.

Коли я повинен використовувати перше, а коли слід використовувати друге?


(Також: попередження про депресацію стосується "динамічних" та "статичних" завдань. Я читав документи, але не розумів їх.)
Ben S

Відповіді:


68

Про цю тему в документації є зовсім небагато:

Основна відмінність:

Усі import*твердження попередньо обробляються під час розбору ігор.
Усі include*твердження обробляються так, як вони стикалися під час виконання ігрової книги.

Так importє статичним, includeдинамічним.

З мого досвіду, ви повинні використовувати, importколи ви маєте справу з логічними "одиницями". Наприклад, відокремте довгий список завдань у файли підзадачі:

main.yml:

- import_tasks: prepare_filesystem.yml
- import_tasks: install_prerequisites.yml
- import_tasks: install_application.yml

Але ви б використовували includeдля вирішення різних робочих процесів та приймали рішення на основі деяких динамічно зібраних фактів:

install_prerequisites:

- include_tasks: prerequisites_{{ ansible_os_family | lower }}.yml

8
Я вважаю це посилання дуже корисним: docs.ansible.com/ansible/latest/… Він називає випадок, коли імпорт та включення поводяться по-різному - "коли" умовно, коли завдання у файлі можуть змінити критерії, які використовуються для визначення імпорту . За допомогою import_tasks кожне завдання перевіряє критерії, тому поведінка змінюється, коли критерії змінюються. Завдяки include_tasks завдання присутні або не ґрунтуються на тому, чи було умова оцінено як істинне при виконанні оператора include_tasks. Якщо я добре розумію ...
Етел Еванс

Якою була поведінка include? Якби ми використовували, includeбуло import_tasksб рівнозначно?
Енді Шінн

includeмав static: yes(поводився як import_tasks) і static: no(як include_tasks).
Костянтин Суворов

Для чого дефолт static?
Енді Шінн

staticце Noneза замовчуванням: Так як анзібль 2.0, завдання включає в себе динамічні і вести себе як реальні завдання. Це означає, що вони можуть бути петельними, пропущеними та використовувати змінні з будь-якого джерела. Ansible намагається автоматично виявити це, але ви можете використовувати статичну директиву (яка була додана в Ansible 2.1) для обходу автоматичного виявлення.
Костянтин Суворов

15

Імпорт є статичним, включає динамічний. Імпорт відбувається під час розбору, включається під час виконання.

Імпорт в основному замінює завдання завданнями з файлу. Немає import_taskпід час виконання. Таким чином, атрибути , як tagsі when(і , швидше за все , інші атрибути) , копіюються в кожній імпортованої завдання.

includes дійсно виконані. tagsі whenвключене завдання стосується лише самого завдання.

Завдання з importтегів із імпортованого файлу виконуються, якщо завдання не позначено. Жодне завдання не виконується із включеного файлу, якщо includeзавдання не позначено.

Усі завдання із імпортованого файлу виконуються, якщо importзавдання позначено тегом. Виконуються лише теговані завдання із включеного файлу, якщо includeзавдання позначено тегами.

Обмеження imports:

  • не можуть бути використані with_*або loopатрибути
  • не вдається імпортувати файл, ім'я якого залежить від змінної

Обмеження includes:

  • --list-tags не показує теги із включених файлів
  • --list-tasks не показує завдання із включених файлів
  • ви не можете використовувати notifyдля запуску ім'я обробника, яке походить зсередини динамічного включення
  • ви не можете використовувати --start-at-taskдля початку виконання завдання в динамічному включенні

Детальніше про це тут і тут .

Для мене це зводиться до того, що imports не можна використовувати атрибути циклу.

importб , звичайно , НЕ в змозі в таких випадках , як це :

# playbook.yml
- import_tasks: set-x.yml
  when: x is not defined

# set-x.yml
- set_fact
  x: foo
- debug:
  var: x

debugне виконується, так як він успадковує whenвід import_tasksзавдання. Отже, не імпортуються файли завдань, які змінюють змінні, використовувані в атрибуті imports when.

У мене була політика починати з imports, але як тільки мені потрібно includeпереконатися, що нічого не імпортується тим файлом, що входить, або файлами, які він включає. Але це досить чортово важко в обслуговуванні. І досі не зрозуміло, чи захистить мене від неприємностей. Значення, змішування includes і imports, які вони не рекомендують.

Я не можу використовувати лише imports, оскільки час від часу мені потрібно циклічно includeвиконувати завдання. Можливо, я міг би перейти лише на includes. Але я вирішив перейти на імпорт скрізь, крім випадків, коли завдання, як передбачається, виконується кілька разів. Я вирішив випробувати всі ці хитрі крайові справи з перших рук. Можливо, у моїх ігрових книгах не буде жодної. Або сподіваюся, я знайду спосіб змусити це працювати.

UPD Можливо корисний трюк для створення файлу завдань, який можна імпортувати багато разів, але виконувати один раз :

- name: ...
  ...
  when: not _file_executed | default(False)

- name: ...
  ...
  when: not _file_executed | default(False)

...

- name: Set _file_executed
  set_fact:
    _file_executed: True

UPD Один з насправді не очікуваних ефектів змішування включає та імпорт, який включає в себе різні варіанти імпорту:

playbook.yml:

- hosts: all
  tasks:
    - import_tasks: 2.yml
      vars:
        v1: 1
    - include_tasks: 2.yml
      vars:
        v1: 1

2.yml:

- import_tasks: 3.yml
  vars:
    v1: 2

3.yml:

- debug:
    var: v1    # 2 then 1

Можливо, тому, що include_tasksспочатку виконується весь додатковий статичний імпорт, а потім змінюються змінні, передані через його varsдирективу.

Власне, це відбувається не тільки з імпортом:

playbook.yml:

- hosts: all
  tasks:
    - import_tasks: 2.yml
      vars:
        v1: 1
    - include_tasks: 2.yml
      vars:
        v1: 1

2.yml:

- debug:
    var: v1    # 2 then 1
  vars:
    v1: 2

UPD Ще один випадок змішування включає і імпорт.

playbook.yml:

- hosts: all
  tasks:
    # here you're bound to use include, some sort of loop
    - include_tasks: 2.yml
      vars:
        https: yes

2.yml:

- import_tasks: 3.yml
  when: https

3.yml:

- import_tasks: 4.yml
  vars:
    https: no  # here we're trying to temporarily override https var
- import_tasks: 4.yml

4.yml:

- debug:
    var: https

Ми отримуємо trueі true, дивіться попередній випадок (включити вари мають перевагу над імпортом vars). Таким чином, ми переходимо до включає в 3.yml. Але тоді перше включення 3.ymlпропускається. Оскільки вона успадковується when: httpsвід батьківського завдання, а остання нібито бере httpsвід задачі vars. Рішенням є також перехід на включення 2.yml. Це заважає поширювати when: httpsзавдання дитини.


4
Чудова відповідь !. Мені було засмучено, що всі в Інтернеті просто повторюють те, що говорить документація. Дякую.
Серхіо Акоста
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.