Aller au contenu
Infrastructure as Code medium

Module user Ansible : créer, modifier, supprimer des utilisateurs

55 min de lecture

Logo Ansible

ansible.builtin.user: gère les utilisateurs Linux : création, modification (shell, home, groupes), hashage de password, suppression. C'est le module n°1 pour l'onboarding de membres d'équipe et le provisioning de comptes applicatifs.

Options critiques RHCE 2026 : name:, state:, shell:, groups: + append:, password: (avec password_hash), uid:, comment:, remove: sur state: absent.

  • Créer un utilisateur avec home, shell, groupes secondaires.
  • Hasher un password avec password_hash('sha512') pour le stockage idempotent.
  • Distinguer groups: + append: true (ajouter) vs groups: seul (remplacer, danger).
  • Forcer un uid: précis pour les comptes système / applicatifs (cohérence multi-hôtes).
  • Supprimer un compte avec remove: true (qui supprime aussi le home).
  • Avoir become: true configuré (création d'user nécessite root).
  • Avoir lu Module group, créer le groupe avant l'user qui le référence.
- name: Creer alice
ansible.builtin.user:
name: alice
comment: "Alice, admin RHCE 2026"
shell: /bin/bash
state: present

À la première exécution : useradd alice -c "Alice, admin RHCE 2026" -s /bin/bash est lancé. Ansible crée le home /home/alice/, génère un groupe primaire alice (UID = GID = premier libre ≥ 1000).

Idempotence : 2e run → changed=0. Ansible vérifie chaque attribut et n'agit que sur ce qui diffère.

Le piège n°1 du module user: est l'oubli de append: true lors de la modification.

# ❌ DANGER : remplace TOUS les groupes secondaires
- name: Gérer le compte bob
ansible.builtin.user:
name: bob
groups: [video]
# ✅ CORRECT : ajoute video sans toucher aux autres
- name: Gérer le compte bob
ansible.builtin.user:
name: bob
groups: [video]
append: true

Sans append: true, si bob était dans [wheel, docker, sudo], après la 1ère tâche il est uniquement dans video. Bob a perdu wheel et docker sans alerte.

Règle : pour modifier les groupes d'un utilisateur existant, toujours append: true. La seule exception : remise à zéro intentionnelle des droits (offboarding).

# Pattern naif (casse l idempotence)
- name: Gérer le compte charlie
ansible.builtin.user:
name: charlie
password: "{{ 'PasswordEnClair' | password_hash('sha512') }}"

Sans salt fixe, password_hash('sha512') génère un hash différent à chaque run → tâche toujours changed.

Pattern propre (RHCE) : générer le hash une fois et le stocker dans host_vars/ (avec Vault).

# host_vars/db1.lab.yml (chiffre avec ansible-vault)
charlie_password_hash: "$6$randomsalt$hashvalue..."
# Dans le playbook :
- name: Gérer le compte charlie
ansible.builtin.user:
name: charlie
password: "{{ charlie_password_hash }}"

Pour générer le hash en CLI :

Fenêtre de terminal
mkpasswd -m sha-512 'PasswordEnClair'
# ou
python3 -c "import crypt; print(crypt.crypt('PasswordEnClair', crypt.mksalt(crypt.METHOD_SHA512)))"

update_password: on_create complète le pattern : ne touche au password que si l'user est nouvellement créé, pas s'il existe déjà.

- name: Compte applicatif deploy avec UID 2000
ansible.builtin.user:
name: deploy
uid: 2000
group: deploy
home: /opt/deploy
create_home: true
shell: /bin/bash

Pourquoi forcer l'UID ? Sur 50 hôtes, useradd auto-attribue le premier UID libre. Si web1 a deploy=1001 et web2 a deploy=1002, un fichier monté en NFS appartenant à 1001 sera inaccessible par deploy sur web2.

uid: force la cohérence. Si l'UID est déjà pris par un autre user, la tâche failed (pas de collision silencieuse).

Convention RHEL :

  • UID < 1000 : comptes système (system: true).
  • UID 1000-2000 : utilisateurs humains.
  • UID 2000+ : comptes applicatifs (réservé par convention).

Tous les attributs sauf name peuvent être modifiés :

- name: Changer le shell de alice
ansible.builtin.user:
name: alice
shell: /bin/zsh
- name: Modifier le commentaire
ansible.builtin.user:
name: alice
comment: "Alice, promue lead admin"

Ansible exécute usermod -s /bin/zsh alice et usermod -c "..." alice. Idempotent : 2e run → ok si valeurs identiques.

# Suppression sans nettoyer le home (defaut)
- name: Gérer le compte charlie
ansible.builtin.user:
name: charlie
state: absent
remove: false
# Suppression complete (home + spool mail)
- name: Gérer le compte charlie
ansible.builtin.user:
name: charlie
state: absent
remove: true

remove: false (défaut) = userdel charlie → home /home/charlie/ conservé. Pattern d'audit-friendly : on peut récupérer les fichiers du compte supprimé.

remove: true = userdel -r charlie → home + mail supprimés. Pour le nettoyage final après archivage des données.

SymptômeCauseFix
Bob a perdu ses droits sudo après modifOubli de append: true sur groups:Toujours append: true en modification
changed=1 à chaque run sur le passwordpassword_hash sans salt fixeStocker le hash dans host_vars/ (Vault)
Conflit d'UID entre hôtesPas de uid: forcéForcer uid: sur les comptes applicatifs
Home reste après state: absentremove: false (défaut)Ajouter remove: true pour nettoyer
Tâche failed "uid already exists"UID déjà utilisé par un autre userChoisir un UID libre, ou résoudre le conflit
  • name: est la clé d'identification, ne jamais modifier.
  • groups: + append: true pour ajouter, pas remplacer.
  • password: = hash SHA-512, idéalement stocké dans host_vars/ (Vault).
  • uid: forcé sur les comptes système / applicatifs (cohérence multi-hôtes).
  • remove: true sur state: absent pour supprimer le home.
  • Création de groupe AVANT création de l'user qui le référence.

La perte silencieuse de groupes secondaires ne se voit qu'en relisant le compte une fois le playbook terminé. Le lab vous fait créer un groupe puis plusieurs comptes sur une machine réelle : un administrateur rattaché à un groupe existant, un compte porteur d'un UID forcé, et un compte applicatif dont le home sort de /home. La vérification interroge la cible pour confirmer chaque UID attribué, les groupes secondaires conservés, le home et le shell attendus.

  • Module authorized_key : provisionner les clés SSH des comptes que vous venez de créer, avec leurs restrictions.
  • Module sudoers : donner à ces comptes des droits d'élévation limités aux seules commandes nécessaires.
  • Module getent : lire passwd et group sur la cible pour conditionner une tâche à l'existence d'un compte.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn