Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici

Manipulation de fichiers sur les hôtes

Introduction

Outre la possibilité de développer votre propre module, Ansible est livré avec une bibliothèque de modules, lesquels sont développés au sein du projet communautaire Ansible. La liste des modules se situe à l’adresse : https://docs.ansible.com/ansible/latest/modules/list_of_all_modules.html

Ces modules peuvent être exécutés directement sur des hôtes distants ou par l’intermédiaire de playbooks. Ils servent à contrôler les ressources du système telles que les services, les paquets, les fichiers ou bien encore gérer l’exécution de commandes...

Ce chapitre va présenter les principaux modules de la bibliothèque Files.

Présentation des modules de fichiers

La bibliothèque de modules Files permet d’accomplir les tâches relatives à la gestion de fichiers. Le tableau ci-dessous fournit une liste de modules de gestion de fichiers fréquemment utilisés.

Nom du module

Description

acl

Appliquer les ACL des fichiers.

file

Manipuler des fichiers et des attributs de fichiers.

copy

Copier un fichier depuis la machine locale vers une machine distante.

Définir les attributs de fichiers.

fetch

Copier un fichier depuis une machine distante vers la machine locale.

find

Rechercher un fichier.

stat

Obtenir l’état d’un fichier.

archiveunarchive

Manipuler des archives de fichiers compressés.

blockinfile

Insérer, mettre à jour ou supprimer un bloc de texte multiligne.

lineinfile

Rechercher et/ou remplacer une ligne dans un fichier.

replace

Remplacer toutes les instances d’une chaîne particulière dans un fichier en utilisant une expression régulière.

template

Créer, à l’aide d’un fichier modèle Jinja2, un fichier sur un hôte distant.

Ces modules et leurs paramètres sont étudiés ci-après.

Appliquer les ACL de fichiers

Le module ACL permet de définir ou de récupérer les informations ACL (Access Control List ou en français Liste de Contrôle d’Accès) d’un fichier.

Le paramètre state a trois valeurs possibles :

Valeur du paramètre

Description

absent

L’ACL doit être supprimée.

present

L’ACL doit être définie.

query

Permet d’obtenir l’ACL courante sans la modifier afin de l’utiliser dans les opérations de registre.

Exemple

Sur l’hôte server2 deux fichiers data.txt et info.txt sont présents dans le répertoire de base (/home/fred) du compte utilisateur fred.

L’objectif est de :

  • définir les permissions RW sur le fichier data.txt pour le compte fred ;

  • supprimer toutes les permissions sur le fichier info.txt pour le compte fred.

--- 
- name: Module FILES - ACL 
  hosts: server2 
 
  tasks: 
  - name: Définir les permissions RW pour fred 
    acl: 
      path: /home/fred/data.txt 
      entity: fred 
      etype: user 
      permissions: rw 
      state: present 
 
  - name: Supprimer les ACL pour fred 
    acl: 
      path: /home/fred/info.txt 
      entity:...

Modifier l’horodatage des fichiers

Manuellement, c’est la commande touch qui est utilisée pour modifier l’horodatage (timestamp) de dernier accès et de dernière modification d’un fichier. Cette commande permet également de créer un fichier vide.

Ansible, quant à lui, s’assure que l’utilisateur propriétaire, le groupe et les autorisations du fichier sont définis.

Exemple

Créez un fichier readme.txt dans le dossier /root sur les machines appartenant au groupe servers. L’utilisateur propriétaire sera john et le groupe propriétaire sera users. Les permissions de ce fichiers seront définies à 0640 :

--- 
- name: Module FILES - touch 
  hosts: servers 
 
  tasks: 
  - name: Touch a file and set permissions 
    file: 
      path: /root/readme.txt 
      owner: john 
      group: users 
      mode: 0640 
      state: touch 

Dans un terminal, constatez le résultat :

[root@server2 ~]# ll /root/readme.txt 
-rw-r-----. 1 john users 0  14 janv. 16:39 /root/readme.txt 
[root@server2 ~]# 

La gestion des attributs de fichier peut s’effectuer grâce à plusieurs modules. Il est utile parfois de se documenter avec la commande...

Copie de fichiers

1. Module copy

Le module copy est utilisé pour copier un fichier situé dans un dossier sur le nœud de contrôle vers les hôtes gérés.

Exemple

