Chapitre 6 - Utilisation des Boucles dans Ansible
📋 Table des Matières
- Étape Préparatoire : Création du Dossier de Travail
- Configurer l'Inventaire Ansible
- Partie 1 : Boucler sur une Liste
- Partie 2 : Boucler sur une Liste de Dictionnaires
- Partie 3 : Boucler sur un Dictionnaire
- Partie 4 : Boucler sur une Plage de Nombres
- Partie 5 : Boucler sur les Hôtes de l'Inventaire
- Partie 6 : Utiliser une Pause dans une Boucle
- Conclusion
Introduction
Dans cette pratique avancée, nous plongeons dans l'univers fascinant des boucles dans Ansible, un outil puissant qui révolutionnera votre approche de l'automatisation. Les boucles sont au cœur de l'efficacité d'Ansible, vous permettant de transformer des tâches répétitives en processus élégants et maintenables.
À travers ce chapitre, vous découvrirez comment :
- Maîtriser les boucles simples avec des listes pour automatiser des installations et des configurations en série
- Orchestrer des configurations complexes en bouclant sur des dictionnaires, parfait pour gérer des configurations de services ou des déploiements multi-environnements
- Automatiser des séquences en itérant sur des plages de nombres, idéal pour la création de ressources séquentielles
- Dynamiser vos déploiements en parcourant intelligemment votre inventaire d'hôtes
- Optimiser la gestion des utilisateurs en automatisant la création et la configuration de multiples comptes
- Déployer des configurations à grande échelle sur l'ensemble de votre infrastructure
Cette approche structurée vous permettra de passer d'une automation basique à une orchestration sophistiquée, transformant des heures de travail manuel en quelques lignes de code élégantes et réutilisables.
🔙 Retournez à la Table des Matières
Prérequis et Étape Préparatoire : Créer le Dossier de Travail
Pour réaliser cette pratique, il est obligatoire d'avoir effectué les étapes 1 à 4 du Chapitre 2 - Déployer une Infrastructure Docker avec Ansible - Pratique 02.
Si vous aviez précédemment arrêté les conteneurs, vous pouvez les redémarrer avec :
docker start node1 node2 node3 node4 node5 node6
ou
docker compose up -d
🔙 Retournez à la Table des Matières
Résumé des Étapes Précédentes (Chapitre 2)
Dans le chapitre 2, nous avons mis en place une infrastructure Docker complète pour nos tests Ansible :
1. Installation des Prérequis
- Installation de Docker et Docker Compose sur Ubuntu 22.04
- Configuration de l'environnement de base
2. Déploiement de l'Infrastructure
- Création d'une architecture avec 6 conteneurs Docker :
- node1, node5, node6 : Ubuntu
- node2 : Debian
- node3, node4 : AlmaLinux
- Configuration réseau avec des IPs statiques (172.20.0.2-7)
- Exposition des ports SSH (22) et HTTP (80)
3. Configuration SSH
- Génération des clés SSH
- Distribution des clés publiques aux conteneurs
- Configuration de l'accès SSH sans mot de passe
- Vérification de la connectivité
4. Structure de l'Inventaire
Organisation des conteneurs en groupes fonctionnels :
- [node_containers] : Tous les nœuds
- [web] : node1, node5
- [database] : node2, node3
- [mail] : node4, node6
Cette infrastructure nous permet maintenant de :
- Tester des playbooks sur différentes distributions Linux
- Organiser nos déploiements par groupes fonctionnels
- Automatiser des tâches de manière structurée
Architecture de l'infrastructure à créer avec docker-compose :
+----------------------+
| Ansible Controller |
| Ubuntu 22.04 |
| IP: 172.20.0.X |
+----------------------+
|
|
--------------------------------------------------------------------------
| | | | | | |
+---------+ +---------+ +---------+ +---------+ +---------+ +---------+ +---------+
| Node1 | | Node2 | | Node3 | | Node4 | | Node5 | | Node6 | | NodeX |
| Ubuntu | | Debian | | AlmaLin | | AlmaLin | | Ubuntu | | Ubuntu | | (opt) |
| 172.20.0.2| 172.20.0.3| 172.20.0.4| 172.20.0.5| 172.20.0.6| 172.20.0.7| ... |
+---------+ +---------+ +---------+ +---------+ +---------+ +---------+ +---------+
🔙 Retournez à la Table des Matières
1 - Configurer l'Inventaire Ansible
1 - Créer un dossier pour le projet Ansible :
mkdir ansible_project_boucles
Ce dossier ansible_project_boucles
contiendra vos fichiers et playbooks Ansible pour cette pratique.
2 - Naviguer dans ce dossier :
cd ansible_project_boucles
3 - Créer un fichier inventory.ini
:
4 - Créer un fichier inventory.ini
pour définir les nœuds :
nano inventory.ini
5 - Ajouter les informations des nœuds :
[node_containers]
node1 ansible_host=172.20.0.2 ansible_user=root ansible_python_interpreter=/usr/bin/python3
node2 ansible_host=172.20.0.3 ansible_user=root ansible_python_interpreter=/usr/bin/python3
node3 ansible_host=172.20.0.4 ansible_user=root ansible_python_interpreter=/usr/bin/python3
node4 ansible_host=172.20.0.5 ansible_user=root ansible_python_interpreter=/usr/bin/python3
node5 ansible_host=172.20.0.6 ansible_user=root ansible_python_interpreter=/usr/bin/python3
node6 ansible_host=172.20.0.7 ansible_user=root ansible_python_interpreter=/usr/bin/python3
Remarque : L'ajout de ansible_python_interpreter=/usr/bin/python3
permet d'éviter les avertissements liés à la découverte automatique de l'interpréteur Python.
6 - Enregistrer et quitter l'éditeur.
🔙 Retournez à la Table des Matières
2 - Boucler sur une Liste
Écrire un Playbook pour Afficher les Éléments d'une Liste
-
Créer un fichier nommé
print-list.yml
:nano print-list.yml
-
Ajouter le contenu suivant pour afficher une liste de nombres premiers :
---
- name: Afficher une Liste de Nombres Premiers
hosts: node1
become: yes
vars:
prime_numbers:
- 2
- 3
- 5
- 7
- 11
tasks:
- name: Afficher les Nombres Premiers
debug:
msg: "Nombre premier : {{ item }}"
loop: "{{ prime_numbers }}"Explications :
vars
: Définit une variableprime_numbers
qui est une liste de nombres premiers.loop
: Itère sur chaque élément de la listeprime_numbers
.{{ item }}
: Représente l'élément courant de la boucle.
-
Enregistrer et quitter l'éditeur.
-
Exécuter le playbook :
ansible-playbook -i inventory.ini print-list.yml
Résultat attendu :
Le playbook affichera chaque nombre premier de la liste.
🔙 Retournez à la Table des Matières
3 - Boucler sur une Liste de Dictionnaires
Ajouter Plusieurs Utilisateurs avec une Boucle
-
Créer un fichier
add-users.yml
pour ajouter plusieurs utilisateurs avec des mots de passe :nano add-users.yml
-
Ajouter le contenu suivant :
---
- name: Ajouter Plusieurs Utilisateurs
hosts: database
become: yes
vars:
db_users:
- username: "alice"
password: "password1"
uid: 1001
- username: "bob"
password: "password2"
uid: 1002
- username: "charlie"
password: "password3"
uid: 1003
tasks:
- name: Créer les Utilisateurs
user:
name: "{{ item.username }}"
uid: "{{ item.uid }}"
password: "{{ item.password | password_hash('sha512') }}"
shell: "/bin/bash"
state: present
loop: "{{ db_users }}"Explications :
db_users
: Liste de dictionnaires, chaque dictionnaire contenant les informations d'un utilisateur.- Module
user
: Utilisé pour gérer les comptes utilisateurs sur les hôtes cibles. password_hash('sha512')
: Hash le mot de passe en utilisant l'algorithme SHA-512 pour la sécurité.loop: "{{ db_users }}"
: Itère sur chaque utilisateur dans la listedb_users
.
-
Enregistrer et quitter l'éditeur.
-
Exécuter le playbook :
ansible-playbook -i inventory.ini add-users.yml
-
Vérification :
Utilisez la commande suivante pour confirmer que les utilisateurs ont été ajoutés :
ansible database -m command -a "getent passwd alice bob charlie" -i inventory.ini
Remarque : La commande
getent passwd
affiche les entrées des utilisateurs spécifiés.
🔙 Retournez à la Table des Matières
4 - Boucler sur un Dictionnaire
Ansible ne peut pas boucler directement sur un dictionnaire. Il faut le transformer en une liste de paires clé/valeur en utilisant le filtre dict2items
.
Afficher les Paires Clé/Valeur d'un Dictionnaire
-
Créer un fichier nommé
print-dictionary.yml
:nano print-dictionary.yml
-
Ajouter le contenu suivant :
---
- name: Afficher les Informations d'un Employé
hosts: node1
become: yes
vars:
employee:
name: "Alice"
title: "Administratrice Système"
company: "TechCorp"
tasks:
- name: Afficher le Dictionnaire Employé
debug:
msg: "{{ item.key }}: {{ item.value }}"
loop: "{{ employee | dict2items }}"Explications :
employee
: Un dictionnaire contenant des informations sur un employé.dict2items
: Convertit le dictionnaire en une liste de paires clé/valeur.{{ item.key }}
et{{ item.value }}
: Représentent respectivement la clé et la valeur de chaque élément.
-
Enregistrer et quitter l'éditeur.
-
Exécuter le playbook :
ansible-playbook -i inventory.ini print-dictionary.yml
Résultat attendu :
Le playbook affichera chaque attribut de l'employé, par exemple :
name: Alice
title: Administratrice Système
company: TechCorp
🔙 Retournez à la Table des Matières
5 - Boucler sur une Plage de Nombres
Afficher une Plage de Nombres
-
Créer un fichier
range-loop.yml
:nano range-loop.yml
-
Ajouter le contenu suivant :
---
- name: Boucler sur une Plage de Nombres
hosts: node1
become: yes
tasks:
- name: Afficher les Nombres de 5 à 14
debug:
msg: "Nombre : {{ item }}"
loop: "{{ range(5, 15) | list }}"Explications :
range(5, 15)
: Génère un itérable de nombres de 5 à 14 (15 est exclu).| list
: Convertit l'itérable en une liste.
-
Enregistrer et quitter l'éditeur.
-
Exécuter le playbook :
ansible-playbook -i inventory.ini range-loop.yml
Résultat attendu :
Le playbook affichera les nombres de 5 à 14.
🔙 Retournez à la Table des Matières
6 - Boucler sur les Hôtes de l'Inventaire
Exécuter une Tâche sur Tous les Nœuds de l'Inventaire
-
Créer un fichier
loop-inventory.yml
:nano loop-inventory.yml
-
Ajouter le contenu suivant :
---
- name: Boucler sur les Hôtes de l'Inventaire
hosts: node1
become: yes
tasks:
- name: Vérifier la Connectivité avec Tous les Hôtes
ping:
data: "Ping depuis node1"
delegate_to: "{{ item }}"
loop: "{{ groups['all'] }}"Explications :
groups['all']
: Contient tous les hôtes définis dans l'inventaire.delegate_to: "{{ item }}"
: Exécute la tâche sur l'hôte spécifié paritem
au lieu du nœud cible (node1
).- Module
ping
: Vérifie la connectivité Ansible entre les hôtes.
-
Enregistrer et quitter l'éditeur.
-
Exécuter le playbook :
ansible-playbook -i inventory.ini loop-inventory.yml
Résultat attendu :
Le playbook testera la connectivité avec chaque hôte de l'inventaire depuis
node1
.
🔙 Retournez à la Table des Matières
7 - Utiliser une Pause dans une Boucle
Créer un Compte à Rebours avec une Pause
-
Créer un fichier
countdown.yml
:nano countdown.yml
-
Ajouter le contenu suivant :
---
- name: Compte à Rebours de 10 Secondes
hosts: node1
become: yes
tasks:
- name: Afficher le Compte à Rebours
debug:
msg: "{{ item }} secondes restantes..."
loop: "{{ range(10, 0, -1) | list }}"
loop_control:
delay: 1
- name: Afficher le Message Final
debug:
msg: "C'est l'heure !"Explications :
range(10, 0, -1)
: Génère une liste de nombres de 10 à 1 en décrémentant de 1.loop_control: delay: 1
: Insère une pause de 1 seconde entre chaque itération de la boucle.{{ item }}
: Représente le nombre de secondes restantes.
-
Enregistrer et quitter l'éditeur.
-
Exécuter le playbook :
ansible-playbook -i inventory.ini countdown.yml
Résultat attendu :
Le playbook affichera un compte à rebours de 10 à 1 avec une pause d'une seconde entre chaque nombre, puis affichera "C'est l'heure !".
🔙 Retournez à la Table des Matières
8 - Résumé
Dans ce chapitre, vous avez appris à :
- Utiliser les boucles simples avec
loop
pour itérer sur des listes. - Boucler sur des listes de dictionnaires pour effectuer des tâches complexes comme la création d'utilisateurs.
- Transformer et boucler sur des dictionnaires en utilisant le filtre
dict2items
. - Utiliser des plages de nombres avec
range()
pour générer des séquences numériques. - Boucler sur les hôtes de l'inventaire pour effectuer des actions sur plusieurs nœuds.
- Introduire des pauses dans les boucles avec
loop_control
pour contrôler le timing des tâches.
Ces techniques vous permettent de rendre vos playbooks plus dynamiques et efficaces, en automatisant des tâches répétitives sans répéter le code.
🔙 Retournez à la Table des Matières
Conseils Supplémentaires
- Filtres Jinja2 : Explorez d'autres filtres comme
items2dict
,map
, etselect
pour manipuler vos données. - Boucles avec
with_items
: Bien queloop
soit recommandé, vous pouvez rencontrerwith_items
dans des playbooks plus anciens. - Contrôle des Boucles : Utilisez
loop_control
pour accéder à des variables spéciales commeindex
,index0
,first
,last
. - Gestion des Échecs dans les Boucles : Pour continuer l'exécution en cas d'erreur sur un élément, utilisez
ignore_errors
oufailed_when
.
🔙 Retournez à la Table des Matières
9 - Ressources Utiles
- Documentation Ansible - Looping Over Items
- Ansible Loop Control
- Jinja2 Template Designer Documentation
🔙 Retournez à la Table des Matières
10 - Conclusion générale
Vous avez amélioré vos compétences en Ansible en apprenant à utiliser les boucles pour automatiser des tâches répétitives. Continuez à explorer ces fonctionnalités pour rendre vos playbooks encore plus puissants et efficaces.