Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Sembra che gli sviluppatori di Terraform offrano pratiche consigliate piuttosto convenienti per lavorare con l'infrastruttura AWS. Tuttavia, c'è un problema. Col passare del tempo, il numero di ambienti aumenta, ognuno con le proprie peculiarità. Praticamente appare una copia del stack applicativo in una regione vicina. E il codice Terraform deve essere copiato e modificato con attenzione in base ai nuovi requisiti, oppure si deve creare una configurazione personalizzata.

La mia presentazione riguarda i modelli in Terraform per combattere il caos e la routine manuale in progetti grandi e a lungo termine.

Video:

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Ho 40 anni, sono 20 anni nel settore IT. Lavoro da 12 anni con l'azienda Ixtens. Ci occupiamo di sviluppo guidato dall'ecommerce. E da 5 anni pratico pratiche DevOps.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

La mia storia riguarderà l'esperienza in un progetto di cui non rivelerò il nome, in virtù di un accordo di riservatezza.

I numeri sullo slide sono indicati per comprendere la scala del progetto. E tutto ciò di cui parlerò in seguito è correlato ad Amazon.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Mi sono unito a questo progetto 4 anni fa. E proprio mentre avveniva la ristrutturazione dell'infrastruttura, il progetto è cresciuto. E i modelli che venivano utilizzati non erano più adeguati. Considerando tutto il previsto aumento del progetto, era necessario trovare qualcosa di nuovo.

Grazie a Matvey, che ieri ha raccontato cosa stava succedendo in Dodo Pizza. È quello che è successo da noi quattro anni fa.

Sono arrivati gli sviluppatori e hanno iniziato a scrivere codice infrastrutturale.

I motivi più evidenti per cui era necessario erano legati al time to market. Era fondamentale fare in modo che il team DevOps non fosse un collo di bottiglia nel rilascio. Inoltre, a livello base, sono stati utilizzati Terraform e Puppet.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Terraform è un progetto open source della HashiCorp. E per chi non fosse a conoscenza, i prossimi slide saranno una spiegazione.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

L'infrastruttura come codice significa che possiamo descrivere la nostra infrastruttura e chiedere a dei robot di creare le risorse che abbiamo descritto.

Ad esempio, abbiamo bisogno di la macchina virtuale. Lo descriveremo, aggiungendo alcuni parametri obbligatori.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Dopo di che, nella console configureremo l'accesso ad Amazon. E chiederemo a Terraform di fare un piano. Terraform ci dirà: «Ok, per la vostra risorsa possiamo fare queste cose». E, almeno, verrà aggiunta una risorsa. Non sono previsti cambiamenti.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Una volta che tutto è a posto, puoi chiedere a Terraform di applicare e Terraform creerà un'istanza per te, e avrai una macchina virtuale nel tuo cloud.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Successivamente, il nostro progetto si sviluppa. Aggiungiamo alcune modifiche. Richiediamo più istanze, aggiungiamo una registrazione 53.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

E ripetiamo. Chiediamo un piano. Vediamo quali modifiche sono previste. Applichiamo. E in questo modo la nostra infrastruttura cresce.

Terraform utilizza qualcosa chiamato file di stato. Vale a dire, tutte le modifiche che vengono inviate ad Amazon vengono salvate in un file, dove per ogni risorsa descritta ci sono le corrispondenti risorse create in Amazon. In questo modo, quando si modifica la descrizione di una risorsa, Terraform sa esattamente cosa deve cambiare in Amazon.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Questi file di stato erano inizialmente solo file. Li abbiamo conservati in Git, il che era estremamente scomodo. Qualcuno dimenticava costantemente di fare commit delle modifiche e si verificavano molti conflitti.

Ora c'è la possibilità di utilizzare un backend, ovvero a Terraform si indica in quale bucket e con quale chiave salvare il file di stato. E Terraform si prenderà cura di ottenere questo file di stato, fare tutta la magia e restituire il risultato finale.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

La nostra infrastruttura è in crescita. Ecco il nostro codice. Ora non vogliamo solo creare una macchina virtuale, vogliamo avere un ambiente di test.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Terraform consente di creare ciò che chiamiamo modulo, ovvero descrivere la stessa cosa in una determinata cartella.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

E, ad esempio, durante il test possiamo chiamare questo modulo e ottenere lo stesso risultato come se avessimo eseguito Terraform apply nel modulo stesso. Per i test, ci sarà questo codice.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Per la produzione possiamo inviare alcune modifiche, perché durante i test non ci servono grandi istanze, mentre in produzione le grandi istanze saranno utili.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

E poi tornerò al progetto. C'era un compito complesso, l'infrastruttura era pianificata per essere molto grande. Era necessario organizzare tutto il codice in modo da esserlo per tutti: sia per chi si occupa della manutenzione di questo codice, sia per chi apporta modifiche. Si prevedeva che ogni sviluppatore potesse andare e modificare l'infrastruttura come necessario per la propria parte della piattaforma.

