Aller au contenu principal

Testez votre infrastructure avec Testinfra

Dans le monde du DevOps, assurer la fiabilité et la sécurité de nos environnements de production est essentiel. C'est là que Testinfra entre en jeu, en nous permettant de tester notre infrastructure avec la même rigueur que nous appliquons aux tests de notre code. En adoptant les principes de l'Infrastructure as Code (IaC), Testinfra nous aide à automatiser et à valider les configurations de nos serveurs, nous assurant ainsi que notre infrastructure répond aux exigences précises de nos projets.

Historique de Testinfra

Testinfra a vu le jour dans un contexte où l'automatisation de l'infrastructure devenait de plus en plus importante pour les équipes DevOps. La nécessité de tester l'infrastructure avec la même attention que le code applicatif a conduit au développement de cet outil, conçu pour étendre les capacités de test au-delà du code vers les systèmes et les services eux-mêmes.

L'outil s'est développé sur la base de pytest, un framework de test populaire dans l'écosystème Python, profitant de sa flexibilité et de sa puissance pour offrir une solution dédiée au testing d'infrastructure. Cette fondation permet à Testinfra de bénéficier d'une syntaxe familière pour ceux qui ont déjà une expérience avec pytest, facilitant ainsi l'adoption de l'outil par de nouvelles équipes.

Au fil du temps, Testinfra a évolué pour supporter une gamme plus large de backends de test, y compris SSH, Docker et Salt, permettant aux utilisateurs de tester leurs configurations sur diverses plateformes et environnements. Cette évolution reflète les changements dans les pratiques DevOps, où les environnements sont de plus en plus diversifiés et distribués.

L'intégration avec d'autres outils et frameworks, comme Ansible, a également marqué l'évolution de Testinfra, le positionnant comme un choix privilégié pour les équipes cherchant à implémenter des tests d'infrastructure automatisés dans leurs pipelines CI/CD. La capacité de Testinfra à s'intégrer dans des environnements complexes et à tester efficacement l'infrastructure a renforcé son rôle dans l'assurance de la qualité des déploiements en production.

Aujourd'hui, Testinfra est reconnu pour sa robustesse et sa flexibilité, offrant aux équipes DevOps un outil précieux pour garantir que leur infrastructure est aussi fiable et sécurisée que leur code.

Concepts clés de Testinfra

Testinfra repose sur plusieurs concepts clés qui le rendent puissant et flexible pour tester l'infrastructure. Comprendre ces concepts est essentiel pour tirer pleinement parti de l'outil et intégrer efficacement les tests d'infrastructure dans les pratiques de développement et de déploiement.

Tests unitaires d'infrastructure

L'idée principale derrière Testinfra est d'appliquer les principes des tests unitaires au monde de l'infrastructure. Cela signifie écrire des tests qui vérifient individuellement les composants de votre infrastructure pour s'assurer qu'ils fonctionnent comme prévu. Par exemple, vérifier si un service est en cours d'exécution, si un fichier de configuration contient les bonnes valeurs, ou si les ports nécessaires sont ouverts.

Assertions

Les assertions sont au cœur des tests avec Testinfra. Elles permettent de déclarer des états attendus de l'infrastructure et de vérifier que ces états sont effectivement atteints. Par exemple, une assertion peut vérifier qu'un package est installé, qu'un service est actif et en cours d'exécution, ou que les réponses à des commandes spécifiques correspondent aux attentes.

Backends de test

Testinfra offre la flexibilité de tester une large gamme d'environnements grâce à son support de multiples backends de test. Que votre infrastructure tourne localement, sur des machines virtuelles, dans des conteneurs Docker, ou à via des connexions SSH sur des serveurs distants, Testinfra peut être configuré pour exécuter des tests dans ces différents contextes. Cette capacité rend Testinfra particulièrement adapté aux environnements cloud modernes et distribués.

Installation de TestInfra

Pour commencer à utiliser Testinfra, l'installation est simple et directe grâce à Python et pip, le système de gestion de paquets Python. Voici comment vous pouvez configurer Testinfra dans votre projet.

Installation via pip

La première étape consiste à installer Testinfra en utilisant pip. Vous pouvez le faire en exécutant la commande suivante dans votre terminal :

pip install pytest-testinfra --user

Cette commande installe Testinfra ainsi que ses dépendances, y compris pytest, si ce n'est pas déjà fait.

Ecrire ses Premiers Tests avec TestInfra

Après l'installation, vous pouvez commencer à écrire vos premiers tests d'infrastructure. Testinfra utilise pytest comme moteur de test, ce qui signifie que vous écrivez vos tests dans des fichiers Python standard. Les tests peuvent être organisés de la manière qui vous convient le mieux, mais il est courant de les placer dans un répertoire dédié, comme tests/.

Créez un fichier nommé test_openssh.py dans votre répertoire de tests. Voici un exemple simple de ce à quoi pourrait ressembler un test Testinfra :

def test_openssh_is_installed(host):
    openssh = host.package("openssh-server")
    assert openssh.is_installed, "Le paquet openssh-server devrait être installé"

Ce test vérifie si le paquet openssh-server est installé sur le système cible.

Supposons que vous voulez vous assurer que le service SSH tourne avec une configuration spécifique, comme le port d'écoute et les options de clés. Voici comment vous pourriez écrire ces tests :

def test_sshd_config(host):
    sshd_config = host.file('/etc/ssh/sshd_config')
    assert sshd_config.exists
    assert sshd_config.contains('PermitRootLogin no')
    assert sshd_config.contains('Port 22')

