Aller au contenu
Infrastructure as Code medium

ansible-pull : pattern GitOps Edge / IoT (mode pull, hors RHCE EX294)

9 min de lecture

Logo Ansible

Ansible fonctionne par défaut en mode push : un control node SSH vers les cibles. Mais il existe un mode pull : la cible récupère son playbook depuis un repo Git (avec ansible-pull) et s’exécute elle-même. Pas besoin de control node centralisé. Pas besoin d’accès SSH inverse. Pas besoin d’IP publique sur la cible.

À la fin de cette page, vous saurez quand choisir pull vs push, configurer un nœud Edge avec ansible-pull + cron + cloud-init, et comprendre les limites du mode pull (pas de centralisation des logs, incompatible AAP Tower).

  • Différence push vs pull : qui initie la connexion.
  • Lancer ansible-pull manuellement contre un repo Git.
  • Configurer une exécution périodique via cron ou systemd timer.
  • Intégrer ansible-pull dans cloud-init pour bootstrap immuable au boot.
  • Comprendre les limites : logs distribués, pas d’AAP Tower, drift indétectable.
  • Choisir push vs pull selon le cas d’usage.
  • Avoir validé le Premier playbook (mode push classique).
  • Bases Git (clone, pull, branches).
CritèreMode push (default)Mode pull (ansible-pull)
Qui initie la connexion ?Control node → cibles (SSH)Cible → repo Git (HTTPS/SSH)
CentralisationOui (control node)Non (chaque nœud autonome)
Visibilité logsCentraliséeDistribuée (sur chaque nœud)
Cas d’usage typiqueDatacenter, fleet maîtriséeEdge, IoT, NAT, bootstrap
Compatible AAP TowerOuiNon (mode pur ansible-core)
FQCN, collections, vaultOuiOui
Testé à RHCE EX294OuiNon

🔍 Observation : ansible-pull utilise les mêmes playbooks qu’ansible-playbook. La différence est juste qui exécute, pas le contenu du playbook. Permet de basculer un projet push vers pull sans réécriture.

Des nœuds isolés derrière un NAT, sans IP publique, qui ne peuvent pas être joints par SSH depuis un control node central. Ils tirent leur config depuis Git :

Fenêtre de terminal
# Sur un nœud IoT (Raspberry Pi, Jetson Nano, etc.)
ansible-pull -U https://github.com/myorg/iot-config.git pull-playbook.yml

Une nouvelle VM se configure elle-même au premier boot :

#cloud-config
packages:
- ansible-core
- git
runcmd:
- ansible-pull -U https://github.com/myorg/infra.git pull-playbook.yml

Pattern immuable : Terraform/Cloud provisionne → cloud-init lance ansible-pull → la VM est prête. Aucune intervention SSH.

Un control node centralisé devient un goulot sur des fleets >1000 nœuds (parallélisme limité par forks, RAM, CPU). En pull, chaque nœud s’exécute indépendamment — pas de goulot.

Le repo Git est la source de vérité. Chaque nœud reflète l’état de la branche. Modification → commit → push → tous les nœuds qui pull cron synchronisent dans la fenêtre suivante.

Fenêtre de terminal
sudo dnf install -y ansible-core git
ansible-pull \
-U https://github.com/stephrobert/ansible-pull-demo.git \
-d /var/lib/ansible-pull \
pull-playbook.yml

Ce que fait ansible-pull :

  1. git clone (ou git pull si déjà clôné) le repo dans /var/lib/ansible-pull/.
  2. ansible-playbook sur pull-playbook.yml avec hosts: localhost (par défaut).
  3. Exit avec le code de retour du playbook.

Options principales :

OptionEffet
-U <git-url>URL du repo (obligatoire)
-d <chemin>Localise le clone (default /var/lib/ansible/local)
-i <inventory>Inventaire (default : seul localhost si absent)
-C <branche>Branche Git à utiliser (default main)
--vault-password-file <path>Compatible Ansible Vault
-K / --ask-become-passDemande le mot de passe sudo
---
- hosts: localhost # ← cible LA MACHINE ELLE-MÊME
connection: local # ← pas de SSH (déjà sur la cible)
become: true
gather_facts: true
tasks:
- name: Marker pull executed
ansible.builtin.copy:
dest: /var/log/ansible-pull-marker.txt
content: |
ansible-pull executed at: {{ ansible_date_time.iso8601 }}
hostname: {{ ansible_hostname }}
mode: "0644"

