Ansible Find Examples - How to use Ansible Find

Ansible find module functions as same as the Linux Find command and helps to find files and directories based on various search criteria such as age of the file, accessed date, modified date,  regex search pattern etcetera.

As said earlier, this is more of an ansible way to execute the Linux find command with some standard in place.

this module is intended to use only on Linux servers, For windows, you should use a win_find module instead.

Since this is going to be a Linux Find command replacement alike. I would list out all the examples with the linux find equivalent.

Ansible Find

Index:

  1. Example1: Find all the log files older than 30 days
  2. Example2: Find all the log files lesser than 30 days age
  3. Example3: Recursively find the files by Size using Ansible Find
  4. Example4: Find All directories excluding few,  as a list
  5. Example5: Find Files with a Regex Pattern - Single or Multiple
  6. Example6: Ansible Find to Delete the matching files

 

Example1:  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.

With Linux Find With Ansible Find
-type f file_type=file
find /var/log paths='/var/log'
-name "*.log" pattern="*.log"
-mtime age_stamp="mtime"
+30 age=30d

 

A Playbook with Ansible Find

The same can be put into the playbook as shown below.

---
- name: Ansible Find Example
  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").

 

Example2:  Ansible Find files age within 30 days - Negative ageing

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.

With Linux Find With Ansible Find
-type f file_type=file
find /var/log paths='/var/log'
-name "*.log" pattern="*.log"
-mtime -30 age=-30d

 

A Playbook with Ansible Find

The same can be put into the playbook as shown below.

---
- name: Ansible Find Example
  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 }}"

Example3:  Recursively find the files by Size using Ansible Find

To find the files by size, Ansible find gives a parameter named size. Just like the Linux find command

The following playbook is to find all the files which are bigger than or equal to 100mb size.

 

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.

With Linux Find With Ansible Find
-type f file_type=file
find /var/log paths='/var/log'
-name "*.log" pattern="*.log"
-size +100M size=100m

 

A Playbook with Ansible Find

The same can be put into the playbook as shown below.

---
- name: Ansible Find Example
  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

 

Example4:  Find All directories excluding few,  as a list

In this example, we are going to see how to find only the directories. As you might have already guessed, we are going to use the file_type parameter of ansible find to filter only the directories

In this example, we are also going to add all the matching directories into an array (or) list for better formatting.

Here is the playbook.

A Playbook with Ansible Find - to find the Directories alone

---
- name: Ansible Find Example
  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 could see that we are having a three tasks. The first one is to find the directories. It is achieved by setting  file_type: directory we are having no recursive as we do not want to traverse the subdirectories. In other words, we want only the directories of /var/log

we are excluding the directories named nginx and mysql from the result.

In the next task. we are traversing through the output register variable captured in the previous task and just filtering the directory names alone and creating an array (or) list using set_fact

this is how you can create a dynamic variable in the playbook.

The output of this playbook would look like this. You can see the output is neat and formatte

Ansible Find

 

Example5:  Find Files with a Regex Pattern in Ansible find

Though we have used the patterns in the previous examples to find the files. They were not complex enough to match the real-world requirements.  So we need some advanced patterns like regex to find the files or directories we want.

Ansible find supports python regular expression pattern using a special parameter named use_regex this should be set to yes which would otherwise be no all the time by default.

Here is the example playbook with the regular expression pattern

 

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  filebeat_29122019.log

---
- name: Ansible Find Example
  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
  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
     


Example6:  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
  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

 

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

For any questions feel free to comment

Cheers
Sarav AK

Follow me on Linkedin My Profile
Follow DevopsJunction onFacebook orTwitter
For more practical videos and tutorials. Subscribe to our channel

Buy Me a Coffee at ko-fi.com

Signup for Exclusive "Subscriber-only" Content

Loading