Copier depuis le nœud de contrôle le fichier ~/workspace/prog.conf vers l’hôte /opt/app/prog.conf. L’utilisateur et le groupe propriétaires sont root. Les permissions sont définies ainsi : u=rw,g=r,o=r.

--- 
- name: Module FILES - copy 
  hosts: server2 
 
  tasks: 
  - name: Copie du fichier prog.conf 
    copy: 
      src: ~/workspace/prog.conf 
      dest: /opt/app/prog.conf 
      owner: root 
      group: root 
      mode: u=rw,g=r,o=r 

Le paramètre mode accepte également l’écriture des permissions en nombre octal. Vous disposez de deux syntaxes pour cela.

La première consiste à ajouter un zéro devant la valeur (par exemple 0644) pour que l’analyseur YAML de Ansible sache que c’est bel et bien un nombre octal.

La seconde consiste à encadrer la valeur avec de simples quotes (par exemple ‘644’) pour que Ansible reçoive une chaîne de caractères et puisse la convertir en nombre.

Si vous ne respectez pas l’une de ces deux règles, alors la valeur octale se traduira par un nombre décimal. Ce qui peut provoquer des résultats inattendus.

Par défaut, le module copy a le paramètre force à yes. Il écrase donc le fichier distant. Si vous ne voulez pas de ce comportement, mettez force à no :

tasks: 
- name: Copie du fichier prog.conf 
  copy: 
    src: ~/workspace/prog.conf 
    dest: /opt/app/prog.conf 
    owner: root 
    group: root 
    mode: 0644 
    force : no 

La commande ansible-doc peut fournir les informations sur le module copy :

[root@server1 ~]# ansible-doc copy 
 
 
**** sortie tronquée **** 
 
 
= dest 
   ...

Suppression de fichiers

Supprimer un fichier sur des hôtes gérés consiste à utiliser le module file avec le paramètre state: absent.

Exemple

Pour supprimer le fichier /home/fred/info.txt :

--- 
- name: Module file - Supprimer un fichier 
  hosts: server2 
  vars: 
    fic: /home/fred/info.txt 
 
  tasks: 
  - name: Supprimer le fichier 
    file: 
      state: absent 
      path: "{{ fic }}" 

Déplacement et renommage des fichiers

Vous avez sans doute constaté dans le tableau au début de ce chapitre que la bibliothèque de modules files ne fournit pas de modules qui permettraient de déplacer ou de renommer des fichiers.

Cette section présente deux possibilités.

Première possibilité

En utilisant le module command et la commande mv du système d’exploitation Linux.

Exemple

Nous voulons déplacer le fichier /home/fred/data.txt dans le dossier /home/fred/old/ si le fichier est existant.

--- 
- name: Module command - déplacer/renommer un fichier 
  hosts: server2 
  vars: 
    fic_src: /home/fred/data.txt 
    fic_dest: /home/fred/old/ 
 
  tasks: 
  - name: Fichier existe ou pas 
    stat: 
      path: "{{ fic_src }}" 
    register: resultat 
 
- name: deplacer fichier si existe 
    command: mv "{{ fic_src }}" "{{ fic_dest }}" 
    when: resultat.stat.exists == True 

Seconde possibilité

En utilisant le module copy pour copier le fichier vers une destination souhaitée. Puis, en utilisant le module file pour supprimer la source de la copie.

Exemple

En reprenant l’objectif de l’exemple précédent :...

Recherche de fichiers

Le module find permet de rechercher un ou plusieurs fichiers sur les hôtes gérés. 

Dans le tableau suivant, vous trouverez les paramètres les plus courants de ce module. D’ailleurs, vous trouverez des similitudes avec la commande find du shell Linux.

Paramètre

Description

paths

Lister des chemins d’accès parmi lesquels il faut rechercher. Tous les chemins doivent être pleinement qualifiés.

age

Trouver les fichiers dont l’âge est égal ou supérieur à la durée spécifiée.

Utiliser un âge négatif pour trouver les fichiers dont l’âge est égal ou inférieur à la durée spécifiée.

Il est possible de spécifier la première lettre de la durée :

  • secondes (s),

  • minutes (m),

  • heures (h),

  • jours (d comme days),

  • semaines (w comme weeks).

Exemple : Pour une semaine, spécifier 1w.

age_stamp

