By Linux Guru 01.01.0001
Excerpt
The Ansible search module works similarly to the Find Linux command and allows searching files and folders based on various search criteria like file age, access date, modification date, expression search pattern regular, etc. As stated earlier, this is a more feasible way to run the Linux find command with an inbuilt standard, this module is designed.
As stated earlier, this is a more efficient way to run the Linux find command with an existing standard.
This module is intended for use on Linux servers only. For Windows, you should use the win_find module instead.
Because this will also be the command to replace Linux Find. I will list all 0 examples equivalent to Linux Find.
Example 01: Find all the log files older than 30 days with Ansible Find
In this section, we are going to see how ansible find is going to help us find the more than 30 days old files.
The Linux find Command
Here is the command that you would ideally execute in the Linux OS
find /var/log -name "*.log" -type f -mtime +30
The Ansible Find AdHoc Command
The same Linux command can be rewritten as ansible ad hoc command as follows
ansible appgroup -i ansible_hosts -m find -a "paths='/var/log' file_type=file patterns='*.log' age_stamp=mtime age=30d"
Look at the following Comparision table between Linux Find and Ansible Find attributes.
I think this would give you a clear picture.
A Playbook with Ansible Find
The same can be put into the playbook as shown below.
---
- name: Ansible Find Example 0
hosts: testserver
tasks:
- name : Find files older than 30 days
find:
paths: /var/log
patterns: '*.log'
age: 30d
age_stamp: mtime
register: output
- debug: var=item.path
with_items: "{{ output.files }}"
The playbook has two tasks, The First one is with the find module to find the files older than 30 days and the output of this task would be saved into a register variable named output
and then it would be used in the next play/task with Debug.
You could see that we are mentioning the age as 30d
to represent 30 days older files and specifying what time validation method should be used like mtime, atime, ctime with help of age_stamp: mtime
How to use keywords like ctime, mtime, atime with ansible find ?
By default,
age_stamp
parameter would be set tomtime
Based on your requirement it can be changed to
atime
orctime
it would function the similar way as same as LinuxHow to use Seconds, Months, Weeks, Year as matric in the age ?
Ansible find supports you to use various matrics in age . By default it would be
seconds
You can choose seconds, minutes, hours, days, or weeks by specifying the first letter of any of those words (e.g., “1w”).
Example 02: Ansible Find files age within 30 days – Negative Age
The Linux find Command
Here is the command that you would ideally execute in the Linux OS to find the files with age less than or equal to 30 days.
find /var/log -name "*.log" -type f -mtime -30
The Ansible Find AdHoc Command
The same Linux command can be rewritten as ansible ad hoc command as follows
ansible appgroup -i ansible_hosts -m find -a "paths='/var/log' file_type=file patterns='*.log' age=-30d"
Look at the following Comparision table between Linux Find and Ansible Find attributes.
I think this would give you a clear picture.
A Playbook with Ansible Find
The same can be put into the playbook as shown below.
---
- name: Ansible Find Example 0
hosts: testserver
tasks:
- name : Find files with age of less than 30 days
find:
paths: /var/log
patterns: '*.log'
age: -30d
register: output
- debug: var=item.path
with_items: "{{ output.files }}"
Example 03: Recursively find the files by Size using Ansible Find
To find files by size, Ansible find gives a parameter named size. Same as Linux find command
The next trick is to find all files that are 100 MB or larger.
The Linux find Command
Here is the command that you would ideally execute in the Linux OS to find the files with age less than or equal to 30 days.
find /var/log -name "*.log" -type f -size +100M
The Ansible Find AdHoc Command
The same Linux command can be rewritten as ansible ad hoc command as follows
ansible appgroup -i ansible_hosts -m find -a "paths='/var/log' file_type=file patterns='*.log' size=100m"
Look at the following Comparision table between Linux Find and Ansible Find attributes.
I think this would give you a clear picture.
A Playbook with Ansible Find
The same can be put into the playbook as shown below.
---
- name: Ansible Find Example 0
hosts: testserver
tasks:
- name : Find files bigger than 100mb in size
become: true
find:
paths: /
file_type: file
size: 100m
recurse: yes
register: output
- debug: var=item.path
with_items: "{{ output.files }}"
Find the Smaller files than the Size Specified
To find the files which are lesser than the specified size, use the negative symbol at the front of the numeric value.
100m – would find the files grater than or equal to 100mb size
-100m – would find the smaller files with 100mb or below in size
Use of other size scales like GB, KB etc
If you want to use 100gb instead of 100mb, All you have to do is use
100g
instead of100m
same goes with kb
100k
and tb100t
Example 04: Find All directories excluding few, as a list
In this example, we will see how to find only folders. As you may have guessed, we will use ansible find’s file_type parameter to filter only directories.
In this example, we will also add all matching folders to the table list (or) for better formatting.
A Playbook with Ansible Find – to find the Directories alone
---
- name: Ansible Find Example 0
hosts: testserver
vars:
Files: []
tasks:
- name : Find files bigger than 100mb in size
become: true
find:
paths: /var/log
file_type: directory
recurse: no
excludes: 'nginx,mysql'
register: output
- name: Adding Files to the LIST
no_log: true
set_fact:
Files: "{{ Files + [item.path]}}"
with_items: "{{ output.files }}"
- debug: var=Files
In the playbook, you can see that we have three missions. First is to find the folders. This is achieved by setting file_type: folder, we don’t have recursion because we don’t want to go through subfolders. In other words, we only want directories in /var/log
We exclude directories named nginx and mysql from the results.
In the next mission. We loop through the output register variable recorded in the previous task and filter only the directory names and create an array list (or) using set_fact. Here’s how you can create fluctuations in your notebook.
The output of this playbook will look like this. You can see that the output is neat and formatted
Example 05: Find Files with a Regex Pattern in Ansible find
Even though we used patterns from 0 previous examples to find files. They are not complex enough to meet real world requirements. So we need advanced patterns like regex to find desired files or folders.
Ansible Find supports the Python regular expression pattern using a special parameter named use_regex. This must be set to yes, otherwise it will always be no by default.
A Playbook with Ansible Find – to find files with regular expression
This playbook has a Single pattern to find the log files starting with letters and then numbers and end with .log
extension
The Example matching file would be something like this file_29122022.log
---
- name: Ansible Find Example 0
hosts: testserver
vars:
Files: []
tasks:
- name : Find files bigger than 100mb in size
become: true
find:
paths: /var/log
file_type: file
patterns: '^[a-z]*_[0-9]{8}\.log$'
size: 100m
use_regex: yes
register: output
- name: Adding Files to the LIST
no_log: true
set_fact:
Files: "{{ Files + [item.path]}}"
with_items: "{{ output.files }}"
- debug: var=Files
A Playbook with Ansible Find – with multiple regular expression
Sometimes, we might want to find various files with a different set of naming conventions. Instead of rewriting the patterns, we can use multiple patterns in a single play as shown below.
---
- name: Ansible Find Example 0
hosts: testserver
vars:
Files: []
tasks:
- name : Find files bigger than 100mb in size
become: true
find:
paths: /var/log
file_type: file
patterns:
- '^[a-z]*_[0-9]{8}\.log$'
- '^_[0-9]{2,4}_.*.log$'
- '^[a-z]{1,5}_.*log$'
size: 100m
use_regex: yes
register: output
- name: Adding Files to the LIST
no_log: true
set_fact:
Files: "{{ Files + [item.path]}}"
with_items: "{{ output.files }}"
- debug: var=Files
Example 06: Ansible Find and Delete the files
Now you already know how to use Ansible Find to find the files you want using various filters and searching elements like time, size, etc.
Now let us see how to use Ansible find to delete the files once they are found. It is more like using xargs rm -rf
in linux find command
A Playbook with Ansible Find – Delete files with Ansible Find
---
- name: Ansible Find Example 0
hosts: testserver
tasks:
- name : Find files older than 30 days
become: yes
find:
paths: /var/log
patterns: '*.log'
age: 30d
age_stamp: mtime
register: output
- name: Delete the files matching
become: yes
file:
path: "{{item.path}}"
state: absent
with_items: "{{ output.files }}"
Here is the execution output of this playbook
I hope this article helps you understand the various uses of the Ansible find module.