Aller au contenu
Infrastructure as Code medium

Module copy Ansible : transférer fichiers et contenu inline

8 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.

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
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'
  • 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.

Cette page a un lab d’accompagnement : labs/modules-fichiers/copy/ dans stephrobert/ansible-training.

Fenêtre de terminal
git clone https://github.com/stephrobert/ansible-training.git
cd ansible-training
cat labs/modules-fichiers/copy/README.md
cat labs/modules-fichiers/copy/challenge/README.md

Challenge — sur web1.lab :

  1. Copier challenge/files/banner-ssh.txt vers /etc/ssh/banner-rhce avec mode: "0644", backup: true.
  2. Écrire en inline (content:) le fichier /etc/motd-rhce.

Validation pytest+testinfra :

Fenêtre de terminal
ansible-playbook solution.yml
pytest -v labs/modules-fichiers/copy/challenge/tests/

6 tests vérifient l’existence, le mode, le contenu et l’owner des deux fichiers.

Ce site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn