Prendre rendez-vous
  1. Accueil
  2. /
  3. Blog
  4. /
  5. Testinfra : tester son infrastructure avec pytest

DevOps
Administration
Linux

Testinfra : tester son infrastructure avec pytest

10 juin 2026

7 min de lecture

Sommaire
Plan de l'article
Pourquoi tester l'infrastructure
Testinfra : architecture et fonctionnement
Premiers tests : services, ports, fichiers
Tests sur backends multiples (SSH, Docker, Ansible)
Intégration avec Ansible et Molecule
Tests réseau, firewall, et conformité
Patterns pytest avancés : fixtures, parametrize
Comparaison avec Goss et Inspec
Sources

Tester l'infrastructure n'est plus optionnel. Les déploiements sans tests post-provisioning génèrent des incidents systématiquement le lundi matin : un service oublié, un firewall mal configuré, un fichier de conf avec une coquille. Goss, Inspec, Testinfra automatisent la validation. Chacun avec ses forces.

Testinfra est l'option Python pour les équipes qui maîtrisent déjà pytest. On écrit les tests d'infrastructure dans le même langage et avec les mêmes patterns que les tests applicatifs. Idéal pour les équipes qui versionnent leurs configs Ansible et veulent une boucle "écrire le test → modifier l'Ansible → faire passer le test" cohérente.

Pour les ops qui font du Python au quotidien, c'est l'outil naturel. Pour les autres, Goss reste plus simple.

Plan de l'article

  • Pourquoi tester l'infrastructure
  • Testinfra : architecture et fonctionnement
  • Premiers tests : services, ports, fichiers
  • Tests sur backends multiples (SSH, Docker, Ansible)
  • Intégration avec Ansible et Molecule
  • Tests réseau, firewall, et conformité
  • Patterns pytest avancés : fixtures, parametrize
  • Comparaison avec Goss et Inspec

Pourquoi tester l'infrastructure

Trois raisons concrètes pour valider l'état d'un serveur après provisioning.

Validation post-déploiement. Après ansible-playbook site.yml sur 50 serveurs, on veut vérifier que tout est conforme. Sans test, on découvre un service éteint sur 3 hôtes après mise en prod.

Régression sur configuration. Une PR Ansible modifie un rôle. Sans test, le commit casse silencieusement un autre rôle dépendant. Avec test, la CI bloque le merge.

Conformité et audit. CIS benchmark, PCI-DSS, ISO 27001 demandent preuves que les contrôles sont en place. Une suite de tests Testinfra exécutée régulièrement produit ces preuves automatiquement.

Documentation exécutable. Le test "le service nginx doit être actif et écouter sur 443" sert de doc en plus de garantie. Plus à jour que n'importe quel wiki.

C'est l'équivalent serveurs de la TDD applicative. La maturité de la pratique côté ops est en retard, mais les outils existent.

Testinfra : architecture et fonctionnement

Testinfra est un plugin pytest. Il fournit des modules pour interroger des serveurs depuis pytest et asserter des propriétés.

Backends supportés :

  • SSH : tests via SSH, le mode classique.
  • Docker : tests à l'intérieur d'un conteneur Docker.
  • Podman : équivalent Podman.
  • LXC : conteneurs LXC.
  • Kubernetes : tests dans des Pods K8s.
  • WinRM : Windows.
  • Ansible : utilise un inventaire Ansible pour déterminer les hôtes cibles.
  • Local : tests sur la machine qui exécute pytest.

Le module testinfra.host.Host fournit des propriétés de base :

  • host.service("nginx") retourne un objet Service avec .is_running, .is_enabled.
  • host.file("/etc/nginx/nginx.conf") retourne un objet File avec .exists, .contains, .user, .group, .mode.
  • host.package("openssl") retourne un Package avec .is_installed, .version.
  • host.process pour interroger les processus.
  • host.socket("tcp://0.0.0.0:443") pour les ports en écoute.
  • host.user("nginx") pour les utilisateurs.
  • host.command("uname -r") pour exécuter une commande arbitraire.

L'API est cohérente, type-friendly, intégrée à pytest.

Premiers tests : services, ports, fichiers

Setup minimal :

pip install pytest testinfra
mkdir tests

Premier test tests/test_baseline.py :

def test_nginx_service(host):
    nginx = host.service("nginx")
    assert nginx.is_running
    assert nginx.is_enabled

def test_nginx_listening(host):
    assert host.socket("tcp://0.0.0.0:80").is_listening
    assert host.socket("tcp://0.0.0.0:443").is_listening

def test_nginx_config(host):
    config = host.file("/etc/nginx/nginx.conf")
    assert config.exists
    assert config.user == "root"
    assert config.mode == 0o644
    assert config.contains("worker_processes auto;")

def test_no_anonymous_ftp(host):
    vsftpd = host.service("vsftpd")
    if vsftpd.exists:
        config = host.file("/etc/vsftpd.conf")
        assert config.contains("anonymous_enable=NO")

Exécution :

pytest --hosts="ssh://prod-web-01.exemple.fr,ssh://prod-web-02.exemple.fr" -v

Sortie pytest classique avec PASS/FAIL par test.

Tests sur backends multiples (SSH, Docker, Ansible)

Pour tester un parc Ansible :

pytest --hosts='ansible://all' --ansible-inventory=/etc/ansible/hosts -v

Testinfra parse l'inventaire Ansible, exécute les tests sur chaque host. Compatible avec les pratiques Ansible standards.

Pour tester une image Docker (ou un container Bootc à valider) :

pytest --hosts='docker://my-container' -v

Pour tester avec Molecule (qui orchestre tests Ansible roles), Testinfra est l'outil de validation par défaut. Molecule provisionne un container, lance le rôle, exécute les tests Testinfra, démolit.

Intégration avec Ansible et Molecule

Pattern Molecule + Testinfra :

# molecule/default/molecule.yml
driver:
  name: docker
platforms:
  - name: instance
    image: debian:12
provisioner:
  name: ansible
verifier:
  name: testinfra

Tests Testinfra dans molecule/default/tests/test_default.py :

def test_role_applied(host):
    # Vérifier les services et configs déployés par le rôle
    assert host.service("postgresql").is_running
    assert host.file("/etc/postgresql/15/main/pg_hba.conf").contains("hostssl")

def test_users_created(host):
    user = host.user("appuser")
    assert user.shell == "/bin/bash"
    assert "developers" in user.groups

Cycle CI :

molecule test
# Provisionne le container, applique le rôle Ansible, exécute Testinfra, démolit

Pour les pipelines, intégrer dans GitLab CI ou GitHub Actions :

test-roles:
  image: python:3.11
  script:
    - pip install molecule[ansible,docker] testinfra
    - cd ansible/roles/postgres
    - molecule test

Tests réseau, firewall, et conformité

Pour des tests réseau et firewall :

def test_firewall_ssh_only_internal(host):
    # nftables policy
    output = host.run("nft list ruleset")
    assert "tcp dport 22 ip saddr 10.0.0.0/8 accept" in output.stdout

def test_no_listening_unexpected_port(host):
    # Aucun service ne doit écouter sur des ports non documentés
    expected_ports = [22, 80, 443]
    output = host.run("ss -tlnp | awk '{print $4}' | grep -oE ':[0-9]+$'")
    listening = {int(p[1:]) for p in output.stdout.splitlines() if p}
    assert listening.issubset(set(expected_ports))

def test_pam_password_complexity(host):
    pam_pwquality = host.file("/etc/security/pwquality.conf")
    assert pam_pwquality.contains("minlen = 14")
    assert pam_pwquality.contains("dcredit = -1")

Pour de la conformité CIS, voir cis-benchmark-audit qui couvre les contrôles à automatiser.

Patterns pytest avancés : fixtures, parametrize

Testinfra hérite de pytest, donc tous les patterns avancés sont disponibles.

Fixtures pour partager du setup :

import pytest

@pytest.fixture
def nginx_config(host):
    return host.file("/etc/nginx/nginx.conf")

def test_nginx_config_exists(nginx_config):
    assert nginx_config.exists

def test_nginx_worker_count(nginx_config):
    assert nginx_config.contains("worker_processes auto;")

Parametrize pour tester plusieurs valeurs :

@pytest.mark.parametrize("service", ["nginx", "postgresql", "redis", "fail2ban"])
def test_critical_services_running(host, service):
    s = host.service(service)
    assert s.is_running
    assert s.is_enabled

