Aller au contenu
English
English
Infrastructure as Code medium

Module copy Ansible : transférer fichiers et contenu inline

60 min de lecture

Logo Ansible

Le module ansible.builtin.copy est le module de transfert de référence en Ansible. Il pousse un fichier du control node vers le managed node, ou écrit un contenu inline via content:. Cette page couvre les options qui font la différence en production : mode:, owner:, backup: true, validate:, et le piège du content: non terminé par \n. copy: agit sur la donnée (octets transférés), pour gérer uniquement les métadonnées, utiliser file:.

  • Les deux modes de copy: : src: (fichier local) vs content: (inline).
  • Les options critiques : mode, owner, group, backup, force, validate.
  • Le piège idempotence/diff quand content: n'est pas terminé par \n.
  • Quand préférer template: plutôt que copy: (interpolation Jinja2 nécessaire).

Le mode le plus courant. Le fichier source est cherché dans files/ du playbook (ou via chemin absolu/relatif), et transféré tel quel sur le managed node.

- name: Deployer le banner SSH
ansible.builtin.copy:
src: files/issue.net
dest: /etc/issue.net
owner: root
group: root
mode: "0644"
backup: true

backup: true crée dest.<timestamp> avant écrasement, utile en troubleshooting et pour les rollbacks rapides. À utiliser systématiquement sur les fichiers de configuration critiques (sshd_config, nginx.conf).

mode: accepte la forme octale ("0644", toujours en string pour éviter le piège YAML qui interprète 0644 comme un nombre) ou la forme symbolique ("u=rw,g=r,o=r"). Préférer l'octale, plus concise.

Pour des fichiers courts (banner, motd, fichier de tag), content: évite de créer un fichier dans files/.

- name: Marquer le serveur comme provisionne
ansible.builtin.copy:
content: "Provisionne par Ansible le {{ ansible_date_time.iso8601 }}\n"
dest: /etc/ansible-managed
mode: "0644"

Piège fréquent : oublier le \n final. Sans newline, la commande cat /etc/ansible-managed affiche la ligne accolée au prompt, et certains parseurs (cron, systemd) refusent les fichiers sans newline final. Toujours terminer content: par \n.

Pour des contenus dépassant 5-10 lignes, passer à template:, content: devient illisible avec des sauts de ligne échappés.

Validate : exécuter une commande de validation avant d'écraser

Section intitulée « Validate : exécuter une commande de validation avant d'écraser »

validate: lance une commande externe sur le fichier temporaire, et n'écrase la cible que si la commande renvoie 0. Pattern critique pour sshd_config, nginx.conf, sudoers, un fichier mal formé verrouille le système.

- name: Deployer sshd_config valide
ansible.builtin.copy:
src: files/sshd_config
dest: /etc/ssh/sshd_config
mode: "0600"
backup: true
validate: 'sshd -t -f %s'

Le %s est remplacé par le chemin du fichier temporaire. Si sshd -t échoue, /etc/ssh/sshd_config reste intact, pas de coupure SSH possible.

copy: est idempotent : si le fichier source a le même checksum que la destination, et les mêmes permissions, la tâche reste ok (pas changed). La détection se fait via SHA1 côté managed node.

Conséquence : modifier le mode: sans toucher au contenu → changed. Modifier juste un caractère du fichier source → changed. Re-exécuter sans modification → ok.

ansible-playbook --check --diff montre précisément les octets qui changeraient, utiliser systématiquement avant un déploiement en production.

Les quatre options ci-dessous répondent chacune à une situation précise, et c'est cette situation qu'il faut reconnaître plutôt que la liste à retenir. force: false sert au fichier d'exemple qu'on pose une fois et qu'on laisse ensuite à l'administrateur, remote_src: true au fichier déjà présent sur la machine, decrypt: à une source chiffrée par Vault et versionnée telle quelle, unsafe_writes: aux rares systèmes de fichiers sans renommage atomique, un partage réseau par exemple. Hors de ces cas, aucune n'est nécessaire.

OptionUsage
force: falseN'écrase pas si dest existe déjà, utile pour des configs initiales que l'utilisateur a customisées
remote_src: truesrc: est sur le managed node, pas sur le control node
directory_mode:Mode des répertoires créés en chemin (utile avec recursive copy)
unsafe_writes: truePermet l'écriture sur des FS qui ne supportent pas rename atomique (NFS sans verrous)
decrypt: trueDéchiffre le fichier source si chiffré avec Ansible Vault

Ces quatre pannes ont un point commun : la tâche réussit, et c'est le résultat sur la machine qui est faux. Deux tiennent au YAML et à la chaîne transmise, le mode non quoté et le saut de ligne manquant, les deux autres à une comparaison que le module fait sans le dire, le checksum d'un fichier source altéré par l'éditeur et la validation qui contrôle le mauvais fichier. La colonne de droite donne à chaque fois un contrôle qui tient en une commande.

SymptômeCauseFix
Fichier copié avec mode: 0644 non quotéYAML interprète 0644 comme nombre 644 (octets 1004)Toujours quoter : mode: "0644"
content: apparaît sans newline finalOubli du \nAjouter \n à la fin de la string
changed: à chaque run sur un fichier statiqueContenu du files/ modifié par éditeur (CRLF, EOF)Vérifier cat -A files/source
validate: ignoréLe %s manque dans la commandeAjouter %s : validate: 'sshd -t -f %s'

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • copy: transfère un fichier (src:) ou un contenu inline (content:) avec idempotence par checksum SHA1.
  • mode: toujours quoté ("0644") pour éviter le piège YAML octal/décimal.
  • backup: true sur tout fichier de config critique, coût nul, valeur énorme en troubleshooting.
  • validate: est obligatoire pour sshd_config, nginx.conf, sudoers : pas de validate = risque de lockout.
  • Au-delà de 5-10 lignes, passer à template: plutôt que content: inline.

Les deux façons d'alimenter copy se pratiquent mieux côte à côte qu'isolément. Ce lab vous fait transférer un fichier depuis le control node avec src: et backup: true, puis écrire un second fichier directement avec content:, sur web1.lab. La correction se connecte à la machine et contrôle le mode, le propriétaire et le contenu réel des deux fichiers, pas le compte rendu du playbook.

  • Module blockinfile : insérer quelques lignes dans un fichier existant, quand écraser le fichier entier est trop brutal.
  • Module fetch : le trajet inverse, du managed node vers le control node.
  • archive et unarchive : transférer une arborescence complète en un seul objet plutôt que fichier par fichier.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens ce site gratuitement, sans publicité, sans profilage et sans compte à créer. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn