Ansible Delete Files in Directory: find & file Modules (Examples)
By Luca Berton · Published 2024-01-01 · Category: troubleshooting
How to delete only files inside a directory in Ansible using find and file modules. Clean up logs, temp files, and old backups by age, pattern, and size.

How to Delete Only Files Inside a Directory with Ansible?
I'm going to show you a live Playbook with some simple Ansible code. I'm Luca Berton and welcome to today's episode of Ansible Pilot.See also: Ansible Delete File: Remove Files & Directories with file Module
Ansible How to Delete Only Files Inside a Directory
•ansible.builtin.find
• Return a list of files based on specific criteria
Today we're talking about the Ansible module find.
The full name is ansible.builtin.find, which means that is part of the collection included in the ansible-core builtin collection.
This module returns a list of files based on specific criteria using the find popular Unix command.
Parameters
• paths string - List of paths of directories to search • hidden boolean - no/yes • recurse boolean - recursively descend into the directory looking for files • file_type string - file/directory/any/linkThe most important parameters of the find module for this use case.
The mandatory parameter paths specify the list of paths of directories to search.
You could include hidden files with the hidden parameter.
As well as recurse in any directory under the main path with the recurse parameter.
Another useful parameter is file_type, defaults to file but you could filter for directory, link or any filesystem object type.
See also: Ansible Backup Windows 10/11/2019/2022: win_robocopy Playbook (Guide)
Links
• ansible.builtin.find • ansible.builtin.file## Playbook
How to delete Ooly files inside a directory with Ansible Playbook.
I'm going to delete only the files and directories under the example folder of my login user (devops).
code
---
- name: delete file(s) in dir Playbook
hosts: all
vars:
mypath: "/home/devops/example"
tasks:
- name: collect files
ansible.builtin.find:
paths: "{{ mypath }}"
hidden: true
recurse: true
file_type: any
register: collected_files
- name: remove collected files
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
with_items: "{{ collected_files }}"
execution
$ ansible-playbook -i virtualmachines/demo/inventory delete\ file\ or\ directory/file_onlyfiles.yml
PLAY [delete file(s) in dir Playbook] *****************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [collect files] ******************************************************************************
ok: [demo.example.com]
TASK [remove collected files and directories] *****************************************************
changed: [demo.example.com] => (item={'path': '/home/devops/example/file1.txt', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 1001, 'gid': 10, 'size': 0, 'inode': 484310, 'dev': 64768, 'nlink': 1, 'atime': 1652197335.6893907, 'mtime': 1652197335.6893907, 'ctime': 1652197335.6893907, 'gr_name': 'wheel', 'pw_name': 'devops', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False})
changed: [demo.example.com] => (item={'path': '/home/devops/example/file2.txt', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 1001, 'gid': 10, 'size': 0, 'inode': 484311, 'dev': 64768, 'nlink': 1, 'atime': 1652197337.6393802, 'mtime': 1652197337.6393802, 'ctime': 1652197337.6393802, 'gr_name': 'wheel', 'pw_name': 'devops', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False})
changed: [demo.example.com] => (item={'path': '/home/devops/example/deleteme', 'mode': '0755', 'isdir': True, 'ischr': False, 'isblk': False, 'isreg': False, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 1001, 'gid': 10, 'size': 23, 'inode': 201823954, 'dev': 64768, 'nlink': 2, 'atime': 1652197359.8632617, 'mtime': 1652197356.4072802, 'ctime': 1652197356.4072802, 'gr_name': 'wheel', 'pw_name': 'devops', 'wusr': True, 'rusr': True, 'xusr': True, 'wgrp': False, 'rgrp': True, 'xgrp': True, 'woth': False, 'roth': True, 'xoth': True, 'isuid': False, 'isgid': False})
ok: [demo.example.com] => (item={'path': '/home/devops/example/deleteme/file3.txt', 'mode': '0644', 'isdir': False, 'ischr': False, 'isblk': False, 'isreg': True, 'isfifo': False, 'islnk': False, 'issock': False, 'uid': 1001, 'gid': 10, 'size': 0, 'inode': 201823955, 'dev': 64768, 'nlink': 1, 'atime': 1652197356.4072802, 'mtime': 1652197356.4072802, 'ctime': 1652197356.4072802, 'gr_name': 'wheel', 'pw_name': 'devops', 'wusr': True, 'rusr': True, 'xusr': False, 'wgrp': False, 'rgrp': True, 'xgrp': False, 'woth': False, 'roth': True, 'xoth': False, 'isuid': False, 'isgid': False})
PLAY RECAP ****************************************************************************************
demo.example.com : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
idempotency
$ ansible-playbook -i virtualmachines/demo/inventory delete\ file\ or\ directory/file_onlyfiles.yml
PLAY [delete file(s) in dir Playbook] *****************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [collect files] ******************************************************************************
ok: [demo.example.com]
TASK [remove collected files and directories] *****************************************************
PLAY RECAP ****************************************************************************************
demo.example.com : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
before execution
$ ssh devops@demo.example.com
[devops@demo ~]$ tree example/
example/
|-- deleteme
| `-- file3.txt
|-- file1.txt
`-- file2.txt
1 directory, 3 files
after execution
$ ssh devops@demo.example.com
[devops@demo ~]$ tree example/
example/
0 directories, 0 files
Conclusion
Now you know how to delete only files inside a directory with Ansible.See also: Ansible Create Directory: file Module with state=directory (Guide)
Delete All Files in Directory
- name: Find all files
ansible.builtin.find:
paths: /tmp/myapp
file_type: file
register: files_to_delete
- name: Delete found files
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ files_to_delete.files }}"
become: true
Delete by Pattern
- find:
paths: /var/log/myapp
patterns: "*.log.gz"
register: compressed_logs
- file: { path: "{{ item.path }}", state: absent }
loop: "{{ compressed_logs.files }}"
become: true
Delete by Age
# Delete files older than 30 days
- find:
paths: /var/log/myapp
age: 30d
file_type: file
register: old_files
- file: { path: "{{ item.path }}", state: absent }
loop: "{{ old_files.files }}"
become: true
Delete by Size
# Delete files larger than 100MB
- find:
paths: /var/log
size: 100m
file_type: file
recurse: true
register: large_files
- file: { path: "{{ item.path }}", state: absent }
loop: "{{ large_files.files }}"
become: true
Delete Files Recursively
- find:
paths: /opt/myapp/cache
recurse: true
file_type: file
register: cache_files
- file: { path: "{{ item.path }}", state: absent }
loop: "{{ cache_files.files }}"
Keep Directory, Delete Contents
# Method 1: Find and delete
- find:
paths: /tmp/build
file_type: any # Files AND directories
hidden: true
register: build_contents
- file: { path: "{{ item.path }}", state: absent }
loop: "{{ build_contents.files }}"
# Method 2: Remove and recreate
- file: { path: /tmp/build, state: absent }
- file: { path: /tmp/build, state: directory, mode: '0755' }
Exclude Pattern
# Delete everything EXCEPT .conf files
- find:
paths: /opt/myapp/config
excludes: "*.conf"
file_type: file
register: non_config
- file: { path: "{{ item.path }}", state: absent }
loop: "{{ non_config.files }}"
Combined Criteria
# Old log files larger than 10MB
- find:
paths: /var/log
patterns: "*.log*"
age: 7d
size: 10m
recurse: true
register: cleanup
- debug:
msg: "Cleaning {{ cleanup.files | length }} files ({{ cleanup.files | map(attribute='size') | sum // 1048576 }}MB)"
- file: { path: "{{ item.path }}", state: absent }
loop: "{{ cleanup.files }}"
become: true
find Module Parameters
| Parameter | Description |
|-----------|-------------|
| paths | Directories to search |
| patterns | Filename patterns (glob) |
| excludes | Patterns to exclude |
| age | Min age (e.g., 7d, 4w, 2m) |
| age_stamp | mtime, atime, or ctime |
| size | Min size (e.g., 10m, 1g) |
| file_type | file, directory, link, any |
| recurse | Search subdirectories |
| hidden | Include hidden files |
| contains | Regex to match file content |
FAQ
Why not just use shell: rm?
find + file is idempotent, handles errors gracefully, and reports exactly what changed. shell: rm is a black box to Ansible.
Can I delete empty directories?
- find:
paths: /opt/myapp
file_type: directory
recurse: true
register: dirs
# Then check each is empty before deleting
How do I do a dry run?
Just run the find task and print results without the file: absent task.
Related Articles
• Ansible inventory best practices • using the ansible.builtin.file moduleCategory: troubleshooting
Watch the video: Ansible Delete Files in Directory: find & file Modules (Examples) — Video Tutorial