ansible

Execute Ansible task only when file exists


I have the following playbook that I want to use to enforce ACL's for directories, but only if those paths exist. What I can't figure out is how to reference my paths with __path after I run a stat task against it:

---
- hosts: all
  become: true
  gather_facts: yes
  vars:
    paths:
      - name: test-group-1
        path: '/path/to/folder/1'
        entity: group1
        etype: group
        permissions: rwX
      - name: test-group-2
        path: '/path/to/folder/2'
        entity: group2
        etype: group
        permissions: rwX
  tasks:
    - name: Get path information.
      ansible.builtin.stat:
        path: "{{ item.path }}"
      register: __path
      with_items: "{{ paths }}"

    - name: Debug
      ansible.builtin.debug:
        msg: "{{ item.stat.path}}"
      with_items: "{{ __path.results }}"

    - name: Set default ACL's.
      ansible.posix.acl:
        path: "{{ item.path }}"
        entity: "{{ item.entity}}"
        permissions: "{{ item.permissions }}"
        etype: group
        state: present
        default: true
      with_items: "{{ paths }}"
      when: "__path | selectattr('path', 'equalto', item.path) | list | length > 0"

Solution

  • The key here is to loop over the results from your ansible.builtin.stat loop rather than sticking to your original paths. Each items in the results list will contain the info from the stat action as well as an item dict containing the orginal item from the loop.

    So you can loop over that list filtering out non existent files. Here's a modified playbook which should meet your target

    - hosts: all
      become: true
      gather_facts: yes
      vars:
        paths:
          - name: test-group-1
            path: '/path/to/folder/1'
            entity: group1
            etype: group
            permissions: rwX
          - name: test-group-2
            path: '/path/to/folder/2'
            entity: group2
            etype: group
            permissions: rwX
      tasks:
        - name: Get path information.
          ansible.builtin.stat:
            path: "{{ item.path }}"
          register: __paths
          with_items: "{{ paths }}"
    
        - name: Debug the stat var filtered out from non existent files
          ansible.builtin.debug:
            var: __paths.results | selectattr("stat.exists")
    
        - name: Set default ACL's.
          ansible.posix.acl:
            path: "{{ current_stat.item.path }}"
            entity: "{{ current_stat.item.entity}}"
            permissions: "{{ current_stat.item.permissions }}"
            etype: "{{ current_stat.item.etype }}"
            state: present
            default: true
          loop: "{{ __paths.results | selectattr('stat.exists') }}"
          loop_control:
            # Replace 'item' with a meaningful name at top level for clarity
            loop_var: current_stat
            # Display only original item data for clarity
            label: "{{ current_stat.item }}"