Aller au contenu

Gestion de Fichiers avec Ansible

Mise à jour :

logo

Dans la gestion des infrastructures, l’automatisation est un atout majeur pour maintenir une cohérence et un gain de temps sur l’ensemble des opérations. Ansible est un outil puissant qui permet cette automatisation, notamment grâce à ses nombreux modules dédiés à la gestion des fichiers et des répertoires. Que ce soit pour créer des dossiers, copier des fichiers, gérer les permissions ou interagir avec des fichiers distants via des API, Ansible offre une gamme complète de solutions.

Dans ce guide, je vais te présenter les principaux modules Ansible dédiés à la gestion des fichiers, en te montrant comment les utiliser efficacement pour accomplir des tâches variées. Tu apprendras à manipuler les fichiers locaux sur tes serveurs distants, à les télécharger depuis des sources externes, à les récupérer ou encore à les modifier en fonction des besoins de ton infrastructure.

Le module file

Le module file est essentiel pour la gestion des fichiers et des répertoires dans Ansible. Il te permet de créer, supprimer ou gérer les permissions, les propriétaires et les groupes des fichiers et répertoires sur les hôtes distants. C’est l’un des modules les plus polyvalents, car il peut être utilisé pour des opérations variées, telles que la gestion des répertoires de projets, la suppression de fichiers temporaires ou encore la configuration des permissions spécifiques.

Création de répertoires avec permissions, propriétaire et groupe

Le module file permet de créer des répertoires très rapidement :

- name: Créer un répertoire pour une application web
ansible.builtin.file:
path: /var/www/html
state: directory
mode: '0755' # Permissions en octal : lecture et exécution pour tous, écriture pour le propriétaire
owner: www-data # Propriétaire du répertoire
group: www-data # Groupe associé au répertoire

Dans cet exemple, nous créons le répertoire /var/www/html avec les permissions 0755, ce qui signifie que le propriétaire peut lire, écrire et exécuter, tandis que le groupe et les autres utilisateurs peuvent seulement lire et exécuter. Le propriétaire et le groupe sont tous deux définis comme www-data, un compte utilisateur couramment utilisé pour les services web comme Apache ou Nginx.

Suppression de fichiers ou répertoires

Le module file est également utile pour supprimer des fichiers ou des répertoires devenus obsolètes ou inutiles. Ici encore, tu dois toujours spécifier l’état du fichier ou du répertoire pour éviter les erreurs.

Exemple de suppression d’un fichier temporaire :

- name: Supprimer un fichier temporaire
ansible.builtin.file:
path: /tmp/fichier_temp.txt
state: absent

Dans cet exemple, le fichier /tmp/fichier_temp.txt sera supprimé si celui-ci existe. Le module ne renverra aucune erreur si le fichier est déjà absent, ce qui le rend sûr à utiliser dans des environnements variés.

Modification des permissions d’un fichier existant

Si un fichier ou un répertoire existe déjà et que tu veux ajuster ses permissions ou son propriétaire, tu peux également utiliser le module file. Encore une fois, il est important de spécifier systématiquement les permissions, le propriétaire et le groupe, même si tu veux juste changer un de ces paramètres.

Exemple pour modifier les permissions d’un fichier de configuration :

- name: Modifier les permissions d’un fichier de configuration
ansible.builtin.file:
path: /etc/app/config.conf
mode: '0644' # Lecture/écriture pour le propriétaire, lecture seule pour les autres
owner: root # Le propriétaire doit être root pour ce fichier de configuration
group: root # Le groupe associé est root

Ici, nous modifions les permissions du fichier config.conf pour qu’il soit accessible en lecture seule pour tout le monde, sauf pour le propriétaire, qui a des droits de lecture et d’écriture. Cela permet de garantir que seules les personnes autorisées peuvent modifier ce fichier tout en assurant qu’il peut être lu par les autres utilisateurs ou services qui en ont besoin.

Création de fichiers vides

Le module file peut aussi être utilisé pour créer des fichiers vides. Cela peut être utile pour préparer des fichiers de log ou des fichiers de configuration avant leur utilisation.

Exemple pour créer un fichier vide avec les bonnes permissions :

- name: Créer un fichier vide pour les logs
ansible.builtin.file:
path: /var/log/app.log
state: touch # Crée un fichier vide s'il n'existe pas, ou met à jour son timestamp
mode: '0640' # Lecture/écriture pour le propriétaire, lecture pour le groupe
owner: syslog # Le propriétaire des fichiers de log peut être syslog
group: adm # Groupe des utilisateurs ayant accès aux logs

Avec cet exemple, nous créons un fichier de log vide nommé app.log avec des permissions qui restreignent l’accès aux membres du groupe adm et au service syslog.

Le module ansible copy

Le module ansible copy est l’un des plus simples et les plus couramment utilisés dans Ansible pour transférer des fichiers depuis l’hôte de contrôle (machine exécutant Ansible) vers les hôtes distants. Il permet de copier des fichiers ou des répertoires locaux, tout en gérant les permissions, le propriétaire et le groupe des fichiers cibles, garantissant ainsi que les fichiers sont correctement configurés dès leur arrivée sur l’hôte distant.

Le module copy utilise automatiquement un système de checksum pour vérifier si le fichier source et le fichier destination sont identiques. Si c’est le cas, le fichier ne sera pas recopié, ce qui optimise les performances et évite les interruptions.

Comme pour le module file, il est important de respecter les bonnes pratiques : toujours définir les permissions (mode), le propriétaire et le groupe lors du transfert des fichiers pour éviter des problèmes de sécurité ou des erreurs d’accès.

Copie de fichiers avec permissions, propriétaire et groupe

Lorsque tu utilises le module copy pour déployer des fichiers, il est essentiel de toujours spécifier les permissions, le propriétaire et le groupe des fichiers cibles pour éviter que ces fichiers n’héritent de permissions incorrectes ou inadéquates, surtout lorsque le fichier est déployé sur plusieurs serveurs.

Voici un exemple de copie d’un fichier de configuration d’application avec les bonnes pratiques de sécurité :

- name: Copier un fichier de configuration vers les serveurs distants
ansible.builtin.copy:
src: /local/path/app.conf
dest: /etc/app/app.conf
mode: '0644' # Lecture/écriture pour le propriétaire, lecture seule pour les autres
owner: root # Le fichier est sous la propriété de root
group: appgroup # Groupe dédié aux utilisateurs de l’application

Dans cet exemple, le fichier app.conf est copié depuis l’hôte local vers l’hôte distant dans le répertoire /etc/app/. Les permissions sont définies sur 0644, ce qui permet au propriétaire d’écrire dans le fichier, mais limite l’accès en écriture pour le groupe et les autres utilisateurs. Le fichier est assigné à root comme propriétaire et au groupe appgroup, ce qui peut correspondre à un groupe d’utilisateurs autorisés à utiliser ou lire le fichier.

Copie de répertoires

Le module copy permet aussi de copier des répertoires entiers vers des hôtes distants. Par défaut, le contenu du répertoire sera copié de manière récursive, avec une attention particulière aux permissions et aux propriétés.

Voici un exemple où un répertoire contenant plusieurs fichiers est copié vers un serveur distant avec les bonnes pratiques :

- name: Copier un répertoire de configuration avec permissions
ansible.builtin.copy:
src: /local/path/config/
dest: /etc/app/config/
mode: '0755' # Permissions du répertoire : lecture/exécution pour tous, écriture pour le propriétaire
owner: appuser # Le propriétaire est un utilisateur dédié à l’application
group: appgroup # Groupe associé aux utilisateurs de l’application
recurse: yes # Copie récursive pour tout le contenu du répertoire

