7.3 : Module authorized_key : distribuer des clés SSH en masse

On a créé des comptes (7.1), on les a rattachés à des groupes (7.2). Reste un problème très concret : comment ces nouveaux employés se connectent-ils, sans que vous ayez à copier-coller une clé publique dans authorized_keys à la main, serveur par serveur, comme on l’a fait dans les tout premiers TP de cette formation ?

C’est exactement ce que corrige le module authorized_key.

Rappel du problème qu’on résolvait manuellement jusqu’ici

Depuis le début de cette formation, on a systématiquement déployé une clé SSH de cette façon :

ssh root@nrd-web1
nano .ssh/authorized_keys
# Coller la clé publique à la main

Ça fonctionnait pour un lab avec un ou deux serveurs. Mais imaginez faire ça pour 15 nouveaux employés, sur 20 serveurs différents : 300 copier-coller manuels, avec un risque d’erreur ou d’oubli à chaque fois. C’est précisément le genre de tâche répétitive qu’Ansible existe pour éliminer.

Le module authorized_key

- name: Déployer la clé publique d'Alice
  ansible.posix.authorized_key:
    user: alice
    state: present
    key: "{{ lookup('file', 'files/alice_id_ed25519.pub') }}"

Décortiquons : user indique le compte cible (celui créé en 7.1), key contient le contenu de la clé publique, et lookup('file', ...) est une fonction Jinja2 qui va lire le contenu d’un fichier local sur le nœud de contrôle — ici, le fichier files/alice_id_ed25519.pub contenant la clé publique d’Alice.

ℹ️ Remarquez ansible.posix.authorized_key plutôt que ansible.builtin : ce module vient d’une collection séparée, ansible.posix, installable via Galaxy (ansible-galaxy collection install ansible.posix) si elle n’est pas déjà présente. On a vu ce principe de collections en 6.3.

Vérifier l’idempotence

Relancez la même tâche : si la clé est déjà présente dans authorized_keys, ok. Sinon, la ligne est ajoutée, changed. Contrairement au copier-coller manuel, Ansible compare le contenu réel de la clé avant d’agir — pas de risque de dupliquer la même clé plusieurs fois dans le fichier au fil des exécutions.

Distribuer plusieurs clés en une seule tâche, avec loop

Dans un vrai contexte Nordika, on ne déploie jamais une seule clé isolément — on gère l’arrivée de plusieurs employés en même temps. On combine naturellement loop (vu en section 4) :

- name: Créer les comptes des nouveaux employés
  ansible.builtin.user:
    name: "{{ item.nom }}"
    state: present
    create_home: yes
  loop:
    - { nom: "alice", cle: "alice_id_ed25519.pub" }
    - { nom: "bob", cle: "bob_id_ed25519.pub" }
  loop_control:
    label: "{{ item.nom }}"

- name: Déployer la clé publique de chacun
  ansible.posix.authorized_key:
    user: "{{ item.nom }}"
    state: present
    key: "{{ lookup('file', 'files/' + item.cle) }}"
  loop:
    - { nom: "alice", cle: "alice_id_ed25519.pub" }
    - { nom: "bob", cle: "bob_id_ed25519.pub" }
  loop_control:
    label: "{{ item.nom }}"

Une seule exécution de playbook, et toute une vague d’arrivées est provisionnée d’un coup, sur autant de serveurs que nécessaire.

Retirer l’accès d’un employé qui part

Symétriquement, state: absent retire une clé précise sans toucher aux autres :

- name: Retirer l'accès SSH d'un employé parti
  ansible.posix.authorized_key:
    user: alice
    state: absent
    key: "{{ lookup('file', 'files/alice_id_ed25519.pub') }}"

Combiné avec la suppression du compte lui-même (vue en 7.1), c’est l’ensemble du processus de départ qui peut être scripté proprement.

Où stocker les clés publiques du projet ?

Un dossier files/ à côté du playbook (ou dans le rôle, comme vu en section 6) est l’endroit naturel : ce sont des fichiers statiques, pas des templates à générer dynamiquement. Rien de sensible à protéger ici, d’ailleurs : une clé publique est, par construction, faite pour être partagée — c’est la clé privée correspondante qui ne doit jamais quitter la machine de son propriétaire.

Ce qu’il faut retenir

  • authorized_key déploie une clé publique de façon idempotente — fini le copier-coller manuel qu’on a fait jusqu’ici dans cette formation.
  • Le module vient de la collection ansible.posix, à installer via Galaxy si besoin.
  • lookup('file', ...) permet de lire le contenu d’un fichier local plutôt que de coller la clé en dur dans le playbook.
  • Combiné à loop, on provisionne l’accès de toute une vague d’employés en une seule exécution.

Dans la prochaine leçon, un aparté utile : sshpass, pour automatiser une authentification par mot de passe — utile en dépannage, mais qu’on écarte vite au profit de ce qu’on vient de voir.