How to loop in Ansible $var number of times?

jwbensley picture jwbensley · Apr 7, 2017 · Viewed 10k times · Source

I want to run a loop in Ansible the number of times which is defined in a variable. Is this possible somehow?

Imagine a list of servers and we want to create some numbered files on each server. These values are defined in vars.yml:

server_list:
  server1:
    name: server1
    os: Linux
    num_files: 3
  server2:
    name: server2
    os: Linux
    num_files: 2

The output I desire is that the files /tmp/1, /tmp/2 and /tmp/3 are created on server1, /tmp/1 and /tmp/2 are created on server2. I have tried to write a playbook using with_nested, with_dict and with_subelements but I can't seem to find any way to to this:

- hosts: "{{ target }}"

  tasks:

    - name: Load vars
      include_vars: vars.yml

    - name: Create files
      command: touch /tmp/{{ loop_index? }}
      with_dict: {{ server_list[target] }}
      loop_control:
        loop_var: {{ item.value.num_files }}

If I needed to create 50 files on each server I can see how I could do this if I were to have a list variable for each server with 50 items in it list which is simply the numbers 1 to 50, but that would be a self defeating use of Ansible.

Answer

Konstantin Suvorov picture Konstantin Suvorov · Apr 7, 2017

There is a chapter in the docs: Looping over Integer Sequences (ver 2.4)

For your task:

- file:
    state: touch
    path: /tmp/{{ item }}
  with_sequence: start=1 end={{ server_list[target].num_files }}

Update: things has changed in Ansible 2.5. See separate docs page for sequence plugin.

New loop syntax is:

- file:
    state: touch
    path: /tmp/{{ item }}
  loop: "{{ query('sequence', 'start=1 end='+(server_list[target].num_files)|string) }}"

Unfortunately sequence accepts only string-formatted parameters, so parameters passing to query looks quite clumsy.