Loop debug msg a json array

Viewed 129

The original playbook is like this:

- debug:
    msg:
      - "{{ intvlan.results[0].cde }}"
      - "{{ intvlan.results[1].cde }}"
      - "{{ intvlan.results[2].cde }}"
      - "{{ intvlan.results[3].cde }}"

And I want to change it into a loop.
So, I changed the code as below:

vars:
  package:
    - { iterations: '1'}
    - { iterations: '2'}
    - { iterations: '3'}
    - { iterations: '4'}

tasks:
  - debug:
      msg:
        - "{{ intvlan.results[{{ item.iterations }}].cde }}"
        - "{{ intvlan.results[{{ item.iterations }}].cde }}"
        - "{{ intvlan.results[{{ item.iterations }}].cde }}"
        - "{{ intvlan.results[{{ item.iterations }}].cde }}"
    loop: "{{ package }}"

And I've got the msg as below:

The error was: 'list object' has no attribute '{{item.iterations}}

What is the problem?

2 Answers

In Ansible, moustaches don't stack.


Other mistakes you have include:

  • your package.*.iterations variables are string when your intvlan.results variable is a list, and, so, it expects int rather:
    iterations: 1
    
    and not
    iterations: '1'
    
  • your package.*.iterations are in the range 1..4 when a list is zero-indexed, so 0..3 rather.

With all this:

- debug:
    msg: "{{ intvlan.results[item.iterations].cde }}"
  loop: "{{ package }}"
  vars:
    package:
      - iterations: 0
      - iterations: 1
      - iterations: 2
      - iterations: 3

Still, it seems to me like an overcomplicated way to go.
The simple way would be:

- debug:
    msg: "{{ item.cde }}"
  loop: "{{ intvlan.results }}"

If you want to loop over debug message, then you should have debug message once and do the iteration from loop. Also I think you are looking to generate a sequence of numbers to target the nth elements of intvlan.results.

There is an option to loop over a range (of numbers).

Example:

  - debug:
      msg: "{{ intvlan.results[item].cde }}"
    loop: "{{ range(0, 4) | list }}"

Also as mentioned in my comment you may be able to iterate with loop: "{{ intvlan.results }}" itself.

Related