Red Cricket
Red Cricket

Reputation: 10460

Confusion with range and with_items nested loops in Ansible

I have this play book that works fine ...

- hosts: localhost
  vars:
    repo_top: "."
    cluster: "ab01"
    stype: "xyz"
    start_zone: 10
    end_zone: 130
    sym_link_dests:
      - "../zones_foo/agent"
      - "../zones_bar/collaborate_zones"

  gather_facts: no
  tasks:
    - name: mkdir group_vars dir
      file:
        path: "{{ repo_top }}/group_vars/{{ cluster }}_oo_{{ stype }}{{ item }}"
        state: directory
      loop: "{{ range(start_zone, end_zone)|list}}"

    - name: Make symlink for ../zones_foo/agent
      shell:
        cmd: "ln -s ../zones_foo/agent"
        chdir: "{{ repo_top }}/group_vars/{{ cluster }}_oo_{{ stype }}{{ item }}"
      loop: "{{ range(start_zone, end_zone)|list}}"

    - name: Make symlink for ../zones_bar/collaborate_zones
      shell:
        cmd: "ln -s ../zones_bar/collaborate_zones"
        chdir: "{{ repo_top }}/group_vars/{{ cluster }}_oo_{{ stype }}{{ item }}"
      loop: "{{ range(start_zone, end_zone)|list}}"

... but I found out that the 'sym_link_dests' list will be growing by 100 or so items.
And I am not sure how to go about creating a nested loop. I do not seem to be able to find any examples where the out loop is a range and the second is with_items. ANy help is appreciated.

Upvotes: 1

Views: 276

Answers (2)

Red Cricket
Red Cricket

Reputation: 10460

Turns out it was straight forward. I don't know why I was having such a hard time:

    - name: Make symlinks
      shell:
        cmd: "ln -s {{ item[1] }}"
        chdir: "{{ repo_top }}/group_vars/{{ cluster }}_oo_{{ stype }}{{ item[0] }}"
      with_nested:
        - "{{ range(start_zone, end_zone)|list}}"
        - '{{ sym_link_dests }}'

Upvotes: 1

Zeitounator
Zeitounator

Reputation: 44595

Following my comment on your self-answer, here is a way to acheive the same result:

  1. using the product filter in a loop: stanza (same functionnality as with_nested in the new generation syntax).
  2. using the file module instead of shell. The trick here is that you must provide a name in the path that points to the exact file you want to create. You can easily get this with the basename filter. After that, things are easy as the src attribute accepts a relative path to the file being created.
    - name: Make symlinks
      file:
        path: "{{ repo_top }}/group_vars/{{ cluster }}_oo_{{ stype }}{{ item.0 }}/{{ item.1 | basename }}"
        src: "{{ item.1 }}"
        state: link
      loop: "{{ range(start_zone, end_zone) | list | product(sym_link_dests) }}"

Upvotes: 1

Related Questions