Contactez-nous

Module `file` : gérer les fichiers et répertoires (création, permissions)

Explorez le module `file` d'Ansible pour créer des fichiers/répertoires, gérer leurs permissions, propriétaires, et créer des liens symboliques ou matériels.

Le module `file` : l'architecte de votre système de fichiers

Tandis que le module copy excelle dans le transfert de contenu de fichiers, le module file est votre outil de prédilection pour sculpter et maintenir la structure même de votre système de fichiers sur les noeuds gérés. Il ne s'occupe pas du contenu des fichiers (sauf pour créer un fichier vide), mais il est indispensable pour s'assurer de l'existence, du type, des permissions, et de la propriété des fichiers, répertoires et liens.

Avec le module file, vous pouvez créer des arborescences de répertoires, toucher des fichiers pour marquer leur présence, établir des liens symboliques ou matériels, et surtout, garantir que les attributs critiques comme le propriétaire, le groupe et les bits de permission sont conformes à l'état désiré. Son idempotence garantit que les opérations ne sont effectuées que si nécessaire, rendant vos playbooks robustes et efficaces.

Maîtriser le module file est fondamental pour préparer l'environnement nécessaire à vos applications, sécuriser votre système et organiser vos données de manière cohérente à travers votre infrastructure.

Paramètres clés du module `file` pour définir l'état désiré

Le module file offre une panoplie de paramètres pour décrire précisément l'état souhaité d'un élément du système de fichiers. Voici les plus importants :

  • path (alias : dest, name) : (Chaîne de caractères, requis) Le chemin absolu de l'élément (fichier, répertoire, lien) à gérer sur le noeud distant.
  • state : (Chaîne de caractères) Définit le type et l'état attendu de path. C'est l'un des paramètres les plus cruciaux. Valeurs courantes :
    • file : S'assure que path est un fichier régulier. S'il n'existe pas, un fichier vide est créé. Si path existe mais est un répertoire ou un lien, la tâche échouera (sauf si force=yes est utilisé, ce qui est dangereux).
    • directory : S'assure que path est un répertoire. S'il n'existe pas, il est créé. Les répertoires parents manquants seront également créés (similaire à mkdir -p).
    • link : S'assure que path est un lien symbolique pointant vers la destination spécifiée par le paramètre src.
    • hard : S'assure que path est un lien matériel pointant vers la destination spécifiée par le paramètre src.
    • touch : S'assure que path existe (s'il n'existe pas, un fichier vide est créé) et met à jour son horodatage de modification. Si path n'existe pas et que vous voulez juste le créer sans modifier l'horodatage s'il existe déjà, utilisez state=file.
    • absent : S'assure que path (fichier, répertoire ou lien) n'existe pas. S'il existe, il est supprimé. Si path est un répertoire, il sera supprimé récursivement.
  • src : (Chaîne de caractères) Utilisé uniquement lorsque state=link ou state=hard. Spécifie le chemin du fichier source vers lequel le lien doit pointer.
  • owner : (Chaîne de caractères) Nom de l'utilisateur propriétaire de path.
  • group : (Chaîne de caractères) Nom du groupe propriétaire de path.
  • mode : (Chaîne de caractères ou nombre) Les permissions à appliquer à path. Peut être en format octal (ex: 0755, 0600) ou symbolique (ex: u=rwx,g=rx,o=rx). Pour les répertoires, si vous souhaitez que les permissions s'appliquent récursivement, utilisez recurse=yes.
  • recurse : (Booléen, défaut: no) Si state=directory et recurse=yes, les attributs owner, group, mode, et selevel/serole/setype/seuser (pour SELinux) sont appliqués récursivement à tous les fichiers et sous-répertoires contenus dans path. Attention, cela peut être une opération longue sur de grandes arborescences.
  • force : (Booléen, défaut: no) Utilisé principalement avec state=link ou state=file. Si yes, permet de remplacer un fichier par un lien, un répertoire par un lien, un lien par un fichier, etc. C'est une opération potentiellement destructive, à utiliser avec une extrême prudence.

Exemples pratiques de gestion du système de fichiers

1. Créer une structure de répertoires pour une application

Votre application webapp nécessite les répertoires /opt/webapp/config, /opt/webapp/logs, et /opt/webapp/data, avec des permissions spécifiques.

