Qual è la differenza tra include_tasks e import_tasks?


63

In Ansible 2.4, il includemodulo è obsoleto. Al suo posto, viene fornito con due moduli di sostituzione import_taskse include_tasks. Ma hanno descrizioni molto simili:

  • include_tasks: Include un file con un elenco di attività da eseguire nel playbook corrente.
  • import_tasks: Importa un elenco di attività da aggiungere al playbook corrente per la successiva esecuzione.

Quando dovrei usare il primo e quando dovrei usare il secondo?


(Inoltre: l'avviso di deprecazione si riferisce ad attività "dinamiche" e "statiche". Ho letto i documenti ma non li ho capiti.)
Ben S

Risposte:


70

C'è un bel po 'di questo argomento nella documentazione:

La differenza principale è:

Tutte le import*dichiarazioni sono preelaborate al momento dell'analisi dei playbook.
Tutte le include*dichiarazioni vengono elaborate nel modo in cui si sono verificate durante l'esecuzione del playbook.

Quindi importè statico, includeè dinamico.

Dalla mia esperienza, dovresti usare importquando hai a che fare con "unità" logiche. Ad esempio, separare un lungo elenco di attività in file di sottoattività:

main.yml:

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

Ma useresti includeper gestire diversi flussi di lavoro e prendere decisioni basate su alcuni fatti raccolti dinamicamente:

install_prerequisites:

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

8
Ho trovato questo link molto utile: docs.ansible.com/ansible/latest/… Richiama un caso in cui l'importazione e l'inclusione si comportano in modo diverso - un condizionale "quando" in cui le attività nel file possono modificare i criteri utilizzati per determinare l'importazione . Con import_tasks, ogni attività controlla i criteri, quindi il comportamento cambia quando i criteri cambiano. Con include_tasks, le attività sono presenti o meno in base alla valutazione della condizione come vera al momento dell'esecuzione dell'istruzione include_tasks. Se ho capito bene ...
Ethel Evans il

Qual è stato il comportamento di include? Se stessimo usando includesarebbe import_tasksl'equivalente?
Andy Shinn,

includeaveva static: yes(comportato come import_tasks) e static: no(come include_tasks).
Konstantin Suvorov,

A cosa serve il default static?
Andy Shinn,

staticè Nonedi default: da Ansible 2.0, le attività incluse sono dinamiche e si comportano più come attività reali. Ciò significa che possono essere collegati in loop, saltati e utilizzare variabili da qualsiasi sorgente. Ansible tenta di rilevarlo automaticamente, ma è possibile utilizzare la direttiva statica (che è stata aggiunta in Ansible 2.1) per ignorare il rilevamento automatico.
Konstantin Suvorov,

17

Le importazioni sono statiche, le inclusioni sono dinamiche. Le importazioni avvengono al momento dell'analisi, include in fase di esecuzione.

Le importazioni sostituiscono sostanzialmente l'attività con le attività del file. Non c'è import_taskin fase di esecuzione. Pertanto, attributi come tagse when(e molto probabilmente altri attributi) vengono copiati in ogni attività importata.

includegli s sono effettivamente eseguiti. tagse whendi un'attività inclusa si applicano solo all'attività stessa.

Le attività contrassegnate da un file importato vengono eseguite se l' importattività non è contrassegnata. Nessuna attività viene eseguita da un file incluso se l' includeattività non è contrassegnata.

Tutte le attività da un file importato vengono eseguite se l' importattività è taggata. Solo le attività contrassegnate da un file incluso vengono eseguite se l' includeattività è contrassegnata.

Limitazioni di imports:

  • non può essere utilizzato con with_*o loopattributi
  • impossibile importare un file, il cui nome dipende da una variabile

Limitazioni di includes:

  • --list-tags non mostra i tag dai file inclusi
  • --list-tasks non mostra attività dai file inclusi
  • non è possibile utilizzare notifyper attivare il nome di un gestore che proviene da un'inclusione dinamica
  • non è possibile utilizzare --start-at-taskper iniziare l'esecuzione in un'attività all'interno di un'inclusione dinamica

Maggiori informazioni qui e qui .

Per me ciò dipende essenzialmente dal fatto che imports non può essere utilizzato con gli attributi di loop.

importfallirebbe sicuramente in casi come questo :

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

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

debugnon viene eseguito, poiché eredita whendall'attività import_tasks. Quindi, nessun file Operazione di importazione che cambiano variabili utilizzate nel import's whenattributo.

Avevo una politica per iniziare con imports, ma una volta ho bisogno di includeassicurarmi che nulla sia importato da quel file incluso o dai file che include. Ma è abbastanza difficile da mantenere. E non è ancora chiaro se mi proteggerà dai problemi. Significato, mescolando includes e imports che non raccomandano.

Non posso usare solo le imports, poiché occasionalmente ho bisogno di eseguire il ciclo delle includeattività. Probabilmente potrei passare solo a includes. Ma ho deciso di passare alle importazioni ovunque, ad eccezione dei casi in cui l'attività dovrebbe essere eseguita più volte. Ho deciso di provare di persona tutti quei casi difficili. Forse non ce ne sarà nessuno nei miei playbook. O speriamo di trovare un modo per farlo funzionare.

UPD Un trucco forse utile per creare un file di attività che può essere importato più volte, ma eseguito una volta :

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

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

...

- name: Set _file_executed
  set_fact:
    _file_executed: True

UPD Un effetto non realmente previsto della miscelazione di inclusioni e importazioni è che includono variare quelli di importazione:

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

Probabilmente, perché include_tasksprima fa tutte le importazioni statiche aggiuntive, quindi cambia le variabili passate tramite la sua varsdirettiva.

In realtà, succede non solo con le importazioni:

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 Un altro caso di miscelazione include e importazioni.

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

Otteniamo truee true, vedi il caso precedente (includere i var ha la precedenza sui import import). Quindi passiamo a include in 3.yml. Ma poi il primo include in 3.ymlviene saltato. Dal momento che eredita when: httpsdall'attività padre e quest'ultima presumibilmente prende httpsdall'attività vars. La soluzione è passare anche a include in 2.yml. Ciò impedisce la propagazione when: httpsalle attività secondarie.


4
Bella risposta!. Ero frustrato dal fatto che tutti su Internet ripetessero ciò che dice la documentazione. Grazie.
Sergio Acosta,
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.