0

My environment:

# cat /etc/debian_version
11.7
# ansible-playbook --version
ansible-playbook [core 2.13.1]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.9/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110]
  jinja version = 3.1.2
  libyaml = True
#

The following task is part of my Ansible role:

- name: _file - state:absent
  ansible.builtin.file:
    path: "{{ item.path }}"
    state: absent
  loop: "{{ find.files | flatten }}"
  register: file
  when: find.matched is defined and find.matched != 0

yet, I've noticed a warning message:

[WARNING]: TASK: XYZ : _file - state:absent: The loop variable 'item' is already in use. You should set the loop_var value in the loop_control option for the task to something else to avoid variable collisions and unexpected behavior.

after reading some:

I modified my task to something like this:

- name: _file - state:absent
  ansible.builtin.file:
    path: "{{ item.path }}"
    state: absent
  loop: "{{ find.files | flatten }}"
  loop_control:
    label: "{{ item.path }}"
    loop_var: find
  register: file
  when: find.matched is defined and find.matched != 0

this task is being called twice within my role, while first time it works fine, second time it fails

TASK [XYZ : _file - state:absent] ******************************************************************************************************************************************************************************
[WARNING]: TASK: XYZ : _file - state:absent: The loop variable 'find' is already in use. You should set the `loop_var` value in the `loop_control` option for the task to something else to avoid variable
collisions and unexpected behavior.
failed: [127.0.0.1] (item=None) => {"ansible_loop_var": "find", "changed": false, "find": {"atime": 1683511713.8529496, "checksum": "ecd34202c34bf761e4c2c9800a39e18dffad5d9e", "ctime": 1683511714.972948, "dev": 2049, "gid": 0, "gr_name": "root", "inode": 150677, "isblk": false, "ischr": false, "isdir": false, "isfifo": false, "isgid": false, "islnk": false, "isreg": true, "issock": false, "isuid": false, "mode": "0644", "mtime": 1683511714.972948, "nlink": 1, "path": "tmp/FILE.CSV", "pw_name": "root", "rgrp": true, "roth": true, "rusr": true, "size": 642, "uid": 0, "wgrp": false, "woth": false, "wusr": true, "xgrp": false, "xoth": false, "xusr": false}, "msg": "Failed to template loop_control.label: 'item' is undefined", "skip_reason": "Conditional result was False"}

Please advise.

1
  • 1
    You should provide the outer loop as well. edit the question and make it mre . May 8 at 3:44

1 Answer 1

1

It's unclear why you need the (undocumented) outer loop that registers the variable item. For example, given the tree

shell> tree /tmp/test
/tmp/test
├── file1
├── file2
└── file3

the play below

shell> cat pb.yml
- hosts: localhost

  tasks:

    - find:
        paths: /tmp/test
      register: find

    - file:
        path: "{{ item.path }}"
        state: absent
      loop: "{{ find.files }}"
      loop_control:
        label: "{{ item.path }}"

gives running in --check --diff mode

shell> ansible-playbook -CD pb.yml

PLAY [localhost] ******************************************************************************

TASK [find] ***********************************************************************************
ok: [localhost]

TASK [file] ***********************************************************************************
--- before
+++ after
@@ -1,2 +1,2 @@
 path: /tmp/test/file3
-state: file
+state: absent

changed: [localhost] => (item=/tmp/test/file3)
--- before
+++ after
@@ -1,2 +1,2 @@
 path: /tmp/test/file2
-state: file
+state: absent

changed: [localhost] => (item=/tmp/test/file2)
--- before
+++ after
@@ -1,2 +1,2 @@
 path: /tmp/test/file1
-state: file
+state: absent

changed: [localhost] => (item=/tmp/test/file1)

PLAY RECAP ************************************************************************************
localhost: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Notes:

  • If you define loop_var use it. The task below gives the same results
- file:
    path: "{{ my_loop_var.path }}"
    state: absent
  loop: "{{ find.files }}"
  loop_control:
    label: "{{ my_loop_var.path }}"
    loop_var: my_loop_var
  • The condition below is redundant. Remove it. When nothing is found (find.matched: 0) the list of files is empty (fined.files: []) and the loop will be skipped anyway
  when: find.matched is defined and find.matched != 0
  • There is nothing to flatten if find is the registered variable of the module find. The filter flatten can be removed
  loop: "{{ find.files }}"
1
  • i completely misunderstood how that suppose to work, but i've got it now) thank you! btw, when is used to make sure to run role to the end, without errors (skips are okay).
    – alexus
    May 8 at 16:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .