Loop e nested loop in Ansible

Andrea Dainese
29 Settembre 2023
Post cover

A mio parere uno dei costrutti meno comprensibili di Ansible riguarda la gestione dei loop. Se poi parliamo di loop annidati, la situazione è ancora più complessa. In questo breve post vediamo le ricette per:

  • loop su una lista;
  • loop su un dizionario;
  • loop annidati.

Loop su una lista

Il loop più semplice prevede di usare una lista ed effettuare una serie di azioni su ciascun elemento, di default item:

- ansible.builtin.debug:
  msg: "Now reading {{ item }}"
  with_items: "{{ list1 }}"

Come vediamo, all’interno del loop l’elemento è accessibile mediante la variabile item.

Loop su un dizionario

Se stiamo facendo un loop (non sarebbe il termine corretto) su un dizionario, probabilmente avremo bisogno di accedere sia alla chiave che al valore. La sintassi è simile al caso precedente:

- ansible.builtin.debug:
  msg: "Now reading {{ item.key }} by {{ item.value }}"
  with_dict: "{{ dict1 }}"

Vediamo in questo caso che la chiave è accessibile tramite item.key mentre il valore associato tramite item.value.

Loop annidati

Se abbiamo bisogno di utilizzare loop annidati, la sintassi si complica e avremo bisogno di appoggiarci a file esterni. Vediamo la sintassi:

- ansible.builtin.include_tasks: sub_task1.yml
  with_items: "{{ list1 }}"
  loop_control:
  loop_var: outer_item

Per ciascun elemento contenuto nella lista list1, il playbook eseguirà i task contenuti nel file sub_task1.yml. Nell’esecuzione dei sotto task, l’elemento corrente è accessibile tramite la variabile outer_item:

- ansible.builtin.debug:
  msg: "Now reading {{ outer_item }} from outer loop"

Nello stesso file possiamo eseguire un ulteriore loop, chiamando un terzo file:

- ansible.builtin.include_tasks: sub_task2.yml
  with_items: "{{ list2 }}"
  loop_control:
  loop_var: inner_item

Il file sub_task2.yml definisce i task che useranno le variabili dal primo (outer) e secondo (inner) loop:

- ansible.builtin.debug:
  msg: "Now reading {{ outer_item}} / {{ inner_item }} from inner loop"