Testare l'infrastruttura come codice con Pulumi. Parte 2

Ciao a tutti. Oggi condividiamo con voi la parte finale dell'articolo. "Test dell'infrastruttura come codice con Pulumi", la cui traduzione è stata preparata appositamente per gli studenti del corso "Pratiche e strumenti DevOps".

Testare l'infrastruttura come codice con Pulumi. Parte 2

Test di distribuzione

Questo stile di test è un approccio potente, che ci consente di eseguire test white-box per verificare gli aspetti interni del codice della nostra infrastruttura. Tuttavia, limita in qualche modo ciò che possiamo testare. I test vengono eseguiti su un piano di distribuzione in memoria creato da Pulumi prima della distribuzione effettiva, quindi la distribuzione stessa non può essere testata. Per questi casi, Pulumi dispone di un framework di test di integrazione. E questi due approcci funzionano alla grande insieme!

Il framework di test di integrazione di Pulumi è scritto in Go ed è quello che utilizziamo per testare la maggior parte del nostro codice interno. Mentre l'approccio di unit testing che abbiamo esaminato in precedenza era più simile a un test white-box, il test di integrazione è una black-box. (Esistono anche opzioni per test interni rigorosi.) Il framework è stato creato per prendere un programma Pulumi completo ed eseguirlo attraverso diverse operazioni del ciclo di vita, come il deployment di un nuovo stack da zero, l'aggiornamento con varianti e lo smantellamento, anche più volte. Eseguiamo queste operazioni regolarmente (ad esempio, ogni notte) e come stress test.

(Noi ci stiamo lavorando, in modo che funzionalità di test di integrazione simili siano disponibili nell'SDK nativo dei linguaggi. È possibile utilizzare il framework di test di integrazione Go indipendentemente dal linguaggio in cui è scritto il programma Pulumi.

Eseguendo il programma utilizzando questo framework è possibile verificare quanto segue:

  • Il codice del tuo progetto è sintatticamente corretto e funziona senza errori.
  • Le impostazioni di configurazione dello stack e dei segreti funzionano e vengono interpretate correttamente.
  • Il tuo progetto può essere distribuito con successo al provider cloud da te scelto.
  • Il tuo progetto può essere aggiornato con successo dallo stato iniziale ad altri N stati.
  • Il tuo progetto può essere distrutto con successo e rimosso dal tuo provider cloud.

Come vedremo tra poco, questo framework può essere utilizzato anche per eseguire la convalida in fase di esecuzione.

Test di integrazione semplice

Per vederlo in azione, daremo un'occhiata al repository pulumi/examples, poiché il nostro team e la community di Pulumi lo utilizzano per testare le proprie richieste pull, commit e build notturne.

Di seguito è riportato un test semplificato del nostro esempio che esegue il provisioning del bucket S3 e di alcuni altri oggetti:

esempio_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,
        },
    })
}

Questo test esegue il ciclo di vita di base di creazione, modifica ed eliminazione di uno stack per una cartella. aws-js-s3-folderCi vorrà circa un minuto per segnalare che il test è stato superato:

$ go test .
PASS
ok      ... 43.993s

Esistono numerose opzioni per personalizzare il comportamento di questi test. Per un elenco completo delle opzioni, vedere nella struttura ProgramTestOptionsAd esempio, è possibile configurare l'endpoint Jaeger per il tracciamento (Tracing), indica che ti aspetti che il test cada se il test è negativo (ExpectFailure), applicare una serie di "modifiche" al programma per passare sequenzialmente da uno stato all'altro (EditDirs) e molto altro ancora. Vediamo come utilizzarli per testare la distribuzione della tua applicazione.

Controllo delle proprietà delle risorse

L'integrazione di cui abbiamo parlato sopra garantisce che il nostro programma "funzioni", ovvero che non si blocchi. Ma cosa succede se vogliamo verificare le proprietà dello stack risultante? Ad esempio, se determinati tipi di risorse sono stati (o non sono stati) preparati e se hanno determinati attributi.

Parametro ExtraRuntimeValidation per ProgramTestOptions Ci consente di esaminare lo stato post-distribuzione acquisito da Pulumi, in modo da poter eseguire ulteriori controlli. Questo include uno snapshot completo dello stato dello stack risultante, inclusi configurazione, valori di output esportati, tutte le risorse e i relativi valori di proprietà, e tutte le dipendenze tra le risorse.

Per vedere un esempio di base di questo, controlliamo che il nostro programma ne crei uno Secchio 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")
        },
    })

