Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

🔧 Ansible – Automatisation, Playbooks & DĂ©ploiement Django

Guide complet IDEO‑Lab : Agentless, Inventaire, Playbooks, Roles & Vault.

1.1 Facile

Vue d'ensemble

Automatisation (IaC), Push, Agentless (SSH).

IaC Agentless
1.2 Facile

Architecture

Control Node -> (SSH) -> Managed Nodes.

Control Node Managed Node
1.3 Facile

Installation (Control Node)

pip install ansible (reco), apt, dnf.

pip Python
1.4 Moyen

Setup Connexion (SSH)

Prérequis : ssh-keygen, ssh-copy-id.

ssh-copy-id SSH
2.1 Facile

Inventaire (Format INI)

inventory.ini, groupes, [all:vars].

Inventory INI
2.2 Moyen

Inventaire (Format YAML)

Syntaxe YAML, groupes imbriqués.

Inventory YAML
2.3 Facile

Commandes Ad-Hoc

ansible [hosts] -m [module] (ping, shell, apt).

ansible Ad-Hoc
3.1 Facile

Anatomie (Playbook)

YAML, hosts, become, tasks, Idempotence.

Playbook YAML
3.2 Moyen

Modules Clés (SystÚme)

apt, dnf, systemd, user, file, copy.

apt systemd file
3.3 Moyen

Exemple : Playbook Django

git, pip (requirements.txt), command (migrate).

Django git pip
3.4 Moyen

Variables (vars)

vars:, vars_files:, -e (extra-vars).

vars {{ my_var }}
3.5 Moyen

Boucles & Conditions

loop:, when:, ansible_facts.

loop when
4.1 Moyen

Handlers (Notification)

notify:, handlers: (ex: restart nginx).

handlers notify
4.2 Avancé

Templates (Jinja2)

template:, .j2, {{}}, {%%}.

template Jinja2
4.3 Avancé

Roles (Architecture)

ansible-galaxy init, tasks/, vars/, handlers/.

Roles ansible-galaxy
4.4 Avancé

Ansible Vault (Secrets)

ansible-vault create, --ask-vault-pass.

Vault Secrets
5.1 Facile

Cheat-sheet

ansible, ansible-playbook, flags (-i, -l, --check).

cheat ansible-playbook
1.1 Vue d'ensemble : L'automatisation "Agentless"
Gestion de Configuration (IaC)

Ansible est un outil d'automatisation IT open-source (Red Hat) qui gÚre la **configuration des serveurs** (Configuration Management) et le **déploiement d'applications** (Application Deployment).

Il s'inscrit dans la philosophie **IaC (Infrastructure as Code)** : la configuration de vos serveurs (quoi installer, quels fichiers copier, quels services démarrer) est écrite dans des fichiers (YAML), versionnée dans Git, et reproductible.

ProblĂšme rĂ©solu : Éviter le "Configuration Drift" (dĂ©rive de configuration), oĂč chaque serveur de production est lĂ©gĂšrement diffĂ©rent car configurĂ© Ă  la main.

"Agentless" (Sans Agent)

C'est la caractéristique principale d'Ansible, qui le différencie de ses concurrents (Puppet, Chef).

ModĂšle "Agent" (ex: Puppet)

Vous devez installer un "Agent" (un service) sur *chaque* serveur. Cet agent contacte un "Master" (serveur central) pour "tirer" (Pull) sa configuration. Lourd Ă  mettre en place.

ModĂšle "Agentless" (Ansible)

Il n'y a **rien Ă  installer** sur les serveurs cibles (Managed Nodes).

Ansible fonctionne en mode **Push** :

  1. Il se connecte Ă  vos serveurs via SSH (standard Linux).
  2. Il copie un petit module Python temporaire (en JSON).
  3. Il exécute le module (ex: `apt install nginx`).
  4. Il rĂ©cupĂšre le rĂ©sultat (OK/ChangĂ©/Échec).
  5. Il supprime le module.

Prérequis : Un accÚs SSH (port 22) et un interpréteur Python (déjà présent sur 99% des Linux).

