Tools/Ansible/Gestion des Boucles : Différence entre versions

De MonPtitSite
Sauter à la navigation Sauter à la recherche
(Page créée avec « {{MediaWiki}} {{FOND_BLEU|Ansible - '''Mise en oeuvre de boucles avancées'''}} =Boucles et plug-in de recherche= L'utilisation de boucles pour itérer sur des tâches p… »)
 
Ligne 47 : Ligne 47 :
 
Ces derniers utilisent principalement des filtres.
 
Ces derniers utilisent principalement des filtres.
 
* Si vous avez besoin d'utiliser un plug-in de recherche pour convertir une construction {{CODE|with_*}} afin d'utiliser {{CODE|loop}}, il peut être plus clair de continuer à utiliser la syntaxe {{CODE|with_*}}.
 
* Si vous avez besoin d'utiliser un plug-in de recherche pour convertir une construction {{CODE|with_*}} afin d'utiliser {{CODE|loop}}, il peut être plus clair de continuer à utiliser la syntaxe {{CODE|with_*}}.
 +
}}
 +
 +
=Scénarios d'itération=
 +
 +
Les exemples suivants montrent comment créer des boucles plus complexes à l'aide d'expressions '''Jinja2''', de '''filtres''', de '''plug-ins de recherche''' et de la syntaxe {{CODE|with_*}}.
 +
 +
== Liste de listes ==
 +
 +
Le mot-clé {{CODE|with_items}} permet d'effectuer une itération sur des listes complexes. Prenons l'exemple d'un playbook hypothétique avec la tâche suivante :
 +
 +
<syntaxhighlight lang="yaml">
 +
- name: Remove build files
 +
  file:
 +
    path: "{{ item }}"
 +
    state: absent
 +
  with_items:
 +
    - "{{ app_a_tmp_files }}"
 +
    - "{{ app_b_tmp_files }}"
 +
    - "{{ app_c_tmp_files }}"
 +
</syntaxhighlight>
 +
 +
La variable {{CODE|app_a_tmp_files}} contient une liste de fichiers temporaires, tout comme {{CODE|app_b_tmp_files}} et {{CODE|app_c_tmp_files}}. Le mot-clé {{CODE|with_items}} associe ces trois listes en une seule liste contenant les entrées des trois listes. Elle effectue automatiquement un aplatissement des niveaux de la liste.
 +
 +
Pour refactoriser une tâche {{CODE|with_items}} afin d'utiliser le mot-clé {{CODE|loop}}, utilisez le filtre {{CODE|flatten}}.
 +
 +
Le filtre {{CODE|flatten}} recherche de manière récursive les listes incorporées et crée une liste unique à partir des valeurs découvertes.
 +
 +
Le filtre {{CODE|flatten}} accepte un argument levels qui spécifie un nombre entier de niveaux à rechercher pour les listes incorporées. Un argument {{CODE|levels=1}} spécifie que les valeurs sont obtenues uniquement par ordre décroissant dans une liste supplémentaire pour chaque élément de la liste initiale. Il s'agit du même aplatissement de niveau que celui obtenu implicitement par {{CODE|with_items}}.
 +
 +
Pour refactoriser une tâche {{CODE|with_items}} afin d'utiliser le mot-clé {{CODE|loop}}, vous devez également utiliser le filtre {{CODE|flatten(levels=1)}} :
 +
 +
<syntaxhighlight lang="yaml">
 +
- name: Remove build files
 +
  file:
 +
    path: "{{ item }}"
 +
    state: absent
 +
  loop: "{{ list_of_lists | flatten(levels=1) }}"
 +
  vars:
 +
    list_of_lists:
 +
      - "{{ app_a_tmp_files }}"
 +
      - "{{ app_b_tmp_files }}"
 +
      - "{{ app_c_tmp_files }}"
 +
</syntaxhighlight>
 +
 +
{{IMPORTANT|
 +
contenu=Étant donné que {{CODE|loop}} ne procède pas à l'aplatissement implicite d'un niveau, il n'est pas exactement équivalent à {{CODE|with_items}}. Cependant, tant que la liste transmise à la boucle est une simple liste, les deux méthodes se comportent de manière identique. La distinction a de l'importance uniquement si vous disposez
 +
d'une liste de listes.
 
}}
 
}}

Version du 26 mai 2020 à 07:12

Accueil SysAdmin Hobbies                  
Ansible - Mise en oeuvre de boucles avancées

Boucles et plug-in de recherche

L'utilisation de boucles pour itérer sur des tâches peut vous aider à simplifier vos playbooks Ansible. Le mot-clé loop effectue une boucle sur une liste d'éléments à plat. Lorsqu'il est utilisé en association avec des plug-ins de recherche, vous pouvez créer des données plus complexes dans vos listes pour vos boucles.

Le mot-clé loop a été introduit dans Ansible 2.5. Avant cela, l'itération de la tâche a été mise en oeuvre à l'aide de mots-clés contenant en premier with_, suivis du nom d'un plug-in de recherche.

