Reprezentarea infrastructurii ca și cod într-un format text revisibil este o practică simplă, dar esențială pentru sistemele care nu necesită intervenție manuală. Această practică poartă denumirea de , iar pentru implementarea acesteia, în special în AWS, există două instrumente populare: și .

Compar experiența mea de lucru cu Terraform și CloudFormation
Înainte de a veni la (cunoscut și ca ) am lucrat și timp de trei ani am folosit Terraform. La noul loc de muncă am utilizat din plin Terraform, apoi compania a insistat pentru o tranziție către tot ce ține de Amazon, inclusiv CloudFormation. Am dezvoltat cu sârguință cele mai bune practici atât pentru unul, cât și pentru celălalt, și am utilizat ambele instrumente în procese de lucru extrem de complexe la nivel organizațional. Ulterior, analizând cu atenție consecințele trecerii de la Terraform la CloudFormation, am realizat că Terraform este probabil cea mai bună alegere pentru o organizație.
Terraform este teribil
Versiunea beta a software-ului
Terraform nici măcar nu are o versiune 1.0, ceea ce este un motiv întemeiat pentru a nu-l folosi. De când l-am încercat pentru prima dată, s-a schimbat foarte mult, dar atunci era încă terraform apply de multe ori se strica după câteva actualizări sau pur și simplu după câțiva ani de utilizare. Aș spune că „acum totul este diferit”, dar... așa spun toți, nu? Există modificări incompatibile cu versiunile anterioare, deși sunt justificate, și chiar am senzația că sintaxa și abstracțiile stocării resurselor sunt acum potrivite. Instrumentul pare să fi devenit într-adevăr mai bun, dar… :-0
Pe de altă parte, AWS a depus eforturi considerabile pentru a menține compatibilitatea cu versiunile anterioare. Probabil că acest lucru se datorează faptului că serviciile lor sunt testate temeinic în cadrul organizației și abia apoi, sub alt nume, sunt publicate. Așa că „au făcut o treabă bună” este o formulare modestă. Menținerea compatibilității cu versiunile anterioare ale API-ului pentru un sistem atât de complex și variat, cum este AWS, este incredibil de dificilă. Oricine a trebuit să susțină API-uri publice utilizate atât de pe scară largă ar trebui să înțeleagă cât de greu este să faci asta de-a lungul anilor. Comportamentul CloudFormation, de care îmi amintesc, nu s-a schimbat niciodată de-a lungul anilor.
Întâlnirea dintre picior și... acea glonț
Din câte știu, să ștergi o resursă externă Stiva CloudFormation nu poate importa resurse dintr-un alt stack CF. Aproape la fel se prezintă și situația cu Terraform. Acesta permite importarea resurselor existente în stack-ul său. Funcția este, să spunem, uimitoare, dar cu o mare putere vine și o mare responsabilitate. Odată ce resursa este adăugată în stack, nu poți să o ștergi sau să o modifici în timp ce lucrezi cu stack-ul tău. O dată, acest lucru a avut consecințe. Pe site-ul Twitch, cineva, fără vreo intenție rea, a importat accidental un grup de securitate AWS în propriul său stack Terraform. A introdus câteva comenzi și… grupul de securitate (inclusiv traficul de intrare) a dispărut.
Terraform Mare
Restaurarea din stări incomplete
Uneori, CloudFormation nu poate trece complet dintr-o stare în alta. Totuși, va încerca să revină la cea anterioară. Din păcate, asta nu este întotdeauna posibil. Este înfricoșător să depanezi apoi ceea ce a rezultat — niciodată nu știi dacă CloudFormation va fi mulțumit că este manipulat — chiar și pentru a repara. Dacă va reuși sau nu să revină la starea anterioară, nu știe exact și, în mod implicit, așteaptă minuni zeci de minute.
Terraform, pe de altă parte, este mai elegant în recuperarea din tranziții nereușite și oferă un instrumentar de depanare extins.
Schimbări mai clare în stările documentului
„Bine, echilibrator de sarcină, te schimbi. Dar cum?”
— inginer îngrijorat, pregătit să apese butonul „accepta”.
Câteodată trebuie să fac câteva manevre cu echilibratorul de sarcină în stack-ul CloudFormation — de exemplu, să adaug un număr de port sau să schimb grupul de securitate. CloudFormation reflectă schimbările slab. Eu, pe de altă parte, verific de fiecare dată fișierul yaml de zece ori pentru a mă asigura că nu am șters nimic esențial și că nu am adăugat ceva necorespunzător.
Terraform este mult mai transparent în acest sens. Uneori este chiar prea transparent (citește: enervant). Din fericire, ultima versiune a inclus o îmbunătățire a vizualizării schimbărilor — acum este clar ce se modifică.
Flexibilitate
Scrieți software-ul de la sfârșit la început.
În mod direct, cea mai importantă caracteristică a software-ului de durată este capacitatea de a se adapta la schimbări. Orice software trebuie să fie construit de la sfârșit spre început. Eu, de cele mai multe ori, am dat greș atunci când am luat un serviciu „simplu” și apoi am încercat să înghesui totul într-un singur stack CloudFormation sau Terraform. Și, desigur, după luni de zile, am descoperit că am înțeles greșit și că serviciul nu era de fapt simplu! Așadar, trebuie să găsesc o modalitate de a descompune un stack mare în părți mai mici. Când lucrezi cu CloudFormation, acest lucru este posibil doar în prealabil recreând stack-ul existent, iar eu, cu bazele mele de date, nu fac asta. Terraform, pe de altă parte, permite descompunerea stack-ului în părți mai ușor de înțeles.
Module în git
Partajarea codului Terraform între numeroase stack-uri este mult mai simplă decât în cazul CloudFormation. Cu Terraform, poți pune codul într-un repository git și să te referi la el folosind controlul versiunilor semantic. Oricine are acces la acest repository poate reutiliza codul comun. Echivalentul în CloudFormation este S3, dar acesta nu are aceleași avantaje, și nu există nicio rațiune pentru care ar trebui să renunțăm la git în favoarea S3.
Organizația creștea, iar capacitatea de a partaja stack-uri comune a ajuns la un nivel critic. Cu Terraform, totul devine ușor și natural, în timp ce CloudFormation te va face să treci prin cercuri înainte de a obține ceva similar.
Operațiuni ca și cod
„Să scriptăm și gata”.
— inginer, cu 3 ani înainte de a inventa bicicleta Terraform.
Când vine vorba de dezvoltarea software-ului, Go sau un program Java nu sunt doar cod.

