Transfert sécurisé de fichiers : Utilisation des modules Ansible Copy et Fetch

Utilisez les commandes ad-hoc Ansible copy et fetch pour envoyer des fichiers vers les nœuds gérés et récupérer les journaux ou configurations vers votre nœud de contrôle.

Transfert sécurisé de fichiers : Utilisation des modules Ansible Copy et Fetch

Déplacer des fichiers est l'une des premières tâches pratiques avec Ansible : pousser une configuration vers vos serveurs, collecter un fichier journal ou sauvegarder un fichier distant avant une modification. Les modules copy et fetch gèrent ces deux directions de manière claire.

Ce guide utilise des commandes ad-hoc, vous permettant d'effectuer des transferts ponctuels sans écrire un playbook complet. Les mêmes arguments de module fonctionnent également dans les playbooks lorsque vous souhaitez que la tâche soit reproductible.

Prérequis

Avant d'exécuter les exemples ci-dessous, assurez-vous de disposer des éléments suivants :

  1. Nœud de contrôle Ansible : Une machine avec Ansible installé.
  2. Fichier d'inventaire : Un fichier d'inventaire opérationnel (par exemple, /etc/ansible/hosts) définissant vos nœuds gérés.
  3. Connectivité : Accès SSH par clé configuré vers vos hôtes distants.

Tous les exemples supposeront que le groupe cible est nommé webservers dans l'inventaire.

Comprendre les commandes ad-hoc pour le transfert de fichiers

Les commandes ad-hoc sont des commandes sur une seule ligne exécutées directement depuis le terminal, idéales pour des tâches rapides qui ne justifient pas un playbook permanent. La structure de base est :

ansible <groupe-hôtes> -m <nom-module> -a "clé=valeur clé2=valeur2 ..."

Pour le transfert de fichiers, nous utilisons les noms de modules -m copy ou -m fetch, en passant les arguments requis avec le drapeau -a.

Le module copy : Envoyer des fichiers vers les nœuds distants

Le module copy est utilisé pour transférer un fichier situé sur la machine de contrôle Ansible vers un ou plusieurs nœuds gérés. C'est la méthode standard pour déployer des fichiers de configuration, des scripts ou de petits assets.

Arguments clés pour copy

Le module copy nécessite deux arguments essentiels et accepte plusieurs arguments optionnels pour la gestion de la configuration :

Argument Description Requis ? Exemple de valeur
src Le chemin local du fichier sur la machine de contrôle Ansible. Les chemins absolus sont les plus clairs pour les commandes ad-hoc. Oui /tmp/config.conf
dest Le chemin où le fichier sera placé sur le nœud distant géré. Oui /etc/app/config.conf
owner Nom de l'utilisateur qui doit posséder le fichier sur le nœud distant. Non nginx
group Nom du groupe qui doit posséder le fichier sur le nœud distant. Non www-data
mode Permissions (octales) à définir sur le fichier de destination. Non 0644
backup Si yes, crée une sauvegarde avant d'écraser le fichier original. Non yes

Exemple 1 : Déploiement simple de fichier

Supposons que vous ayez un fichier personnalisé Message du Jour (motd) localement et que vous souhaitiez le pousser vers tous les serveurs web.

# Chemin local du fichier : /home/user/ansible/motd_banner
# Destination distante : /etc/motd

ansible webservers -m copy -a "src=/home/user/ansible/motd_banner dest=/etc/motd"

Exemple 2 : Définition des permissions et de la propriété

Si vous déployez un fichier de configuration sécurisé, vous devez spécifier le propriétaire, le groupe et les permissions restreintes (par exemple, seul le propriétaire peut lire/écrire).

# Déploiement d'un fichier de configuration d'application, propriétaire 'app_user', groupe 'devops',
# avec permissions de lecture/écriture uniquement pour le propriétaire (0600).

ansible webservers -m copy -b -a "src=/tmp/app_settings.yaml dest=/etc/app/settings.yaml owner=app_user group=devops mode=0600"

