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)

A prima vista, gli sviluppatori di Terraform offrono best practices abbastanza comode per lavorare con l'infrastruttura AWS. Solo che c'è una sfumatura. Col tempo, il numero di ambienti aumenta, ognuno con le proprie peculiarità. Nasce quasi una copia dello stack applicativo in una regione vicina. E il codice Terraform deve essere copiato e modificato con attenzione secondo i nuovi requisiti o realizzare una snowflake.

La mia presentazione riguarda i pattern in Terraform per affrontare il caos e la routine manuale nei grandi progetti 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 in Ixtens. Ci occupiamo di ecommerce-driven-development. E da 5 anni pratico le 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 un'azienda, il cui nome non dirò, coprendomi con un accordo di riservatezza.

I numeri sulla slide sono indicati per comprendere la portata del progetto. Tutto ciò di cui parlerò in seguito è legato 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 nel bel mezzo si stava effettuando il refactoring dell'infrastruttura, perché il progetto era cresciuto. E i pattern utilizzati non erano più adeguati. E considerando tutto il previsto aumento del progetto, era necessario pensare a qualcosa di nuovo.

Grazie a Matvey, che ieri ha raccontato cosa stava succedendo in Dodo Pizza. È ciò che accadeva da noi 4 anni fa.

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

I motivi più ovvi per cui ciò era necessario erano legati al time to market. Bisognava fare in modo che il team DevOps non fosse un collo di bottiglia nel rilascio. E per di più, a livello iniziale, 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 dell'azienda HashiCorp. E per coloro che non sanno cosa sia, le prossime slide.

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 fare in modo che otteniamo le risorse che abbiamo descritto.

Ad esempio, abbiamo bisogno di macchina virtuale. Descriveremo, aggiungeremo 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 pianificare. Terraform pianificherà e dirà: «Ok, per la vostra risorsa possiamo fare queste cose». E, come minimo, una risorsa sarà aggiunta. E non ci sono previsti cambiamenti.

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

Una volta che sei soddisfatto, puoi chiedere a Terraform di applicare e Terraform creerà un’istanza per te, e otterrai 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 53 registrazioni.

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

E ripetiamo. Richiediamo un piano. Vediamo quali modifiche sono pianificate. Applichiamo. In questo modo, la nostra infrastruttura cresce.

Terraform utilizza un concetto chiamato file di stato. Cioè, tutte le modifiche che vengono inviate ad Amazon vengono salvate in un file, in cui per ogni risorsa che hai descritto, ci sono risorse corrispondenti create in Amazon. In questo modo, quando modifichi 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. E li archiviavamo in Git, il che era estremamente scomodo. Qualcuno dimenticava sempre di eseguire il commit delle modifiche, e si verificavano molti conflitti.

Ora è possibile utilizzare un backend, cioè si indica a Terraform in quale bucket e con quale chiave deve salvare il file di stato. E Terraform si prenderà cura di estrarre questo file di stato, fare tutta la magia e riporre il risultato finale.

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

La nostra infrastruttura cresce. Ecco il nostro codice. Ora non vogliamo semplicemente 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 un modulo, cioè descrivere la stessa cosa in una cartella.

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

E, ad esempio, nel test richiamare questo modulo e ottenere la stessa cosa come se avessimo eseguito Terraform apply nel modulo stesso. Per il test ci sarà un codice di questo tipo.

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

Per la produzione possiamo inviare alcune modifiche, perché nei test non abbiamo bisogno di grandi istanze; nella 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. E dovevamo in qualche modo organizzare tutto il codice, in modo che fosse conveniente per tutti: sia per coloro che effettuano la manutenzione di questo codice, sia per coloro che apportano modifiche. Si prevede che qualsiasi sviluppatore possa andare e modificare l'infrastruttura come è necessario per la sua parte della piattaforma.

Questa è la struttura ad albero dei cataloghi, raccomandata dalla stessa HashiCorp, se hai un grande progetto e ha senso suddividere l'intera infrastruttura in pezzi più piccoli, descrivendo ogni pezzo in una cartella separata.

Avere una libreria ricca di risorse consente di richiamare in modo simile nei test e in produzione.

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

Nel nostro caso, ciò non era del tutto adatto, poiché il stack di test per gli sviluppatori o per il testing doveva essere ottenuto in modo più semplice. Non volevamo dover navigare tra le cartelle e applicare in una sequenza specifica, preoccupandoci che il database si avviasse e poi si avviasse l'istanza che utilizza quel database. Pertanto, tutti i test venivano avviati da una sola cartella. Lì venivano richiamati gli stessi moduli, ma tutto avveniva in un'unica esecuzione.