L'équivalent de loop dans cette syntaxe est with_list et est conçu pour l'itération sur une liste plate simple.

Pour les listes simples, loop est la meilleure syntaxe à utiliser.

À titre d'exemple, les trois syntaxes suivantes présentent les mêmes résultats. La première est celle qui est préférée :

- name: using loop
  debug:
    msg: "{{ item }}"
  loop: "{{ mylist }}"
- name: using with_list
  debug:
    msg: "{{ item }}"
  with_list: "{{ mylist }}"
- name: using lookup plugin
  debug:
    msg: "{{ item }}"
  loop: "{{ lookup('list', mylist) }}"

Vous pouvez refactoriser une tâche d'itération de type with_* pour utiliser le mot-clé loop, en utilisant une combinaison appropriée de plug-ins de recherche et de filtres pour correspondre à la fonctionnalité. L'utilisation du mot-clé loop à la place de boucles de type with_* présente les avantages suivants :

  • Il n'est pas nécessaire de mémoriser ou de trouver un mot-clé de type with_* pour votre scénario d'itération. À la place, utilisez des plug-ins et des filtres pour adapter une tâche de mot-clé loop à votre cas d'utilisation.
  • Concentrez-vous sur l'apprentissage des plug-ins et des filtres disponibles dans Ansible, dont la capacité d'application est plus étendue que la simple itération.
  • Vous disposez d'un accès en ligne de commande à la documentation du plug-in de recherche, à l'aide de la commande ansible-doc -t lookup. Cela vous permet de découvrir les plug-ins de recherche et de concevoir des scénarios d'itération personnalisés à l'aide de ces derniers.


IMPORTANT
Le message d'Ansible en amont a évolué depuis Ansible 2.5. Il est recommandé d'utiliser le mot-clé loop au lieu des boucles with_*, mais il existe des cas d'utilisation où l'ancienne syntaxe peut être plus adaptée. Conformément à la documentation, la syntaxe with_* n'est pas obsolète et doit être encore valide dans un avenir proche. La syntaxe de loop peut continuer à évoluer dans les versions à venir d'Ansible.

Voici quelques astuces clés, basées sur les conseils en amont d'Ansible 2.8 :

  • Le mot-clé loop requiert une liste et n'accepte pas de chaîne. Si cela vous pose problème, souvenez-vous de la différence entre lookup et query.
  • Toute utilisation de with_* qui est décrite dans « Migration de with_X vers loop » [1] peut être convertie en toute sécurité.

Ces derniers utilisent principalement des filtres.

  • Si vous avez besoin d'utiliser un plug-in de recherche pour convertir une construction with_* afin d'utiliser loop, il peut être plus clair de continuer à utiliser la syntaxe with_*.

Scénarios d'itération

Les exemples suivants montrent comment créer des boucles plus complexes à l'aide d'expressions Jinja2, de filtres, de plug-ins de recherche et de la syntaxe with_*.

Liste de listes

Le mot-clé with_items permet d'effectuer une itération sur des listes complexes. Prenons l'exemple d'un playbook hypothétique avec la tâche suivante :

- name: Remove build files
  file:
    path: "{{ item }}"
    state: absent
  with_items:
    - "{{ app_a_tmp_files }}"
    - "{{ app_b_tmp_files }}"
    - "{{ app_c_tmp_files }}"

La variable app_a_tmp_files contient une liste de fichiers temporaires, tout comme app_b_tmp_files et app_c_tmp_files. Le mot-clé with_items associe ces trois listes en une seule liste contenant les entrées des trois listes. Elle effectue automatiquement un aplatissement des niveaux de la liste.

Pour refactoriser une tâche with_items afin d'utiliser le mot-clé loop, utilisez le filtre flatten.

Le filtre flatten recherche de manière récursive les listes incorporées et crée une liste unique à partir des valeurs découvertes.

Le filtre flatten accepte un argument levels qui spécifie un nombre entier de niveaux à rechercher pour les listes incorporées. Un argument {{{1}}} spécifie que les valeurs sont obtenues uniquement par ordre décroissant dans une liste supplémentaire pour chaque élément de la liste initiale. Il s'agit du même aplatissement de niveau que celui obtenu implicitement par with_items.

Pour refactoriser une tâche with_items afin d'utiliser le mot-clé loop, vous devez également utiliser le filtre {{{1}}} :

- name: Remove build files
  file:
    path: "{{ item }}"
    state: absent
  loop: "{{ list_of_lists | flatten(levels=1) }}"
  vars:
    list_of_lists:
      - "{{ app_a_tmp_files }}"
      - "{{ app_b_tmp_files }}"
      - "{{ app_c_tmp_files }}"


IMPORTANT
Étant donné que loop ne procède pas à l'aplatissement implicite d'un niveau, il n'est pas exactement équivalent à with_items. Cependant, tant que la liste transmise à la boucle est une simple liste, les deux méthodes se comportent de manière identique. La distinction a de l'importance uniquement si vous disposez

d'une liste de listes.