Aller au contenu

Ansible Pull : Automatisation décentralisée

Mise à jour :

logo

Ansible, avec son modèle de connexion en push, est couramment utilisé pour centraliser la configuration et gérer les nœuds. Mais dans certains contextes, cette approche peut devenir contraignante, notamment pour les infrastructures distribuées ou les environnements nécessitant une résilience accrue.

Qu’est-ce que le modèle Pull d’Ansible ?

Le modèle Pull d’Ansible propose une approche inversée par rapport au modèle classique de push. Dans un déploiement push, un serveur de contrôle Ansible central envoie des configurations aux nœuds, initiant les changements depuis une position centrale. Avec le modèle pull, chaque nœud prend l’initiative : il exécute un script local qui va chercher les configurations nécessaires dans un dépôt Git centralisé, applique les changements localement, et se configure de manière autonome.

Concrètement, le modèle pull repose sur l’exécution régulière d’un script Ansible. Ce script télécharge les derniers playbooks disponibles, applique les rôles et tâches nécessaires, et met à jour le nœud en fonction des dernières configurations sans intervention directe du serveur de contrôle. Pour que cela fonctionne, il est essentiel que chaque nœud dispose d’un accès sécurisé au dépôt Git contenant les configurations.

Avantages d’Ansible Pull

Ansible Pull offre une série d’avantages uniques qui le rendent particulièrement adapté pour certains types d’infrastructures, notamment celles nécessitant autonomie, résilience et réduction de la charge sur les serveurs centraux.

  • Autonomie des nœuds : Avec Ansible Pull, chaque nœud est capable de gérer sa propre configuration en se connectant au dépôt Git et en récupérant les dernières mises à jour de manière autonome. Cette approche libère le serveur de contrôle de la gestion directe des configurations pour chaque nœud et permet aux machines de fonctionner indépendamment, sans dépendre d’une commande push centralisée. Cela est particulièrement utile dans les environnements distribués ou lorsque l’infrastructure comporte des nœuds isolés géographiquement.
  • Résilience en cas de défaillance du serveur de contrôle : L’un des grands avantages d’Ansible Pull est sa capacité à maintenir les nœuds à jour même si le serveur central est temporairement inaccessible. En effet, chaque nœud peut continuer à appliquer les configurations stockées dans le dépôt Git sans dépendre d’un serveur de contrôle en temps réel. En cas de problème sur le serveur central, les nœuds restent opérationnels et continuent de fonctionner avec les configurations les plus récentes, assurant ainsi une meilleure résilience de l’ensemble de l’infrastructure.
  • Réduction des accès réseau et simplification de la sécurité : Avec le modèle pull, il n’est plus nécessaire d’établir des connexions SSH du serveur de contrôle vers chaque nœud. Ce sont les nœuds eux-mêmes qui initient les connexions pour récupérer leurs configurations, ce qui réduit la complexité du réseau et les risques associés. De plus, cette approche est plus sécurisée dans les environnements sensibles, car il n’est plus nécessaire d’ouvrir des ports SSH vers chaque nœud depuis le serveur central.
  • Flexibilité pour les environnements cloud et distribués : Pour les infrastructures en cloud ou hybrides, où les machines peuvent être provisoires et déployées dynamiquement, Ansible Pull apporte une grande flexibilité. Associé à des outils comme Cloud-init, il permet de configurer les nœuds dès leur lancement en leur fournissant la configuration de base, puis de les mettre à jour en continu grâce au modèle pull. Cette capacité d’auto-configuration est particulièrement adaptée aux environnements cloud où les instances peuvent être redéployées et remplacées fréquemment.
  • Chargement équilibré et optimisation des performances : En évitant un serveur de contrôle qui doit simultanément configurer des dizaines ou des centaines de nœuds, Ansible Pull répartit la charge de travail. Chaque nœud s’auto-gère, ce qui diminue la sollicitation sur le serveur central, optimise les performances de déploiement, et réduit les risques de congestion ou d’échec lors de la mise à jour massive de configurations.

Mise en œuvre initiale avec Cloud-init

Pour simplifier et automatiser le déploiement de nœuds avec Ansible Pull, Cloud-init est une solution idéale, surtout dans les environnements cloud. Cloud-init permet de configurer un nœud dès son premier démarrage en exécutant des instructions qui préparent l’environnement, installent les outils nécessaires et lancent un premier pull des configurations.

Avec Cloud-init, chaque nouveau nœud peut être configuré pour devenir autonome, en récupérant automatiquement les dernières configurations depuis un dépôt Git.

Étape 1 : Préparation du dépôt git contenant les playbooks

Le dépôt Git utilisé pour Ansible Pull doit être bien organisé pour faciliter la navigation et la mise à jour. Voici une structure recommandée pour ce dépôt :

  • Répertoiremy-ansible-repo/
    • Répertoireroles/
    • Répertoirevars/
    • Répertoirefiles/
    • Répertoiretemplates/
    • playbook.yml
  • roles/ : ce dossier contient des rôles bien définis pour chaque tâche (par exemple, configuration d’Apache, sécurité du système). Chaque rôle doit avoir sa propre structure avec tasks/, handlers/, et defaults/.
  • vars/ : ce répertoire stocke les variables globales que vous utiliserez dans différents playbooks.
  • files/ et templates/ : ces dossiers hébergent respectivement les fichiers statiques et les modèles de configuration.

Le playbook principal est le fichier que chaque nœud exécutera pour appliquer la configuration. Ce fichier doit être minimaliste et pointer vers les rôles ou tâches nécessaires. Par exemple :

---
- name: Install and configure hosts
connection: local
hosts: localhost
become: true
tasks:
- name: Configure hostname
ansible.builtin.file:
state: touch
path: /home/ansible/test
mode: "0644"
owner: ansible
group: ansible

Dans cet exemple minimaliste, le playbook principal créé un fichier testdans le dossier /home/ansible/.

Utilisation des variables pour la personnalisation

Pour rendre les playbooks plus flexibles, utilisez des variables. Par exemple, stockez les configurations spécifiques aux environnements dans des fichiers vars/. Cela permet aux différents nœuds d’appliquer des configurations adaptées sans modifier le playbook principal.

Vous pouvez alors utiliser des variables pour gérer des aspects comme la version d’Apache ou les paramètres de sécurité.

Gestion des secrets et informations sensibles

Lorsqu’on utilise Ansible Pull, il est essentiel de protéger les informations sensibles. Évitez d’inclure des mots de passe ou clés en clair dans les playbooks. Utilisez Ansible Vault pour chiffrer les données sensibles comme suit :

Terminal window
ansible-vault encrypt vars/secrets.yml

Pour déchiffrer le fichier sur la machine, il suffira dans la configuration cloud-init de déposer le fichier de mot de passe et de créer une configuration ansible indiquant le chemin de ce fichier.

Cette pratique garantit que seules les informations chiffrées sont visibles dans le dépôt Git, augmentant ainsi la sécurité de votre configuration.

Étape 2 : Préparation du fichier Cloud-init

Le fichier Cloud-init est un script de démarrage que vous spécifiez lors de la création d’une instance. Ce fichier contient les instructions pour installer Ansible, configurer Git pour accéder au dépôt central, et exécuter le script Ansible Pull.

Voici un exemple de fichier Cloud-init pour un nœud utilisant Ansible Pull :

#cloud-config
ansible:
install_method: distro
package_name: ansible-core
pull:
playbook_name: install.yaml
url: "https://gitlab.com/b4288/ansible-config.git"
run_user: ansible
package_update: true
package_upgrade: true
packages:
- git
- python3-pip
users:
- groups: sudo
homedir: /home/ansible
name: ansible
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL

Étape 3 : Lancement de l’instance avec Cloud-init

Lorsque vous créez une instance dans un environnement compatible avec cloud-init (comme AWS, Azure, ou GCP), vous pouvez associer ce fichier Cloud-init à l’instance. Au démarrage, Cloud-init s’exécute, installe Ansible, clone le dépôt Git et applique les configurations en utilisant Ansible Pull.

Dans mon guide sur cloud-init, je vous ai expliqué comment créer une machine avec incus pour tester cette configuration. Je reprends ce principe ici :

Terminal window
incus launch images:ubuntu/24.04/cloud master2:test --config=cloud-init.user-data="$(cat cloud-config.yaml)"

Étape 4 : Validation

Après la création de l’instance, il est essentiel de vous connecter sur la machine afin de vous assurer que toutes les étapes s’exécutent correctement et que les configurations sont appliquées sans erreur. Vérifiez notamment que :

  • Ansible est correctement installé.
  • Le dépôt Git est bien cloné dans le répertoire /opt/ansible.
  • Le playbook est exécuté et les configurations sont appliquées comme attendu.
  • Le job cron est bien configuré pour effectuer les mises à jour automatiques.

Vous pouvez vérifier les journaux dans /var/log/cloud-init.log et /var/log/ansible_pull.log pour vous assurer que chaque étape s’est déroulée sans problème.

Mise en place d’un job cron pour exécuter le script Ansible Pull régulièrement

Lorsqu’on utilise Ansible Pull pour configurer des nœuds de manière autonome, il est essentiel de définir une exécution régulière pour s’assurer que chaque nœud est toujours à jour. Pour cela, un cron peut être mis en place pour exécuter automatiquement le script Ansible Pull.

Pour automatiser l’exécution de ce script, nous ajoutons un job cron dans le playbook principal, qui sera déployé lors de l’initiation du nœud avec cloud-init. Ce cron exécutera le script Ansible Pull à intervalles réguliers, par exemple toutes les heures.

Voici le playbook précédent adapater pour cloner le dépôt et créer le job cron :

