Leçon 5 / 6
Leçon 05 · Ansible

Rôles et variables

Pourquoi utiliser des rôles ?

Au fil du temps, tes playbooks grossissent. Tu te retrouves à copier-coller les mêmes tâches d'un projet à l'autre — installer nginx, configurer un utilisateur, déployer une appli. Les rôles sont la réponse d'Ansible à ce problème.

Un rôle, c'est un bloc de code Ansible autonome et réutilisable. Tu l'écris une fois, tu l'utilises dans n'importe quel playbook. Et si tu veux partager tes rôles avec la communauté — ou en récupérer — c'est Ansible Galaxy qui s'en charge.

💡

Ansible Galaxy est le dépôt officiel de rôles communautaires. Des milliers de rôles prêts à l'emploi y sont disponibles : ansible-galaxy install geerlingguy.nginx télécharge et installe le rôle nginx de Jeff Geerling, l'un des plus utilisés.

Structure d'un rôle

Un rôle respecte une structure de dossiers conventionnelle. Ansible reconnaît et charge automatiquement chaque répertoire selon son rôle.

# Structure type d'un rôle Ansible
roles/
└── mon_role/
    ├── tasks/
    │   └── main.yml        # liste des tâches (obligatoire)
    ├── handlers/
    │   └── main.yml        # handlers (ex : restart nginx)
    ├── defaults/
    │   └── main.yml        # variables par défaut (priorité faible)
    ├── vars/
    │   └── main.yml        # variables internes (priorité haute)
    ├── templates/
    │   └── nginx.conf.j2   # templates Jinja2
    ├── files/
    │   └── app.conf        # fichiers statiques à copier
    └── meta/
        └── main.yml        # métadonnées, dépendances

Seul le dossier tasks/main.yml est obligatoire. Les autres dossiers sont optionnels : si handlers/ est absent, Ansible ne s'en plaint pas. Ne crée que ce dont tu as besoin.

Créer un rôle avec ansible-galaxy

La commande ansible-galaxy init génère automatiquement toute la structure du rôle. C'est la façon recommandée de démarrer.

# Créer un rôle nommé "nginx"
ansible-galaxy init roles/nginx

# La structure est générée instantanément :
# roles/nginx/tasks/main.yml
# roles/nginx/handlers/main.yml
# roles/nginx/defaults/main.yml
# ... etc.

# Exemple : tasks/main.yml du rôle nginx
---
# roles/nginx/tasks/main.yml

- name: Installer nginx
  ansible.builtin.apt:
    name: nginx
    state: present
    update_cache: true

- name: Déployer la configuration
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: Restart nginx

- name: Démarrer et activer nginx
  ansible.builtin.service:
    name: nginx
    state: started
    enabled: true

Utiliser un rôle dans un playbook

Dans un playbook, la clé roles remplace (ou complète) la section tasks. Ansible exécute les rôles dans l'ordre indiqué.

---
# site.yml — playbook principal

- name: Déployer les serveurs web
  hosts: webservers
  become: true

  roles:
    - nginx
    - nodejs

# Ou avec des variables par rôle :
- name: Déployer avec config custom
  hosts: webservers
  become: true

  roles:
    - role: nginx
      vars:
        nginx_port: 8080
    - role: nodejs
      vars:
        node_version: "20"

La hiérarchie des variables

Ansible peut recevoir des variables depuis de nombreuses sources. Quand une variable est définie à plusieurs endroits, c'est la priorité qui décide laquelle s'applique. Du plus faible au plus fort :

💡

Ordre de priorité (du plus faible au plus fort) : defaults/main.yml < inventaire < group_vars < host_vars < vars/main.yml < --extra-vars

---
# roles/nginx/defaults/main.yml
# Valeurs par défaut — facilement surchargées

nginx_port: 80
nginx_worker_processes: auto
nginx_log_level: warn
---
# roles/nginx/vars/main.yml
# Variables internes — priorité haute, pas destinées à être surchargées

nginx_config_dir: /etc/nginx
nginx_pid_file: /run/nginx.pid
⚠️

Utilise defaults/ pour tout ce que l'utilisateur du rôle pourrait vouloir personnaliser (port, version, chemin…). Réserve vars/ aux constantes internes que tu ne veux pas qu'on surcharge.

group_vars et host_vars

Pour organiser les variables par groupe d'hôtes ou par hôte individuel, Ansible charge automatiquement les fichiers placés dans group_vars/ et host_vars/ à côté de ton inventaire.

# Structure recommandée du projet Ansible
inventory/
├── hosts.ini             # inventaire
├── group_vars/
│   ├── all.yml           # variables pour TOUS les hôtes
│   ├── webservers.yml    # variables pour le groupe "webservers"
│   └── databases.yml     # variables pour le groupe "databases"
└── host_vars/
    ├── web1.yml          # variables spécifiques à web1
    └── db1.yml           # variables spécifiques à db1
---
# group_vars/all.yml — s'applique partout
ansible_user: deploy
timezone: Europe/Paris
ntp_server: pool.ntp.org

---
# group_vars/webservers.yml
nginx_port: 443
ssl_enabled: true

---
# host_vars/web1.yml — surcharge spécifique à web1
nginx_port: 8080    # écrase la valeur du groupe
server_alias: web1.monlab.fr

Ansible Vault — chiffrer les secrets

Stocker des mots de passe ou des clés API en clair dans un dépôt Git, c'est une faille de sécurité. Ansible Vault permet de chiffrer des valeurs sensibles directement dans tes fichiers YAML.

# Chiffrer une valeur inline (recommandé pour les mots de passe)
ansible-vault encrypt_string 'MonMotDePasse123!' --name 'db_password'

# Résultat à coller dans ton YAML :
# db_password: !vault |
#   $ANSIBLE_VAULT;1.1;AES256
#   61333333...

# Chiffrer un fichier entier
ansible-vault encrypt group_vars/all/secrets.yml

# Déchiffrer pour éditer
ansible-vault edit group_vars/all/secrets.yml

# Lancer un playbook avec le mot de passe vault
ansible-playbook site.yml --ask-vault-pass

# Ou avec un fichier contenant le mot de passe (CI/CD)
ansible-playbook site.yml --vault-password-file ~/.vault_pass
---
# group_vars/all/secrets.yml (chiffré avec Vault)

db_password: !vault |
  $ANSIBLE_VAULT;1.1;AES256
  61333564363339353934323330383263663732306238663865363762336162633963
  6537613733623735366463646439623065336165326530360a353935613764313661

api_key: !vault |
  $ANSIBLE_VAULT;1.1;AES256
  34326366326565613766303130343632653931343561643931303838653066616534
  6532646561326133366332663265343365333438666335310a326363636461633061

Bonne pratique : sépare les variables sensibles dans un fichier dédié (secrets.yml) à côté de tes vars.yml normaux. Chiffre uniquement ce fichier avec Vault. Les autres fichiers restent lisibles et le diff Git reste compréhensible.

// à retenir
  • Un rôle est un bloc de code Ansible réutilisable. ansible-galaxy init roles/mon_role génère la structure.
  • Les dossiers clés : tasks/ (obligatoire), handlers/, defaults/, vars/, templates/, files/.
  • Dans un playbook, utilise roles: [nginx, nodejs] pour appliquer des rôles dans l'ordre.
  • Hiérarchie des variables : defaults/ < group_vars < host_vars < vars/ < --extra-vars.
  • group_vars/ et host_vars/ organisent les variables par groupe ou par machine.
  • Ansible Vault chiffre les secrets en AES256. ansible-vault encrypt_string pour une valeur, encrypt pour un fichier entier.