
Le module ansible.builtin.file est le couteau suisse des métadonnées de fichiers. Contrairement à copy:, il ne transfère aucun contenu — il agit uniquement sur l’existence, le mode, le propriétaire, le type (fichier, directory, symlink, hardlink). C’est le module idéal pour préparer une arborescence, créer un lien symbolique vers la release courante, ou supprimer un fichier obsolète.
file: se distingue par son option state: qui prend 6 valeurs : file, directory, absent, link, hard, touch. Maîtriser ces 6 états couvre 95% des cas d’usage.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Les 6 états possibles :
file,directory,absent,link,hard,touch. - Les options
recurse: true,force: trueet leurs cas d’usage. - Quand
file:suffit et quand il faut enchaîner aveccopy:outemplate:. - Le piège des liens symboliques cassés (
state: linksur cible inexistante).
Prérequis
Section intitulée « Prérequis »- Avoir lu Module copy —
file:complètecopy:, ne le remplace pas.
Les 6 états de state:
Section intitulée « Les 6 états de state: »state: détermine ce que file: va faire. Chaque valeur a son cas d’usage et ses pièges.
state: | Action | Idempotence |
|---|---|---|
file (défaut) | Vérifie que la cible est un fichier ; ajuste mode/owner si différent | ok si déjà fichier avec bonnes perms |
directory | Crée le répertoire (et parents si besoin) avec mode/owner | ok si déjà directory avec bonnes perms |
absent | Supprime le fichier ou le répertoire (récursif) | ok si déjà absent |
link | Crée un lien symbolique : dest → src | ok si lien existe et pointe au bon endroit |
hard | Crée un lien physique (hardlink) : dest et src partagent l’inode | ok si déjà hardlink |
touch | Crée le fichier (vide) ou met à jour le mtime | toujours changed (timestamp à jour) |
touch est le seul état non-idempotent : il modifie systématiquement le mtime. Utiliser uniquement quand on veut explicitement marquer un timestamp (init, healthcheck).
Créer un répertoire — state: directory
Section intitulée « Créer un répertoire — state: directory »- name: Repertoire de logs applicatifs ansible.builtin.file: path: /var/log/myapp state: directory owner: nobody group: nobody mode: "0750"Si /var/log/myapp n’existe pas, il est créé. S’il existe avec mode 0755 et owner root, il est ajusté à 0750 + nobody. S’il existe déjà comme prévu, la tâche est ok.
Création récursive : par défaut, file: state: directory crée les répertoires parents manquants (équivalent mkdir -p). Pas besoin de tâche préalable pour /var/log/.
Liens symboliques — state: link
Section intitulée « Liens symboliques — state: link »Pattern classique pour le déploiement par releases : /opt/myapp/current est un symlink vers la release active.
- name: Pointer current vers la release courante ansible.builtin.file: src: /opt/myapp/releases/v1.2.0 dest: /opt/myapp/current state: link force: trueforce: true est nécessaire si dest est déjà un fichier (non symlink) — sans force, la tâche échoue. Avec force, le fichier existant est remplacé par le symlink.
Piège lien cassé : si src n’existe pas au moment de la création, Ansible crée un symlink cassé sans erreur. Pour échouer si src est absent, ajouter une vérification préalable avec stat: + assert:.
Suppression — state: absent
Section intitulée « Suppression — state: absent »- name: Nettoyer une ancienne config ansible.builtin.file: path: /etc/old-config.conf state: absentabsent est récursif : si path est un répertoire, tout est supprimé (équivalent rm -rf). À utiliser avec précaution — pas de --check automatique en production.
Récursivité — recurse: true
Section intitulée « Récursivité — recurse: true »Uniquement valable pour state: directory. Propage mode/owner/group à toute l’arborescence.
- name: Reparer les permissions sur /etc/myapp ansible.builtin.file: path: /etc/myapp state: directory owner: root group: myapp mode: "0750" recurse: truerecurse: true est puissant mais lent sur de grosses arborescences (Ansible parcourt chaque inode). Pour un répertoire de 50K fichiers, préférer une commande shell unique avec chown -R.
Touch — créer ou mettre à jour le mtime
Section intitulée « Touch — créer ou mettre à jour le mtime »- name: Marquer le timestamp d init ansible.builtin.file: path: /var/log/myapp-init.timestamp state: touch mode: "0644"Le fichier est créé vide s’il n’existe pas, ou son mtime mis à jour s’il existe. Utile pour des flags d’initialisation ou des healthchecks basés sur la date du fichier.
Pièges courants
Section intitulée « Pièges courants »| Symptôme | Cause | Fix |
|---|---|---|
| Symlink cassé sans erreur | src n’existe pas au moment de state: link | Vérifier src avec stat: + assert: avant |
mode: non appliqué récursivement | Oubli de recurse: true | Ajouter recurse: true (state=directory uniquement) |
state: absent supprime tout un dossier sans warning | C’est le comportement par défaut (récursif) | Toujours tester en --check avant |
force: true ignoré | Mauvais state: (force ne sert que pour link/hard) | force: true n’a d’effet que pour les liens |
À retenir
Section intitulée « À retenir »file:gère les métadonnées uniquement — pour le contenu, utilisercopy:outemplate:.state:=file/directory/absent/link/hard/touch— 6 cas couvrant 95% des besoins.recurse: truepropage mode/owner sur toute l’arborescence (lent sur gros volumes).force: truen’a de sens que pourstate: linkouhard— remplace un fichier existant.state: touchest le seul état non-idempotent — toujourschanged.
Pratiquer dans le lab
Section intitulée « Pratiquer dans le lab »Cette page a un lab d’accompagnement : labs/modules-fichiers/file/ dans stephrobert/ansible-training.
Challenge — sur web1.lab :
- Créer
/opt/myapp/releases/v1.0.0avec mode0755. - Créer
/opt/myapp/shared/logsavec mode0750, ownernobody. - Créer un symlink
/opt/myapp/current→/opt/myapp/releases/v1.0.0. - Supprimer
/etc/myapp-old.confs’il existe. - Touch
/var/log/myapp-init.timestampmode0644.
Validation pytest+testinfra :
ansible-playbook solution.ymlpytest -v labs/modules-fichiers/file/challenge/tests/5 tests vérifient l’existence, le type (directory/symlink/file), le mode et l’owner.