Questo è l'albero delle directory raccomandato da HashiCorp, se hai un grande progetto e ha senso suddividere tutta l'infrastruttura in piccoli pezzi, e ogni pezzo descriverlo in una cartella separata.

Avendo una vasta libreria di risorse, è possibile chiamare praticamente le stesse cose sia nei test che in produzione.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Nel nostro caso, questo non era proprio adatto, perché il stack di test per sviluppatori o per il collaudo doveva essere ottenuto in modo più semplice. Non volevamo dover girare tra le cartelle e applicare in sequenza, e preoccuparci che il database venisse sollevato, seguito dall'istanza che utilizza quel database. Pertanto, tutto il testing veniva avviato da una sola cartella. Lì venivano chiamati gli stessi moduli, ma tutto avveniva in un'unica esecuzione.

Terraform si occupa di tutte le dipendenze. E crea sempre le risorse nell'ordine tale da poter ottenere un indirizzo IP, ad esempio, da un'istanza appena creata e ricevere quell'indirizzo IP in una registrazione route53.

Inoltre, la piattaforma è molto grande. E avviare uno stack di test, anche se per un'ora, anche se per 8 ore, è un'operazione piuttosto costosa.

E abbiamo automatizzato tutto questo. Il lavoro di Jenkins permetteva di avviare lo stack. Era necessario eseguire una pull request con le modifiche che lo sviluppatore voleva testare, specificare tutte le opzioni necessarie, i componenti e le dimensioni. Se desiderava eseguire test di performance, poteva prendere più istanze. Se doveva solo verificare che un certo modulo si aprisse, poteva partire con impostazioni minime. Inoltre, poteva specificare se era necessario un cluster o meno, e così via.

Successivamente, Jenkins eseguiva uno script shell, che modificava leggermente il codice nella cartella Terraform. Rimuoveva file non necessari, aggiungeva file necessari. E poi, con un'unica esecuzione, il comando Terraform apply sollevava lo stack.

E poi seguivano altri passaggi, nei quali non voglio approfondire.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Poiché per il testing ci servivano alcune opzioni in più rispetto alla produzione, eravamo costretti a fare copie dei moduli, in modo da poter aggiungere quelle funzionalità necessarie solo per il testing.

E così è accaduto che nel testing si desiderava testare quelle modifiche che alla fine sarebbero andate in produzione. Ma in realtà si testava una cosa, mentre in produzione veniva applicato qualcosa di leggermente diverso. E c'era una piccola disconnessione, dato che in produzione tutte le modifiche venivano applicate dal team operativo. A volte accadeva che quelle modifiche che avrebbero dovuto passare dal testing alla produzione rimanessero in un'altra versione.

Inoltre, c'era un problema relativo all'aggiunta di un nuovo servizio, che differiva in parte da un servizio già esistente. Invece di modificare il modulo esistente, era necessario crearne una copia e apportare le modifiche necessarie.

In sostanza, Terraform non è un vero linguaggio. È una dichiarazione. Se abbiamo bisogno di dichiarare qualcosa, lo facciamo. E tutto questo funziona.

A un certo punto, durante la discussione di una delle mie pull request, uno dei colleghi ha detto che non bisognava creare troppe 'fiocchi di neve'. Mi sono interessato a cosa intendesse. C'è un fatto scientifico che afferma che nel mondo non esistono due fiocchi di neve identici, tutti hanno delle piccole differenze. E non appena ho sentito questo, ho subito percepito il peso del codice Terraform. Perché quando era necessario passare da una versione all'altra, Terraform richiedeva modifiche incompatibili, il che significava che il codice non era più compatibile con la versione successiva. E si doveva fare una pull request che copriva quasi metà dei file nell'infrastruttura, per aggiornare l'infrastruttura alla nuova versione di Terraform.

E dopo che è apparso un tale fiocco di neve, tutto il codice Terraform che avevamo si trasformava in un'enorme montagna di neve.

Per uno sviluppatore esterno, che non è parte delle operazioni, questo non ha molta importanza, perché ha fatto la sua pull request, la sua risorsa è stata avviata. E basta, non è più una sua preoccupazione. Ma per il team DevOps, che si assicura che tutto funzioni, è necessario apportare tutte queste modifiche. E il costo di queste modifiche aumentava in modo significativo con ogni 'fiocco di neve' aggiuntivo.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

C'è una storia su uno studente che durante un seminario disegna due cerchi perfetti con il gesso sulla lavagna. E il docente si sorprende di come sia riuscito a farli così precisi senza compasso. Lo studente risponde: «Molto semplice, ho passato due anni nell'esercito a girare un tritacarne».

Dei quattro anni in cui ho partecipato a questo progetto, circa due anni li ho dedicati a Terraform. E, naturalmente, ho alcune dritte e suggerimenti su come semplificare il codice di Terraform, trattarlo come un linguaggio di programmazione e ridurre il carico sui programmatori che devono mantenerlo aggiornato.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Il primo punto da cui vorrei partire è Symlinks. Terraform ha molto codice ripetitivo. Ad esempio, la chiamata al provider si ripete praticamente ad ogni punto in cui creiamo un pezzo di infrastruttura. È logico quindi estrarlo in una cartella separata. E ovunque ci sia bisogno del provider, creare dei Symlinks a quel file.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Ad esempio, se nel tuo ambiente di produzione utilizzi un assume role, che ti consente di ottenere diritti di accesso su un certo account Amazon esterno. Cambiando un file, tutti gli altri nel tuo albero delle risorse avranno i diritti necessari affinché Terraform sappia a quale segmento di Amazon rivolgersi.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Dove non funzionano i Symlinks? Come ho già detto, in Terraform ci sono file di stato. E sono veramente ottimi. Ma il fatto è che Terraform inizializza il backend come primo passaggio. E non può utilizzare in questi parametri nessuna variabile, devono sempre essere scritte come testo.

E come risultato, quando qualcuno crea una nuova risorsa, copia una parte di codice da altre cartelle. E può sbagliarsi con la chiave o con il bucket. Ad esempio, può creare una cosa per sandbox e poi farla in produzione. E può capitare che il bucket in produzione venga utilizzato da sandbox. Certamente, questo verrà scoperto rapidamente. Si potrà in qualche modo correggere, ma rimane comunque una perdita di tempo e in qualche misura di risorse.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Cosa possiamo fare dopo? Prima di lavorare con Terraform, è necessario inizializzarlo. Durante l'inizializzazione, Terraform scarica tutti i plugin. In un certo modo, si è passati da un'architettura monolitica a una più microservizi. Ed è sempre necessario eseguire Terraform init, affinché possa scaricare tutti i moduli e tutti i plugin.

È possibile utilizzare uno script shell che, da un lato, può estrarre tutte le variabili. Uno script shell non ha limitazioni. Dall'altro lado, anche i percorsi. Se utilizziamo sempre il percorso presente nel repository come chiave per il file di stato, di conseguenza, l'errore sarà escluso.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Da dove ottenere i dati? Da un file JSON. Terraform consente di registrare l'infrastruttura non solo in hcl (HashiCorp Configuration Language), ma anche in JSON.

JSON è facilmente leggibile da uno script shell. Di conseguenza, è possibile posizionare il file di configurazione con il bucket in un determinato posto. E utilizzare questo bucket sia nel codice Terraform che nello script shell per l'inizializzazione.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Perché è importante avere un bucket per Terraform? Perché esiste qualcosa chiamato file di stato remoto. Cioè, quando creo una risorsa, per dirle ad Amazon: "Per favore, avvia un'istanza", è necessario specificare molti parametri obbligatori.

E questi identificatori sono memorizzati in una sorta di altra cartella. Posso dire: «Terraform, per favore vai nel file di stato di quella risorsa e dammi questi identificatori». In questo modo si crea una certa unificazione tra diverse regioni o ambienti.

Non sempre è possibile utilizzare un file di stato remoto. Ad esempio, hai creato manualmente una VPC. E il codice Terraform che crea la VPC genera una VPC così diversa che ci vorrà molto tempo e dovrai adattare l'uno all'altro, perciò puoi usare il seguente trucco.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Cioè, creare un modulo che crea una VPC e ti restituisce gli identificatori, ma in realtà c'è solo un file con valori hardcoded che può essere utilizzato per creare lo stesso instance.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Non è sempre necessario salvare il file di stato nel cloud. Ad esempio, quando si testano i moduli, è possibile utilizzare l'inizializzazione del backend, in cui il file verrà semplicemente salvato su disco durante il periodo di test.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Ora parliamo un po' dei test. Cosa si può testare in Terraform? Probabilmente si può testare molto, ma parlerò di queste 4 cose.

HashiCorp ha una visione chiara su come formattare il codice Terraform. E Terraform fmt ti consente di formattare il codice che stai modificando in linea con questa visione. Pertanto, i test devono assolutamente verificare se la formattazione rispetta quanto stabilito da HashiCorp, evitando di dover cambiare la posizione delle parentesi, ecc.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Il prossimo è Terraform validate. Esegue qualcosa in più di una semplice verifica della sintassi, come controllare se tutte le parentesi sono abbinate. Cosa c'è di importante in questo? La nostra infrastruttura è piuttosto complessa. Ci sono moltissime cartelle diverse. E in ciascuna di esse, è necessario eseguire Terraform validate.

Pertanto, per accelerare i test, eseguiamo più processi in parallelo, utilizzando la modalità parallelo.

Il parallelo è una funzione davvero fantastica, approfittatene.

Ma ogni volta che viene eseguita l'inizializzazione di Terraform, questo si connette a HashiCorp e chiede: «Quali sono le ultime versioni dei plugin? E il plugin che ho nella cache, è quello giusto?» E questo rallenta ogni passo.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Se Terraform riceve indicazioni su dove si trovano i plugin, dirà: «Va bene, probabilmente questa è la cosa più recente. Non andrò da nessuna parte, inizierò subito a convalidare il tuo codice Terraform».

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Per riempire la cartella con i plugin necessari, abbiamo un codice Terraform molto semplice da inizializzare. Qui, ovviamente, è necessario specificare tutti i provider che partecipano in qualche modo al tuo codice, altrimenti Terraform dirà: «Non conosco alcun provider, perché non è nella cache».

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Il passo successivo è Terraform plan. Come già detto, lo sviluppo è ciclico. Creiamo codice con modifiche e poi dobbiamo scoprire quali modifiche sono pianificate per l'infrastruttura.

E quando l'infrastruttura è molto, molto grande, è possibile cambiare un modulo, riparare un ambiente di test o una specifica regione e rompere qualche altro. Pertanto, Terraform plan deve essere eseguita su tutta l'infrastruttura e mostrare quali modifiche sono pianificate.

Puoi farlo in modo intelligente. Noi, ad esempio, abbiamo scritto uno script in Python che risolve le dipendenze. E a seconda di ciò che è stato modificato: un modulo Terraform o semplicemente un componente specifico, crea piani per tutte le cartelle dipendenti.

Il piano Terraform dovrebbe essere eseguito su richiesta. Almeno, è questo che facciamo noi.

È sicuramente utile eseguire test per ogni modifica, per ogni commit, ma i piani sono una cosa piuttosto costosa. E nel pull request diciamo: «Per favore, dammi i piani». Si avvia un robot e invia nei commenti o come allegato tutti i piani previsti dai tuoi cambiamenti.

Il piano è un elemento piuttosto costoso. Richiede tempo, perché Terraform va su Amazon e chiede: «Questo instance esiste ancora? Questo autoscale ha esattamente queste impostazioni?». E per accelerare questo processo, puoi utilizzare un parametro come refresh=false. Questo significa che Terraform scaricherà lo stato da S3 e crederà che lo stato corrisponda esattamente a ciò che si trova su Amazon.

Questo piano di Terraform è molto più veloce, ma lo stato deve corrispondere alla vostra infrastruttura, cioè, da qualche parte, in un momento, Terraform refresh deve essere eseguito. Terraform refresh fa proprio questo, affinché lo stato corrisponda a ciò che si trova nell'infrastruttura reale.

E dobbiamo parlare della sicurezza. Dovevamo iniziare da qui. Lì dove eseguite Terraform e Terraform interagisce con la vostra infrastruttura, c'è una vulnerabilità. Cioè, fondamentalmente, state eseguendo codice. E se la pull request contiene del codice malevolo, potrebbe essere eseguito su un'infrastruttura che ha troppi privilegi. Quindi, fate attenzione a dove eseguite Terraform plan.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Ora, vorrei parlare dei test dei dati utente.

Cos'è il user-data? In Amazon, quando creiamo un'istanza, possiamo inviare da quell'istanza una sorta di messaggio – metadati. Quando l'istanza si avvia, generalmente cloud init è sempre presente su queste istanze. Cloud init legge questo messaggio e dice: «Ok, oggi sono un load balancer». E in base a queste istruzioni, esegue alcune azioni.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Purtroppo, quando eseguiamo Terraform plan e Terraform apply, i dati dell'utente appaiono come una confusa sequenza di numeri. Cioè, ci invia semplicemente un hash. E tutto ciò che possiamo vedere nel piano è se ci saranno delle modifiche o se l'hash rimarrà lo stesso.

E se non ci si fa attenzione, su Amazon, sulla vera infrastruttura, può finire qualche file di testo danneggiato.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Come alternativa, si può specificare solo il template durante l'esecuzione, non l'intera infrastruttura. Nel codice si può dire: «Per favore, stammi questo template». Così, alla fine, si può ottenere una stampa di come appariranno i vostri dati su Amazon.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Un'altra opzione è quella di utilizzare un modulo per generare i dati dell'utente. Applicate questo modulo, ottenete un file sul disco, lo confrontate con quello di riferimento. In questo modo, se qualche junior decide di modificare un po' i dati dell'utente, i vostri test diranno: «Va bene, qui e qui ci sono alcune modifiche – è normale».

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Il prossimo argomento di cui vorrei parlare è Automate Terraform apply.

Certo, è piuttosto spaventoso eseguire Terraform apply in modo automatico, perché chi sa quali cambiamenti sono stati introdotti e quanto possano essere dannosi per l'infrastruttura live.

Per un ambiente di test va bene. Cioè, il job che crea un ambiente di test è ciò di cui tutti gli sviluppatori hanno bisogno. E l’espressione «tutto funzionava» non è un meme divertente, ma la prova che qualcuno si è impegnato, ha sollevato un stack, ha eseguito dei test su quello stack e si è assicurato che fosse tutto a posto, dicendo: «Ok, il codice che sto rilasciando è stato testato».

In ambienti di produzione, sandbox e altri ambienti importanti per il business, è possibile applicare alcuni resource parzialmente in modo relativamente sicuro, perché non porta a situazioni critiche. Questi includono: gruppi di autoscale, gruppi di sicurezza, ruoli, route53 e la lista può essere piuttosto ampia. Ma fate attenzione a ciò che sta accadendo, leggete i report sulle applicazioni automatiche.

Dove è pericoloso o ci si sente esitanti, ad esempio, quando si tratta di risorse persistenti, come i database, è possibile ricevere report su modifiche non applicate in una certa parte dell'infrastruttura. E l'ingegnere, sotto supervisione, avvia jobs per applicarle o lo fa dalla sua console.

In Amazon c'è una funzionalità chiamata Terminate protection. Questa può proteggere in alcuni casi da modifiche indesiderate per te. Vale a dire, Terraform va su Amazon e dice: «Ho bisogno di terminare questo instance per crearne un altro». E Amazon risponde: «Scusa, non oggi. Abbiamo attivato la Terminate protection».

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

E la ciliegina sulla torta è l'ottimizzazione del codice. Quando lavoriamo con il codice Terraform, dobbiamo passare al modulo un numero molto elevato di parametri. Questi sono i parametri necessari per creare una certa risorsa. E il codice si trasforma in grandi elenchi di parametri da passare da un modulo all'altro, soprattutto se i moduli sono nidificati.

E questo è molto difficile da leggere. È molto complicato fare una review. Spesso succede che alcuni parametri superano la revisione e non sono esattamente quelli necessari. Questo comporta tempo e denaro per correggerli in seguito.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Pertanto, vi consiglio di utilizzare una cosa come un parametro complesso, che include un albero di valori. Cioè, avete bisogno di una cartella in cui sono specificati tutti i valori che desiderate avere in un determinato ambiente.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Chiamando questo modulo, si può ottenere un albero che viene generato in un unico modulo generale, cioè in un modulo comune che funziona in modo uniforme per tutta l'infrastruttura.

In questo modulo è possibile eseguire alcuni calcoli, utilizzando una nuova funzionalità in Terraform, chiamata locals. E poi, con un output, fornire un parametro complesso che può includere hash, array, ecc.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Queste sono tutte le migliori scoperte che ho. Vorrei raccontarvi una storia su Colombo. Quando cercava fondi per la sua spedizione per scoprire l'India (come pensava allora), nessuno gli credeva e lo considerava impossibile. Allora disse: «Fate in modo che l'uovo non cada». Tutti i banchieri, persone molto ricche e probabilmente intelligenti, cercarono in ogni modo di mettere l'uovo in piedi, ma continuava a cadere. Poi Colombo prese l'uovo, ci fece un po' di pressione. Il guscio si schiacciò e l'uovo rimase immobile. Dissero: «Oh, è troppo semplice!». E Colombo rispose: «Sì, è troppo semplice. E quando scoprirò l'India, tutti useranno questa via commerciale.»

E ciò che vi ho raccontato ora sono probabilmente cose abbastanza semplici e banali. E quando le conosci e inizi a usarle, diventa del tutto normale. Quindi sfruttateli. E se per voi sono cose del tutto normali, almeno sapete come mettere l'uovo in modo che non cada.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Ricapitolando:

  • Cercate di evitare le 'palle di neve'. Meno neve ci sono, meno risorse vi serviranno per apportare modifiche alla vostra grande infrastruttura.
  • Modifiche continue. Quando ci sono state modifiche nel codice, è necessario adattare la vostra infrastruttura a queste modifiche il più rapidamente possibile. Non deve esserci la situazione in cui qualcuno torna dopo due o tre mesi per controllare Elasticsearch, esegue un piano Terraform e si trova di fronte a numerosi cambiamenti inaspettati. Questo comporta un notevole dispendio di tempo per riportare tutto in ordine.
  • Test e automazione. Più codice avete coperto da test e funzionalità, maggiore sarà la vostra fiducia nel fatto che state facendo tutto correttamente. La consegna automatica aumenterà notevolmente la vostra fiducia.
  • Il codice per l'ambiente di test e quello di produzione deve essere praticamente identico. Praticamente, perché l'ambiente di produzione è comunque un po' diverso e ci saranno sempre delle particolarità che esulano dall'ambiente di test. Tuttavia, è possibile garantire una certa approssimazione.
  • E se hai molto codice Terraform e richiede tanto tempo mantenerlo aggiornato, non è mai troppo tardi per rifattorizzarlo e portarlo in buone condizioni.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

  • Infrastruttura immutabile. Consegna dell'AMI secondo un programma.
  • Struttura per Route53, quando hai molte registrazioni e vuoi che siano in ordine coerente.
  • Affrontare i limiti di richiesta API. È quando Amazon dice: «Basta, non posso accettare altre richieste, per favore aspetta». E mezza azienda aspetta di poter avviare la propria infrastruttura.
  • Spot instances. Amazon non è economico e gli spot consentono di risparmiare molto. E si potrebbe tenere un intero discorso su questo.
  • Sicurezza e ruoli IAM.
  • Ricerca di risorse perse, quando hai in Amazon istanze di origine sconosciuta che consumano denaro. Anche se un'istanza costa 100-150 dollari al mese, in un anno sono più di 1.000. Trovare tali risorse è un'attività redditizia.
  • E le istanze riservate.

Pattern in Terraform per combattere il caos e la routine manuale. Maxim Kostrykin (Ixtens)

Questo è tutto da parte mia. Terraform è davvero fantastico, usatelo. Grazie!

Domande

Grazie per la presentazione! Hai il file di stato in S3, ma come risolvi il problema che più persone possono prendere questo file di stato e cercare di effettuare il deploy?

In primo luogo, non ci affrettiamo. In secondo luogo, ci sono flag in cui comunichiamo che stiamo lavorando su un certo segmento di codice. Cioè, anche se l'infrastruttura è molto grande, non significa che qualcuno stia sempre applicando qualcosa. Durante la fase attiva, questo era un problema, poiché i nostri file di stato erano conservati in Git. Questo era importante, altrimenti qualcuno avrebbe creato un file di stato e dovevamo raccoglierli manualmente per continuare. Ora non ci sono più problemi di questo tipo. In effetti, Terraform ha risolto questo compito. E se ci sono cambiamenti costanti, si possono utilizzare i lock che prevengono ciò che hai menzionato.

Stai utilizzando la versione open o enterprise?

Nessun enterprise, cioè tutto ciò che si può scaricare gratuitamente.

Mi chiamo Stanislav. Vorrei fare un piccolo aggiunta. Hai parlato della funzionalità di Amazon che consente di rendere un'istanza indistruttibile. Questo esiste anche in Terraform, nel blocco Life Second si può scrivere un divieto di modifica o di distruzione.

Il tempo era limitato. Buona osservazione.

Volevo anche chiedere due cose. Prima di tutto, hai parlato dei test. Hai utilizzato qualche strumento per i test? Ho sentito parlare del plugin Test Kitchen. Forse ce n'è qualcun altro. E vorrei chiedere anche dei Local Values. In cosa si differenziano fondamentalmente dalle Input Variables? E perché non posso parametrizzare qualcosa solo tramite i Local Values? Ho cercato di capire questo argomento, ma non ci sono riuscito.

Possiamo parlare più in dettaglio di questo nel corridoio. Gli strumenti per i test sono completamente homemade. Non c'è nulla di specifico da testare. In effetti, ci sono opzioni in cui i test automatici creano l'infrastruttura da qualche parte, verificano che sia a posto e poi distruggono tutto con un report che conferma che la tua infrastruttura è ancora in buone condizioni. Noi non abbiamo questo, perché i stack di test vengono avviati ogni giorno. E questo è sufficiente. Se qualcosa inizia a rompersi, comincerà a rompersi senza che dobbiamo ancora verificarlo da qualche parte.

Per quanto riguarda i Local Values, continuiamo a discuterne nel corridoio.

Ciao! Grazie per la presentazione! È stato molto interessante. Hai detto che avete molto codice simile per descrivere l'infrastruttura. Non avete mai considerato l'idea di generare questo codice?

Ottima domanda, grazie! Il fatto è che, quando utilizziamo l'infrastruttura come codice, presumiamo di guardare il codice e di comprendere quale infrastruttura ci sia dietro di esso. Se il codice viene generato, dobbiamo immaginare quale codice verrà creato per capire quale infrastruttura ci sarà. O generiamo il codice, lo committiamo e, in sostanza, otteniamo lo stesso risultato. Quindi abbiamo seguito il percorso che abbiamo scritto e abbiamo ottenuto questo. In più, i generatori sono emersi un po' più tardi, quando abbiamo iniziato a lavorare. E ormai era troppo tardi per cambiare.

Hai sentito parlare di jsonnet?

No.

Guarda, è una cosa davvero interessante. Vedo un caso specifico in cui possiamo applicarlo e generare una struttura dati.

I generatori sono utili, ma come nella barzelletta sulla macchina da barba. Cioè, la prima volta i volti sono diversi, ma poi tutti hanno lo stesso viso. I generatori funzionano molto bene. Ma noi, sfortunatamente, abbiamo facce un po' diverse. Questo è un problema.

Dai un'occhiata. Grazie!

Mi chiamo Maxim, vengo da Sberbank. Avete accennato a come stavate cercando di rendere Terraform simile a un linguaggio di programmazione. Non sarebbe più semplice usare Ansible?

Sono cose molto diverse. Puoi creare risorse sia con Ansible che con Puppet su Amazon. Ma Terraform è specificamente progettato per questo.

Avete solo Amazon?

Non è solo che abbiamo solo Amazon. Abbiamo quasi esclusivamente Amazon. Ma la caratteristica principale è che Terraform tiene traccia. In Ansible, se dici: 'Alza 5 istanze', le alza, poi dici: 'Ora ne ho bisogno di 3'. E Terraform dirà: 'Ok, ne eliminerò 2', mentre Ansible dirà: 'Ok, ecco 3'. In totale, 8.

Buongiorno! Grazie per la vostra presentazione! È stato molto interessante ascoltare parlare di Terraform. Vorrei subito fare un piccolo commento riguardo al fatto che Terraform non ha ancora una release stabile, quindi dovete prestarci attenzione.

Buon tempo per mangiare. Cioè, se hai bisogno di una soluzione, a volte metti da parte ciò che è instabile, ecc., ma funziona e ci ha aiutato.

Ho una domanda. Usate un backend remoto, usate S3. Perché non usate il backend ufficiale?

Ufficiale?

Terraform Cloud.

Quando è stato lanciato?

Circa 4 mesi fa.

Se fosse comparso 4 anni fa, probabilmente avrei risposto alla tua domanda.

C'è già una funzione incorporata sia per i locks che per memorizzare il file di stato. Prova. Ma anche io non l'ho testata.

Stiamo viaggiando su un grande treno che si muove ad alta velocità. Non si può semplicemente prendere e buttare via alcuni vagoni.

Hai parlato di fiocchi di neve, ma perché non hai usato il branch? Perché non è stato possibile farlo?

Abbiamo un approccio in cui tutta l'infrastruttura è in un unico repository. Terraform, Puppet, tutti gli script che in qualche modo sono collegati a questo, sono tutti in un unico repository. In questo modo possiamo garantire che le modifiche incrementali siano testate una dopo l'altra. Se fosse una miriade di branch, un progetto del genere sarebbe praticamente impossibile da gestire. Passano sei mesi e si scostano così tanto che diventa davvero una punizione. È qualcosa da cui si desidera scappare prima del refactoring.

Cioè, non funziona?

Non funziona affatto.

Nel branch ho rimosso il slide delle cartelle. Cioè, se creiamo una cartella per ciascun stack di test, ad esempio, per il team A – avrà la sua cartella, per il team B la sua cartella, allora questo non funziona. Abbiamo creato un codice unificato per l'ambiente di test, che era abbastanza flessibile da adattarsi a tutti. In altre parole, gestivamo un unico codice.

Ciao! Mi chiamo Yura! Grazie per la presentazione! Ho una domanda sui moduli. Dite che utilizzate i moduli. Come gestite la situazione se in un modulo apportate modifiche che non sono compatibili con le modifiche di qualcun altro? Versionate in qualche modo i moduli o cercate di adattare il sistema per soddisfare entrambe le esigenze?

Questo è un problema di grande accumulo di neve. È ciò di cui soffriamo quando una modifica apparentemente innocua può rompere una parte dell'infrastruttura. E questo sarà evidente solo dopo un certo tempo.

Cioè, non c'è ancora una soluzione?

Create moduli universali. Evitate le modifiche specifiche. E il tutto funzionerà. La seconda parte della presentazione riguarda come evitarlo.

Ciao! Grazie per la presentazione! Vorrei chiarire. Dietro le quinte è rimasta una grande quantità di lavoro, per cui sono qui. In che modo Puppet e la distribuzione dei ruoli sono integrati?

User-data.

Cioè, semplicemente si estrae il file e si esegue in qualche modo?

User-data è una nota, cioè quando cloniamo un'immagine, viene avviato un Daemon che, cercando di capire chi è, legge la nota che dice che è un load balancer.

Cioè, è un processo separato che viene assegnato?

Non lo abbiamo inventato noi. Lo utilizziamo.

Ciao! Ho proprio una domanda su User-data. Hai detto che ci sono problemi, che qualcuno potrebbe inviare dati errati. Esiste qualche modo per memorizzare user-data nello stesso Git, per avere sempre chiaro a cosa fa riferimento User-data?

Generiamo dati utente da template. Cioè, vi entrano un certo numero di variabili. E Terraform genera il risultato finale. Pertanto, non si può semplicemente guardare il template e dire cosa uscirà, perché tutti i problemi sono legati al fatto che lo sviluppatore pensa di trasmettere una stringa in questa variabile, mentre in realtà arriva un array. E a quel punto – bam – sono, ecco, la riga successiva, e tutto si rompe. Se è una nuova risorsa e una persona la sta creando, vedrà che qualcosa non funziona, ma si risolve in fretta. Ma se è stata aggiornata un gruppo di autoscale, a un certo punto le istanze nel gruppo di autoscale iniziano a cambiare. E boom, qualcosa smette di funzionare. È frustrante.

Quindi, l'unica soluzione è testare?

Sì, vedi il problema, aggiungi dei passi di test. Cioè, si può testare anche l'output. Forse non è così comodo, ma si possono comunque mettere delle etichette - verifica che i dati utente siano ben fissati qui.

Mi chiamo Timur. È fantastico che ci siano conferenze su come organizzare correttamente Terraform.

Non ho nemmeno iniziato.

Penso che alla prossima conferenza possa esserci. Ho una domanda semplice. Perché hardcodificare il valore in un modulo separato invece di usare tfvars? Cosa rende un modulo con valori migliore di tfvars?

Cioè, devo scrivere qui (slide: Production/environment/settings.tf): domain = variabile, domain vpcnetwork, variabile vpcnetwork e stvars – per ottenere la stessa cosa?

Esattamente così stiamo facendo. Facciamo riferimento al modulo di impostazione sorgente, per esempio.

Fondamentalmente, è come un tfvars. Tfvars è molto utile nell'ambiente di testing. Ho tfvars per istanze grandi e per istanze piccole. E ho inserito un file nella cartella. E ho ottenuto quello che volevo. Quando lavoriamo sull'infrastruttura, vogliamo che sia facile da capire a colpo d'occhio. Invece, così facendo, è necessario controllare qui e poi dare un'occhiata in tfvars.

