Les boucles with avec ansible

Print Friendly, PDF & Email

Continuons sur notre formation ansible. Alors que j’ai tourné la 123ème d’un cours qui sera assez complet sur ansible, je vous propose de continuer progressivement après notre article sur stat et register. Pour les personnes qui souhaitent accéder à ces vidéos sans attendre, elles sont déjà disponibles pour les membres VIP de la chaine xavki qui la soutiennent.

En matière de formation, je pense qu’il faut être progressif et patient. C’est pour cela que je préfère aborder quelques notions au début mais sans brûler les étapes.

Aujourd’hui nous allons nous former à l’utilisation des boucles dans ansible. Les principales sont faciles à retenir car elles commencent par : with_*. La plus répandu étant with_items.

Avant de commencer, il me semble nécessaire de préciser que ansible est en cours d’évolutions dans ce domaine. L’objectif est de basculer à loop et remplacer potentiellement les with_*. Pour le moment nous n’en sommes pas là et les with_* sont plus faciles à aborder et retenir pour commencer. La documentation précise bien que cette migration ne se fait pas rapidement et que with_* possède encore de beaux jours devant lui, on est loin de le voir déprécier.

Les différentes boucles possible avec with

Si loop ne remplace pas encore les with, c’est essentiellement car il en existe de nombreux et que chacun dispose de boucler sur une fonctionnalité particulière :

  • with_items : sur une liste de dictionnaire (ensemble de clefs/valeurs)
  • with_nested : sur une liste de listes
  • with_dict : parcourir un dictionnaire
  • with_fileglob : sur une liste de fichiers de répertoire avec ou sans pattern mais non récursif
  • with_filetree : sur une liste de fichier d’une arborescence (recursif) et avec pattern
  • with_together : permet de croiser 2 listes
  • with_sequence : pour parcourir un range (interval)
  • with_random_choice : tirage aléatoire dans une liste
  • with_first_found : sur le premier élément trouvé d’une liste
  • with_lines : pour parcourir chaque ligne d’un programme (exemple : shell)
  • with_ini : pour parcourir un fichier au format ini
  • with_inventory_hostnames : pour récupérer et parcourir des éléments d’un inventaire
Découvrez  Ansible - les différents niveaux de variables

On a donc du choix, mes préférés étant with_items et with_fileglob principalement.

Comment utiliser with_* avec ansible ?

C’est très simple. Les éléments d’entrées sont définis dans le with_* et en sortie sont utilisable par une variable “item”. En cas d’éléments si disposant de plusieurs clefs ont les utilisera avec “item.clef1”, “item.clef2″…

Dans le cas le plus simple nous pouvons commencer par parcourir une simple lite d’éléments :

  - name: boucle création de répertoire
    file:
      path: /tmp/xavki/{{ item }}
      state: directory
      recurse: yes
    with_items:
    - xavki1
    - xavki2
    - xavki3
    - xavki4

Ou encore, dans un playbook, nous pouvons faire un test avec une liste de dictionnaires :

  - name: création de fichiers
    file:
      path: /tmp/xavki/{{ item.dir }}/{{ item.file }}
      state: touch
    with_items:
    - { dir: "xavki1", file: "fichierA"}
    - { dir: "xavki2", file: "fichierB"}
    - { dir: "xavki3", file: "fichierC"}
    - { dir: "xavki4", file: "fichierD"}

Nos clefs sont “dir” et “file” et donc nous allons les utiliser avec item.dir et item.file. Ansible fait le reste pour parcourir la boucle. C’est assez facile pour débuter !!! ou encore en passant par une variable.

  vars:
    fichiers:
    - { dir: "xavki1", file: "fichierA"}
    - { dir: "xavki2", file: "fichierB"}
    - { dir: "xavki3", file: "fichierC"}
    - { dir: "xavki4", file: "fichierD"}
  tasks:
  - name: création de fichiers
    file:
      path: /tmp/xavki/{{ item.dir }}/{{ item.file }}
      state: touch
    with_items:
    - "{{ fichiers }}"

Alors maintenant imaginons que nous souhaitions parcourir les machines composant un groupe de notre inventaire. Le premier réflexe en méconnaissant les boucles serait de faire la chose suivante :

 with_items:
    - "{{ groups['all'] }}"

C’est fonctionnel car on pourra bien récupérer la liste des machines avec la variable “item” de notre with_items. Mais nous l’avons vu , il existe un with dédié à cette tâche with_inventory_hostnames. Ainsi nous pouvons le faire de cette manière :

  - name: création de fichiers
    file:
      path: /tmp/{{ item }}
      state: touch
    with_inventory_hostnames:
    - all

Les boucles un outil indispensable

Clairement nous ne verrons pas d’exemples dans cet article. L’idéal pour manipuler les boucles c’est la pratique d’exemples réels. Cela fera l’objet des TP.

Découvrez  [Ansible] : le samedi c'est debug de mon erreur avec include_tasks

Ainsi les boucles vont nous permettre de définir des variables de types dictionnaires de manière à être en mode descriptif et avoir des blocs qui représentent notre infrastructure. Le with_fileglob nécessite un peu plus de pratique et de recul sur la manière d’organiser un code d’infra as code. Ainsi, nous allons pouvoir nous en servir pour sépcifier un répertoire contenant des usitsateurs : clefs ssh, login… Et une fois cela réalisé il ne restera qu’à récupérer les variables contenues dans ces fichiers. Ce point est l’un de mes préférés sur ansible donc nous n’y couperons pas.

Si vous souhaitez ne pas manquer les prochaines vidéos, vous pouvez vous abonner. Et pour m’aider encore plus vous pouvez éventuellement liker les vidéos.