Se connecter a des dizaines de serveurs un par un pour installer des paquets, modifier des fichiers de configuration et redemarrer des services est fastidieux et source d’erreurs. Un pas oublie sur un serveur entraine une derive de configuration, et soudain vos serveurs “identiques” se comportent differemment. Ansible resout ce probleme en vous permettant de definir toute la configuration de vos serveurs dans des fichiers YAML simples et de l’appliquer de maniere coherente sur des centaines de machines avec une seule commande. Comme Ansible est sans agent et communique via SSH, il n’y a rien a installer sur vos serveurs geres — si vous pouvez vous connecter en SSH a un hote, Ansible peut le gerer.
Qu’est-ce qu’Ansible ?
Ansible est un outil d’automatisation open source cree par Red Hat qui gere la configuration des serveurs, le deploiement d’applications et l’orchestration. Contrairement aux outils qui necessitent un agent dedie fonctionnant sur chaque serveur gere, Ansible utilise SSH pour se connecter aux hotes distants et executer des taches.
Caracteristiques principales :
- Sans agent — Aucun logiciel a installer ou maintenir sur les noeuds geres. Ansible utilise les connexions SSH existantes
- Base sur le push — Le noeud de controle pousse les configurations vers les hotes geres a la demande, plutot que les hotes interrogent un serveur central
- Idempotent — Executer un playbook plusieurs fois produit le meme resultat. Ansible verifie l’etat actuel avant d’apporter des modifications
- Base sur YAML — Les playbooks sont ecrits en YAML lisible par l’humain, les rendant accessibles a quiconque peut lire un fichier de configuration
- Extensible — Des milliers de modules integres pour gerer les paquets, fichiers, services, ressources cloud et plus
Comment Fonctionne Ansible
Ansible suit un modele d’execution simple :
- Vous ecrivez un playbook (fichier YAML) decrivant l’etat souhaite de vos serveurs
- Vous definissez un inventaire listant les hotes a gerer
- Vous executez
ansible-playbook, et Ansible se connecte a chaque hote via SSH - Ansible transfere de petits programmes appeles modules vers l’hote distant
- Les modules s’executent, appliquent l’etat souhaite et font un rapport
- Ansible supprime les modules et affiche un resume
Aucun daemon ne tourne sur les hotes geres. Aucune base de donnees ne suit l’etat. Chaque execution de playbook est autonome.
Prerequis
Avant de commencer, assurez-vous d’avoir :
- Une machine Ubuntu 22.04 ou 24.04 comme noeud de controle (ou Ansible s’execute)
- Un ou plusieurs serveurs cibles accessibles via SSH
- L’authentification SSH par cles configuree entre le noeud de controle et les hotes geres
- Python 3 installe sur tous les noeuds geres (pre-installe sur la plupart des distributions Linux)
- Un compte utilisateur avec des privileges sudo sur les hotes geres
Conseil : Si vous n’avez pas encore configure l’authentification SSH par cles, suivez notre guide de durcissement SSH pour configurer un acces securise par cles avant de continuer.
Installer Ansible sur Ubuntu
Avec le gestionnaire de paquets systeme
sudo apt update
sudo apt install ansible -y
Avec pip (recommande pour la derniere version)
sudo apt install python3-pip python3-venv -y
python3 -m venv ~/ansible-venv
source ~/ansible-venv/bin/activate
pip install ansible
Verifier l’installation
ansible --version
Vous devriez voir une sortie affichant la version d’Ansible, le chemin du fichier de configuration et la version de Python :
ansible [core 2.16.x]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/user/.ansible/plugins/modules']
python version = 3.12.x
Fichiers d’Inventaire
L’inventaire indique a Ansible quels hotes gerer. Vous pouvez ecrire des inventaires au format INI ou YAML.
Format INI (simple)
# inventory.ini
[webservers]
web1.example.com
web2.example.com
192.168.1.50
[dbservers]
db1.example.com ansible_port=2222
db2.example.com
[loadbalancers]
lb1.example.com
[production:children]
webservers
dbservers
loadbalancers
[all:vars]
ansible_user=deployer
ansible_ssh_private_key_file=~/.ssh/id_ed25519
Format YAML
# inventory.yml
all:
vars:
ansible_user: deployer
ansible_ssh_private_key_file: ~/.ssh/id_ed25519
children:
webservers:
hosts:
web1.example.com:
web2.example.com:
192.168.1.50:
dbservers:
hosts:
db1.example.com:
ansible_port: 2222
db2.example.com:
loadbalancers:
hosts:
lb1.example.com:
production:
children:
webservers:
dbservers:
loadbalancers:
Tester la connectivite
Verifiez qu’Ansible peut atteindre tous les hotes :
ansible all -m ping -i inventory.ini
Sortie attendue pour une connexion reussie :
web1.example.com | SUCCESS => {
"changed": false,
"ping": "pong"
}
Votre Premier Playbook
Un playbook est un fichier YAML contenant un ou plusieurs “plays.” Chaque play cible un groupe d’hotes et definit des taches a executer.
Installer et configurer nginx
# site.yml
---
- name: Configurer les serveurs web
hosts: webservers
become: true
tasks:
- name: Mettre a jour le cache apt
apt:
update_cache: true
cache_valid_time: 3600
- name: Installer nginx
apt:
name: nginx
state: present
- name: Copier la configuration nginx
copy:
src: files/nginx.conf
dest: /etc/nginx/sites-available/default
owner: root
group: root
mode: "0644"
notify: Redemarrer nginx
- name: Activer le site nginx
file:
src: /etc/nginx/sites-available/default
dest: /etc/nginx/sites-enabled/default
state: link
notify: Redemarrer nginx
- name: S'assurer que nginx fonctionne et est active
service:
name: nginx
state: started
enabled: true
handlers:
- name: Redemarrer nginx
service:
name: nginx
state: restarted
Executer le playbook :
ansible-playbook -i inventory.ini site.yml
Executer avec une sortie detaillee pour le debogage :
ansible-playbook -i inventory.ini site.yml -v
Effectuer une execution a blanc pour voir ce qui changerait sans appliquer :
ansible-playbook -i inventory.ini site.yml --check --diff
Modules Ansible
Les modules sont les unites de travail dans Ansible. Chaque module gere une tache specifique. Voici les modules les plus couramment utilises :
Gestion des paquets (apt)
- name: Installer plusieurs paquets
apt:
name:
- nginx
- curl
- ufw
- fail2ban
state: present
update_cache: true
- name: Supprimer un paquet
apt:
name: apache2
state: absent
purge: true
Gestion des services (service)
- name: Demarrer et activer un service
service:
name: nginx
state: started
enabled: true
- name: Redemarrer un service
service:
name: mysql
state: restarted
Gestion des fichiers (copy, template, file)
- name: Copier un fichier vers l'hote distant
copy:
src: files/app.conf
dest: /etc/app/app.conf
owner: www-data
group: www-data
mode: "0644"
- name: Deployer un template avec des variables
template:
src: templates/vhost.conf.j2
dest: /etc/nginx/sites-available/myapp.conf
owner: root
group: root
mode: "0644"
- name: Creer un repertoire
file:
path: /var/www/myapp
state: directory
owner: www-data
group: www-data
mode: "0755"
Execution de commandes (command, shell)
- name: Executer une commande
command: /usr/bin/myapp --init
args:
creates: /var/lib/myapp/initialized
- name: Executer une commande shell avec des pipes
shell: cat /var/log/syslog | grep error | wc -l
register: error_count
changed_when: false
Gestion des utilisateurs (user)
- name: Creer un utilisateur de deploiement
user:
name: deployer
groups: sudo,www-data
shell: /bin/bash
create_home: true
state: present
- name: Ajouter une cle SSH autorisee
authorized_key:
user: deployer
key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
state: present
Variables et Facts
Les variables rendent vos playbooks flexibles et reutilisables. Ansible prend en charge plusieurs sources de variables.
Definir des variables dans les playbooks
---
- name: Deployer l'application
hosts: webservers
become: true
vars:
app_name: myapp
app_port: 8080
app_user: www-data
packages:
- nginx
- python3
- python3-pip
tasks:
- name: Installer les paquets requis
apt:
name: "{{ packages }}"
state: present
- name: Creer le repertoire de l'application
file:
path: "/var/www/{{ app_name }}"
state: directory
owner: "{{ app_user }}"
mode: "0755"
Variables de groupe et de hote
Creez des repertoires pour les variables specifiques par groupe et par hote :
project/
inventory.ini
group_vars/
all.yml
webservers.yml
dbservers.yml
host_vars/
web1.example.com.yml
db1.example.com.yml
playbook.yml
# group_vars/webservers.yml
http_port: 80
https_port: 443
document_root: /var/www/html
max_workers: 4
# host_vars/web1.example.com.yml
server_name: web1.example.com
ssl_certificate: /etc/ssl/certs/web1.pem
Collecte des facts
Ansible collecte automatiquement les facts systeme (OS, adresses IP, memoire, disque) des hotes geres. Utilisez-les dans les templates et les conditions :
- name: Afficher les informations systeme
debug:
msg: >
Hostname: {{ ansible_hostname }},
OS: {{ ansible_distribution }} {{ ansible_distribution_version }},
IP: {{ ansible_default_ipv4.address }},
RAM: {{ ansible_memtotal_mb }} MB
- name: Installer des paquets selon l'OS
apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
- name: Installer des paquets sur Red Hat
yum:
name: nginx
state: present
when: ansible_os_family == "RedHat"
Handlers et Notifications
Les handlers sont des taches speciales qui ne s’executent que lorsqu’ils sont notifies par une autre tache. Ils sont declenches a la fin d’un play, apres que toutes les taches regulieres sont terminees. Cela empeche les redemarrages inutiles de services.
---
- name: Configurer le serveur web
hosts: webservers
become: true
tasks:
- name: Installer nginx
apt:
name: nginx
state: present
- name: Deployer la configuration principale nginx
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify:
- Valider la configuration nginx
- Redemarrer nginx
- name: Deployer l'hote virtuel
template:
src: templates/vhost.conf.j2
dest: /etc/nginx/sites-available/{{ domain }}.conf
notify:
- Valider la configuration nginx
- Redemarrer nginx
- name: Activer l'hote virtuel
file:
src: /etc/nginx/sites-available/{{ domain }}.conf
dest: /etc/nginx/sites-enabled/{{ domain }}.conf
state: link
notify:
- Valider la configuration nginx
- Redemarrer nginx
handlers:
- name: Valider la configuration nginx
command: nginx -t
listen: "Valider la configuration nginx"
- name: Redemarrer nginx
service:
name: nginx
state: restarted
listen: "Redemarrer nginx"
Meme si trois taches notifient les handlers, Redemarrer nginx ne s’execute qu’une seule fois a la fin du play.
Roles et Structure de Repertoires
Les roles organisent vos playbooks en composants reutilisables et partageables. Chaque role encapsule des taches, handlers, variables, templates et fichiers pour une fonction specifique.
Creer un role
ansible-galaxy init roles/webserver
Cela genere la structure suivante :
roles/
webserver/
tasks/
main.yml
handlers/
main.yml
templates/
files/
vars/
main.yml
defaults/
main.yml
meta/
main.yml
Taches du role
# roles/webserver/tasks/main.yml
---
- name: Installer nginx
apt:
name: nginx
state: present
update_cache: true
- name: Deployer la configuration nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Redemarrer nginx
- name: Deployer l'hote virtuel
template:
src: vhost.conf.j2
dest: "/etc/nginx/sites-available/{{ domain }}.conf"
notify: Redemarrer nginx
- name: Activer l'hote virtuel
file:
src: "/etc/nginx/sites-available/{{ domain }}.conf"
dest: "/etc/nginx/sites-enabled/{{ domain }}.conf"
state: link
notify: Redemarrer nginx
- name: Supprimer l'hote virtuel par defaut
file:
path: /etc/nginx/sites-enabled/default
state: absent
notify: Redemarrer nginx
- name: S'assurer que nginx fonctionne
service:
name: nginx
state: started
enabled: true
Handlers du role
# roles/webserver/handlers/main.yml
---
- name: Redemarrer nginx
service:
name: nginx
state: restarted
Valeurs par defaut du role
# roles/webserver/defaults/main.yml
---
domain: example.com
http_port: 80
https_port: 443
document_root: /var/www/html
worker_processes: auto
worker_connections: 1024
Utiliser des roles dans un playbook
# site.yml
---
- name: Configurer l'infrastructure
hosts: webservers
become: true
roles:
- role: webserver
vars:
domain: knowledgexchange.xyz
- role: security
- role: monitoring
Exemples Pratiques
Deploiement de pile LAMP
# lamp.yml
---
- name: Deployer la pile LAMP
hosts: webservers
become: true
vars:
mysql_root_password: "{{ vault_mysql_root_password }}"
php_version: "8.3"
tasks:
- name: Installer Apache et PHP
apt:
name:
- apache2
- libapache2-mod-php{{ php_version }}
- php{{ php_version }}
- php{{ php_version }}-mysql
- php{{ php_version }}-curl
- php{{ php_version }}-xml
- php{{ php_version }}-mbstring
state: present
update_cache: true
- name: Installer le serveur MySQL
apt:
name: mysql-server
state: present
- name: Demarrer et activer MySQL
service:
name: mysql
state: started
enabled: true
- name: Demarrer et activer Apache
service:
name: apache2
state: started
enabled: true
- name: Deployer la page PHP info pour les tests
copy:
content: "<?php phpinfo(); ?>"
dest: /var/www/html/info.php
owner: www-data
group: www-data
mode: "0644"
Gestion des utilisateurs sur tous les serveurs
# users.yml
---
- name: Gerer les comptes utilisateurs
hosts: all
become: true
vars:
admin_users:
- name: jcarlos
key: "ssh-ed25519 AAAAC3Nza... jcarlos@workstation"
groups: sudo,adm
- name: deployer
key: "ssh-ed25519 AAAAC3Nza... deployer@ci"
groups: www-data
removed_users:
- oldadmin
- tempuser
tasks:
- name: Creer les utilisateurs administrateurs
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
shell: /bin/bash
create_home: true
state: present
loop: "{{ admin_users }}"
- name: Ajouter les cles SSH pour les utilisateurs administrateurs
authorized_key:
user: "{{ item.name }}"
key: "{{ item.key }}"
exclusive: true
loop: "{{ admin_users }}"
- name: Supprimer les anciens utilisateurs
user:
name: "{{ item }}"
state: absent
remove: true
loop: "{{ removed_users }}"
Durcissement de securite
# harden.yml
---
- name: Durcissement de securite
hosts: all
become: true
tasks:
- name: Installer les paquets de securite
apt:
name:
- ufw
- fail2ban
- unattended-upgrades
state: present
update_cache: true
- name: Configurer les valeurs par defaut UFW
ufw:
direction: incoming
policy: deny
- name: Autoriser SSH via UFW
ufw:
rule: allow
port: "2222"
proto: tcp
- name: Autoriser HTTP et HTTPS
ufw:
rule: allow
port: "{{ item }}"
proto: tcp
loop:
- "80"
- "443"
- name: Activer UFW
ufw:
state: enabled
- name: Deployer la configuration fail2ban
copy:
src: files/jail.local
dest: /etc/fail2ban/jail.local
notify: Redemarrer fail2ban
- name: Activer les mises a jour de securite automatiques
copy:
content: |
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";
dest: /etc/apt/apt.conf.d/20auto-upgrades
- name: Desactiver la connexion SSH root
lineinfile:
path: /etc/ssh/sshd_config
regexp: "^PermitRootLogin"
line: "PermitRootLogin no"
notify: Redemarrer sshd
handlers:
- name: Redemarrer fail2ban
service:
name: fail2ban
state: restarted
- name: Redemarrer sshd
service:
name: sshd
state: restarted
Ansible Vault pour les Secrets
Ne stockez jamais les mots de passe ou cles API en texte brut. Ansible Vault chiffre les donnees sensibles :
# Creer un fichier de variables chiffre
ansible-vault create group_vars/all/vault.yml
# Modifier un fichier chiffre
ansible-vault edit group_vars/all/vault.yml
# Chiffrer un fichier existant
ansible-vault encrypt secrets.yml
# Executer un playbook avec vault
ansible-playbook site.yml --ask-vault-pass
# Utiliser un fichier de mot de passe a la place
ansible-playbook site.yml --vault-password-file ~/.vault_pass
Dans le fichier vault, prefixez les variables sensibles avec vault_ :
# group_vars/all/vault.yml (chiffre)
vault_mysql_root_password: "s3cur3P@ssw0rd"
vault_api_key: "abc123def456"
vault_ssl_private_key: |
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
Referencez les variables vault dans votre fichier de variables regulier :
# group_vars/all/vars.yml
mysql_root_password: "{{ vault_mysql_root_password }}"
api_key: "{{ vault_api_key }}"
Depannage
Echecs de connexion SSH
# Tester la connectivite SSH manuellement
ssh -i ~/.ssh/id_ed25519 deployer@web1.example.com
# Executer en mode detaille pour voir les details SSH
ansible all -m ping -i inventory.ini -vvvv
# Verifier si Python est disponible sur l'hote distant
ansible all -m raw -a "python3 --version" -i inventory.ini
Erreurs de permission refusee
# S'assurer que become (sudo) est configure
ansible-playbook site.yml -i inventory.ini --become --ask-become-pass
# Verifier la configuration sudo sur l'hote distant
ssh deployer@web1.example.com "sudo -l"
Erreurs de module introuvable
# Lister tous les modules disponibles
ansible-doc -l | grep apt
# Voir la documentation d'un module specifique
ansible-doc apt
# Verifier la version d'Ansible pour la compatibilite des modules
ansible --version
Erreurs de syntaxe des playbooks
# Valider la syntaxe du playbook sans executer
ansible-playbook site.yml --syntax-check
# Lint du playbook pour les bonnes pratiques
pip install ansible-lint
ansible-lint site.yml
Deboguer la sortie des taches
- name: Executer une commande et capturer la sortie
command: systemctl status nginx
register: nginx_status
ignore_errors: true
- name: Afficher la sortie
debug:
var: nginx_status.stdout_lines
Reference des Commandes Essentielles
| Commande | Description |
|---|---|
ansible --version | Afficher la version et la configuration d’Ansible |
ansible all -m ping -i inventory.ini | Tester la connectivite vers tous les hotes |
ansible all -m setup -i inventory.ini | Collecter et afficher les facts des hotes |
ansible webservers -m apt -a "name=nginx state=present" -i inventory.ini --become | Installer nginx sur les webservers via commande ad-hoc |
ansible-playbook site.yml -i inventory.ini | Executer un playbook |
ansible-playbook site.yml --check --diff | Execution a blanc avec sortie diff |
ansible-playbook site.yml --limit web1.example.com | Executer le playbook sur un seul hote |
ansible-playbook site.yml --tags "nginx,security" | Executer uniquement les taches avec des tags specifiques |
ansible-playbook site.yml --start-at-task "Install nginx" | Reprendre le playbook a partir d’une tache specifique |
ansible-vault create secrets.yml | Creer un nouveau fichier chiffre |
ansible-vault edit secrets.yml | Modifier un fichier chiffre |
ansible-galaxy init roles/myrole | Creer une structure de repertoire pour un nouveau role |
ansible-galaxy install geerlingguy.nginx | Installer un role depuis Ansible Galaxy |
ansible-inventory -i inventory.ini --graph | Afficher le graphe des hotes de l’inventaire |
ansible-doc apt | Voir la documentation du module |
Resume
Ansible fournit un chemin puissant et accessible vers l’automatisation de l’infrastructure. Son architecture sans agent signifie que vous pouvez commencer a automatiser immediatement — si vous pouvez vous connecter en SSH a vos serveurs, vous pouvez les gerer avec Ansible. Commencez par de simples commandes ad-hoc, progressez vers les playbooks pour les taches repetitives et organisez les configurations complexes en roles. La combinaison de la lisibilite YAML, de l’execution idempotente et de milliers de modules integres fait d’Ansible l’outil de reference pour la gestion de configuration dans les environnements Linux et Windows.
Pour provisionner l’infrastructure elle-meme — creer des serveurs cloud, des reseaux et des enregistrements DNS avant de les configurer — explorez notre guide d’infrastructure en tant que code avec Terraform. Pour vous assurer que les serveurs geres par Ansible sont securises des le depart, suivez notre guide de durcissement SSH pour verrouiller l’acces distant avec l’authentification par cles, fail2ban et les regles de pare-feu.