🔍 Observation cruciale : hosts: localhost + connection: local est obligatoire. La machine est elle-même la cible. Un hosts: db1.lab planterait — il n’y a pas de SSH pour atteindre db1.lab, on est sur db1.lab.

/etc/cron.d/ansible-pull
*/30 * * * * root /usr/bin/ansible-pull \
-U https://github.com/myorg/infra.git \
-d /var/lib/ansible-pull \
pull-playbook.yml \
>> /var/log/ansible-pull.log 2>&1

Via Ansible (push initial qui configure le pull) :

- name: Configurer ansible-pull en cron
ansible.builtin.cron:
name: ansible-pull
user: root
minute: "*/30"
job: >-
/usr/bin/ansible-pull
-U https://github.com/myorg/infra.git
-d /var/lib/ansible-pull
pull-playbook.yml
>> /var/log/ansible-pull.log 2>&1

🔍 Observation : pattern bootstrap puis pull — push initial pour installer ansible-core + déposer le cron. Ensuite le nœud s’auto-configure depuis le repo. L’agent reste minimaliste (juste cron + ansible-core + git).

LimitationImpact
Pas de centralisation des logsSur chaque nœud localement (/var/log/ansible-pull.log). Agréger via journalctl + rsyslog vers Loki/ELK central.
Pas d’AAP TowerAAP/Automation Controller est strictement push. Si vous voulez le UI AAP, restez en push.
Auto-update du nœud lui-mêmeRisque si un commit casse ansible-pull lui-même → nœud bloqué dans une boucle. Tester en CI avant de merger sur main.
Drift indétectable depuis le centrePas de “PLAY RECAP” agrégé. Un nœud isolé peut diverger sans alerter. Solution : exporter le code retour cron vers un health-check (Healthchecks.io, Prometheus pushgateway).
Pas de --check --diff interactifCron tourne en arrière-plan. Pour debug, lancer ansible-pull à la main avec -vvv.

Choisir push (ansible-playbook classique) quand :

  • Datacenter classique avec control node maîtrisé.
  • Fleet < 500 nœuds.
  • Vous voulez utiliser AAP / Automation Controller.
  • Logs centralisés via le control node.
  • Workflow “lancer un déploiement maintenant sur toutes les cibles”.

Choisir pull (ansible-pull) quand :

  • Nœuds Edge/IoT derrière NAT, sans IP publique.
  • Bootstrap immuable via cloud-init.
  • Fleet >1000 nœuds (scalabilité).
  • Pattern GitOps strict (repo Git = source unique de vérité).
  • Pas de control node centralisé envisageable.

🔍 Recommandation 2026 : push reste le défaut pour 95 % des cas. Pull est niche (Edge/IoT/GitOps strict). Les deux peuvent coexister dans une org : push pour le datacenter, pull pour les antennes 5G distantes.

Le lab pratiques/ansible-pull-gitops (labs/pratiques/ansible-pull-gitops/) reproduit ce parcours avec un mini-repo Git local + un script orchestrateur qui lance ansible-pull depuis db1.lab. Tests structurels (8 tests pytest) — pas de vrai test infrastructure car le pattern est mis en œuvre, pas mesuré.

  • hosts: db1.lab au lieu de hosts: localhost → erreur de connexion (pas de SSH).
  • git non installé sur le nœud → ansible-pull échoue. Toujours installer ansible-core + git au bootstrap.
  • Repo privé sans deploy key → clone échoue. Déposer une clé SSH déploy via cloud-init.
  • Pas de health-check → un nœud qui plante en boucle est invisible. Ajouter un push vers Prometheus pushgateway en fin de playbook.
  • Push = control node → cibles (SSH). Default. AAP compatible. EX294.
  • Pull = cible → repo Git. ansible-pull -U <url>. Hors EX294.
  • hosts: localhost + connection: local dans le playbook (la machine est elle-même la cible).
  • cron / systemd timer pour exécution périodique (cas datacenter pull) ou cloud-init (cas Edge bootstrap).
  • Logs distribués — agréger via syslog/Loki/ELK pour centralisation.
  • Pull est niche (Edge, IoT, GitOps strict) — push reste le défaut 2026.

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