Testare l'infrastruttura come codice con Pulumi. Parte 2

Ciao a tutti. Oggi condividiamo con voi l'ultima parte dell'articolo «Testare l'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

Testare il deployment

Lo stile di test esaminato è un approccio potente che ci consente di eseguire test di white-box per verificare il funzionamento interno del nostro codice infrastrutturale. Tuttavia, limita un po' ciò che possiamo controllare. I test vengono eseguiti sulla base di un piano di deployment in memoria creato da Pulumi prima del vero e proprio deployment e, quindi, non è possibile testare il deployment stesso. In questi casi, Pulumi dispone di un framework per test di integrazione. E questi due approcci funzionano ottimamente insieme!

Il framework di test di integrazione di Pulumi è scritto in Go, e proprio con questo testiamo la maggior parte del nostro codice interno. Se l'approccio di test modulare esaminato in precedenza assomigliava di più a un test di white-box, il test di integrazione è un black-box. (Esistono anche opzioni per test interni approfonditi.) Questo framework è stato progettato per prendere un intero programma Pulumi e eseguire su di esso varie operazioni di ciclo di vita, come il deployment di un nuovo stack da zero, il suo aggiornamento con variazioni e la sua rimozione, possibilmente diverse volte. Li eseguiamo regolarmente (ad esempio, di notte) e come test di stress.

(Stiamo lavorando affinché, simili opportunità di test di integrazione siano nel SDK nativo dei linguaggi. Puoi usare il framework di test di integrazione Go indipendentemente dal linguaggio in cui è scritto il tuo programma Pulumi).

Eseguendo il programma con questo framework puoi 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 sono interpretate correttamente.
  • Il tuo progetto può essere distribuito con successo nel fornitore di cloud scelto.
  • Il tuo progetto può essere aggiornato con successo dallo stato iniziale a N altri stati.
  • Il tuo progetto può essere distrutto e rimosso dal tuo fornitore di cloud.

Come vedremo presto, questo framework può essere utilizzato anche per eseguire la convalida run-time.

Test di integrazione semplice

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

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

example_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 attraversa il ciclo di vita di base della creazione, modifica e distruzione di uno stack per la cartella aws-js-s3-folder. Ci vorrà circa un minuto per segnalare il test superato:

$ go test .
PASS
ok      ... 43.993s

Ci sono molte opzioni per configurare il comportamento di questi test. L'elenco completo delle opzioni è disponibile nella struttura ProgramTestOptions. Ad esempio, puoi configurare l'endpoint di Jaeger per il tracciamento (Tracing), indicare che ti aspetti un fallimento del test durante il testing negativo (ExpectFailure), applicare una serie di “modifiche” al programma per passare attraverso stati successivi (EditDirs) e molto altro. Vediamo come utilizzarli per verificare il deployment dell’applicazione.

Verifica delle proprietà delle risorse

L'integrazione di cui sopra garantisce che il nostro programma “funziona” — non va in crash. Ma cosa succede se vogliamo verificare le proprietà dello stack ottenuto? Ad esempio, se determinati tipi di risorse sono stati (o non sono stati) preparati e se hanno attributi specifici.

Parametro ExtraRuntimeValidation per ProgramTestOptions ci consente di esaminare lo stato registrato da Pulumi dopo il deployment (stato post-deployment), in modo da poter effettuare controlli aggiuntivi. Questo include una snapshot completa dello stato dello stack risultante, comprese la configurazione, i valori di output esportati, tutte le risorse e i valori delle loro proprietà, così come tutte le dipendenze tra le risorse.

Per vedere un esempio base di questo, controlliamo che il nostro programma crei un S3 Bucket:

  integration.ProgramTest(t, &integration.ProgramTestOptions{
        // come prima...
        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, "Ci si aspettava di trovare un singolo AWS S3 Bucket")
        },
    })

Ora, quando eseguiremo go test, non solo passerà attraverso una serie di test del ciclo di vita, ma anche, dopo un'installazione riuscita dello stack, eseguirà un controllo aggiuntivo dello stato risultante.

Test runtime

