DevOpsFacile
AccueilParcours de formationCertificationsModulesCheat SheetÀ Propos
DevOpsFacile

Une plateforme d'apprentissage complète pour maîtriser les pratiques DevOps modernes, du débutant à l'expert.

contact@devopsfacile.fr

Formation

  • Parcours de formation
  • Modules

Informations

  • À Propos
  • Conditions d'utilisation
  • Confidentialité
  • Mentions légales

© 2026 DevOps Facile. Tous droits réservés.

Fait avec pour la communauté DevOps

ModulesAnsible Intermédiaire : variables, templates et rôles

Module

Maîtrisez les variables, les templates Jinja2, les handlers et structurez vos playbooks avec des rôles Ansible.

  • 1h30
  • Intermédiaire
  • 6 exercices
Voir les exercices

Formation 100 % Linux

Tous les modules nécessitent un environnement Linux. Si vous êtes sur Windows, installez d'abord WSL (Windows Subsystem for Linux) avant de continuer.

Ansible Intermédiaire : variables, templates et rôles

🎯 Objectifs

  • Utiliser les variables pour rendre les playbooks flexibles
  • Créer des fichiers de configuration dynamiques avec les templates Jinja2
  • Déclencher des actions conditionnelles avec les handlers
  • Organiser son code Ansible avec la structure des rôles

📋 Prérequis

  • Ansible Débutant - inventaire, playbook de base, modules essentiels
  • Ansible installé et fonctionnel
  • SSH configuré vers au moins un serveur

📦 Les Variables

Pourquoi des variables ?

Sans variables, si tu veux changer le port d'écoute de Nginx, tu dois modifier le playbook à la main à chaque fois. Avec des variables, tu changes une seule valeur, et tout le playbook s'adapte.

Déclarer des variables dans un playbook

yaml
---
- name: Déployer une application
  hosts: webservers
  become: true

  vars:
    app_port: 8080
    app_user: deploy
    app_dir: /var/www/monapp

  tasks:
    - name: Créer le répertoire de l'application
      ansible.builtin.file:
        path: "{{ app_dir }}"
        state: directory
        owner: "{{ app_user }}"
        mode: '0755'

💡 Les variables s'utilisent avec la syntaxe {{ nom_variable }}. Les accolades doubles viennent de Jinja2, le moteur de templates intégré à Ansible.

Fichiers de variables séparés

Pour ne pas mélanger variables et tâches, crée des fichiers dédiés :

bash
# Arborescence suggérée
playbook.yml
inventaire.ini
vars/
  all.yml        # Variables communes à tous les serveurs
  production.yml # Variables spécifiques à la production
yaml
# vars/all.yml
app_name: monapp
app_port: 8080
nginx_worker_processes: 2
yaml
# playbook.yml
- name: Configurer les serveurs
  hosts: all
  vars_files:
    - vars/all.yml
  tasks:
    - name: Afficher le nom de l'application
      ansible.builtin.debug:
        msg: "Déploiement de {{ app_name }} sur le port {{ app_port }}"

Variables d'inventaire (host_vars et group_vars)

Ansible suit des conventions pour charger les variables automatiquement :

inventaire.ini
group_vars/
  all.yml           # Variables pour tous les hôtes
  webservers.yml    # Variables pour le groupe webservers
host_vars/
  web1.yml          # Variables spécifiques à web1
  web2.yml          # Variables spécifiques à web2
yaml
# group_vars/webservers.yml
nginx_port: 80
nginx_worker_processes: 4

# host_vars/web1.yml
nginx_port: 8080   # web1 utilise un port différent

Variables depuis la ligne de commande

bash
# Passer une variable au moment du lancement
ansible-playbook playbook.yml -e "app_version=2.1.0"

# Passer un fichier de variables
ansible-playbook playbook.yml -e "@vars/custom.yml"

Priorité des variables (de la plus faible à la plus forte)

SourcePriorité
Valeurs par défaut des rôles (defaults/main.yml)La plus basse
Variables d'inventaire (group_vars, host_vars)Moyenne
Variables du playbook (vars:)Haute
Variables en ligne de commande (-e)La plus haute

🧱 Les Facts : informations automatiques sur les serveurs

Ansible collecte automatiquement des informations sur chaque serveur au début d'un play. Ces informations s'appellent des facts.

