Ansible Find Example 0s – How to use Ansible Find

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 to mtime

Based on your requirement it can be changed to atime or ctime it would function the similar way as same as Linux

How 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 of 100m

same goes with kb 100k and tb 100t

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

ansible-playbook_ansiblefind-output

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

ansible-find_and-delete_output

I hope this article helps you understand the various uses of the Ansible find module.

comments powered by Disqus