Note sur -b : Le drapeau -b (ou --become) est nécessaire lorsque la destination distante nécessite des privilèges élevés (comme l'écriture dans /etc).

Le module fetch : Récupérer des fichiers depuis les nœuds distants

Le module fetch effectue l'opération inverse de copy : il récupère un fichier depuis le nœud géré vers la machine de contrôle Ansible. Cela est utile pour sauvegarder des fichiers de configuration, récupérer des journaux ou collecter des informations de diagnostic.

Arguments clés pour fetch

Le module fetch nécessite le fichier source sur le nœud distant et un répertoire de destination sur la machine de contrôle.

Argument Description Requis ? Exemple de valeur
src Le chemin absolu du fichier sur le nœud distant géré. Oui /var/log/nginx/error.log
dest Le chemin absolu du répertoire sur la machine de contrôle où les fichiers seront sauvegardés. Oui /tmp/backups/logs
flat Si yes, le nom de fichier résultant ne contiendra pas la structure de nom d'hôte (déconseillé lors de la récupération depuis plusieurs hôtes). Non no (par défaut)

Différence cruciale : Structure de destination

Contrairement au module copy, le module fetch crée automatiquement un chemin de sous-répertoire structuré basé sur le nom d'hôte distant pour éviter les collisions de noms de fichiers lors de la récupération depuis plusieurs serveurs.

Le chemin résultant sur la machine de contrôle ressemblera à ceci :

<dest>/<nom_hôte>/<src>

Par exemple, récupérer /etc/nginx/nginx.conf depuis host1 vers /tmp/backups donne :

/tmp/backups/host1/etc/nginx/nginx.conf

Exemple 3 : Récupération de sauvegardes de configuration distantes

Pour récupérer le fichier de configuration en cours d'exécution de tous les serveurs web vers un répertoire de sauvegarde local :

# Récupérer nginx.conf de tous les serveurs web vers le répertoire local /tmp/config_backups

ansible webservers -m fetch -a "src=/etc/nginx/nginx.conf dest=/tmp/config_backups"

Après avoir exécuté cette commande, si vous avez ciblé webserver1 et webserver2, votre structure de répertoire locale serait :

/tmp/config_backups/
├── webserver1
│   └── etc
│       └── nginx
│           └── nginx.conf
└── webserver2
    └── etc
        └── nginx
            └── nginx.conf

Exemple 4 : Récupération d'un seul fichier sans structure d'hôte (flat=yes)

Si vous êtes absolument sûr de ne récupérer un fichier que depuis un seul hôte, ou si vous avez seulement besoin du contenu du fichier (pas de la structure d'origine), vous pouvez utiliser flat=yes. Cela place le fichier directement dans le dossier de destination, nommé d'après le fichier distant original.

# Récupérer un rapport d'état de santé local depuis un seul hôte, en le sauvegardant directement.

ansible webserver1 -m fetch -a "src=/tmp/health_status.txt dest=/tmp/reports flat=yes"

# Chemin résultant : /tmp/reports/health_status.txt

Avertissement : Utilisez flat=yes uniquement lorsque vous ciblez un seul hôte ou si vous avez l'intention d'écraser le fichier lors des exécutions suivantes, car Ansible n'empêchera pas les conflits.

Bonnes pratiques et considérations de sécurité

De petites erreurs de transfert de fichiers peuvent devenir des incidents de production, surtout lorsque les fichiers atterrissent dans /etc ou contiennent des secrets.

Toujours définir les permissions avec copy

Ne poussez jamais un fichier de configuration sans définir explicitement le mode et le owner. Si vous vous fiez à l'umask par défaut du système distant, des fichiers sensibles (comme des clés SSH ou des identifiants de base de données) pourraient se retrouver avec des droits d'accès trop permissifs.

# Mauvaise pratique (Mode dérivé de l'umask)
- name: Déployer une clé non sécurisée
  ansible.builtin.copy:
    src: private.key
    dest: /etc/app/private.key

# Bonne pratique (Restreindre explicitement l'accès)
- name: Déployer une clé sécurisée
  ansible.builtin.copy:
    src: private.key
    dest: /etc/app/private.key
    mode: '0600'
    owner: root

Utiliser backup=yes pour les modifications critiques

Lorsque vous utilisez copy pour écraser un fichier existant et critique (par exemple, /etc/sudoers), incluez backup=yes. Ansible créera une copie de sauvegarde horodatée sur le nœud distant avant d'écraser le fichier, offrant une option de restauration facile.

Envisager synchronize pour les transferts volumineux

Bien que copy et fetch fonctionnent bien pour les opérations rapides et les petits fichiers, utilisez ansible.posix.synchronize pour les grandes arborescences de répertoires ou les transferts delta efficaces. Il encapsule rsync, donc le nœud de contrôle et l'environnement cible doivent disposer du bon accès rsync et SSH.

Conclusion

Utilisez copy lorsque la source se trouve sur votre nœud de contrôle et la destination sur le nœud géré. Utilisez fetch lorsque la source se trouve sur le nœud géré et que vous souhaitez sauvegarder le fichier localement.

Module Direction Exemple de commande ad-hoc
copy Nœud de contrôle -> Nœud géré ansible all -m copy -a "src=/local/file dest=/remote/path mode=0644"
fetch Nœud géré -> Nœud de contrôle ansible all -m fetch -a "src=/remote/file dest=/local/dir"

Pour un seul serveur, flat=yes peut rendre les fichiers récupérés plus faciles à lire. Pour un groupe de serveurs, conservez la structure de répertoire par défaut basée sur le nom d'hôte afin que le journal d'un hôte n'écrase pas celui d'un autre.