Cod ca și cod
Există și infrastructura pe care funcționează.

Infrastructure as Code
Dar de unde provine aceasta? Cum o monitorizăm? Unde se află codul tău? Au nevoie dezvoltatorii de permisiune pentru acces?

Operațiuni ca și cod
A fi dezvoltator de software nu înseamnă doar a scrie cod.
Nu doar AWS: cu siguranță folosești servicii de la alți furnizori. SignalFx, PagerDuty sau Github. Poate ai un server intern Jenkins pentru CI/CD sau un panou intern Grafana pentru monitorizare. Infra as Code este adoptat din diverse motive, iar fiecare este la fel de important pentru tot ce ține de software.
Când lucram la Twitch, acceleram serviciile în cadrul sistemelor integrate mixte și sistemelor AWS Amazon. Am creat și întreținut numeroase microservicii, crescând costurile operaționale. Discuțiile se desfășurau cam în felul următor:
- Eu: Ei bine, prea multe mișcări pentru a accelera un singur microserviciu. Trebuie să folosesc această prostie pentru a crea un cont AWS (ne uitam la 2 conturi pe microserviciu), apoi aceasta pentru a seta alertele, încă aceasta pentru depozitul de cod, și asta pentru lista de adrese de email, și uite cealaltă…
- Lead: Hai să-l scriptăm și e gata.
- Eu: Bine, dar scriptul va trebui să se schimbe. Va fi nevoie de o modalitate de a verifica dacă toate aceste instrumente integrate Amazon sunt actualizate.
- Lead: Sună bine. Și pentru asta vom scrie un script.
- Eu: Excelent! Și scriptul va trebui să primească cu siguranță parametrii. Va putea să-i accepte?
- Lead: Sigur că da, altceva nu are ce să facă!
- Eu: Procesul se poate schimba, se va pierde compatibilitatea înapoi. Va fi nevoie de un fel de control semantic al versiunilor.
- Lead: O idee grozavă!
- Eu: Instrumentele pot fi modificate manual, în interiorul interfeței utilizatorului. Va trebui să avem o modalitate de a verifica și corecta asta.
…3 ani mai târziu:
- Lead: Și a ieșit terraform.
Moralul acestei povești este că, chiar dacă ești cu capul în toate lucrurile Amazon, tot folosești ceva care nu provine de la AWS, iar aceste servicii au un stadiu utilizat de un limbaj pentru configurare, pentru a sincroniza acest stadiu.
CloudFormation lambda vs module git terraform
Lambda este soluția CloudFormation pentru problema logicii utilizatorului. Cu ajutorul lambda poți sau . Această abordare prezintă complicații suplimentare, care nu există în controlul semantic al versiunilor modulelor git în Terraform. Problema care m-a frământat cel mai mult a fost gestionarea permisiunilor pentru toate aceste lambda personalizate (și acestea sunt zeci de conturi AWS). O altă problemă importantă a fost tipul „ce a fost mai întâi — oul sau găina?”: aceasta a fost legată de codul lambda. Această funcție — infrastructura și codul — are ea însăși nevoie de monitorizare și actualizări. Ultimul cui în sicriu a fost dificultatea actualizării semantice a modificărilor codului lambda; trebuia să mă asigur că acțiunile stivei nu se schimbă între rulări fără o comandă directă.
Îmi amintesc că, odată, mi-am dorit să creez un deployment canar pentru mediu Elastic Beanstalk cu un balansor de sarcină clasic. Cel mai simplu ar fi fost să fac un al doilea deployment pentru EB alături de mediu de producție, făcând un pas suplimentar: unind grupul auto-scalabil al deployment-ului canar cu LB-ul din mediu de producție. Și având în vedere că Terraform folosește , aceasta ar necesita 4 linii suplimentare de cod în Terraform. Când am întrebat dacă există o soluție similară în CloudFormation, mi s-a indicat un întreg depozit pe git cu un pipeline de deployment și altele: și toate acestea — pentru ceea ce am putea face cu nenorocitele alea 4 linii de cod Terraform.
Este mai bine la detectarea driftilor
Asigurați-vă că realitatea se potrivește cu așteptările.
— este o funcție foarte puternică a operations as code, deoarece ajută să ne asigurăm că realitatea se potrivește cu așteptările. Este disponibilă atât cu CloudFormation, cât și cu Terraform. Dar pe măsură ce crește stiva de lucru, căutarea driftului în CloudFormation oferea tot mai multe false alerte.
Cu Terraform aveți mult mai multe hook-uri avansate de ciclu de viață pentru detectarea driftului. De exemplu, introduceți comanda direct în definiția sarcinii ECS, dacă doriți să ignorați schimbările în definiția unei sarcini specifice, fără a ignora totuși schimbările în întregul deployment ECS.
CDK și viitorul CloudFormation
CloudFormation este greu de gestionat la scară largă, inter-infrastructural. Multe dintre aceste dificultăți sunt recunoscute, iar instrumentul are nevoie de lucruri precum , o structură pentru definirea infrastructurii cloud în cod și desfășurarea acesteia prin AWS CloudFormation. Va fi interesant să vedem ce așteaptă aws-cdk în viitor, dar va fi greu să concureze cu alte avantaje ale Terraform; pentru a atrage CloudFormation, vor fi necesare modificări globale.
Pentru ca Terraform să nu dezamăgească
Este infrastructură ca COD, nu ca text.
Prima impresie despre Terraform mi s-a părut destul de proastă. Cred că pur și simplu nu am înțeles abordarea. Aproape toți inginerii, la început, o percep în mod involuntar ca un format text care trebuie transformat în infrastructura dorită. NU TREBUIE AȘA.
Adevărurile evidente ale unei bune dezvoltări software se aplică și pentru Terraform
Am observat că multe dintre practicile acceptate pentru crearea unui cod bun sunt ignorate în Terraform. Ai învățat ani de zile pentru a deveni un programator bun. Nu renunța la acea experiență doar pentru că lucrezi cu Terraform. Adevărurile de bază ale dezvoltării software se aplică și în cazul Terraform.
Cum să scrii cod și să nu-l documentezi?
Am întâlnit mari stack-uri Terraform complet fără documentație. Cum este posibil să scrii cod pe pagini — complet fără documentație? Adaugă documentație care să explice motivul în care acest segment este important și ceea ce faci. cod Terraform (accentul aici pe cuvântul „cod”), de ce este atât de important acest segment și ce faci.
Cum poți desfășura servicii care anterior erau o singură funcție mare main()?
Am întâlnit stack-uri Terraform foarte complexe, prezentate ca un singur modul. De ce nu desfășurăm software-ul în acest mod? De ce împărțim funcțiile mari în cele mai mici? Aceleași răspunsuri sunt valabile și pentru Terraform. Dacă modulul tău este prea mare — trebuie să-l descompui în module mai mici.
Compania ta nu folosește biblioteci?
Am văzut ingineri care, dezvoltând un nou proiect folosind Terraform, copiau pur și simplu bucăți mari din alte proiecte în ale lor și apoi le ajustau până când începeau să funcționeze. Tu în compania ta ai lucra astfel cu codul „de producție”? Nu folosim biblioteci fără motiv. Da, dar unde am fi fără biblioteci comune în principiu?!
Nu folosești PEP8 sau gofmt?
În majoritatea limbajelor există un schema standard de formatare acceptată. În Python este PEP8. În Go — gofmt. Terraform are propriul său: terraform fmt. Folosește-l cu plăcere!
Vei folosi React fără a cunoaște JavaScript?
Modulele Terraform pot să simplifice o parte din infrastructura complicată pe care o creezi, dar asta nu înseamnă că nu trebuie să înțelegi deloc resursele. Vrei să folosești corect Terraform fără a înțelege resursele? Ești destinat eșecului: timpul va trece și tu tot nu vei învăța Terraform.
Codifici singletoni sau injectând dependențe?
Injecția de dependențe este o practică recunoscută ca fiind cea mai bună pentru dezvoltarea software-ului, preferată de singletonuri. Cum este utilă aceasta în Terraform? Am întâlnit module Terraform care depind de starea externă. În loc să scrieți module care extrag din starea externă, creați un modul care acceptă parametri. Apoi, transmiteți acești parametri în modul.
Bibliotecile dvs. fac zece lucruri bine sau unul — excelent?
Cel mai bine funcționează bibliotecile care se concentrează pe o singură sarcină, pe care o îndeplinesc excelent. În loc să scrieți module mari Terraform care încearcă să facă totul deodată, compuneți-le din părți care fac bine un singur lucru. Apoi, combinați-le așa cum trebuie.
Cum realizați modificări în biblioteci fără compatibilitate inversă?
Un modul Terraform comun, la fel ca o bibliotecă obișnuită, trebuie să comunice utilizatorilor despre modificările fără compatibilitate inversă. Când astfel de modificări au loc în biblioteci, este frustrant, și exact la fel este frustrant când modificările fără compatibilitate inversă sunt aplicate în module Terraform. Se recomandă utilizarea git tags și semver atunci când utilizați module Terraform.
Serviciul de producție este pornit pe laptopul dvs. sau în data center?
Hashicorp are instrumente precum pentru a rula terraformul dvs. Aceste servicii centralizate facilitează gestionarea, auditul și aprobarea modificărilor terraform.
Încă nu scrieți teste?
Inginerii recunosc că trebuie să testeze codul, dar adesea ignoră verificările atunci când lucrează cu Terraform. Acest lucru poate duce la momente dificile în infrastructură. Recomand să 'testați' sau 'creați exemple' de stive folosind modulele care pot fi corect deploiate pentru verificare în timpul CI/CD.
Terraform și microserviciile
Viața și moartea companiilor de microservicii depind de viteză, actualizare și distrugerea noilor stive de lucru microservicii.
Cel mai răspândit aspect negativ asociat arhitecturilor microservicii, de care nu se pot scăpa, este legat de muncă și nu de cod. Dacă considerați Terraform doar ca un mod de a automatiza doar partea infrastructurală a arhitecturii microservicii, vă priviți de adevăratele beneficii ale acestui sistem. Acum este deja .
Sursa: habr.com