---
- name: Install and configure hosts
connection: local
hosts: localhost
tasks:
- name: Cloner le dépôt Git dans /home/ansible/
ansible.builtin.git:
repo: 'https://gitlab.com/b4288/ansible-config.git'
dest: '/home/ansible/config'
version: main
force: true
- name: Créer le script Ansible Pull
ansible.builtin.copy:
dest: /home/ansible/ansible_pull.sh
mode: '0755'
content: |
#!/bin/bash
cd /home/ansible/config
git pull origin main
ansible-playbook /home/ansible/config/playbook2.yml >> /var/log/ansible_pull.log 2>&1
owner: ansible
group: ansible
- name: Créer un job cron pour exécuter Ansible Pull toutes les heures
ansible.builtin.cron:
name: "Ansible Pull job"
minute: "0"
hour: "*"
job: "/home/ansible/ansible_pull.sh >> /var/log/ansible_pull.log 2>&1"

Dans le dépôt git, créé un second playbook qui lui exécutera les taches de configuration du nœud.

Vérification du job cron

Une fois le nœud déployé, vous pouvez vérifier la configuration du job cron pour confirmer qu’il est bien en place :

Terminal window
crontab -l
#Ansible: Ansible Pull job
0 * * * * /home/ansible/ansible_pull.sh >> /var/log/ansible_pull.log 2>&1

Et après ?

Ceci est un exemple simpliste, mais on peut tout imaginer faire pas mal de tâches de configuration avec Ansible Pull. Je vais l’utiliser dans mon homelab désormais, car j’avais cessé de le faire.

Bonnes pratiques pour Ansible Pull

  • Sécuriser l’accès au dépôt Git : Utilisez des dépôts privés pour le stockage des configurations et limitez l’accès via des clés SSH ou des tokens sécurisés pour chaque nœud. Stockez les clés dans des emplacements protégés, comme /root/.ssh/, avec des permissions restreintes (chmod 600).
  • Chiffrement avec Ansible Vault : Protégez les informations sensibles en les chiffrant avec Ansible Vault. Chiffrez des fichiers comme les mots de passe ou clés d’API avec ansible-vault encrypt.
  • Permissions restrictives sur les fichiers : Limitez l’accès aux fichiers et scripts Ansible Pull pour éviter tout accès non autorisé. Définissez des permissions strictes sur le répertoire des playbooks (chmod -R 700 /home/ansible/playbooks).
  • Limiter les actions des playbooks : Évitez d’inclure des actions sensibles dans les playbooks. Concentrez-vous uniquement sur les configurations nécessaires pour chaque nœud et limitez les modifications système au minimum.
  • Suivi et audit des changements : Activez l’historique complet des modifications dans le dépôt Git pour assurer un suivi rigoureux des changements. Configurez également des notifications pour chaque commit ou merge pour suivre les mises à jour de configuration.

Limites d’Ansible Pull

Bien que Ansible Pull soit une solution intéressante pour déployer des configurations de manière décentralisée, il comporte certaines limites qu’il est essentiel de connaître pour évaluer son adéquation à votre infrastructure.

  • Absence de contrôle centralisé en temps réel : Contrairement au mode push d’Ansible, Ansible Pull ne permet pas de surveiller directement l’exécution des tâches sur les nœuds. Il est difficile d’avoir un retour immédiat sur le succès ou l’échec des configurations appliquées, rendant le suivi en temps réel plus complexe.
  • Complexité de la gestion des erreurs : Avec Ansible Pull, chaque nœud exécute les configurations de manière autonome, ce qui complique le suivi des erreurs. En cas de problème, il faut vérifier les logs sur chaque nœud individuellement ou mettre en place un système de centralisation des logs.
  • Synchronisation non garantie entre les nœuds : Comme chaque nœud exécute les mises à jour de manière indépendante (par exemple via cron), il est possible que des nœuds ne soient pas toujours synchronisés en même temps. Cela peut causer des incohérences dans la configuration, particulièrement dans les environnements où une uniformité stricte est requise.
  • Dépendance au dépôt Git : Ansible Pull repose entièrement sur l’accès au dépôt Git pour récupérer les configurations. En cas de problème d’accès au dépôt (réseau, permissions, serveur Git indisponible), les nœuds ne pourront pas se mettre à jour, ce qui peut poser des problèmes dans des environnements nécessitant des mises à jour régulières.
  • Sécurité des accès à chaque nœud : Dans Ansible Pull, chaque nœud doit pouvoir accéder au dépôt Git, ce qui exige des configurations sécurisées pour chaque machine (comme des clés SSH ou des tokens d’accès). Cette multiplication des accès peut accroître les risques de sécurité si les accès ne sont pas gérés de manière stricte.

Conclusion

Ansible Pull propose une approche puissante pour l’automatisation décentralisée, particulièrement utile dans les infrastructures distribuées et les environnements nécessitant autonomie et résilience. En permettant aux nœuds de se gérer de manière indépendante, il réduit la charge du serveur central et simplifie la configuration en environnements cloud et hybrides. Cependant, il présente des limites : absence de contrôle en temps réel, gestion complexe des erreurs et dépendance au dépôt Git. Malgré ces défis, Ansible Pull s’avère idéal pour des déploiements où la flexibilité prime sur le besoin de centralisation stricte.