Ici, tout le répertoire /local/path/config/ est copié vers /etc/app/config/ sur l’hôte distant. Le paramètre recurse: yes indique que tous les fichiers et sous-répertoires du répertoire source seront copiés. Le répertoire cible reçoit des permissions 0755, permettant une lecture et une exécution pour tout le monde, mais limitant l’écriture au propriétaire du fichier. Cela permet d’assurer que seuls les utilisateurs autorisés peuvent modifier les fichiers dans ce répertoire.

Copie d’un fichier avec back-up automatique

Une autre fonctionnalité intéressante du module copy est la possibilité de créer une sauvegarde automatique du fichier existant avant de le remplacer. Cela est particulièrement utile lors de la gestion de fichiers critiques, comme des configurations système, où il est important de conserver une copie du fichier avant de le modifier.

- name: Copier un fichier de configuration avec sauvegarde
ansible.builtin.copy:
src: /local/path/app.conf
dest: /etc/app/app.conf
mode: '0644'
owner: root
group: appgroup
backup: yes # Crée une sauvegarde du fichier existant avant de le remplacer

Dans cet exemple, si le fichier /etc/app/app.conf existe déjà, une copie de sauvegarde sera créée avant que le nouveau fichier ne soit copié. Cette sauvegarde sera stockée avec un suffixe horodaté, te permettant de récupérer le fichier original en cas de besoin.

Le module template

Le module template est essentiel lorsque tu dois déployer des fichiers contenant des variables dynamiques. Il fonctionne en combinaison avec le moteur de templates Jinja2, te permettant de personnaliser des fichiers de configuration ou des scripts selon les besoins de chaque hôte distant. Ce module est idéal pour des scénarios où le même fichier doit être déployé sur plusieurs serveurs, mais avec des valeurs spécifiques à chaque serveur ou environnement.

Pour ceux qui ne connaissent les templates Jinja2, jai écris une documentation assez complète.

Déploiement d’un fichier avec variables

L’un des cas d’utilisation les plus courants du module template est le déploiement de fichiers de configuration où certaines valeurs doivent être modifiées en fonction du serveur. Par exemple, tu peux vouloir déployer un fichier de configuration pour un service web avec un nom de domaine et un port spécifiques à chaque environnement.

Exemple de fichier template (nginx.conf.j2) :

server {
listen {{ nginx_port }};
server_name {{ domain_name }};
location / {
root /var/www/{{ site_root }};
index index.html;
}
}

Exemple de playbook pour déployer ce template :

- name: Déployer un fichier de configuration Nginx
ansible.builtin.template:
src: templates/nginx.conf.j2
dest: /etc/nginx/sites-available/default
mode: '0644'
owner: root
group: root
vars:
nginx_port: 80
domain_name: example.com
site_root: html

Dans cet exemple, le fichier template est copié sur l’hôte distant avec les valeurs dynamiques remplacées par les variables définies dans le playbook. Les variables nginx_port, domain_name et site_root sont automatiquement insérées dans le fichier avant son déploiement.

Gestion des erreurs avec validate

Il est important de s’assurer que le fichier généré par le template est valide avant de l’appliquer. Pour cela, tu peux utiliser l’option validate qui permet de valider un fichier avant qu’il ne soit copié sur l’hôte distant. Cela est particulièrement utile pour les fichiers de configuration qui, s’ils sont mal formés, pourraient causer des erreurs ou empêcher un service de démarrer correctement.

Exemple de validation d’un fichier de configuration Nginx :

- name: Déployer et valider la configuration Nginx
ansible.builtin.template:
src: templates/nginx.conf.j2
dest: /etc/nginx/sites-available/default
mode: '0644'
owner: root
group: root
validate: '/usr/sbin/nginx -t -c %s'

Ici, l’option validate utilise la commande nginx -t pour vérifier que la configuration générée est correcte avant de l’appliquer. Si la validation échoue, le fichier ne sera pas copié et une erreur sera renvoyée, ce qui permet de détecter et corriger les problèmes avant qu’ils n’affectent le service.

Le module lineinfile

Le module lineinfile te permet de manipuler des lignes spécifiques à l’intérieur d’un fichier texte, ce qui est particulièrement utile lorsque tu veux garantir la présence ou la modification d’une ligne dans un fichier de configuration sans toucher à l’intégralité du fichier. Ce module est conçu pour ajouter, remplacer ou supprimer une ligne spécifique en fonction d’un motif de recherche, tout en garantissant que les autres lignes du fichier ne sont pas affectées.

Ce module est souvent utilisé pour ajuster des configurations système ou applicatives, comme ajouter une directive dans un fichier de configuration, ou pour ajuster des paramètres clés sans avoir à réécrire tout le fichier.

Ajout d’une ligne dans un fichier

Si tu as besoin d’ajouter une ligne dans un fichier texte, lineinfile te permet de le faire facilement tout en s’assurant que cette ligne ne sera pas dupliquée si elle existe déjà.

Exemple d’ajout d’une directive dans un fichier de configuration réseau :

- name: Activer la redirection IP dans le fichier sysctl.conf
ansible.builtin.lineinfile:
path: /etc/sysctl.conf
line: 'net.ipv4.ip_forward=1'
state: present
owner: root
group: root
mode: '0644'

Dans cet exemple, la ligne net.ipv4.ip_forward=1 est ajoutée au fichier /etc/sysctl.conf si elle n’existe pas déjà. Si la ligne est présente, elle ne sera pas ajoutée une seconde fois, ce qui garantit que la configuration est maintenue sans duplication. Ce genre d’ajout est essentiel pour des paramètres système critiques, comme la gestion du réseau.

Modification d’une ligne existante avec une regexp

Le module lineinfile permet également de modifier une ligne spécifique si elle existe déjà, en recherchant un motif avec l’option regexp. Cela est utile lorsque tu veux modifier un paramètre déjà existant dans un fichier de configuration sans changer le reste du contenu.

Exemple de modification d’un paramètre dans un fichier de configuration :

- name: Modifier le paramètre IP forwarding
ansible.builtin.lineinfile:
path: /etc/sysctl.conf
regexp: '^net.ipv4.ip_forward='
line: 'net.ipv4.ip_forward=1'
owner: root
group: root
mode: '0644'

Dans cet exemple, le module recherche toute ligne commençant par net.ipv4.ip_forward= et la remplace par net.ipv4.ip_forward=1. Cela garantit que la configuration est correctement appliquée même si une valeur précédente était différente. L’utilisation de l’option regexp permet de s’assurer que seules les lignes correspondant au motif seront modifiées, ce qui évite les erreurs potentielles.

Suppression d’une ligne

Si tu veux retirer une ligne spécifique d’un fichier, lineinfile permet de le faire en utilisant l’option state: absent, qui supprime la ligne correspondant au motif fourni.

Exemple de suppression d’une directive dans un fichier de configuration :

- name: Désactiver l'option IP forwarding
ansible.builtin.lineinfile:
path: /etc/sysctl.conf
regexp: '^net.ipv4.ip_forward='
state: absent
owner: root
group: root
mode: '0644'

Cet exemple retire toute ligne qui commence par net.ipv4.ip_forward= du fichier /etc/sysctl.conf, ce qui est utile lorsque tu veux désactiver une option ou nettoyer un fichier de configuration en supprimant des entrées obsolètes.