Fino a questo momento, tutti i test si sono concentrati esclusivamente sul comportamento durante il deployment e sul modello delle risorse di Pulumi. Cosa fare se vuoi verificare che la tua infrastruttura preparata funzioni realmente? Ad esempio, che una macchina virtuale sia attiva, che il bucket S3 contenga ciò che ci aspettiamo, e così via.

Probabilmente hai già indovinato come farlo: l'opzione ExtraRuntimeValidation per ProgramTestOptions è un'ottima opportunità per questo. A questo punto, esegui un test Go arbitrario con accesso allo stato completo delle risorse del tuo programma. Questo stato include informazioni come gli indirizzi IP delle macchine virtuali, gli URL e tutto ciò che è necessario per interagire realmente con le applicazioni cloud e l'infrastruttura ottenute.

Ad esempio, il nostro programma di test esporta la proprietà webEndpoint del bucket chiamato websiteUrl, che rappresenta l'URL completo tramite il quale possiamo accedere al nostro index document. Anche se potremmo scavare nel file di stato per trovare bucket e leggere direttamente questa proprietà, in molti casi i nostri stack esportano proprietà utili, come questa, che è comodo utilizzare per i controlli:

integration.ProgramTest(t, &integration.ProgramTestOptions{
            // come prima ...
        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 runtime, questa verifica verrà eseguita subito dopo l'installazione dello stack, e tutto ciò in risposta a una semplice chiamata go test. E questo è solo la punta dell'iceberg: tutte le funzionalità di test di Go sono disponibili e possono essere scritte nel codice.

Integrazione continua dell'infrastruttura

È utile avere la possibilità di eseguire test su un laptop quando si apportano molte modifiche all'infrastruttura, per verificarle prima di inviarle per la revisione del codice. Ma noi e molti dei nostri clienti testiamo l'infrastruttura in vari stadi del ciclo di vita dello sviluppo:

  • In ogni pull request aperta per un test prima della fusione.
  • In risposta a ciascun commit, per riconfermare che la fusione sia avvenuta correttamente.
  • Periodicamente, ad esempio, di notte o settimanalmente per test aggiuntivi.
  • Nell'ambito dei test delle prestazioni o dei test di stress, che di solito vengono eseguiti per un lungo periodo di tempo e che eseguono test in parallelo e/o distribuiscono lo stesso programma più volte.

Per ognuno di essi, Pulumi supporta l'integrazione con il tuo sistema di integrazione continua preferito. Con l'integrazione continua, hai la stessa copertura dei test per la tua infrastruttura come per il software applicativo.

Pulumi supporta i principali sistemi CI. Ecco alcuni di essi:

Per ulteriori informazioni, consulta la documentazione su Continuous Delivery.

Ambienti effimeri

Una funzionalità molto potente che si apre è la possibilità di distribuire ambienti effimeri esclusivamente per scopi di test di accettazione. Il concetto di progetti e stack Pulumi è progettato in modo da consentire la distribuzione e la rimozione facile di ambienti completamente isolati e indipendenti, il tutto con pochi semplici comandi CLI o utilizzando un framework di test di integrazione.

Se utilizzi GitHub, Pulumi offre GitHub App, che ti aiuterà a collegare il test di accettazione alle pull request all'interno del tuo pipeline CI. Basta installare l'app nel repository GitHub, e Pulumi nel tuo CI aggiungerà informazioni sulle anteprime dell'infrastruttura, sugli aggiornamenti e sui risultati dei test alle pull request:

Testare l'infrastruttura come codice con Pulumi. Parte 2

Utilizzando Pulumi per i tuoi test di accettazione principali, avrai nuove possibilità di automazione che miglioreranno le prestazioni del team e offriranno fiducia nella qualità delle modifiche.

Risultato

In questo articolo abbiamo visto che, utilizzando linguaggi di programmazione general-purpose, abbiamo accesso a molti metodi di sviluppo software che sono stati utili nella creazione delle nostre applicazioni. Questi includono il testing modulare, il testing di integrazione e le loro interazioni per condurre test runtime completi. I test possono essere facilmente eseguiti su richiesta o nel vostro sistema CI.

Pulumi — software open source, è gratuito da usare e funziona con i vostri linguaggi di programmazione e cloud preferiti — provatelo oggi!

Prima parte

Fonte: habr.com

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