Choisir la propriété du fichier par rapport à laquelle l’âge est comparé :

  • atime pour la date de la dernière lecture.

  • mtime pour la date de la dernière modification (valeur par défaut).

  • ctime pour la date de la dernière connexion.

recurse

Si recurse=yes et que la cible est un dossier, ce dernier sera parcouru récursivement à la recherche de fichiers.

La valeur par défaut...

Informations sur l’état d’un fichier

Le module stat est similaire à la commande qui porte le même nom.

Exemple

Vérifier que le dossier /root/database sur l’hôte server2 existe.

D’abord, le module stat va récupérer les faits de ce dossier. La variable ret va capturer le résultat.

Le module debug affiche le message "Chemin inexistant" si la condition définie avec la clause when « ret.stat.isdir is not defined » est vraie.

Nous utilisons une seconde fois ce module pour afficher le message "Chemin existant" si la condition définie avec la clause when « ret.stat.isdir is defined » est vraie.

Consultez ansible-doc stat pour connaître les paramètres et la valeur de retour.

--- 
- name: Module FILES - stat 
  hosts: server2 
 
  tasks: 
  - name: Tester si le dossier existe 
    stat: 
      path: /root/database 
    register: ret 
 
  - debug: 
      msg: "Chemin inexistant" 
    when: ret.stat.isdir is not defined 
 
  - debug: 
      msg: "Chemin existant" 
   ...

Manipulation d’archives

Cette section va démontrer comment créer et extraire des fichiers d’une archive comme vous le feriez manuellement avec la commande tar.

1. Création d’une archive

Le module archive permet de concevoir une archive compressée. Le tableau ci-dessous décrit les principaux paramètres nécessaires :

Paramètre

Description

path

Spécifie le(s) chemin(s) pour le(s) fichier(s) à archiver.

exclude_path

Spécifie le(s) chemin(s) à exclure de l’archive.

dest

Définit le nom de fichier de l’archive de destination.

format

Définit le format de l’archive qui peut être bz2, gz (valeur par défaut), tar, xz et zip.

Exemple

Créer une archive, au format bzip2, qui contient les fichiers du répertoire /opt/app. Il faut exclure le sous-répertoire /opt/app/images :

--- 
- name: Module archive 
  hosts: server2 
 
