Was ist der Unterschied zwischen include_tasks und import_tasks?

63

In Ansible 2.4 ist das includeModul veraltet. An seiner Stelle es wird mit zwei Ersatzmodule, import_tasksund include_tasks. Aber sie haben sehr ähnliche Beschreibungen:

  • include_tasks: Enthält eine Datei mit einer Liste der auszuführenden Aufgaben im aktuellen Wiedergabebuch.
  • import_tasks: Importiert eine Liste von Aufgaben, die dem aktuellen Playbook zur späteren Ausführung hinzugefügt werden sollen.

Wann sollte ich das erstere und wann das letztere verwenden?

Ben S
quelle
(Außerdem bezieht sich die Warnung auf "dynamische" und "statische" Aufgaben. Ich habe die Dokumente gelesen, aber nicht verstanden.)
Ben S

Antworten:

69

Zu diesem Thema gibt es in der Dokumentation einiges:

Der Hauptunterschied ist:

Alle import*Anweisungen werden zum Zeitpunkt der Analyse der Playbooks vorverarbeitet.
Alle include*Anweisungen werden so verarbeitet, wie sie während der Ausführung des Playbooks aufgetreten sind.

Ist importalso statisch, includeist dynamisch.

Nach meiner Erfahrung sollten Sie verwenden, importwenn Sie sich mit logischen "Einheiten" befassen. Trennen Sie beispielsweise eine lange Liste von Aufgaben in Teilaufgabendateien:

main.yml:

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

Sie würden includesich jedoch mit verschiedenen Workflows befassen und Entscheidungen auf der Grundlage einiger dynamisch gesammelter Fakten treffen:

Installationsvoraussetzungen:

- include_tasks: prerequisites_{{ ansible_os_family | lower }}.yml
Konstantin Suworow
quelle
8
Ich fand diesen Link sehr nützlich: docs.ansible.com/ansible/latest/… Er ruft einen Fall auf, in dem sich Import und Include unterschiedlich verhalten - eine "Wann" -Bedingung, bei der die Aufgaben in der Datei möglicherweise die Kriterien ändern, die zum Bestimmen des Imports verwendet werden . Bei import_tasks überprüft jede Task die Kriterien, sodass sich das Verhalten ändert, wenn sich die Kriterien ändern. Bei include_tasks sind die Tasks entweder vorhanden oder nicht, je nachdem, ob die Bedingung bei der Ausführung der include_tasks-Anweisung als wahr bewertet wurde oder nicht. Wenn ich es richtig verstehe ...
Ethel Evans
Was war das Verhalten von include? Wenn wir das Äquivalent verwenden includewürden import_tasks?
Andy Shinn
includehatte static: yes(benahm sich wie import_tasks) und static: no(wie include_tasks).
Konstantin Suvorov
Wofür ist die Standardeinstellung static?
Andy Shinn
staticist Nonestandardmäßig aktiviert: Seit Ansible 2.0 sind Aufgaben-Includes dynamisch und verhalten sich eher wie echte Aufgaben. Dies bedeutet, dass sie wiederholt, übersprungen und Variablen aus beliebigen Quellen verwendet werden können. Ansible versucht dies automatisch zu erkennen, aber Sie können die statische Direktive (die in Ansible 2.1 hinzugefügt wurde) verwenden, um die automatische Erkennung zu umgehen.
Konstantin Suvorov
15

Importe sind statisch, Includes sind dynamisch. Importe erfolgen zur Parsing-Zeit, einschließlich zur Laufzeit.

Importe ersetzen grundsätzlich die Aufgabe durch die Aufgaben aus der Datei. Zur import_taskLaufzeit gibt es keine . Daher werden Attribute wie tagsund when(und höchstwahrscheinlich auch andere Attribute) in jede importierte Aufgabe kopiert.

includes sind in der Tat ausgeführt. tagsund wheneiner eingeschlossenen Aufgabe gelten nur für die Aufgabe selbst.

Mit Tags versehene Aufgaben aus einer importierten Datei werden ausgeführt, wenn die importAufgabe nicht mit Tags versehen ist. Es werden keine Aufgaben aus einer enthaltenen Datei ausgeführt, wenn die includeAufgabe nicht markiert ist.

Alle Aufgaben aus einer importierten Datei werden ausgeführt, wenn die importAufgabe markiert ist. Nur mit Tags versehene Aufgaben aus einer enthaltenen Datei werden ausgeführt, wenn die includeAufgabe mit Tags versehen ist.

Einschränkungen von imports:

  • kann nicht mit with_*oder loopAttributen verwendet werden
  • kann keine Datei importieren, deren Name von einer Variablen abhängt

Einschränkungen von includes:

  • --list-tags zeigt keine Tags aus enthaltenen Dateien an
  • --list-tasks zeigt keine Aufgaben aus enthaltenen Dateien an
  • Sie können nicht verwenden notify, um einen Handlernamen auszulösen, der aus einem dynamischen Include stammt
  • Sie können nicht verwenden --start-at-task, um mit der Ausführung einer Aufgabe innerhalb eines dynamischen Includes zu beginnen

Mehr dazu hier und hier .

Für mich hängt das im Grunde damit zusammen, dass imports nicht mit Schleifenattributen verwendet werden kann.

importwürde auf jeden Fall in solchen Fällen scheitern diese :

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

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

debugwird nicht ausgeführt, da es whenvon der import_tasksTask erbt . Also, keine Import Aufgabe Dateien , die Variablen verändern verwendet import‚s - whenAttribut.

Ich hatte eine Richtlinie, mit imports zu beginnen , aber sobald ich eine benötige, includestellen Sie sicher, dass nichts von dieser enthaltenen Datei oder den darin enthaltenen Dateien importiert wird. Aber das ist verdammt schwer zu pflegen. Und es ist immer noch nicht klar, ob es mich vor Problemen schützt. Das heißt, Mischen von includes und imports, die sie nicht empfehlen.

Ich kann nicht nur imports verwenden, da ich gelegentlich includeAufgaben in einer Schleife ausführen muss. Ich könnte wohl nur auf includes umstellen . Aber ich habe mich entschieden, überall auf Importe umzusteigen, außer in den Fällen, in denen die Aufgabe mehrmals ausgeführt werden soll. Ich beschloss, all diese kniffligen Fälle aus erster Hand zu erleben. Vielleicht gibt es keine in meinen Spielbüchern. Oder hoffentlich finde ich einen Weg, es zum Laufen zu bringen.

UPD Ein möglicherweise nützlicher Trick zum Erstellen einer Aufgabendatei, die mehrmals importiert, aber einmal ausgeführt werden kann :

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

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

...

- name: Set _file_executed
  set_fact:
    _file_executed: True

UPD Ein nicht wirklich zu erwartender Effekt beim Mischen von Includes und Importen ist, dass Vars Importe überschreiben:

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

Wahrscheinlich, weil include_taskszuerst alle zusätzlichen statischen Importe ausgeführt werden und dann die über die varsDirektive übergebenen Variablen geändert werden .

Eigentlich passiert es nicht nur bei Importen:

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 Ein weiterer Fall des Mischens umfasst und importiert.

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

Wir erhalten trueund truesehen den vorherigen Fall (Include-Variablen haben Vorrang vor Import-Variablen). Also wechseln wir zu Includes in 3.yml. Aber dann wird das erste Include in 3.ymlübersprungen. Da es when: httpsvon der übergeordneten Aufgabe erbt und diese angeblich httpsvon der Aufgabe übernimmt vars. Die Lösung besteht darin, ebenfalls auf Includes zu wechseln 2.yml. Dadurch wird die Weitergabe when: httpsan die untergeordneten Aufgaben verhindert.

x-yuri
quelle
4
Gute Antwort!. Ich war frustriert darüber, dass alle im Internet nur wiederholt haben, was in der Dokumentation steht. Danke.
Sergio Acosta