If you are not familiar with modules, check out Ansible - Getting Started with Modules.
The find module can be used to find files and directories in a target directory on a managed node. In this example, every file in the /tmp directory will be stored in the "out" variable using the register parameter. By default, only non-hidden files in the target directory will be returned, meaning the search is not recursive.
- name: store the files in the /tmp directory in the 'out' variable
find:
paths: /tmp
register: out
The debug module can be used to display the contents of the "out" variable.
- debug:
var: out
If the directory does not exist, something like this should be returned.
TASK [debug]
ok: [server1.example.com] => {
"msg": {
"changed": false,
"examined": 0,
"failed": false,
"files": [],
"matched": 0,
"msg": "/tmp/foo was skipped as it does not seem to be a valid directory or it cannot be accessed\n"
}
}
If the directory exists but is empty, something like this should be returned.
ok: [server1.example.com] => {
"msg": {
"changed": false,
"examined": 0,
"failed": false,
"files": [],
"matched": 0,
"msg": ""
}
}
If the directory exists and is not empty, something like this should be returned. Notice the accessed datetime (atime), changed datetime (ctime), and modified datetime (mtime) of the file will are epoch formated, such as 1583384414.8106842. The strftime (string format time) filter can be used to convert epoch to human readable.
ok: [server1.example.com] => {
"msg": {
"changed": false,
"examined": 1,
"failed": false,
"files": [
{
"atime": 1583384414.8106842,
"mtime": 1583388631.5600421,
"dev": 64768,
"gid": 0,
"inode": 131881,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mode": "0664",
"mtime": 158338361.5600421,
"nlink": 1,
"path": "/tmp/foo.txt",
"rgrp": true,
"roth": true,
"rusr": true,
"size": 8,
"uid": 0,
"wgrp": false,
"woth": false,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
}
],
"matched": 1,
"msg": ""
}
}
Refer to Ansible - Getting Started parsing JSON and Ansible - Looping through JSON array if you want to access specific values in the JSON.
Directories
If you want to search for directories, you'll have to use the file_type: directory parameter. Often, recurse: false is used as well.
- name: store the directories in the /tmp directory in the 'out' variable
find:
paths: /tmp
file_type: directory
recurse: false
register: out
Patterns
The patterns parameter can be used to only match files that contain the patterns. If using a regular expression, use_regex: true must be included. (?i) is used for a case insensitive search.
- name: store .txt files in the /tmp directory in the 'out' variable
find:
paths: /tmp
patterns: (?i).*txt
use_regex: true
register: out
If there are no .txt files in the /tmp directory, matched will be 0.
TASK [store .txt files in the /tmp directory in the 'out' variable]
ok: [server1.example.com] => {
"out": {
"changed": false,
"examined": 15,
"failed": false,
"files": [],
"matched": 0,
"msg": ""
}
}
Multiple paths and patterns can be searched, like this.
- name: store .txt and .docx files in the 'out' variable
find:
paths: /tmp,/home/john.doe
patterns: *.txt,*.docx
use_regex: true
register: out
And here is an example of how to find files contain "foo" or "bar" below the /tmp directory.
- name: find foo and bar files
find:
paths: /tmp
patterns: .*(foo|bar).*
use_regex: true
register: out