Quindi, per avere tutto in un unico posto?

Sì, tfvars è quando hai un codice unico. E viene utilizzato in diversi contesti con variazioni. Allora metteresti tfvars e otterresti le tue specifiche. Noi invece trattiamo l'infrastruttura come codice in modo puro. Dai un'occhiata e capisci.

Ciao! Ti è mai capitato che un provider di cloud interferisse con ciò che hai fatto con Terraform? Supponiamo di modificare alcuni metadati. Ci sono delle chiavi ssh. E Google continua a inserire i suoi metadati, le sue chiavi. E Terraform continua a dire che ci sono delle modifiche. Dopo ogni esecuzione, anche se non cambia nulla, continua a comunicare che sta per aggiornare quel campo.

Con le chiavi, sì, ma parte dell'infrastruttura è colpita da questo problema, cioè Terraform non può modificare nulla. Neanche noi possiamo apportare modifiche manualmente. Dobbiamo conviverci per ora.

Quindi hai già affrontato situazioni simili, ma non hai trovato soluzioni? Continua a fare e fare da solo?

Sfortunatamente, sì.

Ciao! Mi chiamo Stanislav Starkov. Mail.ru Group. Come risolvi il problema con la generazione del tag su ..., come lo trasmetti internamente? Presumo che utilizzi User-data per indicare il nome dell'host, per indirizzare Puppet? E la seconda parte della domanda. Come affronti questa questione negli SG, cioè quando generi SG, centinaia di istanze simili, come le nomini correttamente?

Le istanze che per noi sono molto importanti, le denominiamo in modo significativo. Quelle che non servono, hanno un nome con la dicitura di gruppo autoscale. In teoria, queste possono essere rimosse per ottenere una nuova istanza.

Riguardo al problema con i tag, non si tratta di un problema, ma di una necessità. I tag vengono utilizzati in modo molto intenso, poiché l'infrastruttura è grande e costosa. Dobbiamo monitorare dove vengono spesi i soldi, quindi i tag ci consentono di analizzare dove e come vengono spesi. Di conseguenza, possiamo identificare dove si spendono molti soldi.

Quale era l'altra domanda?

Quando SG crea cento istanze, bisogna differenziarle in qualche modo?

No, non è necessario. Ogni istanza ha un agente che segnala se ha un problema. Se l'agente fa una segnalazione, lui stesso lo sa e, almeno, esiste il suo indirizzo IP. Già possiamo intervenire. Inoltre, utilizziamo Consul per il Discovery, dove non c'è Kubernetes. E Consul mostra anche l'indirizzo IP dell'istanza.

Cioè, vi basate sull'IP e non sul nome host?

Non è possibile basarsi sul nome host, ce ne sono davvero troppi. Esistono identificatori di istanza – come AE, ecc. Può essere trovato da qualche parte o può essere cercato.

Ciao! Ho capito che Terraform è una buona cosa, progettata per il cloud.

Non solo.

È proprio questa domanda che mi interessa. Se decidessi di migrare, per esempio, verso Bare Metal con tutti i tuoi instances? Non ci sarebbero problemi? Oppure dovresti usare altri prodotti, come Ansible, che è stato menzionato qui?

Ansible è un po' diverso. Cioè, Ansible funziona quando l'instance è già avviata. Terraform funziona prima che l'instance sia avviata. La migrazione a Bare Metal non è prevista.

Attualmente no, ma potrebbe capitare che l'azienda dica: «Facciamolo».

La migrazione a un altro cloud sì, ma qui c'è un'altra questione. Bisogna scrivere il codice Terraform in modo che la transizione a un altro cloud avvenga con minor difficoltà.

Inizialmente, l'obiettivo era che tutta la nostra infrastruttura fosse agnostica, ovvero qualsiasi cloud dovesse andare bene, ma a un certo punto l'azienda ha ceduto e ha detto: «Ok, nei prossimi N anni non ci muoveremo, possiamo usare i servizi di Amazon».

Terraform consente di creare lavori nel Front-End, configurare PagerDuty, doc data, e così via. Ha molte funzionalità. Può praticamente controllare il mondo intero.

Grazie per la presentazione! Anche io utilizzo Terraform da 4 anni. Durante la fase di transizione verso Terraform, verso l'infrastruttura e la descrizione dichiarativa, ci siamo trovati di fronte a situazioni in cui qualcuno faceva qualcosa manualmente, mentre tu cercavi di eseguire un plan. E ricevevi qualche errore. Come affrontate questi problemi? Come trovate le risorse perse che erano indicate?

Principalmente a mano e con gli occhi, se vediamo qualcosa di strano nel report, analizziamo cosa sta succedendo, oppure semplicemente eliminiamo. E in generale, le pull request sono una prassi comune.

Se c'è un errore, fate il rollback? Avete mai provato a farlo?

No, è una decisione che spetta alla persona nel momento in cui vede il problema.

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