Files
ansible-role-remote_users_fact/README.md
T

5.7 KiB

remote_users_fact

Rôle Ansible qui gère un local fact comptant les sessions distantes par protocole (SSH, Citrix, Horizon) et évaluant la fiabilité en comparant avec who.

Gestion du state

Le rôle est piloté par la variable remote_users_fact_state :

State Comportement
noop (défaut) Aucune action — le rôle ne touche à rien
present Déploie le fact, valide le JSON, affiche le résumé
absent Supprime le fact, purge ansible_local, nettoie le répertoire si vide

Le state peut être défini à tout niveau (all, groupe, hôte, extra-vars). noop par défaut garantit qu'un hôte ajouté à l'inventaire sans configuration explicite ne sera pas impacté.

Arborescence

├── site.yml                          # Playbook principal
├── inventories/
│   └── hosts.yml                     # Inventaire exemple
└── roles/
    └── remote_users_fact/
        ├── defaults/main.yml         # Variables (dont state)
        ├── files/remote_users.fact   # Script fact
        ├── handlers/main.yml         # Rechargement facts
        ├── meta/main.yml             # Métadonnées Galaxy
        └── tasks/
            ├── main.yml              # Assertions → routage par state
            ├── assert.yml            # Validation stricte du paramétrage
            ├── present.yml           # Déploiement (state=present)
            ├── absent.yml            # Suppression (state=absent)
            ├── validate.yml          # Exécution + assert structure JSON
            └── summary.yml           # Affichage matrice + alertes

Usage

# Appliquer le state défini dans l'inventaire
ansible-playbook -i inventories/hosts.yml site.yml

# Forcer le déploiement partout (override)
ansible-playbook -i inventories/hosts.yml site.yml -e remote_users_fact_state=present

# Supprimer partout
ansible-playbook -i inventories/hosts.yml site.yml -e remote_users_fact_state=absent

# Sur un groupe spécifique
ansible-playbook -i inventories/hosts.yml site.yml -l citrix_servers

# Tags disponibles
ansible-playbook ... --tags assert           # Assertions seules
ansible-playbook ... --tags present,deploy   # Déploiement seul
ansible-playbook ... --tags validate         # Validation seule
ansible-playbook ... --tags summary          # Résumé seul
ansible-playbook ... --tags absent,remove    # Suppression seule

Variables

Variable Défaut Description
remote_users_fact_state noop present / absent / noop
remote_users_fact_dir /etc/ansible/facts.d Répertoire de destination
remote_users_fact_name remote_users.fact Nom du script
remote_users_fact_owner root Propriétaire
remote_users_fact_group root Groupe
remote_users_fact_validate true Activer la validation post-deploy
remote_users_fact_display_summary true Afficher le résumé
remote_users_fact_warn_verdicts voir defaults Verdicts déclenchant un warning

Assertions

Le rôle valide le paramétrage avant toute action :

  • remote_users_fact_state est défini et vaut present, absent ou noop
  • remote_users_fact_dir est un chemin absolu (si state != noop)
  • remote_users_fact_name respecte le pattern *.fact (si state != noop)
  • remote_users_fact_owner et group sont définis (si state == present)
  • remote_users_fact_validate et display_summary sont des booléens
  • remote_users_fact_warn_verdicts est une liste de verdicts valides

En cas de state present, la validation post-déploiement vérifie aussi :

  • Le script s'exécute sans erreur (rc == 0)
  • La sortie est du JSON parsable
  • Toutes les clés obligatoires sont présentes
  • Les compteurs sont >= 0
  • total_by_protocol == ssh + citrix + horizon
  • Le verdict est dans la liste des verdicts connus
  • Le fact est chargé dans ansible_local

Fact déployé

Accessible via ansible_local.remote_users :

{
  "timestamp": "2026-04-13T10:30:00Z",
  "sessions": {
    "ssh": 3,
    "citrix": 12,
    "horizon": 0,
    "total_by_protocol": 15,
    "who_remote": 14
  },
  "users_remote": "alice,bob,charlie",
  "reliability": {
    "ratio_who_over_total": 0.93,
    "verdict": "WHO_INF_TOTAL",
    "detail": "who manque 1 session(s) sans TTY"
  },
  "detection": {
    "citrix_vda_installed": true,
    "horizon_agent_installed": false,
    "ssh_method": "sshd_process_and_ss",
    "citrix_method": "ctxquery",
    "horizon_method": "fallback_ports"
  }
}

Verdicts

Verdict Signification
FIABLE who == total → compteurs alignés
OK Écart <= 1 → tolérable
WHO_SUP_TOTAL who > total → protocole non surveillé
WHO_INF_TOTAL who < total → sessions headless sans TTY
WHO_SEUL total == 0 → protocoles non détectés
PROTO_SEUL who == 0 → sessions sans allocation TTY
NEUTRE 0 == 0 → aucune session

Exemple d'inventaire avec states

all:
  vars:
    remote_users_fact_state: present    # Défaut global

  children:
    prod_servers:
      hosts:
        srv-01: {}
        srv-02: {}

    # Hôte exclu
    dev_servers:
      hosts:
        dev-01:
          remote_users_fact_state: noop

    # Groupe en décommission
    legacy:
      vars:
        remote_users_fact_state: absent

Utilisation dans d'autres playbooks

- hosts: all
  gather_facts: true
  tasks:
    - name: Bloquer un déploiement si trop de sessions
      ansible.builtin.fail:
        msg: "{{ ansible_local.remote_users.sessions.total_by_protocol }} sessions actives"
      when:
        - ansible_local.remote_users is defined
        - ansible_local.remote_users.sessions.total_by_protocol | int > 10