web-dev-qa-db-fra.com

Quelle est la différence entre include_tasks et import_tasks?

Dans Ansible 2.4, le module include est obsolète. À sa place, il est livré avec deux modules de remplacement, import_tasks et include_tasks. Mais ils ont des descriptions très similaires:

  • include_tasks: Inclut un fichier avec une liste de tâches à exécuter dans le playbook actuel.
  • import_tasks: Importe une liste de tâches à ajouter au playbook en cours pour une exécution ultérieure.

Quand dois-je utiliser le premier et quand dois-je utiliser le second?

77
Ben S

Il y a pas mal de choses sur ce sujet dans la documentation:

La principale différence est:

Tout import* les instructions sont prétraitées au moment de l'analyse des playbooks.
Tout include* les instructions sont traitées telles qu'elles se sont produites lors de l'exécution du playbook.

Donc import est statique, include est dynamique.

D'après mon expérience, vous devriez utiliser import lorsque vous traitez avec des "unités" logiques. Par exemple, séparez la longue liste de tâches en fichiers de sous-tâches:

main.yml:

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

Mais vous utiliseriez include pour gérer différents workflows et prendre des décisions basées sur des faits collectés dynamiquement:

install_prerequisites:

- include_tasks: prerequisites_{{ ansible_os_family | lower }}.yml
81
Konstantin Suvorov

Les importations sont statiques, les inclus sont dynamiques. Les importations se produisent au moment de l'analyse, y compris au moment de l'exécution.

Les importations remplacent essentiellement la tâche par les tâches du fichier. Il n'y a pas import_task lors de l'exécution. Ainsi, des attributs tels que tags et when (et probablement d'autres attributs) sont copiés dans chaque tâche importée.

includes sont en effet exécutés. tags et when d'une tâche incluse ne s'appliquent qu'à la tâche elle-même.

Les tâches balisées d'un fichier importé sont exécutées si la tâche import n'est pas balisée. Aucune tâche n'est exécutée à partir d'un fichier inclus si la tâche include n'est pas balisée.

Toutes les tâches d'un fichier importé sont exécutées si la tâche import est balisée. Seules les tâches balisées d'un fichier inclus sont exécutées si la tâche include est balisée.

Limitations de imports:

  • ne peut pas être utilisé avec with_* ou loop attributs
  • impossible d'importer un fichier, dont le nom dépend d'une variable

Limitations de includes:

  • --list-tags n'affiche pas les balises des fichiers inclus
  • --list-tasks n'affiche pas les tâches des fichiers inclus
  • vous ne pouvez pas utiliser notify pour déclencher un nom de gestionnaire provenant de l'intérieur d'une inclusion dynamique
  • vous ne pouvez pas utiliser --start-at-task pour commencer l'exécution d'une tâche à l'intérieur d'une inclusion dynamique

En savoir plus ici et ici .

Pour moi, cela revient essentiellement au fait que imports ne peut pas être utilisé avec des attributs de boucle.

import échouerait certainement dans des cas comme this :

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

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

debug n'est pas exécuté, car il hérite when de import_tasks tâche. Ainsi, aucun fichier de tâches d'importation qui modifie les variables utilisées dans l'attribut import de when.

J'avais une politique pour commencer par imports, mais une fois que j'ai besoin d'un include assurez-vous que rien n'est importé par ce fichier inclus ou les fichiers qu'il contient. Mais c'est sacrément difficile à maintenir. Et on ne sait toujours pas si cela me protégera des ennuis. Signification, mélange de includes et imports qu'ils ne recommandent pas.

Je ne peux pas utiliser uniquement imports, car j'ai parfois besoin de boucler include tâches. Je pourrais probablement passer à seulement includes. Mais j'ai décidé de passer aux importations partout, sauf dans les cas où la tâche est censée être exécutée plusieurs fois. J'ai décidé de faire l'expérience de tous ces cas Edge difficiles. Peut-être qu'il n'y en aura pas dans mes livres de jeu. Ou j'espère que je trouverai un moyen de le faire fonctionner.

[~ # ~] upd [~ # ~] Une astuce peut-être utile pour créer un fichier de tâches qui peut être importé plusieurs fois, mais exécuté une fois:

- 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 effet pas vraiment attendu du mixage inclut et importe est que les vars remplacent ceux importés:

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

Probablement parce que include_tasks effectue d'abord toutes les importations statiques supplémentaires, puis modifie les variables transmises via sa directive vars.

En fait, cela ne se produit pas seulement avec les importations:

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 autre cas de mixage inclut et importe.

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

Nous obtenons true et true, voir le cas précédent (les vars inclus ont priorité sur les vars d'importation). Nous passons donc aux inclusions dans 3.yml. Mais le premier inclut dans 3.yml est ignoré. Puisqu'il hérite when: https de la tâche parent, et cette dernière prend soi-disant https du vars de la tâche. La solution consiste à passer aux inclusions dans 2.yml ainsi que. Cela empêche la propagation de when: https aux tâches enfants.

20
x-yuri