1.2 Architecture : Control Node & Managed Nodes
Les 3 Composants Clés
  1. Control Node (NƓud de ContrĂŽle) : Votre machine (ex: votre PC ou un bastion) oĂč Ansible est **installĂ©**. C'est d'ici que vous lancez les commandes ansible-playbook.
  2. Managed Nodes (NƓuds GĂ©rĂ©s) : Vos serveurs cibles (Web, BDD...). Ils n'ont *rien* d'installĂ©, juste un accĂšs SSH.
  3. Inventory (Inventaire) : Un simple fichier (INI ou YAML) sur le Control Node qui liste les IPs/DNS des Managed Nodes et les organise en groupes (ex: [webservers], [dbservers]).
Schéma de flux (SSH)
[Image d'une architecture Ansible]

+-----------------------+
| Control Node          |
| (Votre PC / Bastion)  |
|                       |
| - Ansible (Installé)  |
| - Inventory (fichier) |
| - Playbook.yml        |
+-----------------------+
      |
      | (ansible-playbook -i inventory playbook.yml)
      |
      | (Connexion SSH, Port 22)
      |
      +-----------------+-----------------+
      |                 |                 |
      ▌                 ▌                 ▌
+-----------+     +-----------+     +-----------+
| Managed 1 |     | Managed 2 |     | Managed 3 |
| (Web 1)   |     | (Web 2)   |     | (DB 1)    |
| (Python)  |     | (Python)  |     | (Python)  |
+-----------+     +-----------+     +-----------+
1.3 Installation (Control Node)
Méthode pip (Python venv)

(Recommandé) Permet d'isoler Ansible et ses dépendances dans un environnement virtuel, et d'avoir la version la plus récente.

# 1. Créer un dossier pour votre config IaC
mkdir ~/ansible_project && cd ~/ansible_project

# 2. Créer un venv Python
python3 -m venv .venv
source .venv/bin/activate

# 3. Installer Ansible (et 'ansible-lint' pour le debug)
pip install ansible ansible-lint
Méthode "Paquet SystÚme" (Simple, mais souvent obsolÚte)
Ubuntu / Debian
sudo apt update
sudo apt install -y ansible
RHEL / Rocky / AlmaLinux
# (Nécessite EPEL ou repo Ansible)
sudo dnf install -y epel-release
sudo dnf install -y ansible-core
1.4 Prérequis : Clés SSH (ssh-copy-id)

Ansible utilise SSH. Pour éviter de taper un mot de passe à *chaque* connexion, on utilise un échange de clés SSH.

1. (Sur le Control Node) Générer une clé

Si vous n'en avez pas déjà une (ls ~/.ssh/id_rsa.pub).

# (Appuyez 'Entrée' 3 fois pour accepter les défauts)
ssh-keygen -t rsa -b 4096
# (Crée id_rsa (privée) et id_rsa.pub (publique))
2. (Sur le Control Node) Copier la clé vers les Cibles

ssh-copy-id copie votre clé publique (id_rsa.pub) dans ~/.ssh/authorized_keys du serveur distant.

# (À faire 1 fois pour chaque serveur)
# (Utilisez l'utilisateur que vous utiliserez pour Ansible, ex: 'ideo_user')
ssh-copy-id ideo_user@192.168.1.10
ssh-copy-id ideo_user@192.168.1.11

# 3. Vérifier (doit se connecter SANS mot de passe)
ssh ideo_user@192.168.1.10
2.1 Inventaire (Format INI)

Créez un fichier inventory.ini (ou hosts.ini). C'est la liste de vos serveurs.

# inventory.ini

# --- Groupe [webservers] ---
[webservers]
web1.ideolab.com      ansible_host=192.168.1.10
web2.ideolab.com      ansible_host=192.168.1.11

# --- Groupe [dbservers] ---
[dbservers]
db1.ideolab.com       ansible_host=192.168.1.12

# --- Groupe de groupes ('children') ---
[production:children]
webservers
dbservers

# --- Variables (s'appliquant Ă  tous) ---
[all:vars]
# L'utilisateur SSH Ă  utiliser (celui de ssh-copy-id)
ansible_user=ideo_user
# Utiliser sudo (devenir root)
ansible_become=true
2.2 Inventaire (Format YAML) (Avancé)

Plus moderne, permet des structures (groupes imbriqués) plus complexes.

# inventory.yml
all:
  # Variables globales (s'applique Ă  'all')
  vars:
    ansible_user: ideo_user
    ansible_become: true
  
  children:
    # Groupe 'production'
    production:
      children:
        webservers:
          hosts:
            web1.ideolab.com:
              ansible_host: 192.168.1.10
            web2.ideolab.com:
              ansible_host: 192.168.1.11
        dbservers:
          hosts:
            db1.ideolab.com:
              ansible_host: 192.168.1.12
2.3 Commandes Ad-Hoc (/usr/bin/ansible)

ansible (sans -playbook) permet de lancer une seule tĂąche rapide sur un groupe de serveurs. Parfait pour le debug ou une action simple.

Syntaxe : ansible [hosts] -i [inventaire] -m [module] -a [args]

# (On suppose inventory.ini dans le dossier)

# 1. Tester la connexion (Module 'ping')
ansible all -m ping

# 2. Exécuter une commande shell (Module 'shell')
ansible webservers -m shell -a "uptime"

# 3. Exécuter une commande (root)
ansible webservers -m shell -a "hostname" --become

# 4. Utiliser un module (Module 'apt')
ansible webservers -m apt -a "name=nginx state=present" --become

# 5. Redémarrer
ansible webservers -m systemd -a "name=nginx state=restarted" --become
3.1 Playbooks (ansible-playbook)
Le "Livre de Recettes"

Un Playbook (fichier .yml) est le cƓur d'Ansible. Il dĂ©crit un Ă©tat dĂ©sirĂ© (idempotent) pour un groupe d'hĂŽtes.

Idempotent : Si vous lancez le playbook 100 fois, le rĂ©sultat est le mĂȘme. S'il est dĂ©jĂ  Ă  l'Ă©tat dĂ©sirĂ©, Ansible ne fait rien (Statut: "OK"). S'il doit changer quelque chose, (Statut: "Changed").

deploy_nginx.yml (Anatomie)
---
# (Un Playbook est une liste de "Plays")
- name: Play 1 - Configurer les serveurs Web
  
  # 1. Cible (Groupe de l'inventaire)
  hosts: webservers
  
  # 2. Devenir 'root' (sudo)
  become: true
  
  # 3. Liste des tĂąches
  tasks:
    - name: "TĂąche 1 - Installer Nginx (Debian)"
      apt:
        name: nginx
        state: present
      when: ansible_facts['os_family'] == "Debian"
      
    - name: "TĂąche 2 - Installer Nginx (RHEL)"
      dnf:
        name: nginx
        state: present
      when: ansible_facts['os_family'] == "RedHat"
      
    - name: "Tùche 3 - Démarrer le service"
      systemd:
        name: nginx
        state: started
        enabled: true
3.2 Modules Clés (SystÚme)
Gestion de paquets (Idempotent)
- name: Installer les paquets de base
  apt:
    name: ['nginx', 'ufw', 'fail2ban']
    state: present
    update_cache: yes

- name: Supprimer un paquet
  apt:
    name: apache2
    state: absent
Gestion de Fichiers
- name: Créer un dossier web
  file:
    path: /var/www/mon_site
    state: directory
    owner: www-data
    mode: '0755'

- name: Copier un fichier local vers le serveur
  copy:
    src: ./files/mon_index.html
    dest: /var/www/mon_site/index.html
    owner: www-data
    
- name: Gérer une ligne dans un fichier
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^PasswordAuthentication'
    line: 'PasswordAuthentication no'
    state: present
Gestion de Services (systemd)
- name: S'assurer que Nginx est démarré et activé
  systemd:
    name: nginx
    state: started
    enabled: true
    daemon_reload: yes

- name: Recharger Nginx
  systemd:
    name: nginx
    state: reloaded
3.3 Exemple : Playbook Déploiement Django (Simple)
---
- name: Déployer l'application Django
  hosts: webservers
  become: true
  vars:
    project_path: /opt/ideo-lab/mon_projet
    repo_url: https://github.com/ideo-lab/mon_projet.git
    
  tasks:
    - name: "1. Installer les paquets systĂšme (Python, Git, Nginx...)"
      apt:
        name: ['python3-venv', 'python3-pip', 'git', 'nginx']
        state: present

    - name: "2. Cloner le dépÎt (Source)"
      git:
        repo: "{{ repo_url }}"
        dest: "{{ project_path }}"
        version: main # (Branche)
        force: yes

    - name: "3. Installer les dépendances Python (requirements.txt)"
      pip:
        requirements: "{{ project_path }}/requirements.txt"
        virtualenv: "{{ project_path }}/.venv"
        
    - name: "4. Lancer les migrations (via 'command')"
      command:
        cmd: "python manage.py migrate"
        chdir: "{{ project_path }}"
      environment:
        # (Charge les variables .env si besoin)
        DJANGO_SETTINGS_MODULE: "mon_projet.settings"

    - name: "5. Lancer collectstatic"
      command:
        cmd: "python manage.py collectstatic --noinput"
        chdir: "{{ project_path }}"
        
    - name: "6. (Voir 4.1) Redémarrer Gunicorn (via Handler)"
      systemd:
        name: gunicorn
        state: restarted
3.4 Variables (vars)
Variables dans le Playbook
---
- hosts: webservers
  
  # 1. Variables du Play
  vars:
    http_port: 8080
    project_path: /var/www/mon_app
    
  tasks:
    - name: Créer le dossier
      file:
        path: "{{ project_path }}"
        state: directory
        
    - name: Installer paquet
      apt:
        name: "{{ 'nginx' if http_port == 80 else 'apache2' }}"
Variables dans un Fichier (vars_files)

Déplacer les variables hors du Playbook (bonne pratique).

# vars/config.yml
http_port: 8080
project_path: /var/www/mon_app
# playbook.yml
---
- hosts: webservers
  vars_files:
    - vars/config.yml
  tasks:
    - name: Créer le dossier
      file:
        path: "{{ project_path }}"
        state: directory
Variables Externes (-e) (Priorité Max)

Passer des variables depuis la ligne de commande. Surcharge tout le reste.

ansible-playbook deploy.yml -e "http_port=9000"

# (Peut aussi charger un fichier)
ansible-playbook deploy.yml -e "@vars/prod_secrets.yml"
4.1 Handlers (Notification)
Concept

ProblÚme : Vous modifiez 10 fichiers de config Nginx. Vous ne voulez pas recharger Nginx 10 fois (lent), mais 1 seule fois, à la fin, et *seulement* si un fichier a changé.

Solution : Un "Handler" (gestionnaire) est une tùche qui n'est exécutée que si elle est "notifiée" par une autre tùche (qui a eu le statut "changed").

Exemple (Reload Nginx)
---
- hosts: webservers
  become: true
  tasks:
    - name: "Copier la config Nginx"
      copy:
        src: files/nginx.conf
        dest: /etc/nginx/nginx.conf
      # 1. Notifier le handler
      notify: Reload Nginx
      
    - name: "Copier le VHost Django"
      copy:
        src: files/django.conf
        dest: /etc/nginx/sites-available/django
      # 2. Notifier le MÊME handler
      notify: Reload Nginx
      
  # 3. Définir le Handler (à la fin du play)
  handlers:
    - name: Reload Nginx
      systemd:
        name: nginx
        state: reloaded
4.2 Templates (Jinja2)
Générer des fichiers de config

copy: est statique. Le module template: utilise le moteur **Jinja2** (le mĂȘme que Django !) pour copier un fichier en remplaçant les variables.

# playbook.yml
---
- hosts: webservers
  become: true
  vars:
    server_domain: "ideolab.com"
    app_socket: "/run/gunicorn.sock"
    
  tasks:
    - name: "Générer et copier le VHost Nginx"
      template:
        src: templates/nginx.conf.j2
        dest: "/etc/nginx/sites-available/{{ server_domain }}"
      notify: Reload Nginx
      
  handlers:
    - name: Reload Nginx
      systemd: { name: nginx, state: reloaded }
templates/nginx.conf.j2 (Template Jinja2)

(Note : La syntaxe {{ ... }} est pour échapper Django, pas pour Ansible).

server {
    listen 80;
    # Utilise la variable du 'vars:'
    server_name {{ server_domain }};

    location /static/ {
        alias /var/www/{{ server_domain }}/static/;
    }

    location / {
        proxy_pass http://unix:{{ app_socket }};
        include proxy_params;
    }
    
    # Boucle (Jinja2)
    {% for user in ['admin', 'dev'] %}
    # (Exemple de directive)
    # allow 192.168.0.{{ loop.index }};
    {% endfor %}
}
4.3 Roles (La bonne architecture)
Factoriser (DRY)

Les Playbooks deviennent illisibles. Un **Role** est une structure de dossiers standardisée pour regrouper des tùches (tasks), des variables (vars), des handlers, et des templates.

Initialiser un Role (ansible-galaxy)
ansible-galaxy init roles/nginx
# (Crée l'arborescence)
Structure (roles/nginx/)
roles/nginx/
├── tasks/
│   └── main.yml  (Tñches: apt, copy, systemd)
├── handlers/
│   └── main.yml  (Handler: "Reload Nginx")
├── templates/
│   └── nginx.conf.j2
├── vars/
│   └── main.yml  (Variables par dĂ©faut)
└── defaults/
    └── main.yml
Utiliser le Role (Playbook principal)

Le playbook devient une simple "liste de courses".

# deploy_stack.yml
---
- name: Configurer les serveurs Web
  hosts: webservers
  become: true
  
  # 1. Appliquer les RĂŽles
  roles:
    - common   # (Installe vim, git, fail2ban...)
    - nginx    # (Installe et configure Nginx via le template)
    - django   # (Installe Gunicorn, code, .env)
    
- name: Configurer les serveurs BDD
  hosts: dbservers
  become: true
  roles:
    - common
    - postgresql
4.4 Ansible Vault (Gestion des Secrets)
Stocker les Secrets

⚠ Ne **jamais** commiter (git) de mots de passe (BDD, API) en clair dans vars/main.yml.

Ansible Vault est un outil (inclus) pour chiffrer (AES-256) des fichiers YAML contenant des secrets.

Commandes ansible-vault
# 1. Créer un fichier de secrets chiffré
ansible-vault create vars/secrets.yml
# (Demande un mot de passe)

# 2. Éditer le fichier
ansible-vault edit vars/secrets.yml

# 3. Lancer le playbook (en demandant le mot de passe)
ansible-playbook deploy.yml --ask-vault-pass

# (Utiliser un fichier de mdp)
ansible-playbook deploy.yml --vault-password-file .vault_pass
Contenu de vars/secrets.yml (chiffré)
$ANSIBLE_VAULT;1.1;AES256
386634... (Données chiffrées)
Contenu (déchiffré)
db_password: "mon_pass_db"
api_key: "sk_live_..."
5.1 Cheat-sheet Ansible
Commandes Ad-Hoc (ansible)
# ( -i = inventaire, -m = module, -a = args, -b = become/sudo)

# Ping (vérifie la connexion)
ansible all -i inventory.ini -m ping

# Commande Shell
ansible webservers -i inv -m shell -a "df -h"

# Utiliser un module (ex: reboot)
ansible all -i inv -m reboot -b
Playbooks (ansible-playbook)
# Lancer un playbook
ansible-playbook -i inventory.ini deploy.yml

# Limiter Ă  un groupe (ex: web)
ansible-playbook -i inv deploy.yml -l webservers

# Limiter Ă  un host
ansible-playbook -i inv deploy.yml -l web1.ideolab.com

# (Dry Run) Voir ce qui *changerait* (ne fait rien)
ansible-playbook -i inv deploy.yml --check

# Voir les changements (diff)
ansible-playbook -i inv deploy.yml --diff

# Demander le mot de passe Vault
ansible-playbook -i inv deploy.yml --ask-vault-pass