Double with_items loop in ansible

p305 picture p305 · Nov 2, 2018 · Viewed 12k times · Source

I want to create a double loop in ansible. I have one things like this :

userslist:
  - name: user1
    primary : user1-group
    groups :
       - group1
       - group2
  - name: user2
    primary : user2-group
    groups :
       - group3
       - group4

- name : Creating Secondary group
  group :
    name : "{{ item.groups }}"
    state: present
  with_items: "{{ userslist}}"

Is it possible for each users create each secondary group ? I think for this i need to do a second with_items loop but i don't know how

Answer

George Shuklin picture George Shuklin · Nov 2, 2018

There are two ways to make a nested (double) loop in Ansible.

  • with_nested. It allows you to have an inner iteration for object you iterate in the outer loop. Examples and explanation are provided in the official documentation: https://docs.ansible.com/ansible/2.5/plugins/lookup/nested.html

  • using with_items together with include_tasks. This is a complicated yet powerful construction. In theory there is no limit (except for the stack depth) on how nested this construction can be.

It requires to put inner code into a separate tasklist. I'll show it with outer.yaml and inner.yaml, outer perform loop over a list, and inner perform a loop over item (loop variable) of the outer loop.

outer.yaml:

- name: Loop over foo
  include_tasks: inner.yaml
  with_items: '{{ foo }}'
  loop_control:
     loop_var: inner_var_name
  vars:
   foo:
    - [1, 2, 3]
    - [a, b, c]

inner.yaml:

- name: Performing operation one
  debug: msg="Action one for {{ item }}"
  with_items: '{{ inner_var_name }}'

- name: Performing operation two
  debug: msg="Action two for {{item}}"
  with_items: '{{ inner_var_name }}'

The key advantage of this method is that inner.yaml can contain any number of statements, all of which will be processed in a loop from outer.yaml.

One important thing: all include things require a bit of caution with anything related to passing values (set_fact, register, etc) from included code. In is rather tricky and non-obvious, so my advice is never use variables set in include code outside of that inclusion.