Terraform si occupa di tutte le dipendenze. E crea sempre le risorse nell'ordine necessario per poter ottenere, ad esempio, un indirizzo IP dall'istanza freschamente creata e per avere quel indirizzo IP in un record route53.

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

E abbiamo automatizzato questo processo. E il job di Jenkins consentiva di avviare lo stack. Doveva essere avviato un pull request con le modifiche che lo sviluppatore desiderava testare, specificando tutte le opzioni necessarie, i componenti e anche le dimensioni. Se desiderava testare le prestazioni, poteva richiedere più istanze. Se doveva semplicemente verificare che un certo modulo si aprisse, poteva avviarlo con le impostazioni minime. Poteva anche specificare se aveva bisogno di un cluster o meno, ecc.

E poi Jenkins eseguiva uno script shell che modificava leggermente il codice nella cartella Terraform. Rimuoveva file non necessari e aggiungeva file richiesti. E poi, tramite un'unica esecuzione, Terraform apply alzava lo stack.

E poi seguivano altri passaggi, in cui non voglio addentrarmi.

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

Poiché per il testing avevamo bisogno di un po' più di opzioni rispetto alla produzione, abbiamo dovuto creare copie dei moduli, in modo da poter aggiungere quelle funzionalità necessarie solo nel testing.

E così è successo che nel testing si desiderava testare quelle modifiche che alla fine sarebbero andate in produzione. Ma in realtà si testava una cosa e in produzione si applicava qualcos'altro. E c'era un piccolo divario di schemi, in quanto in produzione tutte le modifiche venivano applicate dal team operativo. E a volte accadeva che quelle modifiche che avrebbero dovuto passare dal testing alla produzione rimanessero in un'altra versione.

Inoltre, c'era un problema in cui veniva aggiunto un nuovo servizio che si differenziava leggermente da uno già esistente. E invece di modificare il modulo esistente, era necessario fare una copia e aggiungere le modifiche necessarie.

Fondamentalmente, Terraform non è un vero linguaggio. È una dichiarazione. Se dobbiamo dichiarare qualcosa, lo facciamo. E tutto questo funziona.

A un certo punto, durante la discussione di una delle mie pull request, un collega ha detto che non era necessario creare troppi fiocchi di neve. Sono rimasto incuriosito da cosa intendesse. C'è un fatto scientifico che nel mondo non esistono due fiocchi di neve identici, si differenziano sempre un po'. E non appena ho ascoltato questa cosa, ho subito percepito tutto il peso del codice Terraform. Perché quando era necessario passare da una versione all'altra, Terraform richiedeva modifiche che spezzavano la catena, cioè il codice non era più compatibile con la versione successiva. Così dovevo fare una pull request che copriva quasi metà dei file nell'infrastruttura per portare l'infrastruttura alla versione successiva di Terraform.

E dopo che è apparso un tale fiocco di neve, tutto il codice Terraform che avevamo si trasformava in una grande grande massa di neve.

Per uno sviluppatore esterno, che non fa parte dell'operazione, questo non ha molta importanza, perché ha fatto la pull request e la sua risorsa è partita. E tutto, poi non è più affare suo. Ma per il team DevOps, che si assicura che tutto sia a posto, bisogna fare tutte queste modifiche. E il costo di queste modifiche aumentava molto con ogni ulteriore fiocco di neve.

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

C'è una storia su come uno studente durante un seminario disegna con il gesso sulla lavagna due cerchi perfetti. E il docente si sorprende di come sia riuscito a disegnarli così bene senza compasso. Lo studente risponde: 'È molto semplice, ho girato un macinacarne per due anni nell'esercito'.

E dei quattro anni in cui partecipo a questo progetto, circa due anni mi occupo di Terraform. E, naturalmente, ho alcuni trucchi, alcuni consigli su come semplificare il codice Terraform, lavorarci come un linguaggio di programmazione e ridurre il carico sui programmatori che devono mantenere questo codice aggiornato.

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

La prima cosa da cui vorrei iniziare sono i Symlinks. Terraform ha molto codice ripetitivo. Ad esempio, la chiamata al provider praticamente in ogni punto in cui creiamo un pezzo di infrastruttura è la stessa. Quindi è logico estrarla in una cartella separata. E ovunque sia necessario il provider, fare Symlinks su questo file.

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