Le module replace

Le module replace d’Ansible permet de remplacer des motifs de texte spécifiques dans un fichier en utilisant des expressions régulières (regex). Contrairement à lineinfile, qui se concentre sur l’ajout, la modification ou la suppression de lignes entières, replace est idéal lorsque tu as besoin de remplacer des parties précises de texte à l’intérieur d’une ligne ou lorsque le motif à modifier se trouve dans plusieurs lignes à la fois. Ce module est donc particulièrement utile pour les fichiers de grande taille ou complexes où des modifications ciblées sont nécessaires.

Remplacement d’un motif spécifique

Le module replace est souvent utilisé pour modifier une configuration déjà présente dans un fichier. Il permet de cibler des motifs précis et de les remplacer par d’autres. Par exemple, imaginons que tu souhaites modifier le port d’écoute d’un serveur web dans un fichier de configuration sans affecter les autres paramètres.

Exemple de remplacement d’un port dans une configuration :

- name: Remplacer le port d'écoute du serveur web
ansible.builtin.replace:
path: /etc/nginx/nginx.conf
regexp: 'listen\s+80;'
replace: 'listen 8080;'
owner: root
group: root
mode: '0644'

Dans cet exemple, nous utilisons une expression régulière pour rechercher la ligne contenant listen 80; et la remplacer par listen 8080; dans le fichier /etc/nginx/nginx.conf. L’utilisation de \s+ dans le regexp permet de prendre en compte n’importe quel nombre d’espaces entre listen et 80.

Utilisation de groupes capturants avec les expressions régulières

L’un des avantages du module replace est sa compatibilité avec les groupes capturants dans les expressions régulières. Cela permet de cibler et de modifier seulement une partie du texte tout en préservant le reste du motif. Cette technique est particulièrement utile lorsque tu veux modifier une valeur sans affecter d’autres parties du fichier.

Exemple de remplacement d’une partie d’un motif avec des groupes capturants :

- name: Remplacer l'adresse IP dans une configuration réseau
ansible.builtin.replace:
path: /etc/network/interfaces
regexp: '(address\s+)([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})'
replace: '\1 192.168.1.100'
owner: root
group: root
mode: '0644'

Dans cet exemple, nous utilisons un groupe capturant pour repérer l’adresse IP actuelle dans une configuration réseau. Le premier groupe (address\s+) capture la partie “address ” tandis que le second groupe capture l’adresse IP. Ensuite, nous remplaçons l’adresse IP tout en conservant la partie “address” inchangée grâce à \1, qui fait référence au premier groupe capturant.

Sauvegarde du fichier avant remplacement

Dans certains cas, il peut être nécessaire de conserver une copie de sauvegarde du fichier avant d’effectuer des remplacements, surtout lorsque tu modifies des fichiers critiques. Le module replace permet de créer automatiquement une sauvegarde du fichier avant d’appliquer les changements.

Exemple avec création d’une sauvegarde :

- name: Remplacer une ligne dans le fichier avec sauvegarde
ansible.builtin.replace:
path: /etc/nginx/nginx.conf
regexp: 'worker_processes\s+1;'
replace: 'worker_processes 4;'
backup: yes
owner: root
group: root
mode: '0644'

Dans cet exemple, une sauvegarde du fichier /etc/nginx/nginx.conf sera créée avant que le remplacement de worker_processes 1 par worker_processes 4 ne soit effectué. Cela te permet de restaurer le fichier original si quelque chose ne se passe pas comme prévu.

Le module blockinfile

Le module blockinfile te permet d’insérer, de modifier ou de supprimer des blocs de texte complets dans un fichier, tout en délimitant ces blocs avec des balises spécifiques. Contrairement aux modules lineinfile ou replace, qui opèrent sur des lignes ou des motifs individuels, blockinfile est idéal pour gérer des sections entières de fichiers, telles que des configurations groupées, des règles dans un fichier ou des directives structurées.

L’un des principaux avantages de blockinfile est qu’il garantit que les modifications sont bien encadrées par des balises (appelées markers), ce qui rend la gestion et la réversibilité des changements plus faciles à l’avenir.

Ajout d’un bloc de configuration

Le scénario le plus courant avec blockinfile est l’ajout d’un bloc de texte entier à un fichier, comme une section de configuration dans un fichier système ou une application.

Si un bloc existe déjà et que tu veux le modifier ou le remplacer, blockinfile repère automatiquement le bloc en fonction des balises et met à jour son contenu. Cela permet d’assurer que tu puisses modifier des sections entières sans toucher au reste du fichier.

Voici un exemple où nous ajoutons un bloc de configuration pour SSH dans le fichier sshd_config :

- name: Ajouter un bloc de configuration SSH
ansible.builtin.blockinfile:
path: /etc/ssh/sshd_config
block: |
# Configuration personnalisée SSH
AllowUsers admin
PermitRootLogin no
PasswordAuthentication no
marker: "# {mark} Configuration SSH"
owner: root
group: root
mode: '0600'

Dans cet exemple, un bloc contenant plusieurs directives SSH est ajouté à /etc/ssh/sshd_config. Le paramètre marker permet de délimiter le bloc avec des commentaires spécifiques, ici # BEGIN Configuration SSH et # END Configuration SSH, ce qui facilite la gestion de ce bloc par la suite. De plus, le fichier reçoit les bonnes permissions pour garantir qu’il n’est modifiable que par le super-utilisateur.

Suppression d’un bloc

blockinfile peut également être utilisé pour supprimer un bloc de texte complet. Cela est pratique lorsque tu dois retirer des configurations obsolètes ou réverser une modification effectuée par le biais d’Ansible.

Insertion d’un bloc à un emplacement spécifique

Par défaut, blockinfile ajoute le bloc à la fin du fichier cible. Cependant, dans certains cas, il peut être nécessaire de l’insérer à un emplacement particulier, comme avant ou après une ligne spécifique.

Exemple d’insertion d’un bloc avant une ligne particulière :

- name: Ajouter une configuration avant une directive existante
ansible.builtin.blockinfile:
path: /etc/nginx/nginx.conf
block: |
# Configuration personnalisée Nginx
worker_processes 4;
worker_connections 1024;
marker: "# {mark} Configuration Nginx"
insertbefore: '^http'
owner: root
group: root
mode: '0644'

Dans cet exemple, le bloc de configuration Nginx est inséré juste avant la première ligne contenant le mot http. L’option insertbefore permet de spécifier le point d’insertion basé sur une expression régulière, ce qui est utile lorsque tu veux insérer un bloc à un emplacement logique dans le fichier.

Le module stat

Le module stat d’Ansible est un outil très utile qui permet de récupérer des informations détaillées sur les fichiers ou les répertoires présents sur les hôtes distants. Il est similaire à la commande stat des systèmes Unix, qui fournit des informations comme les permissions, la taille, les horodatages (création, dernière modification) et les propriétaires. Ce module est souvent utilisé dans les playbooks pour prendre des décisions basées sur l’état des fichiers ou des répertoires, comme vérifier si un fichier existe ou si ses permissions sont correctes avant d’effectuer des modifications.

Utilisation de base pour obtenir des informations sur un fichier

Le scénario le plus simple avec stat est de vérifier si un fichier ou un répertoire existe et d’obtenir ses métadonnées. Cela permet, par exemple, de vérifier la présence d’un fichier de configuration avant de le modifier, ou de s’assurer que les permissions sont correctes avant d’effectuer des opérations sensibles.

