93 labs pratiques pour préparer le Red Hat Certified Engineer (EX294), soit environ 68 heures de travail, chacun noté sur l'état réel de votre machine et non sur les commandes tapées. Ils se jouent chez vous avec la ligne de commande `dsoxlab`, et ne coûtent rien.
L'automatisation avec Ansible, sur des machines Red Hat Enterprise Linux. Le RHCSA en est le prérequis, et l'épreuve reste entièrement pratique.
- 93labs
- 68heures de pratique
- 86sur machines virtuelles
Niveaux 30 débutant 43 intermédiaire 20 avancé
Objectifs officiels de l'examen publiés par Red Hat
Ce ne sont pas des questions d'examen. Ce sont des exercices pratiques sur les compétences que l'examen mesure, notés sur l'état de votre machine.
Ansible et la RHCE EX294
Ajouter ce catalogue dsoxlab catalog add https://github.com/stephrobert/ansible-training
Préparer l'environnement
Découvrir Ansible
-
Déclaratif vs impératif : pourquoi Ansible ne dérive pas
Comparer un script Bash qui dérive à chaque run et un playbook qui converge, puis prouver l'idempotence par le changed=0 du second passage.
dsoxlab start decouvrir-declaratif-vs-imperatif -
Installation d'Ansible : vérifier son poste de contrôle
Identifier sa méthode d'installation, vérifier les 8 binaires du PATH, les modules accessibles via ansible-doc et les collections du dépôt.
dsoxlab start decouvrir-installation-ansible -
ansible.cfg : précédence et options critiques
Écrire un ansible.cfg projet, vérifier la config active avec ansible-config dump, surcharger par variable d'environnement et activer un callback.
dsoxlab start decouvrir-configuration-ansible -
CLI Ansible : les 8 commandes du quotidien
Enchaîner ad-hoc, ansible-doc, ansible-config, ansible-inventory, ansible-galaxy, ansible-vault et ansible-lint sur le lab.
dsoxlab start decouvrir-prise-en-main-cli
Premiers pas
-
Premier playbook : installer nginx sur les webservers
Écrire un playbook de 5 tâches (dnf, systemd, firewalld), lire le PLAY RECAP, capturer une sortie avec register et vérifier l'idempotence.
dsoxlab start premiers-pas-premier-playbook -
Premiers pas avec ansible-vault
Chiffrer un fichier de secrets avec ansible-vault, le consommer via vars_files et protéger la sortie avec no_log et un .vault_password en 0600.
dsoxlab start premiers-pas-ansible-vault
Écrire du code Ansible
-
Plays et tasks : anatomie et ordre d'exécution
Structurer un play avec pre_tasks, tasks, post_tasks et handlers, puis prouver l'ordre d'exécution réel par des fichiers marqueurs horodatés.
dsoxlab start ecrire-code-plays-et-tasks -
Handlers : le pattern restart-on-config-change
Notifier plusieurs handlers, les découpler avec listen, forcer meta: flush_handlers et combiner validate pour ne jamais appliquer une config invalide.
dsoxlab start ecrire-code-handlers -
Tags : cibler ou ignorer un sous-ensemble de tâches
Poser des tags, cibler avec --tags et exclure avec --skip-tags, inspecter le plan via --list-tasks et exploiter les tags spéciaux always et never.
dsoxlab start ecrire-code-tags -
Check mode et diff : dry-run et visualisation
Lancer un playbook en --check --diff, repérer les modules non compatibles, forcer check_mode: false et diagnostiquer un faux positif changed.
dsoxlab start ecrire-code-checkmode-diff -
Variables : déclaration et portées
Déclarer des variables via vars et vars_files, les surcharger avec --extra-vars et diagnostiquer une valeur inattendue liée au typage YAML.
dsoxlab start ecrire-code-variables-base -
Types collections : listes, dicts, structures imbriquées
Déclarer listes et listes de dicts en YAML, boucler dessus avec loop_control: label, filtrer par when et accéder aux champs imbriqués.
dsoxlab start ecrire-code-types-collections -
Facts et magic vars : ansible_facts, hostvars
Lire les facts système, exploiter inventory_hostname, groups et hostvars, puis réduire le coût de collecte avec gather_subset.
dsoxlab start ecrire-code-facts-magic-vars -
Custom facts : facts.d et ansible_local
Déposer un custom fact INI puis un script exécutable retournant du JSON dans /etc/ansible/facts.d, et les lire via ansible_local.
dsoxlab start ecrire-code-custom-facts -
Précédence des variables : les 22 niveaux
Superposer la même variable à plusieurs niveaux pour démontrer lequel gagne, du role defaults jusqu'à --extra-vars.
dsoxlab start ecrire-code-precedence-variables -
register et set_fact : capturer et créer des variables
Capturer la sortie d'un module avec register, la réutiliser dans when et loop, créer un fact au runtime et le persister avec cacheable: true.
dsoxlab start ecrire-code-register-set-fact -
Parallélisme : forks, serial, throttle, strategy
Distinguer forks de serial, jouer un rolling update en serial: 1, comparer les stratégies linear et free et limiter une tâche avec throttle.
dsoxlab start ecrire-code-parallelisme-strategies -
Async et poll : tâches longues sans bloquer SSH
Détacher une tâche longue en async + poll: 0, récupérer son résultat via async_status, faire du polling actif et diagnostiquer un job orphelin.
dsoxlab start ecrire-code-async-poll -
Délégation : delegate_to, run_once, local_action
Rediriger une tâche vers un autre hôte, ne l'exécuter qu'une fois dans un play multi-hôtes et cibler le control node avec local_action.
dsoxlab start ecrire-code-delegation -
Lookups : récupérer des données externes
Lire un fichier, une variable d'environnement ou la sortie d'une commande côté control node, générer un mot de passe et distinguer lookup de query.
dsoxlab start ecrire-code-lookups -
Jinja2 : interpolation, logique et whitespace
Interpoler des variables, boucler et conditionner dans un template, puis supprimer les sauts de ligne parasites par le whitespace control.
dsoxlab start ecrire-code-jinja2-base -
Filtres Jinja2 essentiels : default, combine, selectattr
Gérer les variables absentes avec default, manipuler des listes, filtrer une liste de dicts avec selectattr et map, fusionner des dicts avec combine.
dsoxlab start ecrire-code-filtres-jinja-essentiels -
Conditions when : opérateurs et tests Jinja
Conditionner une tâche sur un fact, combiner plusieurs conditions, tester la définition d'une variable et diagnostiquer un when qui matche faux.
dsoxlab start ecrire-code-conditions-when -
Boucles loop : itérer sur listes et dicts
Boucler sur une liste et une liste de dicts, rendre la sortie lisible avec loop_control: label, itérer sur un dict via dict2items.
dsoxlab start ecrire-code-boucles-loop -
Boucles legacy with_* : migrer vers loop
Reconnaître with_items, with_dict et with_subelements, les migrer vers loop plus filtres Jinja2 et automatiser avec ansible-lint --fix.
dsoxlab start ecrire-code-boucles-with-deprecated -
block, rescue, always : try/catch/finally
Grouper des tâches dans un block, capturer l'erreur avec rescue pour rollback, garantir le nettoyage avec always et lire ansible_failed_task.
dsoxlab start ecrire-code-block-rescue-always -
failed_when et changed_when : redéfinir succès et changement
Neutraliser le changed des commandes lecture-seule, définir changed_when sur la sortie et accepter certains codes retour comme succès.
dsoxlab start ecrire-code-failed-when-changed-when -
ignore_errors : usage légitime vs anti-pattern
Mesurer l'effet d'ignore_errors sur le PLAY RECAP, identifier ses rares cas légitimes et lui préférer failed_when ou block/rescue.
dsoxlab start ecrire-code-ignore-errors -
any_errors_fatal : arrêter le play à la première erreur
Activer any_errors_fatal sur un play multi-hôtes, le comparer au défaut et à max_fail_percentage, et le combiner avec serial.
dsoxlab start ecrire-code-any-errors-fatal -
Filtres Jinja2 avancés : regex, b64, password_hash
Extraire avec regex_search, encoder en base64, hacher un mot de passe en sha512, interroger un JSON avec json_query et manipuler des CIDR.
dsoxlab start ecrire-code-filtres-jinja-avances -
Tests Jinja2 : is defined, is mapping, is sequence
Tester la définition et le type d'une variable, matcher une regex avec is match et is search, et combiner ces tests dans when et {% if %}.
dsoxlab start ecrire-code-tests-jinja -
Module template : validate, backup, whitespace
Générer une config depuis un template Jinja2, rejeter une syntaxe invalide avec validate, sauvegarder l'ancienne et poser mode, owner et group.
dsoxlab start ecrire-code-module-template -
lineinfile vs template : quand utiliser quoi
Arbitrer entre lineinfile, blockinfile et template, les combiner (base plus overrides) et diagnostiquer un lineinfile qui empile faute de regexp.
dsoxlab start ecrire-code-lineinfile-vs-template -
Import vs include : statique ou dynamique
Choisir entre import_* parsé au démarrage et include_* résolu au runtime, et observer comment tags et when changent de comportement selon le cas.
dsoxlab start ecrire-code-import-include
Modules de fichiers
-
Module copy : transférer fichiers et contenu inline
Transférer un fichier avec src: ou écrire un contenu inline avec content:, en maîtrisant mode, owner, backup et validate.
dsoxlab start modules-fichiers-copy -
Module file : états, permissions et liens symboliques
Gérer l'état d'un fichier ou d'un répertoire (directory, absent, link, hard, touch), les permissions récursives et les liens symboliques.
dsoxlab start modules-fichiers-file -
Module blockinfile : bloc multi-lignes idempotent
Insérer et maintenir un bloc multi-lignes dans un fichier existant avec markers personnalisés, insertafter/insertbefore et idempotence.
dsoxlab start modules-fichiers-blockinfile -
Module lineinfile : modifier une ligne dans un fichier
Ajouter, remplacer par regexp ou supprimer une ligne d'un fichier de configuration, avec backrefs et validation de syntaxe avant écriture.
dsoxlab start modules-fichiers-lineinfile -
Module replace : remplacer un motif dans un fichier
Substituer un motif regex dans tout un fichier, borner la zone avec before/after et préserver une partie via groupes de capture.
dsoxlab start modules-fichiers-replace -
Module fetch : rapatrier des fichiers des managed nodes
Collecter logs et configurations des managed nodes vers le control node, en arborescence par hôte ou en mode flat avec inventory_hostname.
dsoxlab start modules-fichiers-fetch -
Modules archive et unarchive : compresser et extraire
Créer une archive tar.gz sur le managed node et extraire des tarballs locaux, distants ou déjà présents, de façon idempotente avec creates.
dsoxlab start modules-fichiers-archive-unarchive
Modules de paquets
-
Module package : installation agnostique multi-distro
Installer et désinstaller des paquets sans dépendre du gestionnaire de la distribution, en pesant state: present contre state: latest.
dsoxlab start modules-paquets-package -
Module dnf : enablerepo, security, exclude, autoremove
Activer un repo à la volée, patcher uniquement les CVE, exclure le kernel d'un upgrade massif et nettoyer les dépendances orphelines.
dsoxlab start modules-paquets-dnf-options -
Module yum_repository : déclarer un dépôt RPM
Déclarer un dépôt yum/dnf avec gpgcheck, importer sa clé GPG via rpm_key et désactiver un dépôt sans le supprimer.
dsoxlab start modules-paquets-yum-repository
Modules de services
-
Module systemd_service : gérer les services systemd
Démarrer, activer, recharger et masquer des services, déposer un unit file custom avec daemon_reload et notifier un service depuis un handler.
dsoxlab start modules-services-systemd -
Module cron : planifier des jobs idempotents
Planifier des jobs cron idempotents via crontab user ou /etc/cron.d, avec variables d'environnement et désactivation propre.
dsoxlab start modules-services-cron
Modules d'utilisateurs
-
Module user : créer, modifier et supprimer des comptes
Créer des comptes avec home, shell et groupes secondaires, hasher un mot de passe, forcer un UID et supprimer un compte avec son home.
dsoxlab start modules-utilisateurs-user -
Module group : gérer les groupes Linux
Créer des groupes avec GID forcé, distinguer groupe système et groupe utilisateur, et créer le groupe avant les utilisateurs qui le référencent.
dsoxlab start modules-utilisateurs-group -
Module authorized_key : clés SSH des utilisateurs
Provisionner des clés SSH publiques, forcer une liste exclusive, restreindre une clé avec key_options et traiter plusieurs users avec subelements.
dsoxlab start modules-utilisateurs-authorized-key -
Module sudoers : gérer les droits sudo sans risque
Créer des règles dans /etc/sudoers.d/ avec validation visudo, limiter les commandes autorisées et gérer nopassword sur un groupe.
dsoxlab start modules-utilisateurs-sudoers
Modules RHEL
-
Module firewalld : gérer le pare-feu RHEL
Autoriser services prédéfinis et ports custom par zone, avec le piège permanent + immediate et la recharge du pare-feu.
dsoxlab start modules-rhel-firewalld -
Module sysctl : paramètres kernel persistés
Modifier des paramètres kernel (ip_forward, tcp_syncookies, swappiness) avec application immédiate et persistance via /etc/sysctl.d/.
dsoxlab start modules-rhel-sysctl -
Module selinux : modes, booléens et contextes
Passer SELinux en enforcing, modifier un booléen avec persistance et poser un contexte custom avec sefcontext puis restorecon.
dsoxlab start modules-rhel-selinux -
Module mount : gérer fstab et les montages
Gérer les 5 états de mount, monter un loop device, poser des options noatime/nodev/nosuid et faire survivre un montage au reboot.
dsoxlab start modules-rhel-mount -
Module parted : créer une partition disque
Créer des partitions alignées en MBR ou GPT de façon idempotente, poser des flags (lvm, boot, esp) et inspecter la table existante.
dsoxlab start modules-rhel-parted -
Module filesystem : créer un système de fichiers
Formater des partitions en ext4 et xfs, choisir le bon fstype selon l'usage et forcer une recréation avec force: true.
dsoxlab start modules-rhel-filesystem -
LVM : chaîner lvg, lvol, filesystem et mount
Construire un PV, un VG et un LV sur un disque secondaire, le formater, le monter via fstab et l'étendre à chaud avec resizefs.
dsoxlab start modules-rhel-lvm-storage
Modules réseau
-
Module get_url : télécharger un fichier HTTP/HTTPS
Télécharger un fichier sur le managed node de façon idempotente, vérifier son intégrité par checksum sha256 et authentifier la requête.
dsoxlab start modules-reseau-get-url -
Module uri : appels API REST
Appeler une API REST en GET/POST avec body JSON, accepter plusieurs status_code et boucler un healthcheck avec until/retries.
dsoxlab start modules-reseau-uri
Modules de diagnostic
-
Module stat : inspecter fichiers et dossiers
Vérifier existence, type, taille, mode et checksum d'un fichier sans le modifier, pour piloter une logique conditionnelle.
dsoxlab start modules-diagnostic-stat -
Module find : recherche multi-fichiers
Rechercher des fichiers par glob, regex, âge, taille et type, puis enchaîner loop et file pour un cleanup ciblé et idempotent.
dsoxlab start modules-diagnostic-find -
Modules assert et fail : validation défensive
Valider les prérequis en début de play, personnaliser fail_msg et success_msg, et échouer explicitement sur une branche d'erreur.
dsoxlab start modules-diagnostic-assert-fail -
Modules wait_for et pause : synchronisation
Attendre l'ouverture ou la fermeture d'un port TCP, l'apparition d'un fichier ou d'une regex, et marquer une pause simple ou interactive.
dsoxlab start modules-diagnostic-wait-for-pause
Inventaires
-
Écrire un inventaire statique de zéro : groupes, enfants et variables de groupe
Rédiger un inventaire statique Ansible à la main : déclarer des groupes d'hôtes, un groupe parent avec enfants, et des variables de groupe, puis prouver l'inventaire résolu avec ansible-inventory et ansible -m ping.
dsoxlab start inventaires-statiques -
group_vars et host_vars : structurer les variables
Répartir les variables d'inventaire entre all, groupe et host, puis vérifier la valeur résolue avec ansible-inventory --host.
dsoxlab start inventaires-group-vars-host-vars -
Patterns d'hôtes : wildcards et opérateurs :, &, !
Cibler exactement les hôtes voulus avec --limit et les opérateurs union, intersection et exclusion, sans toucher au playbook.
dsoxlab start inventaires-patterns-hotes -
Inventaire dynamique KVM avec community.libvirt
Découvrir automatiquement les VMs libvirt via le plugin d'inventaire, créer des groupes Jinja et keyed_groups, sans inventaire manuel.
dsoxlab start inventaires-dynamique-kvm
Rôles
-
Créer son premier rôle avec ansible-galaxy role init
Générer la structure d'un rôle webserver, remplir tasks, defaults, handlers et meta, puis l'appeler depuis un playbook avec roles:.
dsoxlab start roles-creer-premier-role -
Variables d'un rôle : defaults/ vs vars/ et précédence
Répartir les variables entre defaults/ (surchargeables) et vars/ (internes), les brancher aux tâches et à un template Jinja2, puis vérifier la précédence.
dsoxlab start roles-variables-defaults-vars -
Handlers et meta d'un rôle : notify et galaxy_info
Écrire plusieurs handlers (service et non-service), les déclencher avec notify, arbitrer restarted vs reloaded, puis compléter meta/main.yml pour Galaxy.
dsoxlab start roles-handlers-meta -
argument_specs : valider les variables d'entrée d'un rôle
Écrire meta/argument_specs.yml pour typer, contraindre et documenter les variables d'entrée, puis observer le rejet automatique d'une entrée invalide.
dsoxlab start roles-argument-specs -
Consommer un rôle : roles:, import_role, include_role
Appeler un même rôle des trois façons possibles et choisir entre statique et dynamique, notamment quand un when: entre en jeu.
dsoxlab start roles-consommer-role -
Dépendances entre rôles via meta/main.yml
Chaîner des rôles avec dependencies:, leur passer des variables, maîtriser l'ordre d'exécution et éviter le piège du diamant avec allow_duplicates.
dsoxlab start roles-dependencies -
Rôles système RHEL : converger la synchronisation horaire avec timesync
Consommer un rôle éditeur de linux-system-roles : piloter chronyd sur db1.lab par les variables de timesync, sans écrire chrony.conf à la main.
dsoxlab start roles-system-roles
Galaxy et publication
-
CLI ansible-galaxy : init, install, list, build, publish
Initialiser un rôle et une collection, installer depuis Galaxy ou Git, lister l'existant, builder un tarball et publier avec un token API.
dsoxlab start galaxy-ansible-galaxy-cli -
Installer rôles et collections depuis Galaxy ou Git
Écrire un requirements.yml mêlant rôles Galaxy, sources Git et collections, épingler chaque version et vendoriser un rôle pour un projet reproductible.
dsoxlab start galaxy-installer-roles
Ansible Vault
-
Ansible Vault : chiffrer un premier fichier de secrets
Chiffrer un fichier YAML avec ansible-vault, le consulter, l'éditer, le consommer dans un playbook, puis le rekey et le déchiffrer.
dsoxlab start vault-introduction -
encrypt_string ou chiffrement du fichier entier
Chiffrer une valeur isolée avec encrypt_string, la mêler à des variables en clair via le tag !vault, et arbitrer entre inline et fichier complet.
dsoxlab start vault-chiffrer-fichier-variable -
Vault-ids multiples : isoler dev, staging et prod
Chiffrer chaque environnement avec un vault-id étiqueté, déchiffrer plusieurs vault-ids dans un même run et organiser les group_vars par environnement.
dsoxlab start vault-id-multiples -
Playbooks mixtes : main.yml et vault.yml par groupe
Séparer variables publiques et secrets dans chaque group_vars, adopter la convention vault_*, et vérifier qu'Ansible fusionne les deux fichiers sans effort.
dsoxlab start vault-playbooks-mixtes -
Vault dans un rôle : defaults en clair, vars chiffré
Exposer dans defaults/main.yml des variables publiques qui pointent vers des vault_* d'un vars/main.yml chiffré, et les surcharger depuis le playbook.
dsoxlab start vault-dans-roles -
Récupérer des secrets depuis HashiCorp Vault ou OpenBao
Démarrer un Vault local, y stocker un secret, le lire depuis Ansible avec community.hashi_vault, et comparer les auth token, AppRole et JWT.
dsoxlab start vault-integration-hashicorp -
Récupérer des secrets depuis Passbolt
Démarrer un Passbolt CE local, l'authentifier par clé OpenPGP, lire un secret depuis Ansible et comparer le modèle Passbolt à HashiCorp Vault.
dsoxlab start vault-integration-passbolt
Dépannage
-
Niveaux de verbosité et callback plugins
Choisir le niveau -v adapté au symptôme, activer profile_tasks et la sortie YAML (callback_result_format), et constater ce qu'un no_log manquant laisse fuiter.
dsoxlab start troubleshooting-verbosite -
Débogueur interactif : debugger: on_failed
Activer le débogueur sur échec, inspecter task, task_vars et result dans le REPL, corriger les arguments à chaud puis rejouer la tâche avec redo.
dsoxlab start troubleshooting-debugger -
Réparer l'idempotence cassée et optimiser les performances
Rendre idempotent un shell avec creates ou changed_when, mesurer un baseline avec profile_tasks, puis activer pipelining, forks et ControlPersist.
dsoxlab start troubleshooting-idempotence-perfs
Collections
-
Explorer les collections Ansible : FQCN et structure
Lister et inspecter les collections installées, lire un galaxy.yml, parcourir la structure plugins/roles/playbooks et retrouver un module par son FQCN.
dsoxlab start collections-decouvrir -
Automation content navigator : découvrir un module dans une collection et l'utiliser
Utiliser ansible-navigator pour trouver un module dans une collection installée, l'appliquer pour produire un état kernel vérifiable sur db1.lab, puis valider un inventaire avec ansible-navigator inventory.
dsoxlab start collections-navigator -
requirements.yml multi-sources et signatures GPG
Déclarer quatre sources dans un requirements.yml, épingler chaque version, vérifier l'intégrité et cibler plusieurs serveurs Galaxy.
dsoxlab start collections-requirements
Pratiques avancées
-
Versionner ses playbooks avec Git
Initialiser un dépôt Git pour ses playbooks, les suivre et les committer, puis les pousser vers un dépôt bare local : le geste exact attendu à l'EX294, sans forge à monter.
dsoxlab start pratiques-versionner-git
Examen RHCE EX294
-
Examen blanc RHCE EX294 : 18 tâches en 4 heures
Traiter sous chrono 18 tâches couvrant inventaires, variables, vault, fichiers, paquets, services, rôles, gestion d'erreur, déploiement par vagues, délégation, tags, tâches planifiées et facts personnalisés, chacune validée par pytest.
dsoxlab start rhce-mock-ex294 -
Examen blanc RHCE EX294 #2
Un second examen blanc EX294 complet et chronométré : les 19 mêmes catégories que le mock #1, mais toutes les valeurs concrètes changent (pile Apache/valkey, autres utilisateurs, autre découpage LVM, autres ports, autre booléen SELinux, autre horaire de cron, autre collection). Rien ne se recopie de mémoire. Chaque tâche est prouvée par pytest.
dsoxlab start rhce-mock-ex294-2