Ad esempio, nel tuo ambiente di produzione utilizzi un'assunzione di ruolo, che ti consente di ottenere diritti di accesso a un determinato account Amazon esterno. E cambiando un file, tutti gli altri che si trovano nell'albero delle risorse avranno i diritti richiesti affinché Terraform sapesse a quale segmento Amazon fare riferimento.

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

Dove i Symlinks non funzionano? Come già detto, in Terraform ci sono file di stato. E sono davvero molto utili. Ma il fatto è che Terraform inizializza il backend prima di ogni altra cosa. E non può utilizzare in questi parametri alcuna variabile, devono sempre essere scritti come testo.

E come risultato, quando qualcuno crea una nuova risorsa, copia una parte del codice da altre cartelle. E può commettere un errore con la chiave o con il bucket. Ad esempio, crea una cosa sandbox e poi la fa in produzione. E potrebbe capitare che il bucket in produzione venga utilizzato dalla sandbox. Certo, questo verrà scoperto rapidamente. Si potrà correggere in qualche modo, ma comunque è una perdita di tempo e in una certa misura di risorse.

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

Cosa possiamo fare successivamente? Prima di lavorare con Terraform, bisogna inizializzarlo. Durante il processo di inizializzazione, Terraform scarica tutti i plugin. A un certo punto, da un monolite si sono spezzati in un'architettura più microservizi. E bisogna sempre eseguire Terraform init, affinché possa caricare tutti i moduli, tutti i plugin.

E puoi utilizzare uno script shell che, da un lato, sarà in grado di recuperare tutte le variabili. Gli script shell non hanno limitazioni. E, dall'altro, i percorsi. Se utilizziamo sempre quello che è presente nel repository come chiave per il file di stato, allora, 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? File JSON. Terraform consente di registrare l'infrastruttura non solo in hcl (HashiCorp Configuration Language), ma anche in JSON.

Il JSON è facilmente leggibile dallo script shell. Di conseguenza, è possibile posizionare un file di configurazione con il bucket in un certo 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 remoti. Cioè, quando sollevo qualche risorsa, per dire ad Amazon: «Per favore, crea un'istanza», devo specificare molti parametri obbligatori.

E questi identificatori sono memorizzati in un'altra cartella. Posso dire: «Terraform, vai per favore nel file di stato di quella risorsa e portami questi identificatori». In questo modo si ottiene 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 crea una VPC così diversa, che ti ci vorrà molto tempo per adattare una cosa all'altra, quindi puoi utilizzare il trucco successivo.

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

Cioè, creare un modulo che in pratica crea la VPC e fornisce gli identificatori, ma in realtà c'è semplicemente un file con valori hardcoded, che può essere usato per creare la stessa istanza.

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 vengono testati i moduli, è possibile utilizzare l'inizializzazione del backend, in cui il file verrà salvato semplicemente sul disco durante il test.

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

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

HashiCorp ha una comprensione di come formattare il codice Terraform. Terraform fmt consente di formattare il codice che stai modificando in conformità a questa guida. Pertanto, i test devono necessariamente verificare se la formattazione corrisponde a quella stabilita da HashiCorp, per non dover cambiare la posizione delle parentesi e così via.

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

Il prossimo è Terraform validate. Fa qualcosa in più che una semplice verifica della sintassi, tipo controllare se tutte le parentesi sono abbinate. Cosa è importante qui? La nostra infrastruttura è molto ramificata. Ci sono molte cartelle diverse. E in ognuna è necessario eseguire Terraform validate.

Pertanto, per accelerare il testing, eseguiamo più processi in parallelo, utilizzando la parallelizzazione.

Il parallelo è una cosa molto utile, sfruttatelo.

Ma ogni volta che si verifica l'inizializzazione di Terraform, va su HashiCorp e chiede: «Quali sono le versioni più recenti dei plugin? E quel plugin che ho in cache – è quello giusto o no?». E questo rallentava ogni passo.

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

Se Terraform è informato su dove si trovano i plugin, dirà: «Ok, probabilmente quella è la versione più recente. Non andrò da nessuna parte, inizierò subito a validare 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 indicare tutti i provider che in qualche modo partecipano 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 è il Terraform plan. Come ho detto, lo sviluppo è ciclico. Scriviamo il codice con delle modifiche. E poi dobbiamo scoprire quali modifiche sono previste per l'infrastruttura.