Exemple de vérification de l’existence d’un fichier :

- name: Vérifier si le fichier de configuration SSH existe
ansible.builtin.stat:
path: /etc/ssh/sshd_config
register: sshd_stat
- name: Continuer uniquement si le fichier existe
ansible.builtin.debug:
msg: "Le fichier /etc/ssh/sshd_config existe."
when: sshd_stat.stat.exists

Dans cet exemple, nous utilisons stat pour vérifier si le fichier /etc/ssh/sshd_config existe. La clé sshd_stat.stat.exists est un booléen qui indique si le fichier est présent ou non. Le module debug affichera un message uniquement si le fichier existe, ce qui montre comment nous pouvons prendre des décisions conditionnelles basées sur cette information.

Vérification des permissions

Il est souvent nécessaire de vérifier que les fichiers ou répertoires sur les systèmes distants ont les bonnes permissions avant de les modifier ou de les utiliser. Par exemple, un fichier de configuration sensible doit avoir des permissions restreintes pour éviter tout accès non autorisé.

Exemple de vérification des permissions d’un fichier :

- name: Vérifier les permissions du fichier /etc/passwd
ansible.builtin.stat:
path: /etc/passwd
register: passwd_stat
- name: Vérifier si le fichier a les permissions correctes
ansible.builtin.debug:
msg: "Les permissions du fichier sont correctes."
when: passwd_stat.stat.mode == '0644'

Dans cet exemple, nous récupérons les informations du fichier /etc/passwd et vérifions si ses permissions sont 0644. Cela permet de s’assurer que le fichier a les bonnes permissions avant d’effectuer d’autres actions. La clé stat.mode fournit les permissions en octal, ce qui est utile pour faire des comparaisons.

Le module slurp

Le module slurp d’Ansible permet de récupérer le contenu d’un fichier en base64 depuis un hôte distant et de le stocker localement sous forme de variable. slurp est principalement utilisé lorsque tu veux lire et traiter des fichiers distants, mais que tu ne veux pas (ou ne peux pas) accéder directement au fichier sur l’hôte distant via des commandes système. Ce module est idéal pour manipuler des petits fichiers, des contenus sensibles ou des fichiers dont tu veux capturer les informations pour les traiter localement dans un playbook.

Utilisation de base pour récupérer le contenu d’un fichier

L’utilisation la plus simple de slurp est de récupérer le contenu d’un fichier à distance et de le stocker dans une variable. Le contenu récupéré est encodé en base64, une méthode de codage utilisée pour représenter des données binaires sous forme de texte, ce qui permet de transmettre ces données de manière sûre.

Exemple de récupération du contenu d’un fichier distant :

- name: Récupérer le contenu du fichier de configuration
ansible.builtin.slurp:
path: /etc/myapp/config.yml
register: config_content

Dans cet exemple, slurp lit le fichier /etc/myapp/config.yml sur l’hôte distant et stocke son contenu encodé en base64 dans la variable config_content. Cette variable peut ensuite être utilisée pour afficher ou manipuler le contenu du fichier à distance.

Décodage du contenu en base64

Comme le contenu récupéré par slurp est encodé en base64, tu devras souvent le décoder pour le rendre lisible ou exploitable dans ton playbook. Ansible permet d’utiliser des filtres pour décoder le contenu.

Exemple de décodage du contenu récupéré avec slurp :

- name: Afficher le contenu du fichier de configuration décodé
ansible.builtin.debug:
msg: "{{ config_content['content'] | b64decode }}"

Ici, nous utilisons le filtre b64decode pour décoder le contenu base64 et le rendre lisible. Cela te permet de voir le contenu réel du fichier récupéré depuis l’hôte distant. Ce processus est utile si tu veux inspecter ou utiliser des parties spécifiques du fichier dans tes tâches suivantes.

Exemple avancé : utilisation du contenu récupéré

Après avoir récupéré et décodé le contenu d’un fichier, il est courant de l’utiliser pour prendre des décisions dans un playbook ou pour effectuer des comparaisons avec d’autres fichiers. Par exemple, tu peux vouloir récupérer un fichier de configuration, analyser son contenu, puis déclencher des actions en fonction de ce contenu.

Exemple de comparaison du contenu d’un fichier distant avec une valeur attendue :

- name: Récupérer le fichier de configuration actuel
ansible.builtin.slurp:
path: /etc/myapp/config.yml
register: config_content
- name: Vérifier si le fichier contient une configuration spécifique
ansible.builtin.debug:
msg: "La configuration est correcte."
when: "'my_setting: true' in (config_content['content'] | b64decode)"

Dans cet exemple, nous utilisons slurp pour récupérer le fichier de configuration, puis nous décodons son contenu et vérifions s’il contient une chaîne spécifique (ici my_setting: true). Si la condition est remplie, nous affichons un message de débogage. Cela est utile pour s’assurer qu’une configuration est présente dans un fichier avant de continuer avec d’autres étapes du playbook.

Limites de slurp

Bien que le module slurp soit très pratique pour récupérer des fichiers distants, il est important de noter qu’il est conçu pour manipuler des petits fichiers. Étant donné que slurp stocke le contenu du fichier encodé en base64 dans une variable, la taille des fichiers manipulés peut rapidement devenir problématique. Pour des fichiers volumineux, il est recommandé d’utiliser d’autres modules comme fetch ou copy, qui gèrent directement le transfert de fichiers.

Exemple de limitation de taille :

- name: Tenter de récupérer un fichier volumineux
ansible.builtin.slurp:
path: /var/log/largefile.log
register: large_file_content

Dans cet exemple, si le fichier largefile.log est trop volumineux, cela peut entraîner une surcharge de mémoire ou une lenteur d’exécution, car Ansible devra encoder l’intégralité du fichier en base64. Dans ces cas-là, il est préférable d’utiliser des modules comme fetch pour télécharger le fichier directement.

Le module fetch

Le module fetch d’Ansible permet de télécharger des fichiers ou des répertoires d’un hôte distant vers l’hôte de contrôle. Il est souvent utilisé pour récupérer des logs, des fichiers de configuration, ou d’autres fichiers critiques après avoir exécuté des tâches sur un serveur distant. Contrairement au module slurp, qui est conçu pour des fichiers de petite taille et encode les données en base64, fetch transfère directement les fichiers et est capable de gérer des fichiers de taille plus importante.

Utilisation de base du module fetch

Le cas d’utilisation le plus simple de fetch est de copier un fichier d’un hôte distant vers l’hôte de contrôle. C’est particulièrement utile pour récupérer des fichiers après des tâches d’audit, des exécutions de commandes ou pour centraliser des fichiers sur une machine locale.

Exemple de téléchargement d’un fichier distant vers l’hôte de contrôle :

- name: Récupérer un fichier de configuration distant
ansible.builtin.fetch:
src: /etc/myapp/config.yml
dest: /local/path/configs/
flat: yes

Dans cet exemple, fetch copie le fichier /etc/myapp/config.yml depuis l’hôte distant vers le répertoire local /local/path/configs/. L’option flat: yes est utilisée pour s’assurer que le fichier est copié directement dans le répertoire spécifié et non dans un sous-répertoire correspondant au nom de l’hôte distant.

Structure des fichiers téléchargés

Par défaut, fetch crée une structure de répertoires reflétant l’arborescence des hôtes distants. Par exemple, si tu télécharges plusieurs fichiers depuis plusieurs serveurs, fetch les organise automatiquement en sous-répertoires nommés d’après les adresses ou noms des hôtes.

