Aller au contenu
Infrastructure as Code medium

Modules archive et unarchive Ansible : compresser et extraire

9 min de lecture

Logo Ansible

archive et unarchive sont les deux modules complémentaires pour gérer des tarballs et zips dans Ansible. archive: crée une archive sur le managed node à partir d'un ou plusieurs chemins. unarchive: extrait une archive vers un dossier, depuis le control node (auto-copy), une URL, ou une archive déjà présente sur le managed node.

Cas d'usage typiques : backup avant migration (archive d'un /etc/myapp/), déploiement applicatif depuis un tarball stocké sur S3, restauration d'un dump SQL compressé.

  • Les formats supportés par archive: (gz, bz2, xz, zip, tar).
  • Les 3 modes de unarchive: : auto-copy, URL, remote_src: true.
  • L'option creates: pour rendre unarchive: idempotent.
  • Le piège du slash final sur archive: path: qui change la structure de l'archive.
  • Connaître copy: et file: (souvent enchaînés avec archive/unarchive).
- name: Archiver les logs Apache
ansible.builtin.archive:
path: /var/log/httpd/
dest: /var/backups/httpd-logs.tar.gz
format: gz
remove: false
OptionRôle
path:Chemin(s) source, string ou liste, sur le managed node
dest:Archive de sortie sur le managed node
format:gz (défaut), bz2, xz, zip, tar
remove: trueSupprime les sources après l'archivage (utile pour rotation logs)
exclude_path:Liste de chemins à exclure de l'archive

Piège du slash final : path: /var/log/httpd/ (avec slash) archive le contenu du dossier au niveau racine de l'archive. path: /var/log/httpd (sans slash) archive le dossier lui-même. Conséquence : à l'extraction, le résultat diffère.

Fenêtre de terminal
# Avec slash : fichiers a la racine de l archive
$ tar tzf httpd-logs.tar.gz
access.log
error.log
# Sans slash : fichiers sous httpd/
$ tar tzf httpd-logs.tar.gz
httpd/
httpd/access.log
httpd/error.log
- name: Deployer myapp depuis tarball local
ansible.builtin.unarchive:
src: ./files/myapp-1.0.tar.gz
dest: /opt/myapp
creates: /opt/myapp/bin/myapp

Ansible copie d'abord le tarball depuis files/ du playbook vers le managed node, puis l'extrait. creates: rend l'opération idempotente, si /opt/myapp/bin/myapp existe déjà, la tâche est skipped.

- name: Telecharger et extraire grafana
ansible.builtin.unarchive:
src: https://dl.grafana.com/oss/release/grafana-10.4.0.linux-amd64.tar.gz
dest: /opt/grafana
remote_src: true
creates: /opt/grafana/grafana-10.4.0/bin/grafana-server
extra_opts:
- "--strip-components=1"

Ansible télécharge depuis l'URL directement sur le managed node (pas de passage par le control node). extra_opts: ["--strip-components=1"] est l'astuce classique pour enlever le dossier racine de l'archive, utile quand la convention upstream est archive-X.Y.Z/....

Mode 3 : archive déjà sur le managed node (remote_src: true)

Section intitulée « Mode 3 : archive déjà sur le managed node (remote_src: true) »
- name: Restaurer le dump deja copie
ansible.builtin.unarchive:
src: /var/backups/dump-2026-04-25.tar.gz
dest: /var/restore
remote_src: true

remote_src: true indique que src: est sur le managed node, pas sur le control node. Pas de copy automatique. Mode utilisé après un fetch: + redéploiement ou pour restaurer un backup local.

unarchive: n'est pas idempotent par défaut, il extrait à chaque run. Pour rendre l'opération idempotente, deux options :

# Option 1 : creates (le plus simple)
unarchive:
src:
dest: /opt/myapp
creates: /opt/myapp/bin/myapp # Skip si ce fichier existe deja
# Option 2 : verifier le checksum manuellement
- ansible.builtin.stat:
path: /opt/myapp/version
register: version_check
- ansible.builtin.unarchive:
src:
dest: /opt/myapp
when: not version_check.stat.exists

Privilégier creates:, c'est le pattern standard et le plus lisible.

- ansible.builtin.unarchive:
src: app.tar.gz
dest: /opt/myapp
owner: myapp
group: myapp
mode: "0750"
remote_src: true

Les options owner:, group:, mode: s'appliquent aux fichiers extraits, pas à l'archive elle-même. Pratique pour s'assurer que les fichiers déployés ont le bon propriétaire sans tâche file: state: directory recurse: true séparée.

SymptômeCauseFix
Extraction à chaque runPas de creates:Ajouter creates: <fichier_marqueur>
Structure de l'archive inattendueSlash final sur path:Vérifier avec tar tzf ; ajuster le slash
Téléchargement échouePas de remote_src: true sur URLToujours remote_src: true avec URL HTTPS
Dossier racine archive-1.0/ non vouluConvention upstreamextra_opts: ["--strip-components=1"]
archive: échoue avec "permission denied"path: contient des fichiers non lisibles par becomeVérifier les permissions ou ajouter become: true
  • Idempotence : archive: ne recrée pas si rien n'a changé. command: tar -czf recrée à chaque run.
  • Multi-format : archive: gère gz/bz2/xz/zip via une seule option. tar ne fait pas de zip.
  • Lisibilité : archive: est explicite, un lecteur comprend l'intention sans connaître les flags tar.
  • archive: crée des tarballs (gz, bz2, xz, zip), idempotent.
  • unarchive: a 3 modes : auto-copy (defaut), URL (remote_src: true), local-au-managed (remote_src: true).
  • creates: est obligatoire pour rendre unarchive: idempotent.
  • Slash final sur archive: path: change la structure, toujours vérifier avec tar tzf.
  • extra_opts: ["--strip-components=1"] = le pattern pour enlever le dossier racine d'une archive upstream.

Cette page a un lab d'accompagnement : labs/modules-fichiers/archive-unarchive/ dans stephrobert/ansible-training.

Challenge, sur db1.lab :

  1. Préparer 3 fichiers dans /opt/data-source/.
  2. Archiver vers /opt/backup/data.tar.gz (format gz).
  3. Extraire vers /opt/restored/ avec remote_src: true et creates:.

Validation pytest+testinfra :

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

6 tests vérifient les fichiers source, l'archive (taille > 100 octets) et l'extraction.

Ce site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracking. 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