E quando l'infrastruttura è molto, molto grande, puoi modificare un modulo, riparare un ambiente di test o un singolo regione e rompere qualche vicino. Pertanto, il Terraform plan deve essere eseguito su tutta l'infrastruttura e mostrare quali modifiche sono previste.

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

Il Terraform plan deve essere eseguito su richiesta. Almeno, è ciò che facciamo noi.

I test sono sicuramente utili per ogni modifica, per ogni commit, ma i piani sono abbastanza costosi. E noi nella pull request diciamo: «Per favore, dammi i piani». Si attiva un robot e invia nei commenti o in allegato tutti i piani previsti per le tue modifiche.

Il piano è un'operazione piuttosto costosa. Richiede tempo, perché Terraform va su Amazon e chiede: «Questo instance esiste ancora? E per questo autoscale, le specifiche sono davvero quelle?». E per velocizzare questo processo, si può utilizzare un parametro come refresh=false. Questo significa che Terraform scaricherà dallo stato S3. E crederà che lo stato corrisponda esattamente a ciò che si trova su Amazon.

Questo piano Terraform è molto più veloce, ma lo stato deve corrispondere alla vostra infrastruttura, cioè, da qualche parte, in un certo momento, deve essere eseguito Terraform refresh. Terraform refresh fa esattamente ciò che serve affinché lo stato corrisponda a quello che c'è nella reale infrastruttura.

E bisogna parlare di sicurezza. Da qui sarebbe stato opportuno iniziare. Lì dove eseguite Terraform e Terraform lavora con la vostra infrastruttura, c'è una vulnerabilità. Cioè, in sostanza, state eseguendo codice. E se la richiesta di pull contiene del codice dannoso, questo può essere eseguito sull'infrastruttura che ha troppi privilegi. Pertanto, fate attenzione a dove eseguite Terraform plan.

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

Il prossimo argomento di cui vorrei parlare è il test di user-data.

Cos'è user-data? Su Amazon, quando creiamo un'istanza, possiamo inviare dall'istanza una sorta di messaggio - metadati. Quando l'istanza si avvia, di solito cloud init è sempre presente su queste istanze. Cloud init legge questo messaggio e dice: "Ok, oggi sono un bilanciatore di carico". E in conformità con queste istruzioni compie alcune azioni.

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

Ma, sfortunatamente, quando facciamo Terraform plan e Terraform apply, user-data appare come una sorta di miscuglio di numeri. Cioè, vi invia semplicemente un hash. E tutto ciò che potete vedere nel piano è se ci saranno delle modifiche o se l'hash rimarrà lo stesso.

E se non ci si presta attenzione, su Amazon, potrebbe finire un qualche file di testo danneggiato nella vera infrastruttura.

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

Come opzione, potete specificare solo il template invece di tutta l'infrastruttura durante l'esecuzione. E nel codice dire: "Per favore, mostrami questo template". E alla fine potete 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 è utilizzare un modulo per generare user-data. Applicate questo modulo. Ottenete un file sul disco. Lo confrontate con quello di riferimento. E in questo modo, se un principiante decide di modificare un po' user-data, i vostri test diranno: "Ok, qui e qui ci sono delle modifiche - va bene".

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, è abbastanza spaventoso fare Terraform apply in modalità automatica, perché, chi sa quali cambiamenti sono arrivati e quanto possano essere devastanti per l'infrastruttura in uso.

Per l'ambiente di test va tutto bene. Cioè, il job che crea l'ambiente di test è ciò di cui tutti gli sviluppatori hanno bisogno. E un'affermazione come «tutto ha funzionato» non è un meme divertente, ma una prova che la persona si è impegnata, ha avviato lo stack, ha eseguito alcuni test su di esso. E si è accertata che tutto va bene e ha detto: «Ok, il codice che sto rilasciando è stato testato».

In production, sandbox e altri ambienti che sono più importanti per il business, è possibile applicare parzialmente alcune risorse in modo abbastanza sicuro, perché non porta a situazioni in cui qualcuno muore. Questi sono: gruppi autoscale, gruppi di sicurezza, ruoli, route53 e l'elenco può essere abbastanza lungo. Ma fai attenzione a ciò che accade, leggi i report sulle applicazioni automatiche.

Dove è pericoloso o si ha paura di applicare, per esempio, se si tratta di risorse persistenti o di database, allora ricevi report su eventuali modifiche non applicate in qualche parte dell'infrastruttura. E l'ingegnere, sotto supervisione, avvia i job per applicare o lo fa dalla propria console.