Markers pour grouper les tests :

@pytest.mark.security
def test_ssh_no_root_login(host):
    sshd = host.file("/etc/ssh/sshd_config")
    assert sshd.contains("PermitRootLogin no")

@pytest.mark.compliance
def test_audit_running(host):
    assert host.service("auditd").is_running

Exécution sélective : pytest -m security pour ne lancer que les tests sécurité.

Comparaison avec Goss et Inspec

CritèreTestinfraGossInspec
LangagePython (pytest)YAMLRuby DSL
Cible primaireServeurs AnsibleContainers, imagesServeurs, conformité
VitesseRapideTrès rapideMoyenne
CIS profiles natifsNonLimitéOui
Reportingpytest standardJSON, junitExcellence (HTML, JSON, JUnit)
Courbe apprentissageFaible si PythonTrès faibleMoyenne
CommunautéActiveActiveActive (Chef)

Testinfra gagne pour les équipes Python avec stack Ansible. Goss gagne pour les tests d'images container/Bootc rapides. Inspec gagne sur les profils CIS prêts à l'emploi et le reporting de conformité.

Sur les pipelines Packer + Ansible golden images, on voit souvent les trois cohabiter : Goss pour les images, Testinfra pour les tests post-Ansible, Inspec pour les rapports d'audit conformité formels.

Testinfra est l'outil par défaut quand l'équipe Ops a une appétence Python. Dans les autres contextes, Goss prend la place. L'objectif n'est pas l'outil mais l'existence de tests : 10 tests Goss valent mieux que 0 tests Testinfra parfaits jamais écrits. Écrire puis maintenir cette suite par-dessus l'exploitation courante demande du temps que peu d'équipes ont ; cette part se confie.

Sources

  • Testinfra documentation officielle : référence install, modules, examples.
  • GitHub pytest-dev/pytest-testinfra : code source.
  • pytest documentation officielle : framework parent, fixtures, parametrize.
  • Molecule documentation : framework de test pour rôles Ansible.
  • Goss tool : alternative YAML pour images.
  • Chef Inspec : alternative pour conformité formelle.
Besoin d'aide sur ce sujet ?

Notre équipe d'experts est là pour vous accompagner dans vos projets d'infrastructure et d'infogérance.

Contactez-nous

Articles similaires

Python pour les sysadmins : automatiser son infrastructure efficacement
Administration
DevOps
Linux

Python pour les sysadmins : automatiser son infrastructure efficacement

Exploitez Python pour automatiser l'administration système. Bibliothèques essentielles, scripts pratiques et comparaison avec Bash pour l'infrastructure.

25 févr. 2026

Lire plus

Cron et Crontab Linux 2026 : guide complet planification tâches automatiques
Administration
DevOps
Linux

Cron et Crontab Linux 2026 : guide complet planification tâches automatiques

Maîtriser cron et crontab Linux 2026 : syntaxe complète, exemples concrets, alternatives systemd timers, debugging et bonnes pratiques production. Guide débutant à expert.

25 janv. 2026

Lire plus

systemd-cryptenroll et TPM2 : déchiffrement automatique LUKS
Sécurité
Linux
Administration

systemd-cryptenroll et TPM2 : déchiffrement automatique LUKS

Lier une partition LUKS au TPM2 de la machine avec systemd-cryptenroll. Déchiffrement automatique au boot, attestation Secure Boot, sealing PCR, retours ops.

8 juin 2026

Lire plus


SHPV, votre partenaire de confiance en infrastructure et infogérance informatique en France.

SHPV
Prendre rendez-vousNous contacter
Expertise
InfrastructureDatacenterInfogéranceCloudHébergementTransit IP
Légales
Conditions Générales de VenteCPS - Contrat de ServicesCPS - Hébergement CloudCPS - Microsoft 365Accord sous-traitance RGPDTarifs interventions

SHPV © 2026 - Tous droits réservés

Mentions légalesPolitiques de confidentialité
SHPV FRANCE - SAS au capital de 16 000 € - 52 Rue Romain Rolland, 71230 Saint-Vallier - SIRET n°80886287400035 - R.C.S. Chalon-sur-Saône. Par téléphone 09 72 310 818 - Email: support@shpv.fr