Exemple de structure par défaut avec plusieurs serveurs :

- name: Récupérer un fichier depuis plusieurs serveurs
ansible.builtin.fetch:
src: /var/log/myapp.log
dest: /local/path/logs/

Dans cet exemple, si tu exécutes cette tâche sur plusieurs serveurs, fetch créera un répertoire dans /local/path/logs/ pour chaque hôte distant, contenant le fichier myapp.log respectif. Par exemple, pour deux hôtes server1 et server2, la structure serait :

/local/path/logs/server1/var/log/myapp.log
/local/path/logs/server2/var/log/myapp.log

Cela permet de bien organiser les fichiers récupérés depuis plusieurs serveurs tout en évitant d’écraser des fichiers.

Gestion des permissions avec fetch

Lorsque fetch copie des fichiers depuis un hôte distant, les permissions du fichier source ne sont pas nécessairement préservées. Par défaut, Ansible définit les permissions sur 0664 pour les fichiers téléchargés. Si tu veux changer ces permissions après avoir récupéré les fichiers, tu peux utiliser le module file pour ajuster ces droits.

Exemple de modification des permissions après récupération :

- name: Récupérer un fichier distant
ansible.builtin.fetch:
src: /etc/myapp/config.yml
dest: /local/path/configs/
flat: yes
- name: Ajuster les permissions du fichier récupéré
delegate_to: localhost
ansible.builtin.file:
path: /local/path/configs/config.yml
mode: '0640'

Dans cet exemple, après avoir téléchargé le fichier config.yml avec fetch, nous utilisons le module file pour définir les permissions sur 0640, garantissant que seuls le propriétaire et le groupe peuvent lire et modifier le fichier.

Utilisation avancée : téléchargement conditionnel

fetch peut également être utilisé de manière conditionnelle pour ne télécharger un fichier que si certaines conditions sont remplies. Par exemple, tu peux vouloir récupérer un fichier uniquement s’il a été modifié récemment ou s’il dépasse une certaine taille.

Exemple de téléchargement conditionnel basé sur la taille d’un fichier :

- name: Vérifier les informations du fichier de log
ansible.builtin.stat:
path: /var/log/myapp.log
register: log_stat
- name: Récupérer le fichier de log si sa taille dépasse 10 Mo
ansible.builtin.fetch:
src: /var/log/myapp.log
dest: /local/path/logs/
flat: yes
when: log_stat.stat.size > 10485760 # 10 Mo en octets

Dans cet exemple, nous utilisons stat pour vérifier la taille du fichier de log, puis nous utilisons fetch pour télécharger le fichier uniquement s’il dépasse 10 Mo.

Limites de fetch

Bien que fetch soit très puissant pour récupérer des fichiers depuis des hôtes distants, il est important de noter qu’il n’est pas conçu pour des transferts de fichiers volumineux via des connexions instables. Si tu as besoin de télécharger de très gros fichiers, tu pourrais envisager des méthodes plus robustes comme rsync ou des outils spécifiques à la gestion des gros volumes de données.

Conclusion sur le module fetch

Le module fetch est un outil incontournable pour télécharger des fichiers depuis des hôtes distants vers l’hôte de contrôle. Il est idéal pour centraliser des logs, sauvegarder des configurations avant modification, ou récupérer tout fichier critique depuis un serveur. Grâce à sa flexibilité, il permet de gérer facilement des environnements multi-serveurs en organisant les fichiers de manière structurée et l’option flat offre un contrôle supplémentaire sur l’emplacement des fichiers téléchargés. Ce module t’aide à automatiser la gestion des fichiers sur des environnements distants tout en offrant une grande souplesse.

Le module tempfile

Le module tempfile d’Ansible permet de créer des fichiers ou des répertoires temporaires sur un hôte distant. Il est particulièrement utile lorsque tu as besoin de créer des fichiers ou des répertoires temporaires pour des tâches spécifiques, comme stocker des données intermédiaires, effectuer des tests, ou préparer des fichiers avant leur utilisation dans des tâches ultérieures. tempfile garantit que les fichiers créés ne sont utilisés que temporairement, ce qui aide à maintenir un environnement propre et à éviter des conflits ou des erreurs de sécurité liées aux fichiers permanents.

Création d’un fichier temporaire

L’utilisation la plus courante de tempfile est la création de fichiers temporaires. Le module te permet de spécifier un répertoire de destination où le fichier temporaire sera créé, ainsi qu’un suffixe ou un préfixe pour le nom du fichier, afin d’identifier facilement sa fonction.

Exemple de création d’un fichier temporaire :

- name: Créer un fichier temporaire
ansible.builtin.tempfile:
state: file
suffix: '.tmp'
register: temp_file

Dans cet exemple, nous créons un fichier temporaire avec l’extension .tmp. Le chemin complet du fichier temporaire créé sera stocké dans la variable temp_file, qui pourra être utilisée dans les tâches suivantes. Le module garantit que ce fichier temporaire sera unique pour éviter tout conflit avec d’autres fichiers.

Utilisation du fichier temporaire créé

Une fois que le fichier temporaire est créé, tu peux utiliser la variable dans d’autres tâches Ansible pour référencer le chemin complet du fichier temporaire. Cela est utile pour stocker des données, des résultats intermédiaires, ou des fichiers générés dynamiquement avant de les utiliser dans des étapes ultérieures.

Exemple d’utilisation du fichier temporaire pour stocker du contenu :

- name: Créer un fichier temporaire pour stocker un résultat
ansible.builtin.tempfile:
state: file
suffix: '.log'
register: temp_log_file
- name: Écrire du contenu dans le fichier temporaire
ansible.builtin.copy:
content: "Contenu temporaire à stocker"
dest: "{{ temp_log_file.path }}"

Dans cet exemple, un fichier temporaire avec le suffixe .log est créé et nous utilisons le module copy pour écrire du contenu dans ce fichier. Le fichier temporaire permet de stocker des données sans altérer les fichiers permanents du système.

Création d’un répertoire temporaire

Le module tempfile permet également de créer des répertoires temporaires sur un hôte distant. Cela est utile lorsque tu as besoin de créer des environnements temporaires pour exécuter des tests, préparer des fichiers ou organiser des ressources avant de les déplacer ailleurs.

Exemple de création d’un répertoire temporaire :

- name: Créer un répertoire temporaire
ansible.builtin.tempfile:
state: directory
register: temp_dir

Dans cet exemple, un répertoire temporaire est créé et son chemin est stocké dans la variable temp_dir. Ce répertoire peut être utilisé pour stocker temporairement des fichiers ou pour des opérations nécessitant un espace de travail temporaire.

Utilisation du préfixe et du suffixe

tempfile te permet d’ajouter un suffixe ou un préfixe aux fichiers ou répertoires temporaires que tu crées. Cela est particulièrement utile lorsque tu veux identifier facilement ces fichiers ou répertoires en fonction de leur usage, ou pour les différencier d’autres fichiers temporaires.

Exemple de création d’un fichier temporaire avec un préfixe et un suffixe :

- name: Créer un fichier temporaire avec préfixe et suffixe
ansible.builtin.tempfile:
state: file
suffix: '.json'
prefix: 'report_'
register: temp_json_file

Dans cet exemple, un fichier temporaire est créé avec le préfixe report_ et le suffixe .json, ce qui donne un nom du type /tmp/report_abc123.json. Cela te permet d’identifier plus facilement la fonction ou le contenu du fichier temporaire.

Suppression des fichiers temporaires

