You are currently viewing Automatiser la gestion d’infrastructure avec Ansible : de la configuration manuelle à l’Infrastructure as Code

Automatiser la gestion d’infrastructure avec Ansible : de la configuration manuelle à l’Infrastructure as Code

Automatiser la gestion d’infrastructure avec Ansible : de la configuration manuelle à l’Infrastructure as Code

Quand on administre une infrastructure auto-hébergée composée de multiples services — CKAN, Nextcloud, Keycloak, Gitea, Superset — la tentation est grande de tout configurer à la main, serveur par serveur. Ça fonctionne au début, mais dès que l’environnement grandit ou qu’il faut reconstruire un nœud, la dette technique explose. Ansible propose une approche radicalement différente : décrire l’état souhaité de chaque machine dans des fichiers YAML versionnés, puis laisser l’outil appliquer la configuration de manière idempotente.

Pourquoi passer à l’Infrastructure as Code

L’Infrastructure as Code (IaC) consiste à traiter la configuration de vos serveurs exactement comme du code applicatif : versionné dans Git, relu en pull request, testé avant déploiement. Les avantages sont concrets. La reproductibilité permet de recréer un environnement complet à partir de zéro en une commande. La traçabilité offre un historique clair de chaque modification apportée à l’infrastructure. L’auditabilité rend visible qui a changé quoi, quand, et pourquoi. Enfin, la scalabilité permet d’ajouter un nouveau serveur en l’inscrivant simplement dans l’inventaire.

Ansible se distingue des autres outils d’IaC (Terraform, Puppet, Chef) par son architecture sans agent : il se connecte en SSH aux machines cibles, exécute les tâches, et se déconnecte. Pas de daemon à installer, pas de PKI à maintenir. Pour une infrastructure open source de taille modeste à moyenne, c’est un atout majeur.

Structurer un projet Ansible pour une infrastructure multi-services

Un projet Ansible bien organisé repose sur trois piliers : l’inventaire, les rôles et les playbooks. L’inventaire décrit vos machines et les regroupe par fonction. Les rôles encapsulent la logique de configuration d’un service donné. Les playbooks orchestrent l’application des rôles sur les bons groupes de machines.

Voici une structure type pour un projet gérant une infrastructure comme celle d’askem.eu :

infrastructure/
├── inventory/
│   ├── production.yml
│   └── staging.yml
├── roles/
│   ├── common/          # Paquets de base, sécurité SSH, fail2ban
│   ├── docker/          # Installation et configuration de Docker
│   ├── nginx/           # Reverse proxy, certificats TLS
│   ├── keycloak/        # SSO et gestion d'identité
│   ├── ckan/            # Portail de données ouvertes
│   ├── nextcloud/       # Collaboration et stockage
│   ├── gitea/           # Forge Git auto-hébergée
│   ├── monitoring/      # Prometheus, Grafana, Loki
│   └── backup/          # Stratégie de sauvegarde automatisée
├── playbooks/
│   ├── site.yml         # Playbook principal
│   ├── deploy-ckan.yml
│   └── update-tls.yml
└── group_vars/
    ├── all.yml
    └── production.yml

L’inventaire : cartographier son infrastructure

L’inventaire YAML décrit chaque machine et son appartenance à un ou plusieurs groupes. Il peut aussi contenir des variables spécifiques à chaque hôte ou groupe :

all:
  children:
    webservers:
      hosts:
        proxy-01:
          ansible_host: 10.0.1.10
          nginx_worker_processes: 4
    appservers:
      hosts:
        app-01:
          ansible_host: 10.0.1.20
          services:
            - ckan
            - keycloak
            - nextcloud
        app-02:
          ansible_host: 10.0.1.21
          services:
            - gitea
            - superset
    monitoring:
      hosts:
        mon-01:
          ansible_host: 10.0.1.30

Les rôles : encapsuler la logique de configuration

Chaque rôle gère un aspect précis de l’infrastructure. Prenons l’exemple d’un rôle common qui sécurise la base de chaque serveur :

# roles/common/tasks/main.yml
---
- name: Mettre à jour les paquets système
  apt:
    upgrade: safe
    update_cache: yes
    cache_valid_time: 3600

- name: Installer les paquets de base
  apt:
    name:
      - curl
      - htop
      - unattended-upgrades
      - fail2ban
      - ufw
    state: present

- name: Configurer le pare-feu UFW
  ufw:
    rule: allow
    port: "{{ item }}"
    proto: tcp
  loop:
    - "22"
    - "80"
    - "443"

- name: Activer le pare-feu
  ufw:
    state: enabled
    default: deny

- name: Durcir la configuration SSH
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: "{{ item.regexp }}"
    line: "{{ item.line }}"
  loop:
    - { regexp: '^#?PermitRootLogin', line: 'PermitRootLogin no' }
    - { regexp: '^#?PasswordAuthentication', line: 'PasswordAuthentication no' }
  notify: restart sshd

L’idempotence est la propriété clé : chaque tâche vérifie l’état actuel avant d’agir. Si le pare-feu est déjà configuré correctement, Ansible ne touche à rien. On peut relancer le playbook autant de fois qu’on veut sans effet de bord.

Gérer les secrets avec Ansible Vault

Une infrastructure réelle contient des mots de passe de base de données, des clés API, des certificats. Ansible Vault permet de chiffrer ces données directement dans le dépôt Git, sans compromettre la sécurité :

# Chiffrer un fichier de variables sensibles
ansible-vault encrypt group_vars/production/vault.yml

# Exécuter un playbook avec déchiffrement
ansible-playbook -i inventory/production.yml playbooks/site.yml --ask-vault-pass

# Ou utiliser un fichier de mot de passe (pour la CI/CD)
ansible-playbook -i inventory/production.yml playbooks/site.yml \
  --vault-password-file ~/.vault_pass

Les variables chiffrées sont utilisées comme n’importe quelle autre variable dans les templates et les tâches. L’intégration avec Gitea Actions permet d’automatiser le déploiement tout en gardant les secrets protégés.

Intégrer Ansible dans une chaîne CI/CD

L’étape suivante consiste à déclencher les playbooks automatiquement. Avec Gitea Actions (déjà couvert sur ce site), on peut créer un workflow qui exécute Ansible à chaque push sur la branche principale du dépôt d’infrastructure :

# .gitea/workflows/deploy.yml
name: Deploy infrastructure
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Ansible
        run: pip install ansible

      - name: Run playbook
        env:
          ANSIBLE_VAULT_PASSWORD: ${{ secrets.VAULT_PASSWORD }}
          SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_KEY }}
        run: |
          echo "$SSH_PRIVATE_KEY" > /tmp/deploy_key
          chmod 600 /tmp/deploy_key
          echo "$ANSIBLE_VAULT_PASSWORD" > /tmp/vault_pass
          ansible-playbook -i inventory/production.yml playbooks/site.yml \
            --vault-password-file /tmp/vault_pass \
            --private-key /tmp/deploy_key

Chaque modification de l’infrastructure passe par une pull request, est relue, puis appliquée automatiquement. Plus de SSH en direct sur les serveurs pour modifier une configuration à la volée.

Bonnes pratiques pour un projet Ansible durable

Quelques principes éprouvés pour maintenir un projet Ansible sur la durée. Premièrement, versionner tout : inventaires, rôles, playbooks, variables (chiffrées). Le dépôt Git est la source de vérité unique. Deuxièmement, séparer les environnements avec des inventaires distincts pour staging et production, en partageant les mêmes rôles. Troisièmement, tester avant de déployer en utilisant le mode --check (dry run) et l’option --diff pour visualiser les changements avant de les appliquer. Quatrièmement, documenter les rôles avec un fichier README.md dans chaque rôle décrivant ses variables, ses dépendances et son usage. Enfin, limiter la portée : un playbook qui prend plus de 10 minutes à s’exécuter est probablement trop large — découpez-le en playbooks ciblés.

Aller plus loin

Ansible peut aussi gérer le provisionnement de conteneurs Docker (via le module community.docker), orchestrer des mises à jour rolling sur plusieurs serveurs, ou encore générer dynamiquement des fichiers de configuration Nginx à partir de templates Jinja2. Combiné à un inventaire dynamique qui interroge votre hyperviseur ou votre cloud provider, il devient le point d’entrée unique pour toute opération sur l’infrastructure.

Pour une infrastructure comme celle d’askem.eu, le passage à Ansible représente un investissement initial de quelques jours qui se rentabilise dès la première reconstruction de serveur ou le premier audit de sécurité. L’infrastructure cesse d’être un savoir tacite dans la tête de l’administrateur pour devenir un artefact versionné, testable et partageable.