In Amazon esiste una funzione chiamata protezione dalla terminazione. Questa può proteggerti in alcuni casi da modifiche non richieste. Cioè, Terraform si connette a Amazon e dice: «Devo eliminare questa istanza per crearne un'altra». E Amazon risponde: «Spiacenti, non oggi. Abbiamo attivato la protezione dalla terminazione».

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 modulo a modulo, da modulo a modulo, specialmente se i moduli sono annidati.

E questo è molto difficile da leggere. È molto complicato fare una revisione. E molto spesso succede che alcuni parametri passano la revisione, ma non sono proprio quelli necessari. Questo richiede tempo e denaro per essere corretto in seguito.

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

Pertanto, ti propongo di utilizzare una cosa come un parametro complesso che include una sorta di albero di valori. Cioè, hai bisogno di una certa cartella in cui sono indicati tutti i valori che desideri avere in un determinato ambiente.

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

E chiamando questo modulo, si può ottenere un albero che viene generato in un unico modulo generale, cioè in un modulo generale che funziona allo stesso modo per tutta l'infrastruttura.

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

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

A questo punto, tutte le migliori scoperte che ho sono esaurite. E vorrei raccontare una storia su Colombo. Quando cercava soldi per la sua spedizione per scoprire l'India (come pensava allora), nessuno credeva in lui e lo considerava impossibile. Allora disse: "Fate in modo che l'uovo non cada". Tutti i banchieri, persone molto ricche e probabilmente intelligenti, cercavano in tutti i modi di tenere in equilibrio l'uovo, e continuava a cadere. Allora Colombo prese l'uovo, premette un po'. Il guscio si ruppe, e l'uovo rimase fermo. Dissero: "Oh, è troppo semplice!". E Colombo rispose: "Sì, è troppo semplice. E quando scoprirò l'India, tutti utilizzeranno questa rotta commerciale".

E ciò che vi ho appena raccontato sono probabilmente cose abbastanza semplici e banali. E quando ne vieni a conoscenza e inizi a utilizzarle, è normale. Quindi, approfittatene. E se per voi queste cose sono assolutamente normali, almeno sapete come far sì che l'uovo non cada.

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

Facciamo un riepilogo:

  • Cercate di evitare le nevicate. E meno nevicate ci sono, meno risorse vi serviranno per apportare modifiche a tutta la vostra grande infrastruttura.
  • Cambiamenti continui. Cioè, quando ci sono state delle modifiche nel codice, bisogna allineare la vostra infrastruttura a queste modifiche il prima possibile. Non deve esserci la situazione in cui qualcuno dopo due o tre mesi viene a vedere Elasticsearch, esegue un piano Terraform e trova un sacco di modifiche che non si aspettava. E si spende molto tempo per rimettere tutto in ordine.
  • Test e automazione. Più codice avete coperto da test e funzionalità, maggiore sarà la vostra sicurezza che state facendo tutto correttamente. E la consegna automatica aumenterà notevolmente la vostra fiducia.
  • Il codice per gli ambienti di test e produzione deve essere praticamente identico. Praticamente, perché la produzione è comunque un po' diversa e ci saranno sempre alcuni dettagli che andranno oltre l'ambiente di test. Tuttavia, si può comunque garantire una certa somiglianza.
  • E se hai molto codice Terraform e mantenere questo codice aggiornato richiede molto tempo, non è mai troppo tardi per fare un refactoring e riorganizzarlo in una forma migliore.

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

  • Infrastruttura immutabile. Consegna AMI programmata.
  • Struttura per route53, quando hai molte registrazioni e desideri che siano in un ordine coerente.
  • Gestire i limiti di API. È quando Amazon dice: «Basta, non posso accettare più richieste, per favore aspetta». E metà dell'azienda aspetta finché non può avviare la propria infrastruttura.
  • Istanza spot. Amazon non è un affare economico e le spot consentono di risparmiare molto. E si potrebbe tenere una presentazione su questo.
  • Sicurezza e ruoli IAM.
  • Ricerca di risorse perdute, quando hai in Amazon istanze di origine sconosciuta che consumano denaro. Anche se le istanze costano 100-150 dollari al mese, in un anno si accumulano più di 1.000. La ricerca di queste risorse è un affare redditizio.
  • E istanze riservate.

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

Per quanto mi riguarda, è tutto. Terraform è fantastico, usatelo. Grazie!

Domande

