Ansible Delete File: Remove Files & Directories (state=absent Guide)
By Luca Berton · Published 2024-01-01 · Category: installation
How to delete files and directories in Ansible with the file module (state=absent). Remove files, recursive directory deletion, check before delete.

How to Delete files or directory with Ansible?
See also: ansible.builtin.find Module: Search Files by Pattern, Size & Age (Guide)
Ansible delete file/directory
Today we're talking about the Ansible module file.
The full name is ansible.builtin.file, which means that is part of the collection of modules "builtin" with ansible and shipped with it.
It's a module pretty stable and out for years.
It works in a different variety of operating systems.
It manages files and file properties.
For Windows targets, use the ansible.windows.win_file module instead.
Main Parameters
- path _string_ (dest, name) - file path
- owner _string_ - user
- group _string_ - group
- mode _raw_ - Ex: '0644' or 'u=rw,g=r,o=r'
- state _string_ - file/absent/directory/hard/link/touch
- setype/seuser/selevel - SELinux
## Playbook Let's jump into a real-life playbook on how to delete files or directories with Ansible.
- file.yml
---
- name: file module demo
hosts: all
vars:
mypath: "/home/devops/deleteme"
become: false
tasks:
- name: "{{ mypath }}" not present
ansible.builtin.file:
path: "{{ mypath }}"
state: "absent"See also: Ansible Search String in File: lineinfile & regex Guide
Conclusion
Now you know better the Ansible module win_chocolatey and how you could use it successfully in your playbook to automate your day-to-day activities.Advanced Deletion Examples
Delete with wildcard (using find module)
The file module doesn't support wildcards. Use find first:
- name: Find all .tmp files
ansible.builtin.find:
paths: /tmp
patterns: "*.tmp"
age: "7d" # Only files older than 7 days
register: old_files
- name: Delete old .tmp files
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_files.files }}"Delete multiple paths
- name: Clean up deployment artifacts
ansible.builtin.file:
path: "{{ item }}"
state: absent
loop:
- /tmp/build-cache
- /tmp/deploy-staging
- /var/log/myapp/old-logs
become: trueSafe deletion with confirmation
- name: Check what we're about to delete
ansible.builtin.stat:
path: "{{ delete_target }}"
register: target_info
- name: Fail if trying to delete system directory
ansible.builtin.fail:
msg: "Refusing to delete {{ delete_target }} — it's a system directory!"
when:
- target_info.stat.exists
- delete_target in ['/etc', '/usr', '/var', '/home', '/']
- name: Safe to delete
ansible.builtin.file:
path: "{{ delete_target }}"
state: absent
when: target_info.stat.existsDelete directory contents but keep the directory
- name: Find all files in directory
ansible.builtin.find:
paths: /opt/myapp/cache
file_type: any
register: cache_contents
- name: Delete directory contents
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ cache_contents.files }}"See also: Ansible Check If Directory Exists: stat Module Guide
Important Notes
⚠️ state: absent is recursive — deleting a directory removes everything inside it. There's no "trash" or "undo".
⚠️ No wildcard support — use find module + loop for pattern-based deletion.
⚠️ Idempotent — running state: absent on a non-existent path succeeds without error (changed=false).
FAQ
How do I delete a file on Windows?
- name: Delete file on Windows
ansible.windows.win_file:
path: C:\Temp\oldfile.txt
state: absentHow do I delete files matching a regex pattern?
- name: Find files matching regex
ansible.builtin.find:
paths: /var/log
patterns: "^app\.log\.\d+$"
use_regex: true
register: rotated_logs
- name: Delete matched files
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ rotated_logs.files }}"What happens if I delete a mounted filesystem?
Ansible deletes the mount point contents, not the underlying filesystem. This can cause unexpected data loss. Always check mount points before bulk deletion.
Delete File
- name: Remove config file
ansible.builtin.file:
path: /etc/myapp/old-config.yml
state: absent
become: trueDelete Directory (Recursive)
- name: Remove entire directory
ansible.builtin.file:
path: /opt/old-app
state: absent
become: true
# Removes directory and ALL contents (like rm -rf)Delete Multiple Files
- ansible.builtin.file:
path: "{{ item }}"
state: absent
loop:
- /tmp/deploy.tar.gz
- /tmp/installer.sh
- /var/log/myapp/debug.log
become: trueDelete with Find (Pattern)
# Find and delete old log files
- ansible.builtin.find:
paths: /var/log/myapp
patterns: "*.log.gz"
age: 30d
register: old_logs
- ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_logs.files }}"
become: trueDelete Symlink
- ansible.builtin.file:
path: /opt/myapp-current
state: absent # Removes link only, not targetCleanup Pattern
---
- name: Clean up after deployment
hosts: webservers
become: true
tasks:
- name: Remove temp files
file: { path: "{{ item }}", state: absent }
loop:
- /tmp/deploy-{{ version }}.tar.gz
- /opt/myapp/install.log
- /opt/myapp/.maintenance
- name: Remove old versions (keep last 3)
find:
paths: /opt/releases
file_type: directory
register: versions
- file:
path: "{{ item.path }}"
state: absent
loop: "{{ (versions.files | sort(attribute='mtime') | list)[:-3] }}"
when: versions.files | length > 3Check Before Delete
- stat: { path: /opt/myapp-old }
register: old_app
- file:
path: /opt/myapp-old
state: absent
when: old_app.stat.exists
become: trueWindows Delete
- ansible.windows.win_file:
path: C:\Temp\old-installer.exe
state: absent
- ansible.windows.win_file:
path: C:\OldApp
state: absent # Recursive deleteFAQ
Does state: absent fail if file doesn't exist?
No — it's idempotent. If the file doesn't exist, the task reports "ok" (no change).
Can I recover deleted files?
No — state: absent permanently deletes. Use backup: true on copy/template tasks, or create a backup task before deletion.
Is it like rm -rf?
Yes for directories — it removes the directory and all contents recursively. Be careful with the path!
How do I delete files matching a pattern?
Use find module first, then loop file: state=absent over the results.
Delete File
- ansible.builtin.file:
path: /tmp/old-config.conf
state: absent
become: trueDelete Directory (Recursive)
- file:
path: /opt/old-app
state: absent # Removes directory and all contents
become: trueDelete Multiple Files
- file:
path: "{{ item }}"
state: absent
loop:
- /tmp/temp1.txt
- /tmp/temp2.txt
- /opt/old-app/cache
become: trueFind and Delete (Pattern)
# Delete all .log files older than 30 days
- find:
paths: /var/log/myapp
patterns: "*.log"
age: 30d
register: old_logs
- file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_logs.files }}"
become: trueDelete with Condition
- stat:
path: /opt/myapp/v1
register: old_version
- file:
path: /opt/myapp/v1
state: absent
when: old_version.stat.exists
become: trueDelete Symlink
# Removes the link, not the target
- file:
path: /opt/myapp/current
state: absentSafe Cleanup Pattern
# Keep last 5 releases, delete older ones
- find:
paths: /opt/releases
file_type: directory
register: releases
- file:
path: "{{ item.path }}"
state: absent
loop: "{{ (releases.files | sort(attribute='mtime') | list)[:-5] }}"
become: trueDelete File Content (Not File)
# Truncate file (keep file, remove content)
- copy:
content: ""
dest: /var/log/myapp/app.log
become: trueFAQ
Is state=absent idempotent?
Yes — if the file doesn't exist, the task reports "ok" (no change). If it exists, it's removed and reports "changed".
Does it delete directory contents?
Yes — state: absent on a directory removes everything inside it recursively, like rm -rf.
Can I recover deleted files?
No — file: state=absent permanently deletes. Consider using a "move to trash" pattern instead for important files.
Delete a File
- ansible.builtin.file:
path: /tmp/old-file.txt
state: absent
become: trueDelete a Directory
- file:
path: /opt/old-app
state: absent # Recursively removes everything
become: trueDelete Multiple Files
- file:
path: "{{ item }}"
state: absent
loop:
- /tmp/cache.db
- /var/log/old-app.log
- /opt/deprecated-tool
become: trueDelete Files by Pattern (find + file)
- find:
paths: /var/log
patterns: "*.log.gz"
age: "30d" # Older than 30 days
register: old_logs
- file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_logs.files }}"
become: trueDelete Contents But Keep Directory
- find:
paths: /opt/myapp/tmp
file_type: any
register: tmp_contents
- file:
path: "{{ item.path }}"
state: absent
loop: "{{ tmp_contents.files }}"
become: trueConditional Delete
- stat:
path: /opt/myapp/old-config.yml
register: old_config
- file:
path: /opt/myapp/old-config.yml
state: absent
when: old_config.stat.exists
become: trueCleanup Playbook
- hosts: all
become: true
tasks:
- name: Remove old application
file:
path: "{{ item }}"
state: absent
loop:
- /opt/myapp-v1
- /etc/myapp-v1
- /var/log/myapp-v1
- name: Clean temp files older than 7 days
find:
paths: /tmp
age: "7d"
recurse: true
register: old_tmp
- file:
path: "{{ item.path }}"
state: absent
loop: "{{ old_tmp.files }}"Remove Symlink
# Removes the symlink, not the target
- file:
path: /opt/myapp/current
state: absentFAQ
state: absent on nonexistent file?
No error — Ansible reports ok (not changed). It's safe to always run.
How to move instead of delete?
Ansible has no mv module. Use command: mv or copy + file: state=absent.
Can I recover deleted files?
No — state: absent is permanent. For safety, consider archiving first with archive module.
Related Articles
Category: installation
Watch the video: Ansible Delete File: Remove Files & Directories (state=absent Guide) — Video Tutorial