hosts: all
become: true
vars:
collect_dirs:

  • /tmp/pki
  • /etc/pki
  • /opt/app/certs

tasks:

  • name: Check directories

ansible.builtin.stat:
path: "{{ item }}"
loop: "{{ collect_dirs }}"
register: dir_checks

  • name: Find files in existing directories

ansible.builtin.find:
paths: "{{ item.item }}"
recurse: true
file_type: file
loop: "{{ dir_checks.results }}"
register: found_files
when:

  • item.stat.exists
  • item.stat.isdir

loop_control:
label: "{{ item.item }}"

  • name: Fetch files from existing directories

ansible.builtin.fetch:
src: "{{ item.1.path }}"
dest: "collected/{{ inventory_hostname }}/"
flat: false
loop: "{{ found_files.results | subelements('files', skip_missing=True) }}"
loop_control:
label: "{{ item.1.path }}"

###################################

  • name: Archive remote directories and fetch archive

hosts: all
become: true
vars:
collect_dirs:

  • /tmp/pki
  • /etc/pki
  • /opt/app/certs

remote_archive: "/tmp/{{ inventory_hostname }}-collect.tar.gz"
local_collect_dir: "collected/"

tasks:

  • name: Check which directories exist

ansible.builtin.stat:
path: "{{ item }}"
loop: "{{ collect_dirs }}"
register: dir_checks

  • name: Build list of existing directories

ansible.builtin.set_fact:
existing_collect_dirs: >-
{{
dir_checks.results
| selectattr('stat.exists', 'defined')
| selectattr('stat.exists')
| selectattr('stat.isdir')
| map(attribute='item')
| list
}}

  • name: Create archive from existing directories

community.general.archive:
path: "{{ existing_collect_dirs }}"
dest: "{{ remote_archive }}"
format: gz
remove: false
when: existing_collect_dirs | length > 0

  • name: Fetch archive to control node

ansible.builtin.fetch:
src: "{{ remote_archive }}"
dest: "{{ local_collect_dir }}"
flat: false
when: existing_collect_dirs | length > 0

  • name: Remove temporary archive from remote host

ansible.builtin.file:
path: "{{ remote_archive }}"
state: absent
when: existing_collect_dirs | length > 0

[file-name 000359_2026-04-06_15-13-25.txt]