Tester l'infrastructure en tant que code avec Pulumi. Partie 2

Salut tout le monde. Aujourd’hui, nous partageons avec vous la dernière partie de l’article. "Tester l'infrastructure en tant que code avec Pulumi", dont la traduction a été préparée spécifiquement pour les étudiants du cours "Pratiques et outils DevOps".

Tester l'infrastructure en tant que code avec Pulumi. Partie 2

Tests de déploiement

Ce style de test est une approche puissante et nous permet d'effectuer des tests en boîte blanche pour tester le fonctionnement interne de notre code d'infrastructure. Cependant, cela limite quelque peu ce que nous pouvons tester. Les tests sont effectués sur la base du plan de déploiement en mémoire créé par Pulumi avant le déploiement réel et le déploiement lui-même ne peut donc pas être testé. Pour de tels cas, Pulumi dispose d'un cadre de test d'intégration. Et ces deux approches fonctionnent très bien ensemble !

Le framework de test d'intégration Pulumi est écrit en Go, c'est ainsi que nous testons la plupart de notre code interne. Alors que l’approche des tests unitaires évoquée précédemment ressemblait davantage à des tests en boîte blanche, les tests d’intégration sont une boîte noire. (Il existe également des options pour des tests internes rigoureux.) Ce cadre a été créé pour prendre un programme Pulumi complet et y effectuer diverses opérations de cycle de vie, telles que le déploiement d'une nouvelle pile à partir de zéro, sa mise à jour avec des variantes et sa suppression, éventuellement plusieurs fois. . Nous les exécutons régulièrement (par exemple la nuit) et sous forme de tests de résistance.

(Nous nous y travaillons, afin que des fonctionnalités de test d'intégration similaires soient disponibles dans le SDK natif des langues. Vous pouvez utiliser le framework de test d'intégration Go quel que soit le langage dans lequel votre programme Pulumi est écrit).

En exécutant le programme à l'aide de ce framework, vous pouvez vérifier les éléments suivants :

  • Le code de votre projet est syntaxiquement correct et s'exécute sans erreurs.
  • Les paramètres de configuration de la pile et des secrets fonctionnent et sont interprétés correctement.
  • Votre projet peut être déployé avec succès chez le fournisseur cloud de votre choix.
  • Votre projet peut être mis à niveau avec succès de l’état initial vers N autres états.
  • Votre projet peut être détruit et supprimé avec succès de votre fournisseur de cloud.

Comme nous le verrons bientôt, ce framework peut également être utilisé pour effectuer une validation d'exécution.

Test d'intégration simple

Pour voir cela en action, nous examinerons le référentiel pulumi/examples, car notre équipe et la communauté Pulumi l'utilisent pour tester nos propres demandes d'extraction, commits et builds nocturnes.

Ci-dessous un test simplifié de notre exemple qui fournit le compartiment S3 et quelques autres objets:

exemple_test.go :

package test
 
import (
    "os"
    "path"
    "testing"
 
    "github.com/pulumi/pulumi/pkg/testing/integration"
)
 
func TestExamples(t *testing.T) {
    awsRegion := os.Getenv("AWS_REGION")
    if awsRegion == "" {
        awsRegion = "us-west-1"
    }
    cwd, _ := os.Getwd()
    integration.ProgramTest(t, &integration.ProgramTestOptions{
        Quick:       true,
        SkipRefresh: true,
        Dir:         path.Join(cwd, "..", "..", "aws-js-s3-folder"),
        Config: map[string]string{
            "aws:region": awsRegion,
        },
    })
}

Ce test passe par le cycle de vie de base de création, de modification et de destruction d'une pile pour un dossier. aws-js-s3-folder. Il faudra environ une minute pour signaler un test réussi :

$ go test .
PASS
ok      ... 43.993s

Il existe de nombreuses options pour personnaliser le comportement de ces tests. Voir la liste complète des options. dans la structure ProgramTestOptions. Par exemple, vous pouvez configurer le point de terminaison Jaeger pour tracer (Tracing), indiquez que vous vous attendez à ce que le test échoue si le test est négatif (ExpectFailure), appliquer une série de « modifications » au programme pour une transition séquentielle d'états (EditDirs) et beaucoup plus. Voyons comment les utiliser pour tester le déploiement de votre application.

Vérification des propriétés des ressources

L’intégration évoquée ci-dessus garantit que notre programme « fonctionne » : il ne plante pas. Mais que se passe-t-il si nous voulons vérifier les propriétés de la pile résultante ? Par exemple, que certains types de ressources ont (ou non) été provisionnés et qu’elles possèdent certains attributs.

Paramètre ExtraRuntimeValidation pour ProgramTestOptions nous permet d'examiner l'état post-déploiement enregistré par Pulumi afin que nous puissions effectuer des vérifications supplémentaires. Cela inclut un instantané complet de l'état de la pile résultante, y compris la configuration, les valeurs de sortie exportées, toutes les ressources et leurs valeurs de propriété, ainsi que toutes les dépendances entre les ressources.

Pour en voir un exemple basique, vérifions que notre programme en crée un Compartiment S3:

  integration.ProgramTest(t, &integration.ProgramTestOptions{
        // as before...
        ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) {
            var foundBuckets int
            for _, res := range stack.Deployment.Resources {
                if res.Type == "aws:s3/bucket:Bucket" {
                    foundBuckets++
                }
            }
            assert.Equal(t, 1, foundBuckets, "Expected to find a single AWS S3 Bucket")
        },
    })

