Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Întrebările legate de structura codului Terraform sunt de departe cele mai frecvente în comunitate. La un moment dat, toată lumea s-a gândit la cea mai bună structură de cod pentru proiect.
Aceasta este una dintre întrebările pentru care există o mulțime de soluții și este foarte greu să dai sfaturi universale, așa că este util să începem prin a înțelege cu ce avem de-a face.
Care este complexitatea proiectului?
Numărul de resurse aferente
Numărul de furnizori Terraform (vezi nota de mai jos despre „furnizorii logici”)
Cât de des se schimbă infrastructura proiectului?
De la o dată pe lună/săptămână/zi
La continuu (de fiecare dată când există un nou commit)
Tirggeri pentru schimbari in cod? Permiteți serverului CI să actualizeze Git repository atunci când este construit un nou artefact?
Doar dezvoltatorii pot face push în repository-ul de infrastructură
Toată lumea poate propune o schimbare la orice, deschizând un PR (inclusiv activități automate care rulează pe serverul CI)
Ce platformă de implementare sau serviciu de implementare utilizați?
AWS CodeDeploy, Kubernetes, sau OpenShift au nevoie de o abordare ușor diferită
Cum sunt grupate mediile?
După mediu, regiune, proiect
Punerea întregului cod în main.tf
este o idee bună atunci când începeți sau scrieți un exemplu de cod. În toate celelalte cazuri, va fi mai bine să aveți mai multe fișiere împărțite logic astfel:
main.tf
- apelați module, informații locale și surse de date pentru a crea toate resursele
variables.tf
- conține declarații ale variabilelor utilizate în main.tf
outputs.tf
- conține rezultate din resursele create înmain.tf
versions.tf
- conține cerințele de versiune pentru Terraform și furnizori
terraform.tfvars
nu trebuie folosit nicăieri decât in Compoziţia de infrastructură.
Vă rog să vă asigurați că înțelegeți conceptele cheie - modulul de resurse, modulul de infrastructură și compoziția de infrastructură, așa cum sunt utilizate în exemplele următoare.
Este mai ușor și mai rapid să lucrezi cu un număr mai mic de resurse
terraform plan
șiterraform apply
ambele fac apeluri API în cloud pentru a verifica starea resurselor
Dacă aveți întreaga infrastructură într-o singură compoziție de infrastructură, acest lucru poate dura ceva timp
O rază de impact este mai mică, cu mai puține resurse
Izolarea resurselor care nu depind unele de altele prin plasarea lor în compoziții separate reduce riscul în cazul în care ceva nu merge bine
Începeți proiectul folosind remote state deoarece:
Laptopul nu este un loc bun pentru stocarea stării infrastructurii
Gestionarea unui fișiertfstate
în git este un coșmar
Mai târziu, când straturile de infrastructură vor începe să crească în mai multe direcții (număr de dependențe sau resurse), va fi mai ușor să țineți lucrurile sub control
Practicați o structură consecventă și o convenție de denumire a resurselor (naming convention):
La fel ca în cazul codului procedural, codul Terraform ar trebui scris pentru ca oamenii să-l citească mai întâi, consecvența va ajuta atunci când vor avea loc schimbări peste șase luni
Este posibil să mutați resurse în fișierul de stare Terraform, dar poate fi mai greu de făcut dacă aveți o structură și o denumire inconsecventă
Păstrați modulele de resurse cât mai simple posibil
Nu puneți simplu text (hardcoded) valorile care pot fi transmise ca variabile sau descoperite folosind surse de date
Utilizați surse de date șiterraform_remote_state
în special ca legatură între modulele de infrastructură din cadrul compoziției
În această carte, exemplele de proiecte sunt grupate în funcție de complexitate - de la infrastructuri mici la infrastructuri foarte mari. Această separare nu este strictă, așa că verificați și alte structuri.
A avea o infrastructură mică înseamnă că există un număr mic de dependențe și puține resurse. Pe măsură ce proiectul crește, necesitatea de a înlănțui execuția configurațiilor Terraform, conectarea diferitelor module de infrastructură și transmiterea valorilor într-o compoziție, devine evidentă.
Există cel puțin 5 grupuri distincte de soluții de orchestrare pe care dezvoltatorii le folosesc:
Doar Terraform. Foarte simplu, dezvoltatorii trebuie să cunoască doar Terraform pentru a duce treaba la bun sfârșit.
Terragrunt. Instrument de orchestrare pur, care poate fi folosit pentru a orchestra întreaga infrastructură, precum și pentru a gestiona dependențe. Terragrunt operează cu module de infrastructură și compoziții în mod nativ, astfel încât reduce duplicarea codului.
Scripturi interne. Adesea, acest lucru se întâmplă ca punct de plecare către orchestrare și înainte de a descoperi Terragrunt.
Instrument de automatizare Ansible sau altceva asemănător. Utilizat de obicei atunci când Terraform este adoptat după Ansible sau când Ansible UI este utilizat în mod activ.
Crossplane și alte soluții inspirate de Kubernetes. Uneori, este logic să utilizați ecosistemul Kubernetes și să folosiți o funcție de buclă de reconciliere pentru a obține starea dorită a configurațiilor Terraform. Vizualizați videoclipul Crossplane vs Terraform pentru mai multe informații.
Având în vedere acest lucru, această carte trece în revistă primele două dintre aceste structuri de proiect, doar Terraform și Terragrunt.
Vezi exemple de structuri de cod pentru Terraform sau Terragrunt în capitolul următor.
Sursă: https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/large-terraform
Acest exemplu conține un cod ca exemplu de structurare a configuraților Terraform pentru o infrastructură de dimensiuni mari care folosește:
2 conturi AWS
2 regiuni
2 medii de lucru separate (prod
și stage
care nu au procese comune). Fiecare mediu de lucru există într-un cont AWS separat și conține resurse în două regiuni
Fiecare mediu de lucru folosește o altă versiune a modulelor de infrastructură gata de folosire (alb
) provenite din Terraform Registry
Fiecare mediu de lucru folosește aceeași versiune a unui modul intern modules/network
provenind din aceeași sursă locală (local directory)
Într-un proiect de dimensiuni mari ca cel descris aici, beneficiile utilizării Terragrunt devin foarte vizibile. Vezi Exemple de structuri de cod - Terragrunt.
Perfect pentru proiecte în care infrastructura este separată logic (conturi AWS separate)
Potrivit când nu este nevoie de modificarea resurselor partajate între conturile AWS (un mediu de lucru = un cont AWS = un fișier de stare)
Potrivit când nu este necesară orchestrarea schimbărilor între mediile de lucru
Potrivit când resursele care formează infrastructura sunt diferite in funcție de mediul de lucru cu un anumit scop și nu poate fi generalizată (ex.: anumite resurse nu există într-un mediu de lucru sau într-o anumită regiune)
O dată cu expansiunea proiectului, o să fie din ce în ce mai dificil de păstrat aceste medii de lucru la curent cu fiecare. Considerați folosirea modulelor de infrastructură (gata de folosire sau interne) pentru sarcini repetitive.
Documentația oficială pentru Terraform descrie toate aspectele configurației în detaliu. Citiți-o cu atenție pentru a înțelege restul capitolului.
Acest capitol descrie conceptele cheie folosite în această carte.
Resursele sunt, de exemplu, aws_vpc
, aws_db_instance
, etc. O resursă aparține unui furnizor (provider), acceptă argumente, întoarce atribute și are cicluri de viață. O resursă poate fi creată, preluată, actualizată și ștearsă.
Modulul de resurse este o colecție de resurse conectate care realizează împreună o acțiune comună (de exemplu, modulul Terraform pentru AWS VPC creează VPC, subrețele, NAT gateway etc.). Depinde de configurația furnizorului, care poate fi definită în acesta, sau în structuri de nivel superior (de exemplu, în modulul de infrastructură).
Un modul de infrastructură este o colecție de module de resurse, care în mod logic nu pot fi conectate, dar în situația actuală/proiectul/setarea servesc aceluiași scop. Acesta definește configurația pentru furnizori, care este transmisă modulelor de resurse din interior și resurselor. În mod normal, este limitat să funcționeze într-o singură entitate per separator logic (de exemplu, Regiune AWS, Proiect Google).
De exemplu, modulul terraform-aws-atlantis folosește module de resurse ca terraform-aws-vpc și terraform-aws-security-group pentru a gestiona infrastructura necesară rulării Atlantis în AWS Fargate.
Un alt exemplu este modulul terraform-aws-cloudquery unde mai multe module de terraform-aws-modules sunt utilizate împreună pentru a gestiona infrastructura, precum și pentru a folosi resursele Docker pentru a face build, push, și deploy imaginilor de Docker. Toate într-un singur set.
Compoziţia este o colecție de module de infrastructură, care se pot întinde pe mai multe zone separate logic (de exemplu, regiuni AWS, mai multe conturi AWS). Compoziţia este utilizată pentru a descrie infrastructura completă necesară pentru întreaga organizație sau întreagul proiect.
O compoziţie este constituită din module de infrastructură, care sunt constituite din module de resurse, care implementează resurse individuale.
Sursa de date efectuează o operație doar de citire și depinde de configurația furnizorului, este utilizată într-un modul de resurse și într-un modul de infrastructură.
Sursa de date terraform_remote_state
acționează ca o legătură între module de nivel superior și compoziții.
Sursa externă de date permite unui program extern să acționeze ca sursă de date, expunând date arbitrare pentru a fi utilizate în altă parte în configurația Terraform. Iată un exemplu din modulul terraform-aws-lambda în care numele fișierului este calculat prin apelarea unui script de Python extern.
Sursa de date http face o solicitare HTTP GET către adresa URL dată și exportă informații despre răspuns, care sunt adesea utile pentru a obține informații de la punctele finale (endpoints) în care nu există un furnizor Terraform nativ.
Modulele de infrastructură și compozițiile ar trebui să-și păstreze starea Terraform într-o locație la distanță numită remote state, unde pot fi preluate de către alții într-un mod controlabil (de exemplu, specificații ACL, versionări, logging).
Providers, provisioners, și alți câțiva termeni sunt descriși foarte bine în documentația oficială și nu are rost să repet aici. După părerea mea, au puțin de-a face cu scrierea unor module bune de Terraform.
În timp ce resursele individuale sunt ca atomii din infrastructură, modulele de resurse sunt ca moleculele. Un modul este cea mai mică unitate versionabilă și partajabilă. Are o listă exactă de argumente, implementează logica de bază pentru ca o astfel de unitate să facă funcția necesară. De exemplu, modulul terraform-aws-security-group creează resursele aws_security_group
și aws_security_group_rule
pe baza informației de intrare. Acest modul de resurse poate fi folosit împreună cu alte module pentru a crea modulul de infrastructură.
Accesul la date între molecule (module de resurse și module de infrastructură) se realizează folosind datele de ieșire ale modulelor (outputs) și sursele de date (data sources).
Accesul între compoziții se realizează adesea folosind surse de date de la distanță (remote state data sources). Există mai multe moduri de a partaja date între configurații.
Când puneți conceptele descrise mai sus în pseudo-relații, acestea pot arăta astfel:
Exemplele următoare prezintă cazul în care AWS a fost ales ca furnizor, dar majoritatea principiilor descrise pot fi refolosite pentru ceilalți furnizori de cloud și de asemenea în cazul în care alegem alți furnizori în general (de DNS, baze de date, monitorizare, etc.).
PFT (Probleme Frecvente cu Terrafom)
Ar trebui specificate versiunile modulelor de resurse și infrastructură. Furnizorii de infrastructură (providers) ar trebui configurați în afara modulelor, dar numai în compoziție. Versiunea furnizorilor și cea a Terraform pot fi, de asemenea, blocate.
Acest exemplu conține un cod ca exemplu de structurare a configuraților Terraform pentru o infrastructură de dimensiuni mici, unde nu există dependențe externe.
Perfect pentru a începe și pentru a edita pe parcurs
Perfect pentru module cu resurse puține
Bun pentru un număr redus de resurse (mai puține de 20-30)
Un singur fișier de stare pentru toate resursele poate face procesul de lucru cu Terraform să încetinească dacă numărul de resurse crește (considerați folosirea unui argument ca-target
pentru a limita numărul de resurse).
Exemplele și modulele Terraform ar trebui să conțină documentație care explică caracteristicile și modul de utilizare a acestora.
Toate linkurile din fișierele README.md ar trebui să fie absolute pentru ca site-ul Terraform Registry să le arate corect.
Cu configurații Terraform pre-commit
poate fi folosit pentru a formata și valida codul, precum și pentru a actualiza documentația.
@todo: Versiuni ale modulelor de documente, release, acțiuni GH
Acest exemplu conține un cod ca exemplu de structurare a configuraților Terraform pentru o infrastructură de dimensiuni medii care folosește:
2 conturi AWS
2 medii de lucru separate (prod
și stage
care nu au procese comune). Fiecare mediu de lucru există într-un cont AWS separat
Fiecare mediu de lucru folosește aceeași versiune a unui modul intern modules/network
provenind din aceeași sursă locală (local directory)
Perfect pentru proiecte în care infrastructura este separată logic (conturi AWS separate)
Potrivit când nu este nevoie de modificarea resurselor partajate între conturile AWS (un mediu de lucru = un cont AWS = un fișier de stare)
Potrivit când nu este necesară orchestrarea schimbărilor între mediile de lucru
Potrivit când resursele care formează infrastructura sunt diferite in funcție de mediul de lucru cu un anumit scop și nu poate fi generalizată (ex.: anumite resurse nu există într-un mediu de lucru sau într-o anumită regiune)
O dată cu expansiunea proiectului, o să fie din ce în ce mai dificil de păstrat aceste medii de lucru la curent cu fiecare. Considerați folosirea modulelor de infrastructură (gata de folosire sau interne) pentru sarcini repetitive.
Tip | Descriere | Disponibilitate |
---|---|---|
Tip | Descriere | Disponibilitate |
---|---|---|
- Instrument de orchestrare
- Cod linter
- Manager de versiuni
- Automatizare pentru Pull Requests
- O colecție de git hooks pentru Terraform pentru a fi folosite cu
Nu există un instrument principal de gestionare a dependenței, dar există câteva sfaturi pentru a face iadul dependenței mai puțin problematic. De exemplu, poate fi folosit pentru a automatiza actualizările dependenței. Dependabot creează pull requests pentru a vă menține dependențele în siguranță și actualizate. Dependabot acceptă configurații Terraform.
Sursă:
Bun pentru module de infrastructură mici si lineare (ex: )
Documentația poate include diagrame create cu și schițe create cu .
Folosiți to asigurați-vă că codul este valid, formatat corespunzător și documentat automat înainte de a fi salvat în git și revizuit de oameni.
este un cadru (framework) pentru gestionarea și menținerea pre-commit hooks în mai multe limbi. Este scris în Python și este un instrument puternic pentru a face ceva automat pe mașina unui dezvoltator înainte ca acel cod să fie salvat într-un git repository. În mod normal, este folosit pentru a rula linters și pentru a formata cod (vezi ).
Verificați pentru a vă familiariza cu acesta și cu repositories existente (ex.: ) unde acesta este deja folosit.
este un instrument care generează documentație din modulele Terraform în diverse formate de ieșire. Îl puteți rula manual (fără pre-commit hooks) sau puteți utiliza pentru a actualiza automat documentația.
Blog post de :
Sursă:
Fiecare mediu de lucru folosește o altă versiune a modulelor de infrastructură gata de folosire (alb
) provenite din