Les fichiers et répertoires créés avec tempfile ne sont pas automatiquement supprimés à la fin de l’exécution du playbook. Par conséquent, il est bon de prévoir une étape pour les nettoyer après utilisation, surtout si ces fichiers ne sont plus nécessaires après la fin des tâches.

Exemple de suppression d’un fichier temporaire après utilisation :

- name: Supprimer un fichier temporaire
ansible.builtin.file:
path: "{{ temp_file.path }}"
state: absent

Dans cet exemple, nous utilisons le module file pour supprimer le fichier temporaire créé précédemment, en s’assurant que l’environnement reste propre. Cette approche est essentielle pour éviter l’accumulation de fichiers temporaires qui pourraient encombrer le système.

Utilisation dans un scénario de test

tempfile est souvent utilisé dans des scénarios de test ou de préparation, où tu veux créer des environnements ou des fichiers temporaires pour simuler certaines opérations avant de les appliquer réellement sur le système. Par exemple, tu peux vouloir tester la création de fichiers de configuration ou d’autres tâches avant de les appliquer sur les fichiers réels.

Exemple de test avec un fichier temporaire :

- name: Créer un fichier de configuration temporaire pour test
ansible.builtin.tempfile:
state: file
suffix: '.conf'
register: temp_conf_file
- name: Simuler la génération d'une configuration
ansible.builtin.copy:
content: |
[app]
setting=value
dest: "{{ temp_conf_file.path }}"
- name: Vérifier le contenu du fichier temporaire
ansible.builtin.shell: cat "{{ temp_conf_file.path }}"
register: conf_test
- debug:
msg: "Le fichier temporaire contient : {{ conf_test.stdout }}"
- name: Nettoyer le fichier temporaire après test
ansible.builtin.file:
path: "{{ temp_conf_file.path }}"
state: absent

Dans cet exemple, nous créons un fichier temporaire pour simuler la génération d’un fichier de configuration. Après avoir testé la création et vérifié son contenu, nous supprimons le fichier temporaire pour ne pas encombrer le système.

Le module get_url

Le module get_url d’Ansible permet de télécharger des fichiers depuis une URL distante vers un hôte distant ou local. C’est un outil très pratique pour récupérer des fichiers depuis des sites web, des dépôts de packages, ou des API et les placer directement dans un répertoire cible sur un hôte distant. Ce module gère également des fonctionnalités avancées comme la gestion des checksum, l’authentification et les proxies, ce qui en fait un outil polyvalent pour le téléchargement sécurisé de fichiers dans des environnements automatisés.

Utilisation de base pour télécharger un fichier depuis une URL

Le scénario le plus simple avec get_url est de télécharger un fichier depuis une URL et de le placer dans un répertoire sur l’hôte distant.

Exemple de téléchargement d’un fichier depuis une URL :

- name: Télécharger un fichier depuis une URL
ansible.builtin.get_url:
url: https://example.com/software.tar.gz
dest: /tmp/software.tar.gz
mode: '0644'

Dans cet exemple, nous téléchargeons le fichier software.tar.gz depuis https://example.com et le plaçons dans le répertoire /tmp sur l’hôte distant. L’option mode permet de définir les permissions du fichier une fois téléchargé.

Vérification de l’intégrité avec checksum

L’un des principaux avantages de get_url est sa capacité à vérifier l’intégrité du fichier téléchargé via un checksum. Cela garantit que le fichier téléchargé n’a pas été corrompu ou altéré pendant le transfert. Tu peux spécifier un SHA256 (ou un autre type de checksum) pour comparer le fichier téléchargé à une valeur connue.

Exemple avec vérification du checksum :

- name: Télécharger un fichier avec vérification du checksum
ansible.builtin.get_url:
url: https://example.com/software.tar.gz
dest: /tmp/software.tar.gz
checksum: "sha256:9c44e0fddffb8d4b40e3e4d0563dbe7705ff739f8e3e123cf6826ed8ed4b7f2b"

Dans cet exemple, nous spécifions un checksum SHA256 qui sera utilisé pour vérifier l’intégrité du fichier après téléchargement. Si le fichier téléchargé ne correspond pas au checksum spécifié, Ansible renverra une erreur, ce qui permet de garantir la fiabilité du fichier téléchargé.

Gestion de la mise à jour des fichiers avec get_url

get_url peut également gérer la mise à jour des fichiers. Par défaut, si un fichier existe déjà sur l’hôte distant, get_url ne le téléchargera pas à nouveau, sauf si tu forces le téléchargement ou si le fichier sur l’URL distante a changé.

Exemple de téléchargement conditionnel avec mise à jour du fichier :

- name: Télécharger un fichier seulement s'il a changé
ansible.builtin.get_url:
url: https://example.com/latest-release.tar.gz
dest: /opt/releases/latest-release.tar.gz
checksum: "sha256:9c44e0fddffb8d4b40e3e4d0563dbe7705ff739f8e3e123cf6826ed8ed4b7f2b"
force: no

Dans cet exemple, get_url ne téléchargera le fichier que si le checksum du fichier distant a changé. L’option force: no permet de s’assurer qu’Ansible ne télécharge pas le fichier s’il n’a pas été modifié.

Téléchargement avec authentification HTTP ou HTTPS

Dans certains cas, le fichier que tu veux télécharger peut être protégé par une authentification (HTTP basique ou HTTPS) et tu auras besoin de fournir un nom d’utilisateur et un mot de passe pour accéder à l’URL.

Exemple de téléchargement avec authentification HTTP basique :

- name: Télécharger un fichier protégé par authentification
ansible.builtin.get_url:
url: https://example.com/protected/file.tar.gz
dest: /tmp/file.tar.gz
url_username: myuser
url_password: mypassword
mode: '0644'

Dans cet exemple, le fichier file.tar.gz est protégé par une authentification HTTP basique. Nous spécifions le nom d’utilisateur et le mot de passe via les options url_username et url_password pour permettre le téléchargement.

Téléchargement via un proxy

Si ton hôte distant est situé derrière un proxy, get_url te permet de configurer un proxy pour télécharger des fichiers en passant par celui-ci.

Exemple de téléchargement via un proxy :

- name: Télécharger un fichier en passant par un proxy
ansible.builtin.get_url:
url: https://example.com/download/file.zip
dest: /tmp/file.zip
proxy: http://proxy.example.com:8080

Dans cet exemple, nous téléchargeons le fichier file.zip en utilisant le proxy http://proxy.example.com:8080. Cela est utile dans des environnements où les serveurs n’ont pas un accès direct à Internet.

Le module unarchive

Le module unarchive d’Ansible est utilisé pour extraire des fichiers d’archives sur un hôte distant. Il prend en charge plusieurs formats courants d’archives comme .tar, .tar.gz, .zip et .bz2. Ce module est essentiel pour des tâches de déploiement automatisé, notamment lorsque tu veux distribuer des applications, des packages ou des fichiers compressés sur plusieurs serveurs. unarchive te permet de gérer des fichiers compressés de manière flexible tout en t’offrant des options avancées comme le téléchargement direct depuis une URL, la gestion des permissions après extraction, ou la vérification des checksum.

Utilisation de base pour extraire une archive

Le cas d’usage le plus simple de unarchive est l’extraction d’un fichier d’archive qui est déjà présent sur l’hôte distant.

Exemple d’extraction de base d’une archive tar.gz :

- name: Extraire une archive tar.gz sur l'hôte distant
ansible.builtin.unarchive:
src: /tmp/app-release.tar.gz
dest: /opt/myapp/
remote_src: yes

