# Provisionner un serveur WordPress avec Ansible, de zéro à la production

> Un playbook nginx, PHP-FPM, MariaDB, certificats et utilisateurs, rejouable à l'identique pour chaque nouveau serveur, sans jamais reconfigurer à la main.

- Auteur : Clément Hadrot
- Publié le : 2024-11-20
- Mis à jour le : 2024-11-20
- Catégorie : Outils &amp; workflow
- URL : https://wpmoderne.dev.wordpress-developpement.fr/outils/provisionner-serveur-ansible-production/

## L’essentiel

- Un playbook décrit l'état voulu, pas les commandes
- Les rôles séparent nginx, PHP, MariaDB et les certificats
- Rejouable sans risque grâce à l'idempotence

Configurer un serveur WordPress à la main — installer nginx, PHP-FPM, MariaDB, créer les utilisateurs système, générer les certificats — prend facilement une demi-journée la première fois, et redevient un exercice de mémoire incertain la fois suivante, six mois plus tard, quand il faut provisionner un nouveau serveur pour un nouveau client. Ansible résout ce problème en transformant la configuration serveur en code versionné, rejouable à l'identique.

Contrairement à un script bash qui exécute une suite de commandes, un playbook Ansible décrit un état voulu (« le paquet nginx doit être installé », « ce fichier de configuration doit avoir ce contenu ») et se charge lui-même de vérifier ce qui doit changer. Rejouer un playbook sur un serveur déjà configuré ne casse rien : c'est la propriété d'idempotence, essentielle pour oser relancer le même playbook en confiance.

## Structure d'un playbook par rôles

Un playbook bien organisé sépare chaque responsabilité dans un rôle distinct, ce qui permet de réutiliser un rôle d'un projet à l'autre sans tout dupliquer :

```
provisionnement/
├── inventaire.ini
├── site.yml
└── roles/
    ├── nginx/
    │   └── tasks/main.yml
    ├── php/
    │   └── tasks/main.yml
    ├── mariadb/
    │   └── tasks/main.yml
    └── certificats/
        └── tasks/main.yml
```

```
# inventaire.ini
[serveurs_wordpress]
srv-client-cabinet.exemple.test ansible_user=deploiement
```

## Le rôle nginx et PHP-FPM

```
# roles/nginx/tasks/main.yml
- name: Installer nginx
  apt:
    name: nginx
    state: present
    update_cache: yes

- name: Déployer la configuration du site
  template:
    src: site.conf.j2
    dest: /etc/nginx/sites-available/{{ nom_domaine }}
  notify: recharger nginx

- name: Activer le site
  file:
    src: /etc/nginx/sites-available/{{ nom_domaine }}
    dest: /etc/nginx/sites-enabled/{{ nom_domaine }}
    state: link
```

Le module `template` injecte les variables du projet (nom de domaine, chemin racine) dans un fichier de configuration Jinja2, ce qui évite de dupliquer un fichier statique par serveur. Le mot-clé `notify` déclenche un « handler » — ici un rechargement de nginx — uniquement si le fichier a réellement changé, jamais sinon.

> L'essentiel à retenir : Un playbook décrit l'état voulu, pas les commandes ; Les rôles séparent nginx, PHP, MariaDB et les certificats ; Rejouable sans risque grâce à l'idempotence

## Le rôle MariaDB et la création de la base

```
# roles/mariadb/tasks/main.yml
- name: Installer MariaDB
  apt:
    name: mariadb-server
    state: present

- name: Créer la base de données du site
  mysql_db:
    name: "{{ nom_base }}"
    state: present

- name: Créer l'utilisateur applicatif
  mysql_user:
    name: "{{ utilisateur_base }}"
    password: "{{ mot_de_passe_base }}"
    priv: "{{ nom_base }}.*:ALL"
    state: present
```

Les modules `mysql_db` et `mysql_user` font partie de la collection `community.mysql`, à installer séparément via `ansible-galaxy collection install community.mysql`. Le mot de passe de la base ne doit jamais rester en clair dans le dépôt : on le stocke chiffré avec **Ansible Vault**, qui protège tout fichier de variables sensibles derrière un mot de passe maître.

```
ansible-vault encrypt group_vars/serveurs_wordpress/secrets.yml
ansible-playbook site.yml --ask-vault-pass
```

## Certificats TLS automatisés

Le rôle certificats installe Certbot et obtient un certificat Let's Encrypt sans intervention manuelle, en utilisant le plugin nginx qui configure lui-même le renouvellement automatique :

```
# roles/certificats/tasks/main.yml
- name: Installer certbot et son plugin nginx
  apt:
    name:
      - certbot
      - python3-certbot-nginx
    state: present

- name: Obtenir le certificat
  command: >
    certbot --nginx -d {{ nom_domaine }}
    --non-interactive --agree-tos -m {{ email_contact }}
  args:
    creates: "/etc/letsencrypt/live/{{ nom_domaine }}"
```

L'argument `creates` indique à Ansible de ne relancer la commande que si le dossier de certificat n'existe pas encore, préservant l'idempotence même pour une commande shell brute.

## Créer les utilisateurs système avec les bons droits

Un dernier rôle, souvent oublié, gère les comptes système : un utilisateur applicatif dédié au déploiement, sans accès root direct, avec sa clé publique SSH ajoutée aux `authorized_keys` :

```
- name: Créer l'utilisateur de déploiement
  user:
    name: deploiement
    shell: /bin/bash
    groups: www-data
    append: yes

- name: Ajouter la clé publique de déploiement
  authorized_key:
    user: deploiement
    key: "{{ lookup('file', 'cles/deploiement.pub') }}"
```

> Un playbook qu'on ne rejoue jamais devient obsolète sans qu'on s'en aperçoive. On le relance systématiquement sur chaque serveur existant après une modification, en mode `--check` d'abord, pour voir ce qui changerait avant de l'appliquer pour de vrai.

## En résumé

Un playbook Ansible bien structuré transforme le provisionnement d'un nouveau serveur WordPress en une commande unique, reproductible et documentée par le code lui-même. Le temps investi dans les rôles nginx, PHP, MariaDB et certificats se rentabilise dès le deuxième serveur provisionné, et devient indispensable à partir du dixième.