Désormais, lorsque nous exécuterons go test, il effectuera non seulement une batterie de tests de cycle de vie, mais également, après un déploiement réussi de la pile, il effectuera une vérification supplémentaire sur l'état résultant.

Tests d'exécution

Jusqu'à présent, tous les tests portaient uniquement sur le comportement de déploiement et le modèle de ressources Pulumi. Que faire si vous souhaitez vérifier que votre infrastructure provisionnée fonctionne réellement ? Par exemple, que la machine virtuelle est en cours d'exécution, le compartiment S3 contient ce que nous attendons, et ainsi de suite.

Vous avez peut-être déjà deviné comment procéder : option ExtraRuntimeValidation pour ProgramTestOptions - c'est une excellente opportunité pour cela. À ce stade, vous exécutez un test Go personnalisé avec accès à l'état complet des ressources de votre programme. Cet état inclut des informations telles que les adresses IP des machines virtuelles, les URL et tout ce qui est nécessaire pour réellement interagir avec les applications et l'infrastructure cloud résultantes.

Par exemple, notre programme de test exporte la propriété webEndpoint seau appelé websiteUrl, qui est l'URL complète où nous pouvons obtenir le fichier configuré index document. Même si nous pourrions fouiller dans le dossier de l'État pour trouver bucket et lisez cette propriété directement, mais dans de nombreux cas, nos piles exportent des propriétés utiles comme celle-ci que nous trouvons pratiques à utiliser pour la vérification :

integration.ProgramTest(t, &integration.ProgramTestOptions{
            // as before ...
        ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) {
            url := "http://" + stack.Outputs["websiteUrl"].(string)
            resp, err := http.Get(url)
            if !assert.NoError(t, err) {
                return
            }
            if !assert.Equal(t, 200, resp.StatusCode) {
                return
            }
            defer resp.Body.Close()
            body, err := ioutil.ReadAll(resp.Body)
            if !assert.NoError(t, err) {
                return
            }
            assert.Contains(t, string(body), "Hello, Pulumi!")
        },
    })

Comme nos précédentes vérifications d'exécution, cette vérification sera exécutée immédiatement après avoir augmenté la pile, le tout en réponse à un simple appel go test. Et ce n'est que la pointe de l'iceberg : toutes les fonctionnalités de test Go que vous pouvez écrire dans le code sont disponibles.

Intégration continue de l'infrastructure

C'est bien de pouvoir exécuter des tests sur un ordinateur portable lorsque de nombreuses modifications d'infrastructure sont apportées pour les tester avant de les soumettre pour révision du code. Mais nous et bon nombre de nos clients testons l’infrastructure à différentes étapes du cycle de vie de développement :

  • Dans chaque demande d'extraction ouverte pour tester avant la fusion.
  • En réponse à chaque commit, vérifier que la fusion a été effectuée correctement.
  • Périodiquement, par exemple la nuit ou chaque semaine pour des tests supplémentaires.
  • Dans le cadre de tests de performances ou de tests de résistance, qui s'exécutent généralement sur une longue période et exécutent des tests en parallèle et/ou déploient le même programme plusieurs fois.

Pour chacun d'entre eux, Pulumi prend en charge l'intégration avec votre système d'intégration continue préféré. Avec une intégration continue, cela vous offre la même couverture de tests pour votre infrastructure que pour vos logiciels d'application.

Pulumi prend en charge les systèmes CI courants. En voici quelques uns:

Pour des informations plus détaillées, veuillez vous référer à la documentation de Livraison continu.

Environnements éphémères

Une opportunité très puissante qui s’ouvre est la possibilité de déployer des environnements éphémères uniquement à des fins de tests d’acceptation. Concept projets et piles Pulumi est conçu pour déployer et supprimer facilement des environnements complètement isolés et indépendants, le tout en quelques commandes CLI simples ou en utilisant un cadre de test d'intégration.

Si vous utilisez GitHub, Pulumi propose Application GitHub, qui vous aidera à connecter les tests d'acceptation aux demandes d'extraction au sein de votre pipeline CI. Installez simplement l'application dans le référentiel GitHub et Pulumi ajoutera des informations sur les aperçus de l'infrastructure, les mises à jour et les résultats des tests à vos demandes de CI et de pool :

Tester l'infrastructure en tant que code avec Pulumi. Partie 2

Lorsque vous utilisez Pulumi pour vos principaux tests d'acceptation, vous bénéficierez de nouvelles capacités d'automatisation qui amélioreront la productivité de votre équipe et vous donneront confiance dans la qualité de vos modifications.

Total

Dans cet article, nous avons vu qu'en utilisant des langages de programmation à usage général, de nombreuses techniques de développement de logiciels deviennent disponibles et se révèlent utiles dans le développement de nos applications. Ils incluent les tests unitaires, les tests d'intégration et la manière dont ils fonctionnent ensemble pour effectuer des tests d'exécution approfondis. Les tests sont faciles à exécuter à la demande ou dans votre système CI.

Pulumi - logiciel open source, gratuit à utiliser et fonctionnant avec vos langages de programmation et cloud préférés - essayez-le aujourd'hui!

La première partie

Source: habr.com

Ajouter un commentaire