💡 Vous arrivez directement à ce lab sans avoir fait les précédents ? Chaque lab de ce dépôt est autonome. Pré-requis unique : les 4 VMs du lab doivent répondre au ping Ansible.
cd /home/bob/Projets/ansible-training ansible all -m ansible.builtin.ping # → 4 "pong" attendusSi KO, lancez
make bootstrap && make provisionà la racine du repo (cf. README racine pour les détails).
ansible.builtin.group: gère les groupes Linux : création, suppression,
forçage du GID. Module compagnon de user: —
on crée d'abord les groupes, puis on rattache les utilisateurs.
Options principales : name:, state:, gid:, system: true
(pour les groupes système avec GID < 1000).
À la fin de ce lab, vous saurez :
- Créer un groupe simple et un groupe avec GID forcé (cohérence multi-hôtes).
- Distinguer un groupe utilisateur (GID ≥ 1000) d'un groupe système
(
system: true, GID < 1000). - Supprimer un groupe avec
state: absent(et son comportement quand des users en font encore partie). - Ordonner les tâches : créer le groupe avant l'utilisateur qui le référence.
cd /home/bob/Projets/ansible-training
ansible db1.lab -m ping
ansible db1.lab -b -m shell -a "for g in dev-team ops-team rhce-shared; do groupdel \$g 2>/dev/null; done; true"Créez lab.yml :
---
- name: Demo group simple
hosts: db1.lab
become: true
tasks:
- name: Creer le groupe dev-team
ansible.builtin.group:
name: dev-team
state: present
- name: Verifier la creation
ansible.builtin.command: getent group dev-team
register: dev_team_check
changed_when: false
- name: Afficher l entree /etc/group
ansible.builtin.debug:
var: dev_team_check.stdout
# → dev-team:x:1001:Lancez :
ansible-playbook labs/modules-utilisateurs/group/lab.yml🔍 Observation :
- 1er run :
changed=1—groupadd dev-team. - 2ème run :
changed=0— déjà présent. - Le GID est auto-attribué (premier libre ≥ 1000).
- name: Creer ops-team avec GID 3000 force
ansible.builtin.group:
name: ops-team
gid: 3000
state: present
- name: Creer rhce-shared avec GID 3001 force
ansible.builtin.group:
name: rhce-shared
gid: 3001
state: present🔍 Observation : sur 50 hôtes, ces groupes auront toujours le même GID. C'est essentiel pour :
- NFS : si un fichier appartient à
gid=3001côté serveur NFS, il faut que le client ait aussigid=3001pour pouvoir l'ouvrir. - Containers : volumes partagés entre hôte et conteneur.
- Audit : comparer les GIDs entre hôtes pour détecter une divergence.
Si le GID est déjà pris par un autre groupe : la tâche failed. Pas de collision silencieuse.
- name: Creer un groupe systeme (GID auto < 1000)
ansible.builtin.group:
name: myapp-system
system: true
state: present🔍 Observation : system: true indique à Ansible de chercher un GID < 1000
(par convention RHEL pour les groupes système). Sans system:, le GID
auto-attribué est ≥ 1000 (groupe utilisateur).
Cas d'usage : créer un groupe applicatif réservé au démon (nginx, postgres, etc.) qui ne doit pas être confondu avec un groupe utilisateur.
- name: Supprimer le groupe dev-team
ansible.builtin.group:
name: dev-team
state: absentAvant la suppression, créer un user qui utilise ce groupe :
- name: Creer carl dans dev-team (avant la suppression)
ansible.builtin.user:
name: carl
group: dev-team # Groupe primaireSi vous tentez de supprimer un groupe qui est encore le groupe primaire d'un utilisateur, la tâche failed :
groupdel: cannot remove the primary group of user 'carl'
🔍 Observation : protection système. Pour supprimer le groupe, il faut d'abord supprimer ou réassigner le user.
- name: Reassigner carl a un autre groupe primaire
ansible.builtin.user:
name: carl
group: nogroup
- name: Maintenant on peut supprimer dev-team
ansible.builtin.group:
name: dev-team
state: absentPattern classique : créer le groupe d'abord, puis les users qui le référencent.
- name: Step 1 — creer le groupe
ansible.builtin.group:
name: rhce-team
gid: 5000
state: present
- name: Step 2 — creer alice avec rhce-team comme primaire
ansible.builtin.user:
name: alice
group: rhce-team # Le groupe DOIT exister deja
state: present🔍 Observation : si vous inversez l'ordre, user: créerait alice avec un
groupe rhce-team généré automatiquement (GID auto-attribué). Puis quand
group: gid: 5000 tente de le créer, conflit entre le GID demandé (5000)
et celui généré (1001 ou autre).
Convention : dans un même play, toujours ordonner :
group:(création des groupes)user:(création des users qui les utilisent)authorized_key:(clés SSH des users — voir lab 42)lineinfile:ou autre (config sudo etc.)
- name: Tenter de changer le GID d ops-team
ansible.builtin.group:
name: ops-team
gid: 3500 # Avant : 3000🔍 Observation : la tâche réussit — groupmod -g 3500 ops-team. Mais
tous les fichiers appartenant à gid=3000 sont maintenant orphelins :
# Avant changement
$ ls -la /home/alice/data
-rw-r--r-- 1 alice ops-team 0 ... data
$ stat -c '%g' /home/alice/data
3000 ← OK
# Apres changement
$ ls -la /home/alice/data
-rw-r--r-- 1 alice 3000 0 ... data # Plus de nom !Solution : ne jamais modifier un GID d'un groupe en production. Si nécessaire :
- Supprimer le groupe.
- Recréer avec le nouveau GID.
chgrp -Rsur tous les fichiers concernés.
name:= clé d'identification.gid:forcé pour la cohérence multi-hôtes (NFS, containers, audit).system: true= groupe avec GID < 1000 (convention RHEL).- Suppression d'un groupe primaire d'un user → failed. Réassigner d'abord.
- Ordonner :
group:AVANTuser:qui le référence. - Ne pas modifier le GID d'un groupe existant — fichiers orphelins.
-
Vous avez 10 utilisateurs à créer dans
rhce-team, plus 5 dansdev-team, plus 3 dansops-team. Quel pattern (loop:surusersavec un champgroups, ou plays séparés) ? -
Pourquoi
system: trueest-il important pour un groupe applicatif (nginx,postgres) ? Quel est le risque concret d'un groupe applicatif avec GID ≥ 1000 ? -
Vous voulez garantir qu'un groupe a un GID précis sur 50 hôtes. Comment articulez-vous
group: gid:avecfailed_when:pour échouer si le GID diffère ?
Voir challenge/README.md pour la validation pytest+testinfra.
local: true: forcer la création dans/etc/groupmême si le système utilise NIS/LDAP. Utile sur des hôtes intégrés à un annuaire mais qui doivent avoir des groupes locaux.- Module
getent:: récupérer les infos d'un groupe depuis NSS (LDAP, AD, NIS) sans dépendre de/etc/grouplocal. - Pattern
groupinstall: pour des groupes liés à des paquets DNF (@web-server), c'estdnf: name: '@web-server'et pasgroup:. - Combinaison
group:+user:+authorized_key:: pattern d'inscription d'un nouveau membre dans une équipe — voir lab 42.
Avant de lancer pytest, validez la qualité de votre lab.yml et de votre
challenge/solution.yml avec ansible-lint :
# Lint de votre fichier de lab (tutoriel guidé)
ansible-lint labs/modules-utilisateurs/group/lab.yml
# Lint de votre solution challenge
ansible-lint labs/modules-utilisateurs/group/challenge/solution.yml
# Profil production (le plus strict — cible RHCE 2026)
ansible-lint --profile production labs/modules-utilisateurs/group/challenge/solution.ymlSi ansible-lint retourne Passed: 0 failure(s), 0 warning(s), votre code
est conforme aux bonnes pratiques : FQCN explicite, name: sur chaque tâche,
modes de fichier en chaîne, idempotence respectée, modules dépréciés évités.
💡 Astuce CI : intégrez
ansible-lint --profile productiondans un hook pre-commit pour bloquer tout commit qui introduirait des anti-patterns.