158 votes

Quelle est la différence entre include_tasks et import_tasks ?

Dans Ansible 2.4, l'option include est déprécié. À sa place, il est livré avec deux modules de remplacement, import_tasks y 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 actuel pour une exécution ultérieure.

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

173voto

Konstantin Suvorov Points 3696

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

La principale différence est :

Tous import* sont pré-traitées au moment où les playbooks sont analysés.
Tous include* sont traitées au fur et à mesure qu'elles sont rencontrées pendant l'exécution du playbook.

Alors import est statique, include est dynamique.

D'après mon expérience, vous devriez utiliser import lorsque vous traitez des "unités" logiques. Par exemple, séparer une 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 traiter des flux de travail différents et prendre des décisions sur la base de faits recueillis de manière dynamique :

install_prerequisites :

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

57voto

ROSE Points 134

Les importations sont statiques, les inclusions sont dynamiques. Les importations se produisent au moment de l'analyse syntaxique, les inclusions au moment de l'exécution.

Les importations remplacent essentiellement la tâche par les tâches du fichier. Il n'y a pas de tâches d'importation au moment de l'exécution. Ainsi, des attributs comme tags y when (et très probablement le reste) sont copiés dans chaque tâche importée.

sont en effet exécutés. tags y 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 une tâche d'importation n'est pas balisée. Aucune tâche n'est exécutée à partir d'un fichier inclus si une tâche d'inclusion n'est pas balisée.

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

Limitations des importations :

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

Limites de l'inclusion :

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

En savoir plus ici y ici .

Pour moi, cela se résume essentiellement au fait que les importations ne peuvent pas être utilisées avec l'option loop attribut.

Les importations échoueraient certainement dans des cas comme este :

# 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é, puisqu'il hérite de when de la import_tasks tâche. Ainsi, il n'est pas possible d'importer des fichiers de tâches qui modifient les variables utilisées dans la tâche d'importation. when attribut.

J'avais pour principe de commencer par les importations, mais dès que j'avais besoin d'une inclusion, je m'assurais que rien n'était importé par le fichier inclus ou ses enfants. Mais c'est sacrément difficile à maintenir. Et ce n'est toujours pas clair si ça me protégera des problèmes. Je veux dire, mélanger les includes et les imports n'est pas recommandé.

Je ne peux pas utiliser uniquement des importations, car j'ai parfois besoin de boucles. Je pourrais probablement passer aux includes uniquement. Mais j'ai décidé de passer aux importations partout, sauf dans les cas où j'ai besoin de boucles. J'ai décidé de faire l'expérience directe de tous ces cas limites délicats. Peut-être qu'il n'y en aura pas dans mes playbooks. Ou, avec un peu de chance, je trouverai un moyen de le faire fonctionner.

UPD Une astuce éventuellement utile pour créer un fichier de tâches qui peut être importé plusieurs fois, mais exécuté une seule 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 mélange des inclusions et des importations est que les variables d'une tâche incluse remplacent celles des tâches importées :

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 importe d'abord les fichiers, puis applique son vars directive.

En fait, on peut aussi le reproduire comme ça :

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 mélange d'inclusions et d'importations.

playbook.yml :

- hosts: all
  tasks:
    # say, you're bound to use include here (because you need a 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 the https var
- import_tasks: 4.yml

4.yml :

- debug:
    var: https

On obtient true y true voir le cas précédent ( include_tasks Les variables ' ont la priorité sur import_tasks ). Pour éviter cela, nous pouvons passer aux includes dans 3.yml . Mais ensuite, la première inclusion dans 3.yml est ignoré. Puisqu'il hérite de when: https de la tâche parentale, de sorte que la première tâche lit essentiellement :

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

La solution consiste à passer aux inclusions dans 2.yml également. Cela empêche la propagation de when: https aux tâches de l'enfant.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X