Ce premier module théorique présente les fondamentaux d'Ansible, son architecture et ses bonnes pratiques.
1. Concepts fondamentaux
Définition : Ansible est un outil d'automatisation IT open-source permettant l'orchestration, le déploiement d'applications et la configuration de serveurs.
Architecture "Agentless" : Contrairement à d'autres outils, Ansible ne nécessite l'installation d'aucun agent sur les machines cibles. Il utilise une architecture « push » où le nœud de contrôle envoie des tâches via SSH.
Playbooks : Les tâches sont décrites dans des fichiers appelés playbooks, rédigés en YAML, un langage simple et lisible.
Idempotence : C'est un concept clé assurant que l'exécution répétée d'un playbook produit toujours le même résultat final, sans effets de bord ni reconfiguration inutile.
2. Approche : Procédurale vs Déclarative
Le cours insiste sur la distinction entre deux manières d'écrire des playbooks :
Procédural (À éviter) : On décrit les étapes séquentielles (le "comment") comme une recette (ex: commandes shell mkdir, git clone). Cette méthode manque souvent d'idempotence et de vérifications.
Déclaratif (Recommandé) : On décrit l'état final souhaité (le "quoi"), et Ansible se charge de l'atteindre via des modules spécialisés (ex: modules file, git, service). Cette approche est plus robuste et maintenable.
Ce travail dirigé détaille deux méthodes pour installer Ansible sur un serveur de contrôle Debian 12.
Option A : Installation via le gestionnaire de paquets (APT)
C'est la méthode la plus simple pour une installation globale.
Il suffit de mettre à jour le système et d'exécuter la commande : sudo apt install -y ansible.
La vérification se fait via la commande ansible --version.
Option B : Installation dans un environnement virtuel Python (Recommandée) Cette méthode permet d'isoler l'installation pour éviter les conflits de versions entre différents projets.
Création : On utilise le module venv pour créer un dossier isolé (ex: ~/.venv/ansible).
Activation : L'environnement doit être activé via la commande source.
Installation : Ansible est ensuite installé via pip install ansible, ce qui permet souvent d'obtenir une version plus récente que celle des dépôts Debian.
Gestion : Des commandes utiles comme deactivate permettent de sortir de l'environnement, et pip list permet de voir les paquets installés.
Ce document explique comment sécuriser et automatiser la connexion entre le serveur Ansible (nœud de contrôle) et les machines gérées.
1. Préparation de la machine cible
Le service SSH doit être actif sur la machine gérée.
Il est nécessaire de créer un utilisateur dédié (nommé ansible).
Cet utilisateur doit être ajouté au groupe sudo pour avoir les droits d'administration.
2. Gestion des clés SSH
Génération : Sur le serveur Ansible, on génère une paire de clés RSA avec la commande ssh-keygen -t rsa -b 4096.
Déploiement de la clé publique :
Méthode automatique : Utilisation de la commande ssh-copy-id vers le serveur distant.
Méthode manuelle : Copier le contenu de id_rsa.pub et le coller dans le fichier ~/.ssh/authorized_keys de l'utilisateur sur le serveur distant.
3. Sécurité et Permissions
Le document insiste lourdement sur les permissions des fichiers. Une clé privée trop ouverte (droits 0644) sera ignorée par SSH.
Il est impératif de restreindre les droits sur le dossier .ssh (chmod 700 ou similaire) et les fichiers de clés (chmod 600).
Ce document explique comment référencer les machines que Ansible doit piloter.
1. Le concept d'inventaire
Définition : L'inventaire est la liste des hôtes gérés par Ansible. Par défaut situé dans /etc/ansible/hosts, il est souvent préférable d'en créer un spécifique et de l'appeler via l'option -i.
2. Structure du fichier (hosts.ini)
Le tutoriel guide la création d'un fichier contenant deux types de cibles :
Le serveur local (Localhost) :
Configuré avec ansible_connection=local pour exécuter des actions directement sur la machine de contrôle (tests, déploiement local).
Le serveur distant (Managed Node) :
On définit un alias (ex: SRV-DEB12) et on précise les paramètres de connexion : ansible_host (IP) et ansible_user (utilisateur SSH).
Les hôtes peuvent être organisés en groupes (ex: [srv_debian]) pour faciliter le ciblage.
3. Test de connectivité
La validation se fait via la commande ansible all -m ping -i <chemin_inventaire>. Une réponse "pong" confirme que Ansible communique correctement avec les cibles.
Ce module est le cœur de l'automatisation : il détaille l'écriture et l'exécution d'un playbook YAML.
1. Structure et Syntaxe
Playbook : Fichier YAML contenant des "plays" (scénarios) qui ciblent des hôtes et exécutent une liste de "tasks" (tâches).
Modules : Les tâches appellent des modules spécialisés (ex: apt, user, service) plutôt que des commandes brutes.
2. Création du premier playbook (setup.yaml)
L'exercice consiste à configurer le serveur Debian 12 avec trois tâches principales :
Installation de paquets : Utilisation du module ansible.builtin.apt pour installer htop.
Gestion des utilisateurs : Utilisation de ansible.builtin.user pour créer l'utilisateur tutotech_admin.
Gestion des clés SSH : Utilisation de ansible.posix.authorized_key pour déployer une clé publique (stockée localement dans un dossier files) vers le serveur distant.
3. Exécution et Idempotence
Commande : ansible-playbook -i hosts setup.yaml --ask-become-pass.
L'option --ask-become-pass est cruciale pour fournir le mot de passe sudo nécessaire aux privilèges d'administration.
Résultat :
Première exécution : État changed (les modifications sont appliquées).
Seconde exécution : État ok (rien ne change), illustrant le principe d'idempotence.
Astuce : Le document suggère de configurer le fichier /etc/sudoers.d/ansible pour ne plus avoir à saisir le mot de passe sudo à l'avenir.
Ce document constitue un exercice pratique pour valider les acquis.
1. Consignes (TP)
L'objectif est d'étendre l'automatisation en réalisant deux nouvelles actions en autonomie :
Installer le logiciel cmatrix.
Créer un utilisateur nommé tutotech_stagiaire.
Ce document est la correction de l'exercice pratique pour valider les acquis.
2. Solution (Correction)
La correction montre comment ajouter simplement ces tâches à la suite des précédentes dans le fichier YAML :
Tâche 1 : Appel au module ansible.builtin.apt avec name: cmatrix et state: present.
Tâche 2 : Appel au module ansible.builtin.user pour créer tutotech_stagiaire avec un shell /bin/bash.
3. Vérification Le TP se conclut par la vérification manuelle sur le serveur distant via les commandes id tutotech_stagiaire (pour vérifier l'UID/GID) et le lancement de cmatrix pour voir l'animation dans le terminal.
Ce document explique comment organiser un projet Ansible lorsqu'il gagne en complexité.
1. Pourquoi utiliser des rôles ?
Problème : Maintenir tout le code dans un seul fichier YAML devient difficile à mesure que l'on ajoute des fonctionnalités.
Solution : Un rôle permet de regrouper un ensemble de tâches, variables, fichiers et templates liés à une fonction métier (ex: webserver, users, base).
Avantages : Cette approche favorise la réutilisation du code, le partage (via Ansible Galaxy) et respecte le principe DRY (Don't Repeat Yourself).
2. Structure et Création
Arborescence standard : Un rôle contient des dossiers spécifiques comme tasks/ (pour les actions), files/ (pour les fichiers statiques), vars/, templates/, etc..
Commande d'initialisation : Pour éviter de créer ces dossiers manuellement, on utilise la commande : ansible-galaxy init <nom_du_role>.
Utilisation : Le playbook principal (souvent appelé site.yml) devient très concis : il se contente de lister les rôles à appliquer sur les hôtes cibles.
Ce document évalue l'apprenant dans la création pratique d'un rôle pour la gestion des utilisateurs.
1. Objectif du TP
Il faut créer un rôle nommé users qui effectue deux actions sur la machine distante :
Créer l'utilisateur tutotech_technicien.
Lui autoriser l'accès SSH via une clé publique existante (récupérée du projet précédent).
Ce document guide l'apprenant dans la création pratique d'un rôle pour la gestion des utilisateurs.
1. Mise en œuvre technique
Préparation : On crée un dossier roles/ et on génère le squelette avec ansible-galaxy init users.
Gestion des fichiers : La clé publique id_rsa.pub est copiée dans le dossier roles/users/files/.
Définition des tâches (tasks/main.yml) :
Utilisation du module ansible.builtin.user pour créer l'utilisateur et son répertoire personnel.
Utilisation du module ansible.posix.authorized_key pour injecter la clé SSH.
2. Point de vigilance technique (astuce importante)
La correction soulève une subtilité concernant la fonction lookup. Par défaut, elle cherche les fichiers par rapport au dossier d'exécution du playbook, et non dans le dossier du rôle.
La solution : Il faut utiliser la variable magique role_path pour indiquer le chemin absolu vers le fichier du rôle.
Syntaxe correcte : key: "{{ lookup('file', role_path + '/files/id_rsa.pub') }}".
4. Déploiement
Un playbook principal site.yml est créé à la racine pour cibler le groupe SRV-DEB12 et appeler le rôle users avec les droits d'administration (become: yes).
L'exécution confirme la création de l'utilisateur et l'ajout de la clé.
Ce document théorique présente le concept des "Handlers", des tâches conditionnelles essentielles pour optimiser l'exécution des playbooks.
Définition et Fonctionnement : Les handlers sont des tâches spéciales qui ne s'exécutent que si elles sont explicitement "notifiées" par une autre tâche. Contrairement aux tâches classiques, elles ne s'exécutent pas automatiquement mais attendent un déclencheur.
La directive notify : Pour déclencher un handler, on utilise la directive notify au sein d'une tâche standard. Le handler ne s'activera que si la tâche parente applique une modification réelle au système (statut "changed").
Cas d'usage : Les handlers sont principalement utilisés pour redémarrer des services après une mise à jour, recharger une configuration sans interruption de service, ou effectuer des nettoyages de fichiers temporaires.
Exemple de flux : Le cours illustre le processus avec un serveur Nginx : si la tâche de déploiement du fichier de configuration détecte un changement, elle notifie le handler "reload nginx". Si aucune modification n'est détectée (idempotence), le handler reste inactif.
Ce fichier de travaux pratiques guide l'apprenant dans la mise en œuvre concrète d'un handler au sein d'un rôle.
Objectif : L'exercice consiste à installer le serveur web Nginx et à déployer sa configuration tout en gérant le redémarrage du service via un handler.
Création du rôle : Il est demandé de générer un nouveau rôle nommé webserver dans le dossier roles/ existant.
Tâches à implémenter :
Installer le paquet nginx.
Déployer un fichier de configuration basé sur un template Jinja2.
Mise en place du Handler : Le handler doit être configuré pour redémarrer Nginx uniquement si l'une des tâches précédentes (installation ou config) applique un changement.
Ressources : Le TP fournit un lien vers un dépôt GitHub (geerlingguy) pour récupérer un modèle de template vhost.j2 adapté.
Intégration : L'étudiant doit mettre à jour son playbook principal (site.yml) pour inclure ce nouveau rôle webserver.
Ce document fournit la solution détaillée étape par étape pour réaliser le TP précédent.
Initialisation : La correction commence par la création de l'arborescence du rôle via la commande ansible-galaxy init webserver.
Définition des tâches (tasks/main.yml) :
La tâche d'installation du paquet nginx inclut la ligne notify: restart nginx.
La tâche de déploiement du template (ansible.builtin.template) vers /etc/nginx/sites-available/monsite.conf inclut également la même notification.
Récupération du Template : Le document donne la commande curl exacte pour télécharger le fichier vhost.j2 et le placer dans le dossier templates/ du rôle.
Configuration du Handler (handlers/main.yml) : Le handler est défini avec le module ansible.builtin.service, ciblant nginx avec l'état restarted.
Exécution et Vérification :
Le playbook site.yml est mis à jour pour inclure le rôle webserver à la suite du rôle users.
Lors de l'exécution, la sortie standard montre bien l'étape RUNNING HANDLER [webserver : restart nginx] en fin de jeu, confirmant que le redémarrage a eu lieu suite aux changements.
La validation finale se fait en accédant à la page d'accueil par défaut de Nginx via l'adresse IP du serveur.
Ce module théorique explique comment remplacer les valeurs codées en dur par des éléments dynamiques, augmentant ainsi la flexibilité du code.
Définition et Utilité : Les variables permettent de stocker des valeurs (comme des noms de paquets, des ports ou des chemins) pour les réutiliser dynamiquement à travers le projet.
Emplacements de définition : Le cours détaille les différents endroits où l'on peut déclarer des variables, classés par portée :
Inventaire : Dans les dossiers group_vars (pour un groupe de machines) ou host_vars (pour une machine spécifique).
Playbook : Directement dans une section vars pour une application spécifique.
Rôles : Dans defaults/main.yml pour les valeurs par défaut (faible priorité) ou vars/main.yml pour des constantes (haute priorité).
Mécanisme de Précédence : Un point crucial est la hiérarchie des variables. Ansible applique un ordre strict de surcharge : une variable passée en ligne de commande (CLI) l'emporte sur celle du Playbook, qui l'emporte sur l'Inventaire, qui l'emporte enfin sur les valeurs par défaut du Rôle.
Syntaxe et Facts : L'utilisation se fait via la syntaxe Jinja2 {{ ma_variable }}. Le document mentionne également les Ansible Facts, des variables collectées automatiquement (IP, OS, processeur) au début de l'exécution.
Cet exercice pratique vise à rendre le rôle webserver (créé lors des modules précédents) configurable via des variables.
Objectif : Modifier la configuration du serveur web pour que le port d'écoute HTTP ne soit plus figé, mais défini par une variable.
Consignes :
Définir une variable par défaut nommée http_port avec la valeur 80 dans le fichier approprié du rôle (defaults/main.yml).
Mettre à jour le modèle de configuration Nginx (vhost.conf.j2) pour utiliser cette variable {{ http_port }} à la place du chiffre 80.
Surcharger cette variable dans le playbook principal site.yml pour forcer l'utilisation du port 8080 au lieu du port par défaut.
Validation : L'étudiant doit vérifier que le fichier de configuration généré sur le serveur distant contient bien le port personnalisé.
Ce document détaille les modifications de code nécessaires pour réussir l'intégration des variables.
Modification du Rôle (Defaults) : La correction montre l'ajout de la ligne http_port: 80 dans le fichier roles/webserver/defaults/main.yml, établissant une valeur de repli.
Modification du Template : Le fichier vhost.conf.j2 est édité pour intégrer la syntaxe Jinja2 : listen {{ http_port }};.
Surcharge dans le Playbook : Le fichier site.yml est mis à jour en ajoutant une section vars: sous l'appel du rôle ou du play, définissant http_port: 8080.
Résultat : Lors de l'exécution, Ansible utilise la valeur définie dans le playbook (8080) car elle a la priorité sur la valeur par défaut du rôle (80). La vérification confirme que Nginx écoute désormais sur le nouveau port.
Ce document présente le concept de templating, une fonctionnalité clé pour générer des fichiers de configuration dynamiques plutôt que statiques.
Principe de base : Un template est un fichier texte contenant des variables qui sont remplacées par leurs valeurs réelles lors de l'exécution du playbook. Cela permet de séparer la structure du fichier (le squelette) de ses données (les variables).
Moteur Jinja2 : Ansible utilise le moteur de templating Jinja2, qui est standard dans l'écosystème Python. Les fichiers templates portent généralement l'extension .j2.
Syntaxe : Le cours distingue deux types de balises principales :
{{ ma_variable }} : Pour afficher la valeur d'une variable.
{% condition %} : Pour exécuter des instructions logiques comme des boucles ou des conditions.
Module Template : Le module Ansible template est utilisé pour traiter le fichier .j2 sur le nœud de contrôle et copier le fichier résultant (compilé) sur la machine cible.
Ce fichier de travaux pratiques propose un exercice pour personnaliser la page d'accueil du serveur web Nginx en utilisant une variable système.
Objectif : Remplacer la page index.html par défaut de Nginx par une page personnalisée qui affiche dynamiquement le nom de la machine hébergeant le site.
Création du Template : L'étudiant doit créer un fichier index.html.j2 dans le répertoire roles/webserver/templates/.
Utilisation de Variable : Ce fichier doit contenir du code HTML standard ainsi que la variable {{ inventory_hostname }} pour afficher le nom du serveur tel que défini dans l'inventaire Ansible
Mise à jour du Rôle : Il est demandé d'ajouter une tâche dans le rôle webserver pour déployer ce template vers /var/www/html/index.html.
Vérification : Le TP se termine par l'exécution du playbook et la vérification du résultat via un navigateur ou la commande curl.
Ce document détaille la solution technique pour réussir le déploiement de la page web dynamique.
Structure du fichier : La correction montre le contenu exact du fichier index.html.j2, mélangeant HTML (<h1>Bienvenue...</h1>) et la syntaxe Jinja2 ({{ inventory_hostname }}).
Configuration de la Tâche : Le fichier roles/webserver/tasks/main.yml est modifié pour inclure le module ansible.builtin.template.
Paramètres du Module : La correction insiste sur les paramètres importants :
src: index.html.j2 : Le fichier source local.
dest: /var/www/html/index.html : La destination sur le serveur distant.
owner: www-data et mode: 0644 : Pour assurer que le serveur web a les droits de lecture sur le fichier.
Résultat : Une fois le playbook exécuté, l'accès au serveur via son IP affiche désormais "Bienvenue sur SRV-DEB12" (ou le nom correspondant), prouvant que la variable a bien été interprétée.
Ce cours explique comment automatiser l'installation du moteur Docker sur des serveurs distants en s'appuyant sur l'écosystème Ansible Galaxy.
Utilisation de Rôles Existants : Plutôt que de réécrire des tâches d'installation complexes, le cours recommande l'utilisation du rôle officiel et maintenu par la communauté : geerlingguy.docker.
Installation du Rôle : Il détaille la commande nécessaire pour récupérer ce rôle depuis Ansible Galaxy : ansible-galaxy install geerlingguy.docker.
Intégration : Le document montre comment appeler ce rôle dans un playbook via la section roles:, permettant à Ansible de chercher le rôle localement ou dans le dossier global .ansible/roles/.
Ce document de travaux pratiques demande à l'apprenant de créer un playbook nommé install_docker.yml pour déployer Docker Engine sur une machine virtuelle.
Objectifs :
Utiliser le rôle geerlingguy.docker vu dans le cours.
Créer un utilisateur spécifique nommé admin_docker.
Ajouter cet utilisateur au groupe de sécurité docker pour lui permettre de lancer des conteneurs sans privilèges root.
Méthode suggérée : Le TP invite à utiliser la variable docker_users documentée dans le rôle Galaxy, ou à réutiliser des tâches de création d'utilisateurs vues dans les modules précédents.
Validation : L'exercice se conclut par une vérification manuelle via la commande docker run hello-world.
Ce fichier fournit la solution technique pour installer Docker et configurer les permissions utilisateurs correctement.
Prérequis : La correction rappelle l'importance d'installer le rôle via ansible-galaxy et de configurer l'inventaire hosts.ini avec un groupe [docker_hosts].
Configuration par Variable : Le cœur de la solution réside dans l'utilisation de la variable docker_users passée directement au rôle dans le playbook. Cela permet d'ajouter l'utilisateur admin_docker au groupe Docker automatiquement sans écrire de tâches "user" manuelles.
Exécution : Le document fournit la commande de lancement ansible-playbook et montre la sortie attendue, où l'on voit les tâches du rôle geerlingguy.docker s'exécuter (installation de paquets, configuration du service, gestion des utilisateurs).
Ce travail dirigé introduit la gestion du cycle de vie des conteneurs (l'équivalent des commandes docker run, stop, etc.) directement via Ansible.
Collection community.docker : Le document présente cette collection indispensable qui fournit les modules nécessaires (docker_image, docker_network, docker_volume).
Installation : Il précise comment installer cette collection via ansible-galaxy collection install community.docker.
Le module docker_container : Le TD se concentre sur ce module central qui permet de décrire l'état désiré d'un conteneur de manière déclarative (ex: image à utiliser, ports exposés, état started ou absent).
Avantage : Il explique que cette méthode permet à Ansible de gérer le "diff" (différence entre l'état actuel et l'état désiré) automatiquement, contrairement à des scripts shell impératifs.