Infrastructure en tant que code et TDD

11

L'infrastructure en tant que code nous dit d'utiliser des outils qui automatisent vos builds. Génial. Des outils comme ansible , chef , marionnette , pile de sel et autres nous poussent à écrire à quoi ressemble l'infrastructure, tout en résolvant les différences.

Dans Salt Stack, ces bits sont appelés états . Si l'état ne correspond pas à la réalité, l'outil le résoudra pour nous. En d'autres termes - nous écrivons un test pour notre infrastructure et si le test échoue, l'outil le réparera de lui-même. C'est du moins l'idée.

XP nous apprend à utiliser TDD et la question est de savoir s'il est applicable à l'infrastructure? L'outillage le suggère.

Je peux imaginer quelques types de tests qui peuvent être très utiles.

Nous rédigeons des tests de fumée fournis avec le service déployé pour garantir que le service déployé de bout en bout fonctionne et s'exécute comme prévu. Ce serait un appel d'API ou / et une vérification de systemctl pour vous assurer que ce que nous venons de déployer fonctionne. Une grande partie de cette fonctionnalité peut être couverte dans les mêmes états car des outils comme ansible ont des états pour s'assurer qu'un service est en cours d'exécution.

Il existe un projet Molecule qui permet d'exécuter des rôles individuels (comme l'appelle ansible ses états) contre Docker ou un autre moteur de virtualisation temporaire. Cela oblige à découpler les rôles et permet de les exécuter indépendamment du playbook tout en travaillant dessus. Les tests permettent principalement de se moquer des variables avec lesquelles le rôle est censé fonctionner. Cependant, d'autres exemples semblent être une duplication du moteur ansible (affirmer qu'un fichier appartient à un utilisateur ...).

Le radar technologique de ThoughtWorks vante en ce moment des outils comme inspec , serverspec ou goss pour valider que le serveur répond aux spécifications. Mais nous écrivons une spécification, n'est-ce pas?

Alors, y a-t-il un intérêt à tester davantage l'infrastructure si nous décrivons l'infrastructure dans les états / rôles? Je pourrais soupçonner que cela devient plus nécessaire dans les grandes organisations où une équipe fournit les spécifications et d'autres suit, ou s'il y a un grand ensemble de rôles, vous voudrez peut-être exécuter un sous-ensemble de ceux-ci et bénéficier de la vitesse des tests? J'ai du mal à voir pourquoi vous écririez un test si vous pouviez avoir un rôle / état pour la même question à l'esprit.

JackLeo
la source

Réponses:

6

En bref, je vois deux catégories de tests pour votre infrastructure: 1) a-t-il tout ce dont vous avez besoin pour exécuter votre application et 2) n'a-t-il rien de superflu.

Tout d'abord, vous pouvez traiter la suite de tests de votre logiciel réel comme une sorte de «méta-test» pour votre infrastructure. Tant que vous créez l'infrastructure à partir de zéro pour chaque exécution de test et que la suite de tests s'exécute complètement sur cette infrastructure (c'est-à-dire qu'elle n'utilise pas de services externes), le fait que toute la suite soit verte signifie que votre infrastructure codifiée est également suffisante. .

Deuxièmement, en particulier du point de vue de la sécurité, vous pouvez écrire des tests sur votre infrastructure. C'est-à-dire, si une partie de votre infrastructure est une machine virtuelle exécutant Linux, vous pouvez écrire un test qui effectue une analyse des ports par rapport à cette machine virtuelle, pour vous assurer qu'aucun port involontaire n'est ouvert, ce qui peut avoir été installé par un apt-get installeffet secondaire involontaire. . Ou vous pouvez écrire des tests qui vérifient si des fichiers inattendus ont été modifiés après la fin de votre suite de tests appropriée. Ou vous pouvez vérifier les pssorties de vos machines virtuelles ou conteneurs Docker pour les processus inattendus et autres, créer des listes blanches, etc., et ainsi obtenir une notification automatique si un package tiers a changé de manière non documentée (ou inaperçue) dans une mise à niveau.

Ces deuxièmes types de tests sont, en quelque sorte, similaires à ce que vous feriez de toute façon dans un environnement d'opérations classique, c'est-à-dire durcir vos serveurs et vérifier les intrusions, éviter la pleine ressource et autres.

AnoE
la source
Donc, après un certain temps, c'est exactement la position que j'ai prise. Les parties exécutées par ansible ne sont pas testées par elles-mêmes, mais les effets secondaires de ces actions sont testés à l'aide goss. Ainsi, par exemple, RPM est installé (ansible) puis testé si le fichier par défaut attendu est mis en place, ou si le service est en cours d'exécution et écoute un port spécifique. Je ne veux pas résoudre ce problème automatiquement, mais soyez averti et arrêtez la progression. Bien sûr, Ansible peut également tester le système pour vous, il vous suffit d'être explicite à ce sujet, mais dans notre cas, nous utilisons gosspour tester le comportement du service dans un conteneur
JackLeo
1

À mon humble avis, il est plutôt redondant d'écrire des tests TDD pour des éléments entièrement couverts par la spécification d'état IaaC. Cela implique que l'efficacité de l'IaaC est discutable - pourquoi l'utiliseriez-vous dans ce cas?

Le regarder d'un autre IaaC prospectif lui-même (si / quand fait correctement) intègre des capacités déjà testées et considérées comme fonctionnant de manière fiable. C'est ce qui le rend attractif et rend redondant l'écriture de tests d'appariement TDD.

Par exemple, une configuration IaaC spécifiant un système avec SSH en cours d'installation intègre déjà une vérification fiable de la bonne installation de SSH et, sinon, des mécanismes pour l'installer correctement. Ce qui rend un test TDD pour vérifier si SSH est installé redondant. Si votre configuration IaaC spécifie également que sshd doit être démarré et écouté sur un port spécifique, les tests TDD pour l'exécution de sshd et l'écoute du port respectif seraient également redondants.

Notez que ma réponse ne cible pas TDD ou tout autre type de test qui vérifie si votre configuration IaaC dans son ensemble correspond à un certain objectif. Cela reste valable et peut être utilisé dans les vérifications TDD, CI ou similaires pendant le développement de cette spécification IaaC - je crois que la réponse de @ AnoE est applicable dans ce cas.

Dan Cornilescu
la source
Appliquez-vous la même pensée pour vous assurer que SSH (ou autre) est activé sur un port personnalisé spécifique, qui est analysé à partir d'un fichier de configuration externe? Cela ne repose pas sur des unités testées, c'est une nouvelle logique.
Jon Lauridsen
1
Il devrait faire partie de l'IaaC, s'il le prend en charge. Sinon - alors cette discussion ne s'applique pas vraiment. Oui, cela pourrait glisser sur la quantité de choses pouvant être couvertes par l'IaaC, mais c'est une discussion différente.
Dan Cornilescu
1
Je suppose également que nous ne sommes pas dans un contexte où des vérifications redondantes sont requises - dans certains cas, des vérifications redondantes suivant des chemins de code complètement différents ou même une infrastructure peuvent être nécessaires.
Dan Cornilescu
1

Il semble que tout le monde ici suppose qu'un outil IAC fonctionne toujours comme prévu, mais je peux dire (d'après ma propre expérience) que ce n'est pas toujours le cas, sinon le test unitaire serait en fait inutile.

Je me souviens d'une photo disant "Ansible playbook a couru, tout va bien" avec un bâtiment brûlant en arrière-plan ...

Exécuter un état déclaratif et avoir le serveur dans cet état déclaré réel sont au moins deux choses différentes de mon point de vue et de mon expérience.

Un environnement large et hétérogène, réparti sur plusieurs DC, accessible via le réseau public, etc.

Pour toutes ces raisons, il y a de la place pour des tests unitaires permettant d'obtenir un instantané de l'état réel du serveur, qui, encore une fois, peut différer de l'état visé.

Je dirais donc oui, les tests unitaires sont utiles même dans un environnement géré par IAC.

ÉDITER

Qu'en est-il du côté non-régression de la branche dev de la base de code IaC? donc vous feriez des changements à votre code dans la branche dev et le fusionneriez à la branche prod en espérant ne pas tout casser? les tests unitaires sont si précieux, et généralement simples à mettre en œuvre Je ne vois pas pourquoi on coderait sans cette fonctionnalité.

Référence (désolé pour ça): https://fr.slideshare.net/logilab/testinfra-pyconfr-2017

Jetée
la source
1
Ce serait au moins poli d'ajouter un commentaire avec un vote négatif, ne pensez-vous pas, votant contre? Surtout sur ce genre de question où le débat pourrait être très informatif voire constructif.
Pier
Je suppose que le ton de votre réponse qui est assez agressif pour tous ceux qui ont interagi avec cette question, ajouté au fait que vous ne donnez aucune référence à partir de votre propre exemple ni ne décrivez aucun dysfonctionnement observé était la raison du vote négatif. Vous finissez par dire la même chose que les autres réponses, faites des tests de fumée dans votre système d'approvisionnement pour vous assurer que le système est OK, ce que la plupart des systèmes échouent s'ils ne peuvent pas faire converger le système dans l'état souhaité. Concernant votre montage, la fusion se fait généralement après le déploiement en mise en scène et la réussite des tests de fumée ...
Tensibai
Je n'avais certainement pas l'intention d'être agressif, je n'utilise pas ici mon langage natif (c'est évident je suppose :)).
Pier
Nous pouvons en discuter dans DevOps Chat si vous le souhaitez, je pense avoir vu cette présentation ou une autre lors d'un événement devoxx il y a quelques années. Je suis légèrement en désaccord avec le fait d'appeler ce test unitaire, ce sont des tests plus fonctionnels.
Tensibai
Quelqu'un de mon équipe de développement m'a dit la même chose que ce n'était pas un test unitaire, je ne suis pas un développeur, donc je peux me tromper d'appeler ce test unitaire, certainement
Pier
1

D'après mon expérience, l'une des principales différences entre Dev et Ops sont les "fortes dépendances de temps d'exécution". L'installation de packages dépend fortement des référentiels, des réseaux ou des clés valides, ou disons l'instanciation d'un nouveau serveur cloud - cela dépend des ressources de votre fournisseur.

En termes de provisionnement de serveur même si vous n'avez pas changé votre code de provision, votre image sera valide la plupart du temps mais parfois non. Je pense donc que les tests sont vraiment essentiels pour fournir des images de travail.

Si vous allez au-delà de serveurs uniques, les choses empirent encore ... comment allez-vous tester l'accessibilité dans des configurations de réseau entières? Y compris la résolution DNS, le routage et le pare-feu? Même si votre API de fournisseurs IaaC fonctionne comme prévu (j'ai vu des problèmes de câblage dans ce domaine), j'aime vraiment TDD dans ce cas.

Comme je n'ai trouvé aucun outil de test dans ce domaine, nous en avons rédigé un dans notre temps libre: https://github.com/DomainDrivenArchitecture/dda-serverspec-crate

Je pense donc que TDD est vraiment important dans le monde DevOps!

secousse
la source