Grazie per la presentazione! Il vostro file di stato è su S3, come risolvete il problema che più persone potrebbero accedere a questo file di stato e tentare di eseguire il deployment?

In primo luogo, non abbiamo fretta. In secondo luogo, ci sono flag che indicano che stiamo lavorando su un certo pezzo di codice. Cioè, nonostante l'infrastruttura sia molto ampia, non significa che ci siano sempre persone che applicano modifiche. E quando la fase attiva era in corso, era un problema, i nostri file di stato erano archiviati in Git. Era importante, altrimenti qualcuno avrebbe creato un file di stato e dovevamo raccoglierli a mano per continuare. Adesso questo problema non esiste. In generale, Terraform ha risolto questa questione. E se ci sono frequenti cambiamenti, si possono utilizzare i lock che prevengono quanto hai detto.

Utilizzate la versione open source o l'enterprise?

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

Mi chiamo Stanislav. Volevo fare una piccola aggiunta. Hai parlato di una funzione di Amazon che consente di rendere istanze indistruttibili. Questo è presente anche in Terraform stesso, nel blocco Life Second è possibile specificare un divieto di modifica o un divieto di distruzione.

Il tempo era limitato. Buona osservazione.

Volevo anche chiedere due cose. In primo luogo, hai parlato di testing. Hai utilizzato qualche strumento per il testing? Ho sentito parlare del plugin Test Kitchen. Forse c’è qualcos’altro. E vorrei anche chiedere riguardo ai Local Values. In cosa differiscono fondamentalmente dalle Input Variables? E perché non posso parametrizzare qualcosa solo attraverso i Local Values? Ho cercato di approfondire questo argomento, ma non ci sono riuscito.

Possiamo parlare più nel dettaglio dopo questa sala. Gli strumenti per il testing qui sono una nostra creazione. Non ci sono nulla di particolare per testare. In realtà, ci sono opzioni in cui i test automatici alzano un'infrastruttura da qualche parte, controllano che vada bene e poi distruggono tutto con un report che indica che la tua infrastruttura è ancora in buona forma. Noi non abbiamo questo, perché gli stack di test vengono eseguiti ogni giorno. E questo è sufficiente. E se qualcosa inizia a rompersi, inizierà a rompersi senza che dobbiamo verificarlo ulteriormente.

Per quanto riguarda i Local Values, continuiamo la conversazione dopo la sala.

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

Ottima domanda, grazie! Il punto è che quando utilizziamo l'infrastruttura come codice, presupponiamo di guardare il codice e comprendere quale infrastruttura sta dietro quel codice. Se il codice è generato, dobbiamo immaginarci quale codice verrà generato per capire quale infrastruttura sarà lì. Oppure generiamo il codice, lo committiamo e, in sostanza, è la stessa cosa. Quindi abbiamo seguito il percorso che avevamo scritto, e così abbiamo ottenuto. Inoltre, i generatori sono emersi qualche tempo dopo, quando abbiamo iniziato a fare. Ed era già tardi per cambiare.

Hai sentito parlare di jsonnet?

No.

Guarda, è una cosa davvero interessante. Vedo un caso specifico in cui può essere applicato e generare una struttura di dati.

I generatori sono buoni, quando hai, come nella barzelletta sulla macchina da barba. Cioè, la prima volta il viso è diverso, ma poi diventa lo stesso per tutti. I generatori sono molto interessanti. Ma purtroppo, noi abbiamo volti un po' diversi. Questo è il problema.

Guarda semplicemente. Grazie!

Mi chiamo Maxim, vengo da Sberbank. Hai detto un po' che cercavi di portare Terraform a un parallelo con un linguaggio di programmazione. Non è più facile usare Ansible?

Sono cose molto diverse. Puoi usare Ansible per creare risorse, e puoi usare Puppet per creare risorse in Amazon. Ma Terraform è proprio ottimizzato per questo.

Avete solo Amazon?

Non è che abbiamo solo Amazon. Abbiamo quasi solo Amazon. Ma la caratteristica chiave è che Terraform memorizza. In Ansible, se dici: "Alza 5 istanze", lui lo fa, poi dici: "Ora ne ho bisogno di 3". E Terraform dirà: "Ok, ne distruggerò 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 dare un piccolo commento sul fatto che Terraform non ha comunque un rilascio stabile, quindi fate attenzione con Terraform.

La gallina in tempo. Cioè, se hai bisogno di una soluzione, a volte rimandi quello che è instabile e così via, ma funziona ed è stato utile per noi.

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