yaml
- name: Utiliser les facts
  hosts: all
  tasks:
    - name: Afficher le système d'exploitation
      ansible.builtin.debug:
        msg: "Ce serveur tourne sur {{ ansible_distribution }} {{ ansible_distribution_version }}"

    - name: Afficher la mémoire disponible
      ansible.builtin.debug:
        msg: "Mémoire RAM : {{ ansible_memtotal_mb }} Mo"

Les facts les plus utiles :

FactValeur typique
ansible_hostnameweb1
ansible_distributionUbuntu
ansible_distribution_version22.04
ansible_os_familyDebian
ansible_default_ipv4.address192.168.1.10
ansible_memtotal_mb2048
bash
# Voir tous les facts d'un hôte
ansible web1 -i inventaire.ini -m ansible.builtin.setup

📝 Les Templates Jinja2

Le problème des fichiers statiques

Avec ansible.builtin.copy, tu copies un fichier à l'identique. Mais si tu veux que le fichier de configuration de Nginx contienne le bon nom de domaine, la bonne adresse IP, le bon port... selon chaque serveur ? Il te faut un fichier dynamique.

La solution : le module ansible.builtin.template

Un template Jinja2, c'est un fichier texte avec des variables à l'intérieur. Ansible remplace les variables par leurs valeurs avant de copier le fichier sur le serveur.

nginx
# templates/nginx.conf.j2
server {
    listen {{ nginx_port }};
    server_name {{ ansible_hostname }};

    root /var/www/{{ app_name }};
    index index.html;

    access_log /var/log/nginx/{{ app_name }}_access.log;
    error_log  /var/log/nginx/{{ app_name }}_error.log;
}
yaml
# Dans le playbook
- name: Déployer la configuration Nginx
  ansible.builtin.template:
    src: templates/nginx.conf.j2
    dest: /etc/nginx/sites-available/{{ app_name }}
    owner: root
    group: root
    mode: '0644'

Fonctionnalités Jinja2 utiles

