# Mise en place du serveur Ansible

## Le serveur Ansible, c'est quoi ?

Le serveur Ansible est le nœud de contrôle : la seule machine qui détient le dépôt, la clé SSH d'administration et le mot de passe du Vault. Les VM clientes n'ont rien d'installé en plus que SSH et Python.

<table id="bkmrk-%C3%89l%C3%A9ment-r%C3%B4le-environ"><thead><tr><th>Élément</th><th>Rôle</th></tr></thead><tbody><tr><td>Environnement virtuel Python</td><td>Isole la version d'Ansible du système</td></tr><tr><td>Clé SSH `ed25519`</td><td>Authentifie le serveur Ansible auprès des VM</td></tr><tr><td>Fichier `.vault_pass`</td><td>Contient le mot de passe de déchiffrement du Vault</td></tr></tbody></table>

**Dépôt Git → ansible-playbook → SSH (réseau d'administration) → VM client**

<p class="callout info">Note — Le serveur Ansible est le chemin des machines : il se connecte aux VM de façon automatique. Les interventions humaines, elles, passent par le bastion Teleport (voir le livre [Teleport ](https://docs.rakouns.bzh/books/teleport)et la page de présentation du projet).</p>

Concrètement, la version d'Ansible fournie par `apt` sous Debian 12 est ancienne. L'installation se fait donc dans un environnement virtuel avec `pip`, ce qui permet de figer la version et de la mettre à jour sans toucher au système.

## Prérequis

1. **Une VM Debian 12** dans le réseau d'administration (`10.99.0.2`), avec 2 Go de mémoire.
2. **Un utilisateur non-root** avec `sudo` : la suite est exécutée avec cet utilisateur.
3. **Un accès SSH** aux VM clientes par la clé publique, avec l'utilisateur `deploy` (créé lors du provisioning).

## Étape 1 : mettre le système à jour et installer les outils

```bash
# Mise à jour de l'index des paquets puis des paquets installés.
sudo apt update && sudo apt full-upgrade -y

# python3-venv : création d'environnements virtuels
# python3-pip  : installateur Python
# git          : gestion du dépôt
# jq, curl     : utiles pour interroger des API (voir la page Authentik)
sudo apt install -y python3-venv python3-pip git jq curl
```

## Étape 2 : créer l'environnement virtuel et installer Ansible

```bash
# Création du dépôt de travail. Tout le projet vivra ici.
mkdir -p ~/nebuleuse && cd ~/nebuleuse
git init

# Création de l'environnement virtuel dans un dossier caché du répertoire personnel.
python3 -m venv ~/.venv/ansible

# Activation : le prompt se préfixe de (ansible), et "pip" / "ansible" pointent
# désormais vers l'environnement virtuel.
source ~/.venv/ansible/bin/activate

```

Le fichier `requirements.txt` fige la version d'Ansible utilisée par le projet.

```text
# requirements.txt
# ansible-core : le moteur d'Ansible, sans les collections de modules (installées à part).
# La plage de versions évite une montée de version majeure involontaire.
ansible-core>=2.17,<2.19

# jmespath : requis par le filtre "json_query", utile pour exploiter les réponses d'API.
jmespath

```

```bash
pip install -r requirements.txt
ansible --version   # vérification : affiche la version et le chemin de l'interpréteur Python

```

Les collections de modules sont déclarées dans un second fichier, indépendant de la version du moteur.

```yaml
# requirements.yml
collections:
  # community.docker : modules docker_compose_v2, docker_network...
  - name: community.docker
  # community.general : modules divers (ufw, etc.) utilisés par certains rôles
  - name: community.general
  # ansible.posix : modules système (sysctl, authorized_key...)
  - name: ansible.posix

```

```bash
ansible-galaxy collection install -r requirements.yml

```

## Étape 3 : créer la clé SSH d'administration

```bash
# -t ed25519 : algorithme moderne, clés courtes et rapides
# -f         : chemin du fichier de clé
# -C         : commentaire pour reconnaître la clé dans les authorized_keys
# La clé n'a volontairement pas de passphrase : elle est utilisée par des playbooks
# non interactifs. En contrepartie, le fichier doit rester en mode 600 et le serveur
# Ansible n'est accessible que depuis le réseau d'administration.
ssh-keygen -t ed25519 -f ~/.ssh/nebuleuse_ed25519 -C "ansible@nebuleuse"

```

La clé publique (`~/.ssh/nebuleuse_ed25519.pub`) est celle que le processus de provisioning dépose dans `~deploy/.ssh/authorized_keys` de chaque VM.

## Étape 4 : le mot de passe du Vault

```bash
# Génère 32 caractères aléatoires et les écrit dans .vault_pass.
openssl rand -base64 24 > .vault_pass

# Lecture/écriture pour le propriétaire uniquement.
chmod 600 .vault_pass

```

Le fichier `.gitignore` empêche que le mot de passe du Vault parte dans le dépôt.

```text
# .gitignore
# Ne jamais versionner le mot de passe du Vault ni la clé privée.
.vault_pass
*.pem
*_ed25519

```

Note — Le mot de passe du Vault doit aussi être conservé hors du serveur Ansible (gestionnaire de mots de passe, coffre physique). Sans lui, les fichiers chiffrés sont définitivement illisibles.

## Étape 5 : le fichier de configuration `ansible.cfg`

```ini
# ansible.cfg
[defaults]
# Inventaire utilisé par défaut : évite de passer -i à chaque commande.
inventory = inventory/hosts.yml

# Dossier des rôles du projet.
roles_path = roles

# Utilisateur SSH sur les VM clientes.
remote_user = deploy

# Clé privée utilisée pour la connexion.
private_key_file = ~/.ssh/nebuleuse_ed25519

# Fichier contenant le mot de passe du Vault (créé à l'étape 4).
# Doit exister : Ansible échoue au démarrage si le fichier est introuvable.
vault_password_file = .vault_pass

# Nombre de machines traitées en parallèle.
forks = 10

# Détection automatique de l'interpréteur Python sur les cibles, sans avertissement.
interpreter_python = auto_silent

[privilege_escalation]
# Les tâches s'exécutent en root via sudo : l'utilisateur "deploy" a un sudo sans mot de passe.
become = True
become_method = sudo

[ssh_connection]
# Pipelining : réduit le nombre d'opérations SSH par tâche, donc accélère les playbooks.
pipelining = True

# ControlMaster : réutilise une connexion SSH ouverte pendant 60 s.
# accept-new : accepte la clé d'hôte d'une VM inconnue à la première connexion,
# puis refuse tout changement ultérieur (protection contre l'usurpation).
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=accept-new
```

## Étape 6 : un premier inventaire

```yaml
# inventory/hosts.yml
all:
  children:
    clients:                       # groupe regroupant toutes les VM clientes
      hosts:
        client-alpha:
          # Adresse du réseau d'administration, pas l'adresse publique.
          ansible_host: 10.99.0.21
        client-beta:
          ansible_host: 10.99.0.22
```

## Vérification

```bash
# Affiche l'arbre de l'inventaire : les deux clients doivent apparaître sous "clients".
ansible-inventory --graph

# Test de connectivité SSH et de Python (ce n'est pas un ping réseau).
ansible clients -m ansible.builtin.ping
```

Résultat attendu pour chaque client :

```text
client-alpha | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
```

## Pièges

1. **`vault_password_file` introuvable** : le message « The vault password file ... was not found » apparaît dès la première commande. Il suffit de créer `.vault_pass` (étape 4) avant tout.
2. **`Permission denied (publickey)`** : la clé publique n'est pas dans les `authorized_keys` de l'utilisateur `deploy`, ou la clé privée n'est pas en mode 600.
3. **Mauvais `ansible`** : si l'environnement virtuel n'est pas activé, la commande `ansible` appelle la version système. Le préfixe `(ansible)` du prompt sert de contrôle.
4. **Pas de `changed` sur un `ping`** : normal, ce module est en lecture seule.

Page suivante : **Inventaire et variables**.