exeral
exeral

Reputation: 229

ansible loop list and range

I have a list:

['bob', 'john', 'jack', 'rick']

I have a fixed range: 10,20 step: 2

I want to build this variable:

my_var:
  - name: bob
    content: '10'
  - name: john
    content: '12'
  - name: jack
    content: '14'
  - name: rick
    content: '16'

It seems I have to use loop but I don't understand how !

Upvotes: 0

Views: 4822

Answers (1)

Vladimir Botka
Vladimir Botka

Reputation: 67959

Loop the lists with the zip filter. For example, the playbook

- hosts: localhost
  vars:
    my_users: [bob, john, jack, rick]
  tasks:
    - set_fact:
        my_var: "{{ my_var|default([]) +
                    [{'name': item.1, 'content': item.0}] }}"
      loop: "{{ range(10,20,2)|zip(my_users)|list }}"
    - debug:
        var: my_var

gives

  my_var:
    - {content: 10, name: bob}
    - {content: 12, name: john}
    - {content: 14, name: jack}
    - {content: 16, name: rick}

The iteration is not needed if you can use the collection community.general. For example, the playbook below gives the same result

- hosts: localhost
  vars:
    my_users: [bob, john, jack, rick]
    my_var: "{{ range(10,20,2)|
                zip(my_users)|
                map('zip', ['content', 'name'])|
                map('map', 'reverse')|
                map('community.general.dict')|
                list }}"
  tasks:
    - debug:
        var: my_var

The values of the attribute content are integers in both options above. Convert the integers to strings if you need them. For example, in the loop, change the task

    - set_fact:
        my_var: "{{ my_var|default([]) +
                    [{'name': item.1, 'content': item.0|string}] }}"
      loop: "{{ range(10,20,2)|zip(my_users)|list }}"

, or change the declaration

    my_var: "{{ range(10,20,2)|map('string')|
                zip(my_users)|
                map('zip', ['content', 'name'])|
                map('map', 'reverse')|
                map('community.general.dict')|
                list }}"

Both options give the same result (note the quoted numbers (strings) instead of the unquoted numbers in the first two options)

  my_var:
    - {content: '10', name: bob}
    - {content: '12', name: john}
    - {content: '14', name: jack}
    - {content: '16', name: rick}

Upvotes: 2

Related Questions