# Creation archive bz2 des fichiers /opt/app/* 
# en excluant le dossier /opt/app/images 
  tasks: 
  - name: Creation archive 
    archive: 
      path: /opt/app/* 
      dest: /root/app.tar.bz2 
      exclude_path: /opt/app/images 
      format: bz2 

2. Extraction d’une archive

Le module unarchive permet d’extraire des fichiers d’une...

Modification de fichiers

Pour modifier le contenu d’un fichier, ces trois modules sont disponibles :

  • lineinfile qui est utile lorsqu’une seule ligne est à modifier dans un fichier ;

  • blockinfile permet d’insérer, de mettre à jour ou de supprimer un bloc de lignes dans un fichier ;

  • replace permet de remplacer toutes les instances d’une chaîne particulière dans un fichier.

1. Module lineinfile

Le module lineinfile permet de s’assurer de la présence d’une ligne particulière dans un fichier ou de remplacer une ligne existante en utilisant une expression régulière.

Le tableau ci-dessous décrit les principaux paramètres qui sont essentiels :

Paramètre

Description

path

Définit le chemin d’accès et le nom du fichier à traiter.

regexp

Spécifie le motif de recherche.

line

Spécifie la ligne à insérer ou à remplacer au sein du fichier.

Exemple

Pour s’assurer que SELinux est en mode enforcing : remplacer dans le fichier /etc/selinux/config la ligne qui commence par SELINUX par la nouvelle valeur SELINUX=enforcing :

--- 
- name: Module FILES - lineinfile 
  hosts: servers 
 
  tasks: 
  - name: Verifier que SELinux est en mode enforcing 
    lineinfile: 
      path: /etc/selinux/config 
      regexp: '^SELINUX=' 
      line: SELINUX=enforcing 

2. Module blockinfile

Lorsque vous souhaitez ajouter un bloc de texte à un fichier existant, il faut utiliser le module blockinfile.

Le tableau ci-dessous décrit les principaux paramètres qui sont essentiels :

Paramètre

Description

path

Définit le chemin d’accès et le nom du fichier à...

Modifications de contexte de fichier SELinux

Le module file se comporte comme la commande chcon lors de la définition des contextes de fichier. Par conséquent, les modifications apportées avec ce module pourraient être annulées de manière inattendue en exécutant la commande restorecon.

Après avoir défini le contexte avec le module file, vous pouvez utiliser le module sefcontext de la bibliothèque de modules system afin de mettre à jour la politique SELinux. Ces manipulations sont similaires à l’utilisation de la commande semanage fcontext.

Les paquets suivants sont nécessaires pour l’hôte qui exécute ce module :

  • libselinux-python ;

  • policycoreutils-python.

Exemple

Créer un dossier /common sur l’hôte server2 pour une utilisation future de SAMBA. SELinux est, sur cette machine cible, en mode enforcing.

Faisons manuellement la manipulation avant de concevoir le playbook. Il est nécessaire, tout d’abord, de définir quatre valeurs booléennes SELinux. Par exemple :

[root@server2 /]# setsebool -P samba_enable_home_dirs on 
[root@server2 /]# setsebool -P use_samba_home_dirs on 
[root@server2 /]# setsebool -P samba_export_all_ro on 
[root@server2 /]# setsebool -P samba_export_all_rw on 

Pour vérifier, utilisez la commande getsebool :

[root@server2 /]# getsebool -a | grep...

Synchronisation de fichiers

Le module synchronize est un « wrapper » qui fonctionne autour de la commande rsync qui doit être installé sur le nœud de contrôle et sur l’hôte géré.

Ce module ne fournit pas toute la puissance de la commande rsync. Il facilite, cependant, la mise en œuvre des fonctionnalités les plus courantes. Vous pouvez, néanmoins, avoir besoin d’appeler parfois la commande rsync via les modules command ou shell selon votre cas d’utilisation.

Exemple

Le dossier /root/files du nœud de contrôle (server1) doit être synchronisé avec le dossier /common/files situé sur l’hôte géré (server2) :

--- 
- name: Module FILES - synchronize 
  hosts: server2 
 
  tasks: 
  - name: Synchronisation depuis server1 vers l'hôte server2 
    synchronize: 
      src: /root/files 
      dest: /common/files 

Utilisez la commande ansible-doc synchronize pour plus d’informations sur les paramètres et les exemples de playbook fournis.

Modèles JINJA2

1. Présentation de Jinja2

Jinja2 est un moteur de modèles (templates) pour le langage Python qui est basé sur celui du framework Django. Initialement, il était utilisé pour créer des pages HTML à partir d’un modèle préformaté dans lequel sont injectées des données sous forme de variables, mais aussi, permettant d’utiliser des conditions et des boucles. Vous disposez d’une documentation sur le site : https://jinja.palletsprojects.com/en/2.10.x/templates/

Un modèle Jinja2 est tout simplement un fichier texte avec une extension .j2.

Ansible Engine utilise la syntaxe Jinja2 pour référencer les variables dans les playbooks.

La syntaxe pour définir des commentaires est :

{# mon commentaire #} 

Les expressions, les boucles et les conditions sont exprimées dans cette balise :

{% expression %} 

La balise suivante est utilisée pour générer le résultat d’une expression ou d’une variable :

{{ adresse_IP }} 

Dans les modèles, vous pouvez utiliser des boucles et des conditions Jinja2. Ce qui n’est pas le cas dans les playbooks.

2. Conception et application d’un modèle

Comme vu précédemment, des données, des variables et des expressions composent un modèle Jinja2. Les variables qui sont utilisées peuvent être définies dans la section vars du playbook. Elles sont remplacées par leurs valeurs lorsqu’un modèle est « rendu ». C’est aussi le cas pour les expressions. Vous pouvez utiliser les faits (facts) des hôtes gérés, que nous avons vus dans le chapitre Gestion des faits, comme variables sur un modèle.

Dans le playbook suivant, le module template est utilisé :

tasks: 
 - name: template render 
    template: 
      src: fichier_modele.j2 
      dest: /home/bob/data/fichier_rendu.txt 

Il nécessite plusieurs paramètres :

Paramètre

Description

src

Spécifie le chemin et le nom du fichier modèle (template) au format Jinja2. Il est situé sur le nœud de contrôle.

Le répertoire par défaut est ./templates.

dest

Définit...