Ufficiale?

Terraform Cloud.

Quando è apparso?

Circa 4 mesi fa.

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

Ci sono già funzioni integrate per i lock, e puoi memorizzare il file di stato. Provalo. Ma anche io non l'ho testato.

Stiamo viaggiando in un grande treno che si muove ad alta velocità. E non puoi semplicemente prendere e buttare via diversi vagoni.

Hai parlato di fiocchi di neve, ma perché non hai usato i 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 si riferiscono 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 massa di branch, un progetto del genere sarebbe praticamente impossibile da gestire. Passano sei mesi e si allontanano tanto che è semplicemente una punizione. Questo è quello da cui si vorrebbe scappare fino al refactoring.

Cioè, non funziona?

Questo non funziona affatto.

Nella branch ho rimosso il slide della cartella. Cioè, se si fa un stack di test per ogni squadra, ad esempio, la squadra A ha la sua cartella, la squadra B la sua, allora non funziona neanche questo. Abbiamo creato un codice unificato per l'ambiente di test, che fosse abbastanza flessibile da adattarsi a tutti. Cioè, abbiamo gestito un unico codice.

Ciao! Mi chiamo Yuri! Grazie per la presentazione! Ho una domanda sui moduli. Dite che utilizzate i moduli. Come gestite la situazione se un modulo subisce cambiamenti che non sono compatibili con quelli di un altro? Versionate i moduli in qualche modo o cercate di adattare la soluzione per soddisfare entrambi i requisiti?

È un problema della grande palla di neve. È ciò di cui soffriamo, quando un apparente cambiamento innocuo può rompere una parte dell'infrastruttura. E questo sarà notato solo dopo un certo periodo di tempo.

Cioè, al momento non viene risolto in alcun modo?

Fate moduli universali. Evitate le dipendenze crollanti. E tutto funzionerà. La seconda parte della presentazione riguarda come evitarlo.

Salve! Grazie per la presentazione! Vorrei chiarire. È rimasta una grande questione di cui sono venuto a parlare. In che modo sono integrati Puppet e la distribuzione dei ruoli?

User-data.

Cioè, semplicemente estraete un file e in qualche modo lo eseguite?

User-data è una nota, cioè quando creiamo un clone dell'immagine, si avvia un Daemon che, cercando di capire chi è, legge la nota che dice che è un load balancer.

Cioè, è qualche processo separato che viene assegnato?

Non l'abbiamo inventato noi. Lo utilizziamo.

Salve! Ho proprio una domanda su User-data. Ha detto che ci sono problemi, che qualcuno può inviare informazioni sbagliate. Esiste un modo per memorizzare i dati utente nello stesso Git, in modo che sia sempre chiaro a cosa si sta riferendo User-data?

Generiamo User-data da template. Vale a dire, su di esso si basano un certo numero di variabili. E Terraform genera il risultato finale. Quindi non si può semplicemente guardare il template e dire cosa uscirà, perché tutti i problemi sono legati al fatto che lo sviluppatore pensa di passare una stringa in quella variabile, mentre arriva un array. E lui – puff, e io –questo, quello, la riga successiva, e tutto si rompe. Se si tratta di una nuova risorsa e la persona la avvia, vede che qualcosa non funziona, quindi ciò si risolve rapidamente. Ma se si è aggiornata un gruppo autoscale, a un certo punto le istanze nel gruppo autoscale iniziano a cambiare. E puff, qualcosa non funziona. È frustrante.

Quindi, l'unica soluzione è testare?

Sì, vedete il problema, aggiungete passi di test. Vale a dire, anche l'output può essere testato. Forse non è così comodo, ma è possibile mettere alcune etichette – verificate che User-data sia qui inchiodato.

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

Non ho nemmeno iniziato.

Penso che nella prossima conferenza, forse, ci sarà. Ho una semplice domanda. Perché hardcodate il valore in un modulo separato e non usate tfvars, cioè, in cosa è meglio un modulo con valori rispetto a tfvars?

Vale a dire, qui (slide: Production/environments/settings.tf) devo scrivere: domain = variabile, domain vpcnetwork, variabile vpcnetwork e stvars – estrarre lo stesso?

Lo facciamo esattamente così. Ci riferiamo al modulo impostazione sorgente, per esempio.