Dans cet exemple, nous utilisons unarchive pour extraire l’archive app-release.tar.gz depuis le répertoire /tmp sur l’hôte distant et la décompresser dans /opt/myapp/. L’option remote_src: yes indique que l’archive est déjà présente sur l’hôte distant et non sur la machine de contrôle exécutant Ansible.

Téléchargement et extraction depuis une URL

unarchive te permet également de télécharger et d’extraire une archive directement depuis une URL distante, éliminant ainsi la nécessité de télécharger manuellement l’archive sur l’hôte distant avant de l’extraire.

Exemple d’extraction depuis une URL :

- name: Télécharger et extraire une archive depuis une URL
ansible.builtin.unarchive:
src: https://example.com/releases/app-release.tar.gz
dest: /opt/myapp/
remote_src: no

Dans cet exemple, l’archive app-release.tar.gz est téléchargée directement depuis https://example.com et décompressée dans /opt/myapp/. L’option remote_src: no est utilisée pour indiquer qu’Ansible doit d’abord télécharger l’archive avant de l’extraire sur l’hôte distant.

Gestion des permissions après extraction

Après l’extraction d’une archive, les fichiers peuvent hériter des permissions définies dans l’archive elle-même. Cependant, il peut être nécessaire d’ajuster les permissions des fichiers et des répertoires extraits pour répondre aux exigences de sécurité ou d’accessibilité de l’infrastructure.

Exemple d’ajustement des permissions après extraction :

- name: Extraire une archive et ajuster les permissions
ansible.builtin.unarchive:
src: /tmp/app-release.tar.gz
dest: /opt/myapp/
remote_src: yes
- name: Modifier les permissions des fichiers extraits
ansible.builtin.file:
path: /opt/myapp/
mode: '0755'
recurse: yes
owner: appuser
group: appgroup

Dans cet exemple, nous extrayons l’archive dans /opt/myapp/ et ajustons les permissions des fichiers extraits en utilisant le module file pour définir un mode 0755, tout en spécifiant l’utilisateur appuser et le groupe appgroup.

Remplacement des fichiers existants

Par défaut, unarchive n’écrase pas les fichiers qui existent déjà dans le répertoire de destination. Cependant, tu peux forcer le remplacement des fichiers existants en utilisant l’option extra_opts avec tar ou unzip selon le format de l’archive.

Exemple de remplacement des fichiers existants lors de l’extraction :

- name: Extraire une archive et remplacer les fichiers existants
ansible.builtin.unarchive:
src: /tmp/app-release.tar.gz
dest: /opt/myapp/
remote_src: yes
extra_opts: --overwrite

Dans cet exemple, nous utilisons l’option --overwrite avec extra_opts pour forcer le remplacement des fichiers existants lors de l’extraction de app-release.tar.gz dans /opt/myapp/.

Extraction conditionnelle avec checksum

L’option checksum permet de vérifier l’intégrité de l’archive avant son extraction. Cette vérification garantit que tu n’extrais pas un fichier corrompu ou modifié. Si le checksum ne correspond pas à la valeur fournie, Ansible renverra une erreur et n’extraira pas l’archive.

Exemple d’extraction conditionnelle basée sur un checksum :

- name: Extraire une archive seulement si le checksum est correct
ansible.builtin.unarchive:
src: /tmp/app-release.tar.gz
dest: /opt/myapp/
remote_src: yes
checksum: "sha256:9c44e0fddffb8d4b40e3e4d0563dbe7705ff739f8e3e123cf6826ed8ed4b7f2b"

Dans cet exemple, Ansible compare le checksum SHA256 du fichier app-release.tar.gz avec celui fourni. Si le checksum est correct, l’archive sera extraite dans /opt/myapp/.

Extraction partielle : extraire des fichiers spécifiques

Parfois, il est nécessaire d’extraire uniquement certains fichiers d’une archive au lieu de décompresser tout son contenu. Le module unarchive te permet d’extraire des fichiers spécifiques à l’aide de l’option extra_opts.

Exemple d’extraction de fichiers spécifiques d’une archive :

- name: Extraire uniquement les fichiers .conf d'une archive
ansible.builtin.unarchive:
src: /tmp/app-configs.tar.gz
dest: /opt/myapp/configs/
remote_src: yes
extra_opts: --wildcards '*.conf'

Dans cet exemple, seuls les fichiers avec l’extension .conf sont extraits de l’archive app-configs.tar.gz et placés dans le répertoire /opt/myapp/configs/.

Le module git

Le module git d’Ansible permet de cloner des dépôts Git ou de gérer des versions spécifiques de code sur un hôte distant. Il est principalement utilisé pour déployer du code ou des configurations à partir de dépôts Git hébergés sur des plateformes comme GitHub, GitLab, Bitbucket, ou des serveurs Git privés. Ce module te permet de cloner un dépôt, de gérer les branches ou tags, de récupérer les dernières modifications et de garder les fichiers à jour sur un serveur distant. git est idéal pour automatiser les déploiements d’applications et maintenir la synchronisation entre plusieurs environnements.

Utilisation de base pour cloner un dépôt Git

Le cas d’utilisation le plus simple du module git est de cloner un dépôt Git sur un serveur distant. Cela est utile lorsque tu veux déployer une application, un site web ou une configuration à partir d’un dépôt.

Exemple de clonage d’un dépôt Git :

- name: Cloner un dépôt Git
ansible.builtin.git:
repo: 'https://github.com/example/myapp.git'
dest: /opt/myapp
version: master

Dans cet exemple, le module git clone le dépôt myapp.git depuis GitHub dans le répertoire /opt/myapp. Nous spécifions ici la branche master à cloner, ce qui permet de récupérer la dernière version stable du code sur cette branche.

Mise à jour d’un dépôt Git existant

Le module git ne se contente pas de cloner des dépôts, il peut aussi gérer les mises à jour de dépôts Git déjà clonés. Si le dépôt existe déjà sur l’hôte distant, git va simplement récupérer les dernières modifications sans avoir à re-cloner tout le dépôt, ce qui optimise les performances.

Exemple de mise à jour d’un dépôt Git :

- name: Mettre à jour un dépôt Git existant
ansible.builtin.git:
repo: 'https://github.com/example/myapp.git'
dest: /opt/myapp
version: master
update: yes

Dans cet exemple, le module vérifie si le dépôt est déjà présent dans /opt/myapp. S’il existe, il met à jour la branche master en récupérant les dernières modifications. L’option update: yes garantit que le dépôt sera mis à jour si des changements ont été apportés.

Clonage d’une branche ou d’un tag spécifique

Il peut être nécessaire de déployer une branche ou une version spécifique d’un projet plutôt que la dernière version de la branche principale. Le module git te permet de spécifier une branche, un commit ou un tag pour assurer que tu déploies une version précise de ton code.

Exemple de clonage d’une branche spécifique :

- name: Cloner une branche spécifique
ansible.builtin.git:
repo: 'https://github.com/example/myapp.git'
dest: /opt/myapp
version: feature-branch

Dans cet exemple, nous clonons la branche feature-branch depuis le dépôt myapp.git. Cela te permet de déployer des fonctionnalités ou des correctifs qui sont encore en développement ou en phase de test, sans affecter la version stable en production.

Exemple de clonage d’un tag spécifique :

- name: Cloner un tag spécifique
ansible.builtin.git:
repo: 'https://github.com/example/myapp.git'
dest: /opt/myapp
version: 'v1.0.0'