- name: Créer les répertoires de l'application webapp
  ansible.builtin.file:
    path: "{{ item.path }}"
    state: directory
    owner: webapp_user
    group: webapp_group
    mode: "{{ item.mode }}"
  loop:
    - { path: '/opt/webapp/config', mode: '0750' }
    - { path: '/opt/webapp/logs', mode: '0770' }
    - { path: '/opt/webapp/data', mode: '0770' }

Ici, une boucle (loop) est utilisée pour créer plusieurs répertoires avec des modes différents de manière concise.

2. Créer un fichier vide (fichier de verrouillage ou indicateur)
- name: Créer un fichier de verrouillage pour une tâche de maintenance
  ansible.builtin.file:
    path: /var/run/maintenance.lock
    state: touch  # Crée le fichier s'il n'existe pas, met à jour le timestamp sinon
    owner: root
    group: root
    mode: '0600'
3. Etablir un lien symbolique

Vous souhaitez que /usr/local/bin/my_script pointe vers la version actuelle de votre script située dans /opt/scripts/my_script_v1.2.sh.

- name: Créer un lien symbolique pour my_script
  ansible.builtin.file:
    src: /opt/scripts/my_script_v1.2.sh  # La cible du lien
    dest: /usr/local/bin/my_script       # Le lien lui-même
    state: link
    owner: root
    group: root
4. Assurer l'absence d'un fichier ou répertoire

Pour supprimer un ancien fichier de configuration ou un répertoire de cache obsolète :

- name: Supprimer l'ancien répertoire de cache
  ansible.builtin.file:
    path: /tmp/old_app_cache
    state: absent

Si /tmp/old_app_cache est un répertoire, il sera supprimé récursivement avec tout son contenu.

5. Changer les permissions d'un fichier existant
- name: Restreindre les permissions d'un fichier sensible
  ansible.builtin.file:
    path: /etc/myapp/secret_key.conf
    owner: myapp_user
    group: myapp_group
    mode: '0600'  # Seul le propriétaire peut lire/écrire

Gestion des attributs SELinux et considérations d'idempotence

Sur les systèmes où SELinux est activé (comme RHEL, CentOS, Fedora), le module file peut également gérer le contexte de sécurité SELinux des fichiers et répertoires. Pour cela, il utilise les paramètres suivants (nécessite que les outils SELinux comme libselinux-python ou python3-libselinux soient installés sur les noeuds gérés) :

  • seuser : L'utilisateur SELinux pour le contexte (ex: system_u).
  • serole : Le rôle SELinux (ex: object_r).
  • setype : Le type SELinux (ex: httpd_sys_content_t, var_log_t). C'est le plus couramment utilisé.
  • selevel : Le niveau SELinux (pour MLS/MCS).

Exemple d'application d'un type SELinux à un répertoire web :

- name: Définir le contexte SELinux pour le contenu web
  ansible.builtin.file:
    path: /var/www/html
    state: directory
    owner: apache
    group: apache
    mode: '0755'
    setype: httpd_sys_content_t
    recurse: yes  # Appliquer le type récursivement

Idempotence et le module file :

Le module file est conçu pour être idempotent. Si vous exécutez une tâche file plusieurs fois, elle ne modifiera le système que si l'état actuel de path ne correspond pas à l'état défini par les paramètres. Par exemple, si un répertoire existe déjà avec les bonnes permissions, une tâche state=directory avec les mêmes permissions ne fera rien et rapportera ok (changed: false). Si les permissions diffèrent, elles seront corrigées et la tâche rapportera changed: true.

Cette caractéristique est fondamentale pour écrire des playbooks fiables qui peuvent être réexécutés en toute sécurité, convergeant toujours vers l'état désiré sans effets secondaires indésirables. Faites confiance à l'idempotence du module et évitez d'ajouter des vérifications manuelles (avec des clauses when basées sur l'existence de fichiers, par exemple) qui sont souvent redondantes et peuvent complexifier inutilement vos playbooks.

En conclusion, le module file est un outil polyvalent et indispensable pour toute tâche d'automatisation Ansible impliquant la gestion de la structure du système de fichiers. Sa maîtrise vous permettra de définir et maintenir avec précision l'environnement de vos applications et services.