Fondamentalmente, è un tfvars. Il tfvars è molto utile nell'ambiente di test. Ho tfvars per grandi istanze, per piccole. E ho messo un file nella cartella. E ho ottenuto ciò che volevo. Quando costruiamo l'infrastruttura, vogliamo che si possa vedere e capire tutto subito. Così è, è necessario guardare qui, poi guardare in tfvars.

Quindi, per avere tutto in un unico posto?

Sì, tfvars è quando hai un codice. E viene utilizzato in diversi posti con diverse sfumature. Allora avresti lanciato tfvars e ottenuto le tue sfumature. E noi – è infrastruttura come codice in forma pura. Hai guardato e capito.

Ciao! Ti è mai capitato di affrontare situazioni in cui il provider cloud interviene su ciò che hai fatto con Terraform? Supponiamo che stiamo modificando i metadati. Ci sono chiavi ssh. E Google continua a inserire i suoi metadati, le sue chiavi. E Terraform scrive sempre che ci sono delle modifiche. Dopo ogni esecuzione, anche se nulla cambia, dice sempre che sta per aggiornare questo campo.

Con le chiavi, ma sì, parte dell'infrastruttura è colpita da questa situazione, cioè Terraform non può cambiare nulla. Anche noi a mano non possiamo modificare nulla. Finora conviviamo con questo.

Cioè, ti è capitato di affrontare situazioni del genere, ma non hai trovato soluzioni, lui continua a fare autonomamente?

Purtroppo, sì.

Ciao! Mi chiamo Starkov Stanislav. Mail.ru Group. Come risolvete il problema con la generazione del tag su …, come lo trasmettete internamente? Credo di capire, tramite User — data, per specificare il nome host, da indirizzare con Puppet? E la seconda parte della domanda. Come affrontate questa questione nel SG, cioè quando generate SG, centinaia di istanze simili, come le nominate correttamente?

Le istanze che per noi sono molto importanti, le nominiamo in modo elegante. Quelle che non servono, c'è una notazione che è un gruppo autoscale. E teoricamente, si può uccidere e ottenere un nuovo.

Riguardo al problema con il tag, non è un problema, ma una questione. E noi utilizziamo molto i tag, perché l'infrastruttura è grande e costosa. Abbiamo bisogno di capire dove vanno a finire i soldi, quindi i tag ci permettono di identificare cosa e dove è stato speso. Di conseguenza, facilita la ricerca di eventuali spese eccessive.

Di cosa parlavi ancora?

Quando il SG crea centinaia di istanze, è necessario differenziarle in qualche modo?

No, non è necessario. Su ogni istanza c'è un agente che comunica che ho un problema. Se l'agente comunica, allora l'agente sa di lui e, come minimo, esiste il suo indirizzo IP. Si può già verificare. Inoltre, utilizziamo Consul per il Discovery, dove non c'è Kubernetes. E anche Consul mostra l'indirizzo IP dell'istanza.

Cioè, ti basi proprio sull'IP e non sul nome host?

È impossibile basarsi sul nome host, cioè ce ne sono molti. Ci sono identificatori delle istanze – AE e così via. Può essere trovato da qualche parte, si può cercare.

Ciao! Ho capito che Terraform è una buona cosa, progettata per le nuvole.

Non solo.

Questo è esattamente il punto che mi interessa. Se decidete di migrare, ad esempio, su Bare Metal con tutti i vostri instances? Non ci saranno problemi? Oppure dovrete comunque usare altri prodotti, come lo stesso Ansible menzionato qui?

Ansible è leggermente diverso. Cioè, Ansible funziona già quando l'instance è avviato. Terraform funziona prima che l'instance sia avviato. La migrazione su Bare Metal – no.

Al momento no, ma arriva il business e dice: «Facciamolo».

La migrazione su un altro cloud – sì, ma qui c'è un'altra questione. È necessario scrivere il codice Terraform in modo che si possa migrare su un altro cloud con meno difficoltà.

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

Terraform consente di creare jobs nel Front-End, configurare PagerDuty, documenti dati, ecc. Ha davvero molte funzionalità. Può praticamente controllare il mondo intero.

Grazie per la relazione! Anche io lavoro con Terraform da 4 anni. Durante la transizione verso Terraform, verso l'infrastruttura, verso la descrizione dichiarativa, ci siamo trovati in situazioni in cui qualcuno faceva qualcosa a mano, e tu cercavi di fare un piano. E ricevevi qualche errore. Come affrontate questi problemi? Come trovate le risorse perse che erano state indicate?

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

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

No, è una decisione del momento, quando si vede il problema.

Fonte: habr.com

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