Ansible find Module: Search Files and Directories (Complete Guide)
By Luca Berton · Published 2024-01-01 · Category: troubleshooting
How to use Ansible find module to search for files, directories, and links. Filter by name, age, size, regex patterns.
Ansible find Module: Search Files and Directories (Complete Guide)
The ansible.builtin.find module searches for files, directories, and links on remote hosts. Filter by name patterns, age, size, content, and more — then use the results in subsequent tasks.
See also: ansible.builtin.find Module: Search Files by Pattern, Size & Age (Guide)
Basic Usage
- name: Find all log files
ansible.builtin.find:
paths: /var/log
patterns: '*.log'
register: log_files
- name: Show found files
ansible.builtin.debug:
msg: "Found {{ log_files.files | length }} log files"
Filter by Pattern
# Glob patterns
- name: Find config files
ansible.builtin.find:
paths: /etc
patterns:
- '*.conf'
- '*.cfg'
recurse: true
register: configs
# Regex patterns
- name: Find numbered log files
ansible.builtin.find:
paths: /var/log
patterns: '^app\.\d+\.log$'
use_regex: true
See also: Ansible Search String in File: lineinfile & regex Guide
Filter by Age
# Files older than 30 days
- name: Find old log files
ansible.builtin.find:
paths: /var/log/myapp
patterns: '*.log'
age: 30d
register: old_logs
# Files newer than 1 hour
- name: Find recently modified files
ansible.builtin.find:
paths: /opt/myapp/uploads
age: -1h
age_stamp: mtime
Age units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
Filter by Size
# Files larger than 100MB
- name: Find large files
ansible.builtin.find:
paths: /var/log
size: 100m
recurse: true
register: large_files
# Files smaller than 1KB (possibly empty)
- name: Find tiny files
ansible.builtin.find:
paths: /opt/myapp/data
size: -1k
Size units: b (bytes), k (KB), m (MB), g (GB).
See also: Ansible file Module: Create Files, Directories, Symlinks (Complete Guide)
Filter by Type
# Only directories
- name: Find subdirectories
ansible.builtin.find:
paths: /opt/myapp/releases
file_type: directory
register: release_dirs
# Only symlinks
- name: Find broken symlinks
ansible.builtin.find:
paths: /opt/myapp
file_type: link
follow: false
recurse: true
Filter by Content
# Files containing specific text
- name: Find files with TODO comments
ansible.builtin.find:
paths: /opt/myapp/src
patterns: '*.py'
contains: 'TODO|FIXME|HACK'
recurse: true
register: todo_files
Find and Delete
- name: Find old log files
ansible.builtin.find:
paths: /var/log/myapp
patterns: '*.log'
age: 30d
register: old_logs
- name: Delete old log files
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_logs.files }}"
when: old_logs.matched > 0
Find and Archive
- name: Find files to archive
ansible.builtin.find:
paths: /opt/myapp/reports
patterns: '*.csv'
age: 7d
register: old_reports
- name: Archive old reports
community.general.archive:
path: "{{ old_reports.files | map(attribute='path') | list }}"
dest: /backup/reports-archive.tar.gz
remove: true
when: old_reports.matched > 0
Working with Results
- name: Find log files
ansible.builtin.find:
paths: /var/log
patterns: '*.log'
recurse: true
register: result
# result.files is a list of dicts with:
# path, mode, size, uid, gid, atime, mtime, ctime, ...
# result.matched = count of found files
# result.examined = count of files checked
- name: Show total size
ansible.builtin.debug:
msg: "Total: {{ result.files | map(attribute='size') | sum | human_readable }}"
- name: Show largest files
ansible.builtin.debug:
msg: "{{ item.path }} ({{ item.size | human_readable }})"
loop: "{{ result.files | sort(attribute='size', reverse=true) }}"
loop_control:
label: "{{ item.path }}"
when: result.matched > 0
Common Patterns
Cleanup Old Releases
- name: Find old releases
ansible.builtin.find:
paths: /opt/myapp/releases
file_type: directory
register: releases
- name: Keep only 5 latest releases
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ releases.files | sort(attribute='mtime') | list }}"
loop_control:
label: "{{ item.path | basename }}"
when: releases.matched > 5
with_items: "{{ (releases.files | sort(attribute='mtime'))[:-5] }}"
Find Files with Wrong Permissions
- name: Find world-writable files
ansible.builtin.find:
paths: /opt/myapp
recurse: true
file_type: file
register: all_files
- name: Fix world-writable files
ansible.builtin.file:
path: "{{ item.path }}"
mode: '0644'
loop: "{{ all_files.files }}"
when: item.mode[-1] | int >= 6
loop_control:
label: "{{ item.path }}"
FAQ
How do I find files in Ansible?
Use ansible.builtin.find with paths and patterns. Set recurse: true to search subdirectories. Register the result to use found files in subsequent tasks.
How do I find and delete old files in Ansible?
First find with an age filter (e.g., age: 30d), register the result, then loop over result.files with ansible.builtin.file: state=absent to delete them.
What is the difference between find and stat modules?
find searches for multiple files matching criteria (patterns, age, size). stat checks properties of a single known file path. Use find for discovery, stat for verification.
Can I search file contents with Ansible find?
Yes, use the contains parameter with a regex pattern: contains: 'ERROR|WARNING'. This searches file content on the remote host and returns files that match.
How do I use regex patterns with Ansible find?
Set use_regex: true and provide regex in patterns: patterns: '^access_\d{4}\.log$'. Without use_regex, patterns use glob syntax (*.log).
Conclusion
The ansible.builtin.find module is essential for file management automation — cleanup, auditing, archiving, and discovery. Combine it with file, fetch, or archive modules for complete file lifecycle management.
Related Articles
• Ansible file Module: Manage Files and Directories • Ansible fetch Module: Download Files from Hosts • Ansible stat Module: Check File PropertiesCategory: troubleshooting