ℹ️ À savoir · En bref
Ansible est un outil open source (Red Hat) qui automatise la configuration de serveurs et d'applications. On décrit l'état voulu en YAML ; Ansible se connecte en SSH (Linux) ou WinRM/SSH (Windows), applique ce qui manque, et ne touche à rien si tout est déjà conforme.
Trois mots à retenir : agentless (rien à installer sur les cibles), push (c'est le nœud de contrôle qui pousse), idempotent (rejouer = même résultat).
Objectifs de la fiche
- Comprendre l'architecture et le vocabulaire Ansible.
- Écrire un inventaire et un playbook idempotent.
- Utiliser variables, templates, handlers et rôles.
- Exécuter sans risque (
--check --diff,--limit) et éviter les pièges classiques.
Le vocabulaire en 1 tableau
| Terme | Ce que c'est | Exemple |
|---|---|---|
| Nœud de contrôle | La machine où Ansible est installé et d'où partent les exécutions. | Poste admin Linux, WSL, conteneur |
| Nœud géré | Une cible configurée par Ansible. Aucun agent permanent. | vda-ubuntu01, srv-sf01 |
| Inventaire | La liste des cibles, rangées en groupes, avec leurs variables. | inventory/hosts.yml |
| Module | L'unité de travail : une action idempotente avec des paramètres. | ansible.builtin.apt |
| Task | Un appel de module, avec un nom lisible. | « Installer sssd » |
| Play | Associe un groupe d'hôtes à une liste de tâches. | hosts: vda_linux |
| Playbook | Fichier YAML contenant un ou plusieurs plays. | site.yml |
| Handler | Tâche déclenchée seulement si une autre tâche a changé quelque chose. | Redémarrer un service |
| Rôle | Paquet réutilisable de tâches, templates, variables, handlers. | rôle linux_vda |
| Collection | Distribution de modules/rôles/plugins par éditeur (FQCN). | ansible.windows, microsoft.ad |
| Facts | Infos collectées automatiquement sur la cible au début du play. | ansible_distribution |
Architecture : comment ça s’exécute

À chaque tâche, Ansible copie un petit module sur la cible, l'exécute, récupère un résultat JSON puis nettoie. Le statut retourné est l'un de :
| Statut | Signification | Couleur console |
|---|---|---|
ok | L'état était déjà conforme, rien n'a été modifié. | vert |
changed | Ansible a modifié la cible pour la rendre conforme. | jaune |
failed | La tâche a échoué : l'hôte sort du play. | rouge |
skipped | Tâche ignorée (condition when fausse, mode check…). | cyan |
unreachable | Connexion impossible (SSH, DNS, identifiants). | rouge |
L’inventaire
Il décrit qui est géré. Format YAML (ou INI), statique ou dynamique (plugins Azure, vSphere, etc. qui interrogent l'API à chaque exécution).
inventory/hosts.yml
all:
children:
vda_linux:
hosts:
vda-ubuntu01:
vda-ubuntu02:
vars:
ansible_user: ansible
storefront:
hosts:
srv-sf01:
ansible_host: 10.0.10.21
vars:
ansible_connection: winrm
ansible_winrm_transport: kerberos
ansible_port: 5986
💡 Astuce
Sors les variables de l'inventaire : un dossier group_vars/vda_linux.yml et host_vars/srv-sf01.yml à côté de l'inventaire sont chargés automatiquement. Vérifie le résultat avec ansible-inventory -i inventory --graph --vars.
Anatomie d’un playbook

playbooks/vda_linux.yml
---
- name: Configurer les VDA Linux
hosts: vda_linux
become: true # sudo
vars:
ad_domain: corp.local
tasks:
- name: Installer sssd, realmd et Kerberos
ansible.builtin.apt:
name: [sssd, realmd, krb5-user]
state: present # état voulu, pas une action
update_cache: true
- name: Déployer sssd.conf depuis un template Jinja2
ansible.builtin.template:
src: sssd.conf.j2
dest: /etc/sssd/sssd.conf
owner: root
mode: "0600"
notify: Redémarrer sssd # seulement si le fichier change
handlers:
- name: Redémarrer sssd
ansible.builtin.service:
name: sssd
state: restarted
ℹ️ À savoir · Le concept clé
Idempotence : state: present décrit un résultat, pas une commande. 1re exécution → changed, 2e exécution → ok partout, changed=0.
C'est le test de qualité n°1 d'un playbook : le rejouer deux fois de suite et vérifier qu'il n'y a plus de changement.
Variables, templates et précédence
Les variables s'écrivent {{ ma_variable }} (moteur Jinja2), dans les tâches comme dans les templates .j2. Quand la même variable est définie à plusieurs endroits, la plus « proche » de l'exécution gagne :
| Priorité | Source (version simplifiée) | Usage recommandé |
|---|---|---|
| 1 — la plus faible | Rôle : defaults/main.yml | Valeurs par défaut, faites pour être surchargées |
| 2 | Inventaire : group_vars/all, puis group_vars/<groupe> | Paramètres d'environnement / de groupe |
| 3 | Inventaire : host_vars/<hôte> | Exceptions propres à une machine |
| 4 | Facts collectés | Lecture seule : OS, IP, mémoire… |
| 5 | Play : vars:, vars_files: | Constantes du playbook |
| 6 | Rôle : vars/main.yml | Constantes internes du rôle (rarement surchargées) |
| 7 | set_fact / register | Valeurs calculées pendant l'exécution |
| 8 — la plus forte | Ligne de commande : -e var=valeur | Forçage ponctuel ; gagne toujours |
⚠️ Piège
Une valeur YAML qui commence par {{ doit être entre guillemets : dest: "{{ base_dir }}/app.conf". Sans guillemets, YAML l'interprète comme un dictionnaire et le playbook ne se charge pas.
Rôles et collections
Un rôle est une arborescence normalisée que l'on réutilise d'un projet à l'autre ; on le crée avec ansible-galaxy role init linux_vda.
structure d'un rôle
roles/linux_vda/
├── defaults/main.yml # variables par défaut (priorité basse)
├── vars/main.yml # constantes du rôle
├── tasks/main.yml # point d'entrée des tâches
├── handlers/main.yml # handlers
├── templates/sssd.conf.j2
├── files/ # fichiers copiés tels quels
└── meta/main.yml # dépendances, plateformes
Les collections apportent les modules hors cœur. On les déclare dans collections/requirements.yml puis ansible-galaxy collection install -r collections/requirements.yml. Toujours appeler un module par son FQCN (ansible.windows.win_feature plutôt que win_feature).
Cibles Windows : les différences
| Sujet | Linux | Windows |
|---|---|---|
| Transport | SSH (port 22) | WinRM HTTPS 5986 (ou HTTP 5985), ou OpenSSH |
| Prérequis cible | Python 3 | PowerShell 5.1+ / .NET |
| Authentification | Clé SSH | Kerberos (recommandé en domaine), NTLM, CredSSP, certificat |
| Élévation | become_method: sudo | become_method: runas |
| Modules | ansible.builtin.* | ansible.windows.*, community.windows.*, microsoft.ad.* |
Commandes essentielles
| Commande | À quoi ça sert |
|---|---|
ansible all -m ansible.builtin.ping | Tester la connexion + Python sur les Linux |
ansible storefront -m ansible.windows.win_ping | Idem côté Windows |
ansible-inventory -i inventory --graph | Visualiser groupes et hôtes |
ansible-playbook site.yml --syntax-check | Valider la syntaxe sans rien exécuter |
ansible-playbook site.yml --check --diff | Simulation : montre ce qui changerait (dry run) |
ansible-playbook site.yml --limit vda-ubuntu01 | Restreindre à un hôte / groupe |
ansible-playbook site.yml --tags sssd | N'exécuter que les tâches étiquetées |
ansible-playbook site.yml -e env=prd | Passer une variable (priorité maximale) |
ansible-vault encrypt_string 'S3cret' --name pwd | Chiffrer un secret à coller dans un fichier de vars |
ansible-doc ansible.builtin.template | Documentation hors-ligne d'un module |
ansible-lint | Vérifier les bonnes pratiques |
Pièges classiques
| Symptôme | Cause | Parade |
|---|---|---|
| La tâche est « changed » à chaque exécution | command / shell n'ont aucune notion d'état | Module dédié ; sinon creates:, changed_when: |
| Mot de passe visible dans Git ou les logs | Secret en clair dans les vars | ansible-vault + no_log: true sur la tâche |
| « conflicting action statements » / erreur YAML | Indentation ou {{ }} non quoté | Guillemets, éditeur YAML, ansible-lint |
| Le handler ne s'est pas exécuté | Une tâche a échoué avant la fin du play | --force-handlers ou meta: flush_handlers |
--check « rate » des tâches | Les modules command/shell sont ignorés en check | check_mode: false si la commande est sans effet |
| Module introuvable | Collection non installée ou nom court ambigu | FQCN + requirements.yml |
🔷 En contexte Citrix
Gold image Linux VDA : paquets, jonction AD via sssd/realmd, variables de ctxsetup.sh, puis MCS clone l'image : Ansible rend la préparation reproductible.
Gold image Windows : rôles et fonctionnalités, clés de registre, optimisations, installation silencieuse du VDA.
Infra : configuration homogène des StoreFront, Cloud Connectors (prérequis OS), sauvegardes de config.
Combo classique : Terraform crée les VM / le catalogue, Ansible configure l'intérieur (voir fiche TF-01).
À retenir
- Agentless, push, SSH/WinRM : seul le nœud de contrôle a Ansible.
- On décrit un état ; un bon playbook rejoué donne
changed=0. - Inventaire = qui · Playbook = quoi · Rôle = comment le réutiliser.
--check --diffet--limitavant toute exécution en production.- Secrets dans
ansible-vault, modules appelés par leur FQCN.
Auto-évaluation
Q1. Pourquoi dit-on qu'Ansible est « agentless » ?
→ Il n'y a aucun service permanent sur les cibles : le module est copié et exécuté via SSH/WinRM, puis supprimé.
Q2. Quelle est la différence entre une task et un handler ?
→ Une task s'exécute toujours (sauf condition) ; un handler ne s'exécute qu'une fois, en fin de play, et seulement s'il a été notifié par une task « changed ».
Q3. Une variable port vaut 80 dans defaults/ du rôle, 8080 dans group_vars/web, et on lance -e port=9000. Quelle valeur ?
→ 9000 : les extra vars (-e) ont toujours la priorité la plus haute.
Q4. Comment vérifier ce qu'un playbook va modifier sans rien changer ?
→ ansible-playbook site.yml --check --diff (en gardant en tête que command/shell sont ignorés).