Ora, quando eseguiamo go test, non solo eseguirà la batteria di test del ciclo di vita, ma, dopo che lo stack è stato distribuito correttamente, eseguirà anche un ulteriore controllo sullo stato risultante.

Test di runtime

Finora, tutti i test hanno riguardato esclusivamente il comportamento di distribuzione e il modello di risorse Pulumi. Cosa succede se si desidera verificare che l'infrastruttura fornita funzioni effettivamente? Ad esempio, che la VM funzioni, che il bucket S3 contenga ciò che ci aspettiamo e così via.

Potresti aver già indovinato come fare: opzione ExtraRuntimeValidation per ProgramTestOptions — rappresenta un'ottima opportunità per questo scopo. In questa fase, si esegue un test Go arbitrario con accesso allo stato completo delle risorse del programma. Questo stato include informazioni come indirizzi IP delle macchine virtuali, URL e tutto il necessario per interagire effettivamente con le applicazioni cloud e l'infrastruttura risultanti.

Ad esempio, il nostro programma di test esporta la proprietà webEndpoint bucket'a chiamato websiteUrl, che è l'URL completo dove possiamo ottenere la configurazione index document. Sebbene potremmo scavare nel file di stato per trovare bucket e leggere direttamente quella proprietà, ma in molti casi i nostri stack esportano proprietà utili come questa che troviamo comodo ispezionare:

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!")
        },
    })

Come i nostri precedenti controlli di runtime, questo controllo verrà eseguito immediatamente dopo che lo stack è attivo, il tutto in risposta a una semplice chiamata go testE questa è solo la punta dell'iceberg: tutte le funzionalità di test di Go sono a tua disposizione e puoi scriverle nel codice.

Integrazione continua delle infrastrutture

È utile poter eseguire test su un portatile quando si apportano molte modifiche all'infrastruttura, per testarle prima di inviarle per la revisione del codice. Ma noi e molti dei nostri clienti testiamo l'infrastruttura in varie fasi del ciclo di vita dello sviluppo:

  • In ogni richiesta di pull aperta per il test prima dell'unione.
  • In risposta a ogni commit, per verificare che l'unione sia stata eseguita correttamente.
  • Periodicamente, ad esempio di notte o settimanalmente per ulteriori test.
  • Come parte dei test delle prestazioni o dei test di stress, che in genere vengono eseguiti per un lungo periodo di tempo ed eseguono test in parallelo e/o distribuiscono lo stesso programma più volte.

Per ognuno di questi, Pulumi supporta l'integrazione con il tuo sistema di integrazione continua preferito. Grazie all'integrazione continua, puoi usufruire della stessa copertura di test per la tua infrastruttura e per il tuo software applicativo.

Pulumi supporta i sistemi CI più comuni. Eccone alcuni:

Per ulteriori informazioni, consultare la documentazione. Consegna continua.

Ambienti effimeri

Una caratteristica molto potente che si apre è la possibilità di creare ambienti effimeri esclusivamente per scopi di test di accettazione. Il concetto progetti e pile Pulumi è progettato per semplificare l'implementazione e la dismissione di ambienti completamente isolati e indipendenti, il tutto con pochi semplici comandi CLI o utilizzando un framework di test di integrazione.

Se usi GitHub, Pulumi offre Applicazione GitHub, che ti aiuterà a collegare i test di accettazione alle richieste pull all'interno della tua pipeline di CI. Basta installare l'applicazione in un repository GitHub e Pulumi aggiungerà informazioni sulle anteprime dell'infrastruttura, sugli aggiornamenti e sui risultati dei test alle tue CI e alle tue richieste pull:

Testare l'infrastruttura come codice con Pulumi. Parte 2

Utilizzando Pulumi per i tuoi test di accettazione principali, otterrai nuove funzionalità di automazione che miglioreranno la produttività del tuo team e ti daranno fiducia nella qualità delle tue modifiche.

risultato

In questo articolo, abbiamo visto come l'utilizzo di linguaggi di programmazione generici ci offra accesso a molte delle tecniche di sviluppo software che si sono rivelate utili durante lo sviluppo delle nostre applicazioni. Tra queste, i test unitari, i test di integrazione e il modo in cui interagiscono per eseguire test di runtime approfonditi. I test possono essere facilmente eseguiti su richiesta o nel vostro sistema di integrazione continua.

Pulumi — software open source, è gratuito e funziona con i tuoi linguaggi di programmazione e cloud preferiti — provalo oggi!

La prima parte

Fonte: habr.com

Acquista hosting affidabile per siti con protezione DDoS, server VPS VDS 🔥 Acquista un hosting web affidabile con protezione DDoS, server VPS e VDS | ProHoster