Ce test vérifie que le fichier sshd_config existe, interdit la connexion en tant que root et utilise le port 22 pour SSH.

Pour tester certaines configurations de sécurité, comme s'assurer que le pare-feu est activé et configuré correctement, vous pouvez utiliser Testinfra pour interroger le système :

def test_firewall_status(host):
    firewall = host.service('ufw')
    assert firewall.is_running
    assert firewall.is_enabled

Ce test vérifie que le service de pare-feu UFW est actif et qu'il est configuré pour démarrer automatiquement au boot du système.

Vous pouvez également tester la connectivité réseau et les configurations de base, par exemple, en vérifiant si un serveur peut se connecter à un autre sur un port spécifique. Testinfra permet d'exécuter des commandes et de vérifier leur sortie, ce qui peut être utilisé pour tester la connectivité :

def test_connectivity_to_external_resource(host):
    command = host.run("curl -I http://example.com")
    assert command.rc == 0
    assert 'HTTP/1.1 200 OK' in command.stdout

Ce test utilise curl pour vérifier la capacité du serveur à atteindre example.com et reçoit une réponse HTTP 200, indiquant que la connectivité réseau de base fonctionne comme attendu.

Vous pouvez consulter mon billet sur le TDD appliquer à des playbooks ansible.

Les tests possibles avec Testinfra

Testinfra offre une série de modules pour tester différents aspects d'un système. Voici une liste non exhaustive des types de tests que vous pouvez réaliser avec Testinfra :

  • Tests de Paquets : Vérifier si les paquets logiciels sont installés et leur version.
  • Tests de Services : S'assurer que les services sont en cours d'exécution et activés.
  • Tests de Fichiers : Contrôler les permissions, le contenu et l'existence de fichiers et de dossiers.
  • Tests d'Utilisateurs et de Groupes : Vérifier l'existence d'utilisateurs et de groupes ainsi que leurs propriétés.
  • Tests de Ports : S'assurer que les ports spécifiques sont ouverts ou fermés.
  • Tests de Commandes : Exécuter des commandes et vérifier leur sortie standard, sortie d'erreur et code de retour.
  • Tests de Configuration de Réseau : Examiner la configuration réseau, y compris les adresses IP, les routes et les interfaces réseau.
  • Tests de Sockets : Vérifier l'écoute des sockets TCP/UDP.
  • Tests de Système de Fichiers : Analyser l'espace disque et le montage des systèmes de fichiers.

La documentation de Testinfra sur Read the Docs est le meilleur point de départ. Elle contient des guides, des références API et des exemples de tests.

Exécution des tests

Pour exécuter vos tests Testinfra, utilisez la commande pytest dans le répertoire racine de votre projet ou spécifiez le chemin vers vos tests. Testinfra et pytest découvriront et exécuteront automatiquement les tests définis dans les fichiers.

pytest tests/
== test session starts ===
platform linux -- Python 3.10.12, pytest-8.0.0, pluggy-1.4.0
rootdir: /home/bob/Projects/perso/testinfra
plugins: testinfra-10.0.0, testinfra-6.0.0
collected 1 item

tests/test_example.py .                                                                                                                                                    [100%]

=== 1 passed in 0.02s ====

Spécifier un backend

Testinfra vous permet de tester différents environnements en spécifiant un backend. Par exemple, pour tester une machine distante via SSH, vous pouvez passer l'option --hosts=ssh:// à pytest :

pytest --hosts=ssh://192.168.1.102 tests/
== test session starts ===
platform linux -- Python 3.10.12, pytest-8.0.0, pluggy-1.4.0
rootdir: /home/bob/Projects/perso/testinfra
plugins: testinfra-10.0.0
collected 1 item

tests/test_example.py . [100%]

=== 1 passed in 2.06s ====

Testinfra peut utiliser Ansible comme backend pour exécuter des tests sur vos hôtes gérés par Ansible. Cela vous permet de tirer parti de votre inventaire Ansible existant et de la puissance d'Ansible pour le setup de test. Voici comment vous pourriez spécifier Ansible comme backend dans votre commande pytest :

pytest --hosts=ansible://all

Conclusion

L'adoption de Testinfra pour le testing d'infrastructure représente une avancée significative dans la manière dont les équipes DevOps assurent la fiabilité, la sécurité et la conformité de leurs environnements. En appliquant les principes du développement logiciel, tels que les tests unitaires, à l'infrastructure, Testinfra permet une automatisation profonde et une vérification rigoureuse des configurations système et réseau.

En conclusion, intégrer Testinfra dans vos workflows de développement et d'opération peut transformer la façon dont vous testez et maintenez votre infrastructure. Cela conduit non seulement à une plus grande assurance qualité, mais également à une plus grande tranquillité d'esprit, sachant que chaque déploiement repose sur une base solide et vérifiée. L'avenir du testing d'infrastructure est prometteur avec des outils comme Testinfra et je suis enthousiaste à l'idée de voir comment il continuera à évoluer et à façonner les meilleures pratiques dans l'espace DevOps.

D'ailleurs, je me demande si on ne pourrait pas utiliser Testinfra pour créer un outil de vérification de compliance. Je vais tester d'autres outils comme serverspec, goss, ... avant de me lancer dans ce projet.

Plus d'infos

Pour approfondir vos connaissances sur Testinfra ou contribuer à la communauté, voici quelques liens utiles :