Dans cet exemple, nous clonons le dépôt Git à la version correspondant au tag v1.0.0. Cela est utile pour garantir que tu déploies une version exacte d’un projet, souvent utilisée dans des environnements de production.

Gestion des dépôts privés

Lorsque le dépôt Git que tu veux cloner est privé ou nécessite une authentification, tu peux fournir des identifiants d’accès sous forme d’un nom d’utilisateur et d’un mot de passe, ou en utilisant une clé SSH pour une connexion sécurisée.

Exemple de clonage d’un dépôt Git privé avec des identifiants HTTP basiques :

- name: Cloner un dépôt Git privé avec authentification
ansible.builtin.git:
repo: 'https://github.com/private-repo/myapp.git'
dest: /opt/myapp
version: master
username: 'myuser'
password: 'mypassword'

Dans cet exemple, nous fournissons un nom d’utilisateur et un mot de passe pour cloner un dépôt privé Git hébergé sur GitHub. Les identifiants sont utilisés pour l’authentification HTTP basique.

Exemple de clonage d’un dépôt Git avec une clé SSH :

- name: Cloner un dépôt Git privé en utilisant une clé SSH
ansible.builtin.git:
repo: 'git@github.com:private-repo/myapp.git'
dest: /opt/myapp
key_file: '/home/myuser/.ssh/id_rsa'

Dans cet exemple, nous utilisons une clé SSH située dans /home/myuser/.ssh/id_rsa pour cloner un dépôt Git privé. L’authentification SSH est courante pour accéder à des dépôts sécurisés sans avoir à fournir de mot de passe en clair.

Suppression des modifications locales avec force

Si des modifications locales ont été effectuées dans le répertoire du dépôt (par exemple, si quelqu’un a modifié des fichiers après le clonage), git te permet de forcer la remise à l’état initial du dépôt, supprimant ainsi toutes les modifications non suivies dans Git.

Exemple d’utilisation de force pour écraser les modifications locales :

- name: Forcer la mise à jour du dépôt Git et écraser les modifications locales
ansible.builtin.git:
repo: 'https://github.com/example/myapp.git'
dest: /opt/myapp
version: master
force: yes

Dans cet exemple, l’option force: yes supprime toutes les modifications non suivies localement et remet le dépôt dans l’état correspondant à la branche master. Cela est utile lorsque tu veux t’assurer que le code déployé est toujours identique à celui du dépôt, sans altérations locales.

Réinitialisation d’un dépôt Git

Le module git te permet également de réinitialiser un dépôt à une version spécifique en réinitialisant l’état des fichiers suivis à un commit précis. Cela est utile lorsque tu veux restaurer une version stable d’une application ou revenir à une version antérieure après une mise à jour problématique.

Exemple de réinitialisation d’un dépôt à un commit spécifique :

- name: Réinitialiser le dépôt à un commit spécifique
ansible.builtin.git:
repo: 'https://github.com/example/myapp.git'
dest: /opt/myapp
version: 'a1b2c3d'

Dans cet exemple, nous utilisons version: a1b2c3d pour réinitialiser le dépôt à un commit spécifique (identifié par son hash). Cela permet de revenir à une version stable de l’application après un problème lié à une mise à jour.

Vérification de l’état du dépôt avec bare

Le module git te permet également de gérer des dépôts bare, qui sont des copies spéciales d’un dépôt Git sans l’arborescence de fichiers de travail habituelle. Les dépôts bare sont couramment utilisés pour héberger des serveurs Git qui ne nécessitent pas de modifications locales directes.

Exemple de création d’un dépôt Git bare :

- name: Créer un dépôt bare
ansible.builtin.git:
repo: '/opt/git-repos/myapp.git'
bare: yes

Dans cet exemple, nous créons un dépôt bare dans /opt/git-repos/myapp.git, ce qui est idéal pour héberger un dépôt centralisé que d’autres développeurs ou serveurs peuvent utiliser pour collaborer ou déployer du code.

Suppression des fichiers non suivis

Le module git permet de nettoyer un répertoire de dépôt en supprimant les fichiers non suivis (fichiers qui ne sont pas sous le contrôle de version Git). Cela permet de maintenir un répertoire propre en supprimant les fichiers temporaires ou générés qui ne devraient pas persister entre les déploiements.

Exemple de suppression des fichiers non suivis dans un dépôt Git :

- name: Nettoyer les fichiers non suivis dans le dépôt
ansible.builtin.git:
repo: 'https://github.com/example/myapp.git'
dest: /opt/myapp
version: master
remove_untracked: yes

Dans cet exemple, nous utilisons l’option remove_untracked: yes pour supprimer tous les fichiers non suivis dans le répertoire du dépôt myapp. Cela est utile pour garantir que seuls les fichiers suivis par Git restent dans le répertoire après chaque mise à jour.

Le module assemble

Le module assemble d’Ansible est utilisé pour combiner plusieurs fichiers en un seul. Il permet de rassembler différents fichiers sources, situés dans un répertoire donné et de les fusionner en un fichier de sortie unique sur l’hôte distant. Ce module est particulièrement utile lorsque tu dois construire des fichiers de configuration complexes ou concaténer des fichiers pour former des packages ou des documents.

Le module assemble prend un ensemble de fichiers contenus dans un répertoire et les assemble dans un fichier unique. Les fichiers sont concaténés dans l’ordre alphabétique.

Exemple d’assemblage de plusieurs fichiers en un seul :

- name: Assembler plusieurs fichiers dans un fichier de sortie
ansible.builtin.assemble:
src: /etc/myapp/fragments/
dest: /etc/myapp/config.conf
owner: root
group: root
mode: '0644'

Dans cet exemple, tous les fichiers situés dans le répertoire /etc/myapp/fragments/ sont concaténés et écrits dans le fichier de destination /etc/myapp/config.conf. Les fichiers sont assemblés dans l’ordre alphabétique et les permissions, propriétaire et groupe du fichier final sont correctement définis.

Gestion de l’ordre d’assemblage

Par défaut, assemble combine les fichiers dans l’ordre alphabétique. Si tu veux contrôler précisément l’ordre dans lequel les fichiers sont concaténés, il suffit de nommer les fichiers de manière à forcer cet ordre. Par exemple, tu peux utiliser des numéros ou des préfixes pour garantir l’ordre souhaité.

Exemple de nommage pour contrôler l’ordre des fichiers :

  • 00-header.conf
  • 10-main.conf
  • 20-footer.conf

Avec un tel schéma de nommage, assemble concaténera d’abord 00-header.conf, suivi de 10-main.conf, puis 20-footer.conf.

Conclusion

L’utilisation des modules Ansible pour gérer les fichiers et les répertoires, qu’il s’agisse de téléchargement, d’extraction, de clonage ou de modification de configurations, doit toujours respecter quelques bonnes pratiques pour garantir des déploiements efficaces et sécurisés. Il est essentiel de s’assurer que les outils nécessaires, comme les CLI ou les utilitaires de décompression, sont installés sur les machines distantes avant d’exécuter des tâches spécifiques. Il est également recommandé de vérifier l’intégrité des fichiers à l’aide de checksum, de toujours définir explicitement les permissions, les propriétaires et les groupes des fichiers manipulés et de prendre en compte l’impact de toute mise à jour ou modification locale.

En appliquant ces bonnes pratiques, tu garantis un déploiement fiable et reproductible, tout en minimisant les erreurs et en maintenant un environnement sécurisé.