jinja2
{# Commentaire Jinja2 #}

{# Condition #}
{% if nginx_port == 443 %}
    ssl on;
{% else %}
    ssl off;
{% endif %}

{# Boucle #}
{% for server in upstream_servers %}
    server {{ server }}:8080;
{% endfor %}

{# Filtre #}
{{ app_name | upper }}         {# Mettre en majuscules #}
{{ app_name | default('app') }} {# Valeur par défaut si variable non définie #}
{{ liste | join(', ') }}       {# Joindre une liste #}

🔔 Les Handlers

Le problème sans handlers

Quand tu changes la configuration de Nginx, tu dois le recharger. Tu pourrais ajouter une tâche service: state: reloaded après chaque modification de config. Mais si la config n'a pas changé, tu rechargeras quand même Nginx - inutilement.

La solution : les handlers ne se déclenchent que si une tâche les a notifiés, et seulement si cette tâche a effectivement changé quelque chose.

Définir et utiliser un handler

yaml
---
- name: Configurer Nginx
  hosts: webservers
  become: true

  tasks:
    - name: Déployer la configuration Nginx
      ansible.builtin.template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify: Recharger Nginx          # Notifie le handler

    - name: Activer le site
      ansible.builtin.file:
        src: /etc/nginx/sites-available/monapp
        dest: /etc/nginx/sites-enabled/monapp
        state: link
      notify: Recharger Nginx          # Le même handler peut être notifié plusieurs fois

  handlers:
    - name: Recharger Nginx            # Le nom doit correspondre exactement
      ansible.builtin.service:
        name: nginx
        state: reloaded

💡 Un handler est exécuté une seule fois à la fin du play, même s'il a été notifié plusieurs fois. C'est parfait pour éviter des rechargements inutiles.

Forcer l'exécution des handlers immédiatement

yaml
- name: Forcer les handlers maintenant
  ansible.builtin.meta: flush_handlers

🗂️ Les Rôles : organiser son code

Pourquoi les rôles ?

Un playbook avec 50 tâches, des templates, des variables et des handlers dans un seul fichier devient difficile à maintenir. Les rôles sont la façon Ansible d'organiser et de réutiliser le code.

L'analogie : un rôle, c'est comme un composant d'une application. Tu crées un rôle nginx, un rôle postgresql, un rôle app. Chacun est autonome et réutilisable dans différents projets.

Structure d'un rôle

roles/
  nginx/
    tasks/
      main.yml        # Les tâches du rôle
    handlers/
      main.yml        # Les handlers
    templates/
      nginx.conf.j2   # Les templates
    files/
      index.html      # Les fichiers statiques
    vars/
      main.yml        # Variables internes (priorité haute)
    defaults/
      main.yml        # Valeurs par défaut (priorité basse)
    meta/
      main.yml        # Métadonnées et dépendances
yaml
# 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: Recharger Nginx

- name: Démarrer Nginx
  ansible.builtin.service:
    name: nginx
    state: started
    enabled: true
yaml
# roles/nginx/defaults/main.yml
---
nginx_port: 80
nginx_worker_processes: 1

Utiliser un rôle dans un playbook

yaml
---
- name: Configurer les serveurs web
  hosts: webservers
  become: true

  roles:
    - nginx
    - { role: nginx, nginx_port: 8080 }   # Surcharger une variable

Créer rapidement la structure d'un rôle

bash
ansible-galaxy role init roles/nginx

Cette commande crée toute l'arborescence vide pour toi.


⚠️ Erreurs Courantes

ErreurCauseSolution
undefined variableVariable non déclaréeVérifier defaults/main.yml ou utiliser \| default('valeur')
Handler non déclenchéNom du notify différent du name du handlerLes noms doivent être identiques
Template non trouvéChemin incorrect dans srcLe chemin est relatif au répertoire templates/ du rôle
Facts non disponiblesgather_facts: false dans le playRetirer cette ligne ou activer les facts explicitement
YAML parsing errorGuillemets manquants autour de {{ }}Toujours entourer "{{ variable }}" de guillemets

📊 Récapitulatif

ConceptUtilisationFichier
varsValeurs réutilisables dans un playbookvars/all.yml
group_varsVariables par groupe d'hôtesgroup_vars/webservers.yml
host_varsVariables par hôtehost_vars/web1.yml
factsInfos collectées automatiquementAccès via ansible_*
templateFichier dynamique avec variablestemplates/*.j2
handlerAction déclenchée sur notificationhandlers/main.yml
rôleOrganisation modulaire du coderoles/nom_role/

📚 Ressources

  • Variables Ansible
  • Templates Jinja2
  • Rôles Ansible
  • Ansible Galaxy

🚀 Prochaines étapes

Tu sais maintenant structurer et paramétrer tes playbooks. Passe au niveau confirmé pour sécuriser et industrialiser ton usage d'Ansible :

  1. Ansible Avancé : Vault, inventaires dynamiques et CI/CD - Secrets, production et automatisation avancée

Exercices Pratiques

6 exercices pour mettre en pratique

01

01 - Variables, facts et fichiers de variables

35 minutesIntermédiaire
02

02 - Templates Jinja2 pour des configurations dynamiques

40 minutesIntermédiaire
03

03 - Handlers : déclencher des actions sur changement

30 minutesIntermédiaire
04

04 - Créer et utiliser des rôles Ansible

50 minutesIntermédiaire
05

05 - Boucles, conditions et gestion des erreurs

40 minutesIntermédiaire
06

06 - Projet : déployer une application multi-tiers avec des rôles

60 minutesIntermédiaire
Retour aux modules

Sur cette page

  • 🎯 Objectifs
  • 📋 Prérequis
  • 📦 Les Variables
  • Pourquoi des variables ?
  • Déclarer des variables dans un playbook
  • Fichiers de variables séparés
  • Variables d'inventaire (host_vars et group_vars)
  • Variables depuis la ligne de commande
  • Priorité des variables (de la plus faible à la plus forte)
  • 🧱 Les Facts : informations automatiques sur les serveurs
  • 📝 Les Templates Jinja2
  • Le problème des fichiers statiques
  • La solution : le module ansible.builtin.template
  • Fonctionnalités Jinja2 utiles
  • 🔔 Les Handlers
  • Le problème sans handlers
  • Définir et utiliser un handler
  • Forcer l'exécution des handlers immédiatement
  • 🗂️ Les Rôles : organiser son code
  • Pourquoi les rôles ?
  • Structure d'un rôle
  • Utiliser un rôle dans un playbook
  • Créer rapidement la structure d'un rôle
  • ⚠️ Erreurs Courantes
  • 📊 Récapitulatif
  • 📚 Ressources
  • 🚀 Prochaines étapes