
ansible.builtin.find: recherche plusieurs fichiers par pattern (glob ou regex), âge, taille, type. C'est l'équivalent de la commande find Unix mais avec résultat structuré (liste de dicts) consommable par loop: ensuite.
Là où stat: traite un fichier, find: en parcourt plusieurs. Cas d'usage typiques RHCE 2026 : nettoyer les vieux logs (>7 jours), lister les binaires setuid, supprimer les fichiers temporaires.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Rechercher par pattern (
patterns:glob ouuse_regex: true). - Filtrer par âge (
age: 7d), taille (size: 10m), type (file_type:). - Descendre récursivement avec
recurse: true. - Combiner
find:+loop: + file: state: absentpour cleanup ciblé. - Diagnostiquer un timeout sur un FS lent ou un dossier énorme.
Prérequis
Section intitulée « Prérequis »- Connaître
loop:etregister:pour consommer le résultat.
Recherche par pattern
Section intitulée « Recherche par pattern »- name: Trouver tous les .log ansible.builtin.find: paths: /var/log patterns: '*.log' register: log_fileslog_files.files est une liste de dicts (un par fichier trouvé) avec : path, size, mode, mtime, uid, gid, etc., comme un stat: par fichier.
Champs utiles du registre :
log_files.files: liste des fichiers trouvés (dicts).log_files.matched: nombre total trouvé.log_files.examined: nombre de fichiers parcourus avant filtrage.
Filtrer par taille
Section intitulée « Filtrer par taille »- name: Trouver les .log de 10Mo et plus ansible.builtin.find: paths: /var/log patterns: '*.log' size: 10m register: big_logsFormat size: :
10m= au moins 10 mégaoctets (sans préfixe =>= 10m).-100k= moins de 100 kilooctets (préfixe-uniquement).1g= au moins 1 gigaoctet.- Suffixes :
b(bytes),k,m,g,t.
Filtrer par âge
Section intitulée « Filtrer par âge »- name: Logs de plus de 7 jours ansible.builtin.find: paths: /var/log patterns: '*.log' age: 7d register: old_logs
- name: Fichiers tres recents (< 1h) ansible.builtin.find: paths: /var/log patterns: '*.log' age: -1h register: recent_logsFormat age: :
7d= 7 jours ou plus (basé surmtimepar défaut).-1h= moins d'1 heure (signe-= inférieur).- Suffixes :
s(secondes),m(minutes),h(heures),d(jours),w(semaines).
age_stamp:, choisir le timestamp de comparaison : mtime (défaut), atime, ctime.
Filtrer par type
Section intitulée « Filtrer par type »- name: Trouver tous les dossiers ansible.builtin.find: paths: /tmp file_type: directory
- name: Trouver les symlinks ansible.builtin.find: paths: /etc file_type: linkValeurs file_type: : file (défaut), directory, link, any.
Descente récursive
Section intitulée « Descente récursive »- name: Tous les .conf dans /etc et sous-dossiers ansible.builtin.find: paths: /etc patterns: '*.conf' recurse: true register: all_conf
- name: Compter ansible.builtin.debug: msg: "{{ all_conf.matched }} fichiers .conf trouves"Performance : recurse: true sur / peut prendre des heures sur un système chargé. Toujours scoper avec paths: précis.
Pattern cleanup automatique
Section intitulée « Pattern cleanup automatique »- name: Trouver les .log > 1Mo ansible.builtin.find: paths: /tmp patterns: '*.log' size: 1m register: logs_to_clean
- name: Supprimer ces fichiers ansible.builtin.file: path: "{{ item.path }}" state: absent loop: "{{ logs_to_clean.files }}" loop_control: label: "{{ item.path }}"Pattern find + loop: + file: state: absent. Idempotent : un 2e run trouve 0 fichier → loop: 0 itération.
Alternative shell : find /tmp -name '*.log' -size +1M -delete. Moins lisible, moins idempotent, mais plus rapide sur gros volumes.
Regex au lieu de glob
Section intitulée « Regex au lieu de glob »- name: Find avec regex Python ansible.builtin.find: paths: /var/log patterns: '.*-[0-9]{4}-[0-9]{2}\.log\.gz$' use_regex: true register: archived_logsuse_regex: true : patterns: devient une regex Python. Plus puissant que glob mais plus complexe.
Pièges courants
Section intitulée « Pièges courants »| Symptôme | Cause | Fix |
|---|---|---|
failed to process size: +10m | Préfixe + non accepté | Retirer le +, mettre juste 10m |
Recherche très lente sur / | Pas de scope | Toujours paths: précis |
| Fichiers cachés ignorés | hidden: false (défaut) | Ajouter hidden: true |
| Symlinks suivis non voulus | follow: false (défaut, OK) | Vérifier valeur de follow: |
À retenir
Section intitulée « À retenir »find:retourne<reg>.files(liste de dicts) +<reg>.matched(count).patterns:= glob par défaut,use_regex: truepour regex Python.size: 10m/age: 7d= filtres standards (pas de préfixe+).recurse: true= descente récursive (attention performance).file_type::file/directory/link/any.- Pattern
find + loop + file: state: absent= cleanup idempotent.
Mettre en pratique
Section intitulée « Mettre en pratique »Un find: mal filtré supprime toujours plus que prévu, autant s'en rendre compte sur des fichiers jetables. Le lab vous fait générer sur db1.lab une série de journaux de tailles variées, les filtrer par patterns: puis par size:, et enchaîner loop: avec le module file: pour n'effacer que les plus volumineux. Les tests contrôlent les deux versants du cleanup : les petits fichiers encore là, les gros bel et bien partis.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Modules wait_for et pause : Attendre l'apparition d'un fichier plutôt que de boucler sur des recherches successives.
- raw, command, shell, script : Pourquoi un shell: find reste tentant, et ce qu'il coûte en idempotence.
- debug, setup, add_host, group_by : Afficher la liste retournée par find avant d'enchaîner une suppression.