ANSIBLE — AUTOMATISATION SANS AGENT VIA SSH Noeud de Controle Playbooks Inventaire Roles ansible-playbook SSH Serveurs Web nginx, deploy app Serveurs BD mysql, sauvegardes Repartiteurs haproxy, certs Flux d'Execution du Playbook 1. Collecter les Facts (module setup) 2. Executer les Taches (apt, copy, service) 3. Notifier les Handlers (redemarrer services) 4. Reporter les Resultats (ok/changed/failed) Idempotent — sur a executer plusieurs fois Automatisation push : aucun agent necessaire sur les hotes geres

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 :

  1. Vous ecrivez un playbook (fichier YAML) decrivant l’etat souhaite de vos serveurs
  2. Vous definissez un inventaire listant les hotes a gerer
  3. Vous executez ansible-playbook, et Ansible se connecte a chaque hote via SSH
  4. Ansible transfere de petits programmes appeles modules vers l’hote distant
  5. Les modules s’executent, appliquent l’etat souhaite et font un rapport
  6. 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

CommandeDescription
ansible --versionAfficher la version et la configuration d’Ansible
ansible all -m ping -i inventory.iniTester la connectivite vers tous les hotes
ansible all -m setup -i inventory.iniCollecter et afficher les facts des hotes
ansible webservers -m apt -a "name=nginx state=present" -i inventory.ini --becomeInstaller nginx sur les webservers via commande ad-hoc
ansible-playbook site.yml -i inventory.iniExecuter un playbook
ansible-playbook site.yml --check --diffExecution a blanc avec sortie diff
ansible-playbook site.yml --limit web1.example.comExecuter 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.ymlCreer un nouveau fichier chiffre
ansible-vault edit secrets.ymlModifier un fichier chiffre
ansible-galaxy init roles/myroleCreer une structure de repertoire pour un nouveau role
ansible-galaxy install geerlingguy.nginxInstaller un role depuis Ansible Galaxy
ansible-inventory -i inventory.ini --graphAfficher le graphe des hotes de l’inventaire
ansible-doc aptVoir 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.