Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to loop in Ansible $var number of times?

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.

like image 301
jwbensley Avatar asked Apr 07 '17 16:04

jwbensley


People also ask

What is {{ item }} Ansible?

item is not a command, but a variable automatically created and populated by Ansible in tasks which use loops. In the following example: - debug: msg: "{{ item }}" with_items: - first - second. the task will be run twice: first time with the variable item set to first , the second time with second .

How do you make an Ansible playbook loop?

When creating loops, Ansible provides these two directives: loop and with_* keyword. The loop keyword was recently added to Ansible 2.5. The loop keyword is usually used to create simple and standard loops that iterate through several items.

Is there a for loop in Ansible?

Ansible provides the loop , with_<lookup> , and until keywords to execute a task multiple times.


1 Answers

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.

like image 187
Konstantin Suvorov Avatar answered Oct 01 '22 16:10

Konstantin Suvorov