Terraformer - Infrastructură pentru a codifica

Terraformer - Infrastructură pentru a codifica
Aș dori să vă spun despre noul instrument CLI pe care l-am scris pentru a rezolva o problemă veche.

problemă

Terraform a fost mult timp un standard în comunitatea Devops/Cloud/IT. Lucrul este foarte convenabil și util pentru a trata infrastructura ca cod. Există multe delicii în Terraform, precum și multe furculițe, cuțite ascuțite și greble.
Cu Terraform este foarte convenabil să creați lucruri noi și apoi să le gestionați, să le modificați sau să le ștergeți. Ce ar trebui să facă cei care au o infrastructură uriașă în cloud și nu sunt create prin Terraform? Rescrierea și re-crearea întregului nor este cumva costisitoare și nesigură.
Am întâlnit această problemă la 2 joburi, cel mai simplu exemplu este atunci când doriți ca totul să fie în Git sub formă de fișiere terraform, dar aveți peste 250 de găleți și este mult să le scrieți manual în terraform.
Există problema din 2014 in terrafom care a fost inchis in 2016 cu speranta ca va fi import.

În general, totul este ca în poză doar de la dreapta la stânga

Avertismente: Autorul nu locuiește în Rusia jumătate din viață și scrie puțin în rusă. Atenție la greșelile de ortografie.

Soluții

1. Există soluții gata făcute și vechi pentru AWS terraformare. Când am încercat să-mi trec peste 250 de găleți prin ea, mi-am dat seama că totul era rău acolo. AWS a introdus de multă vreme o mulțime de opțiuni noi, dar terraformarea nu știe despre ele și, în general, este rubin șablonul pare rar. Dupa 2 seara am trimis Trage cerere pentru a adăuga mai multe funcții acolo și a realizat că o astfel de soluție nu este deloc potrivită.
Cum funcționează terraformarea: preia date din SDK-ul AWS și generează tf și tfstate printr-un șablon.
Sunt 3 probleme aici:
1. Va exista întotdeauna un întârziere în actualizări
2. fisierele tf uneori ies sparte
3. tfstate este colectat separat de tf și nu converge întotdeauna
În general, este greu de obținut un rezultat în care `planul de terraform` spune că nu există modificări

2. `terraform import` este o comandă încorporată în terraform. Cum functioneazã?
Scrieți un fișier TF gol cu ​​numele și tipul de resursă, apoi rulați `terraform import` și transmiteți ID-ul resursei. terraform contactează furnizorul, primește datele și realizează un fișier tfstate.
Sunt 3 probleme aici:
1. Primim doar un fișier tfstate, iar tf este gol, trebuie să îl scrieți manual sau să îl convertiți din tfstate
2. Poate lucra doar cu o resursă la un moment dat și nu acceptă toate resursele. Și ce ar trebui să fac din nou cu peste 250 de găleți?
3. Trebuie să cunoașteți ID-ul resurselor - adică trebuie să îl includeți în cod care primește lista de resurse
În general, rezultatul este parțial și nu se scalează bine

Decizia mea

Cerinte:
1. Abilitatea de a crea fișiere tf și tfstate pentru resurse. De exemplu, descărcați toate compartimentele/grupul de securitate/echilibratorul de încărcare și acel „plan de terraform” a returnat că nu există modificări
2. Aveți nevoie de 2 nori GCP + AWS
3. Soluție globală care este ușor de actualizat de fiecare dată și nu pierde timpul cu fiecare resursă pentru 3 zile de lucru
4. Faceți-l Open Source - toată lumea are aceeași problemă

Limbajul Go este motivul pentru care îl iubesc și are o bibliotecă pentru crearea fișierelor HCL care este folosită în terraform + mult cod în terraform care poate fi util

Cale

Încercați mai întâi
Am început cu o versiune simplă. Contactarea cloud-ului prin intermediul SDK-ului pentru resursa necesară și convertirea acesteia în câmpuri pentru terraform. Încercarea a murit imediat pe grupul de securitate pentru că nu mi-au plăcut 1.5 zile pentru a converti doar grupul de securitate (și există o mulțime de resurse). Pentru o lungă perioadă de timp și apoi câmpurile pot fi modificate/adăugate

A doua încercare
Pe baza ideii descrise aici. Doar luați și convertiți tfstate în tf. Toate datele sunt acolo și câmpurile sunt aceleași. Cum să obțineți tfstate complet pentru multe resurse? Aici a venit în ajutor comanda `terraform refresh`. terraform preia toate resursele în tfstate și, prin ID, extrage date despre ele și scrie totul în tfstate. Adică, creați un tfstate gol cu ​​doar nume și ID-uri, rulați `terraform refresh` și apoi obținem tfstates complete. Ura!
Acum să facem pornografia recursivă de a scrie un convertor pentru tfstate la tf. Pentru cei care nu au citit niciodată tfstate, este JSON, dar special.
Iată atributele sale importante ale părții

 "attributes": {
                            "id": "default/backend-logging-load-deployment",
                            "metadata.#": "1",
                            "metadata.0.annotations.%": "0",
                            "metadata.0.generate_name": "",
                            "metadata.0.generation": "24",
                            "metadata.0.labels.%": "1",
                            "metadata.0.labels.app": "backend-logging",
                            "metadata.0.name": "backend-logging-load-deployment",
                            "metadata.0.namespace": "default",
                            "metadata.0.resource_version": "109317427",
                            "metadata.0.self_link": "/apis/apps/v1/namespaces/default/deployments/backend-logging-load-deployment",
                            "metadata.0.uid": "300ecda1-4138-11e9-9d5d-42010a8400b5",
                            "spec.#": "1",
                            "spec.0.min_ready_seconds": "0",
                            "spec.0.paused": "false",
                            "spec.0.progress_deadline_seconds": "600",
                            "spec.0.replicas": "1",
                            "spec.0.revision_history_limit": "10",
                            "spec.0.selector.#": "1",

Există:
1. id - șir
2. metadate - o matrice de dimensiunea 1 și în ea un obiect cu câmpuri care este descris mai jos
3. spec - hash de dimensiunea 1 și cheie, valoare în ea
Pe scurt, un format distractiv, totul poate avea mai multe niveluri adânci

                   "spec.#": "1",
                            "spec.0.min_ready_seconds": "0",
                            "spec.0.paused": "false",
                            "spec.0.progress_deadline_seconds": "600",
                            "spec.0.replicas": "1",
                            "spec.0.revision_history_limit": "10",
                            "spec.0.selector.#": "1",
                            "spec.0.selector.0.match_expressions.#": "0",
                            "spec.0.selector.0.match_labels.%": "1",
                            "spec.0.selector.0.match_labels.app": "backend-logging-load",
                            "spec.0.strategy.#": "0",
                            "spec.0.template.#": "1",
                            "spec.0.template.0.metadata.#": "1",
                            "spec.0.template.0.metadata.0.annotations.%": "0",
                            "spec.0.template.0.metadata.0.generate_name": "",
                            "spec.0.template.0.metadata.0.generation": "0",
                            "spec.0.template.0.metadata.0.labels.%": "1",
                            "spec.0.template.0.metadata.0.labels.app": "backend-logging-load",
                            "spec.0.template.0.metadata.0.name": "",
                            "spec.0.template.0.metadata.0.namespace": "",
                            "spec.0.template.0.metadata.0.resource_version": "",
                            "spec.0.template.0.metadata.0.self_link": "",
                            "spec.0.template.0.metadata.0.uid": "",
                            "spec.0.template.0.spec.#": "1",
                            "spec.0.template.0.spec.0.active_deadline_seconds": "0",
                            "spec.0.template.0.spec.0.container.#": "1",
                            "spec.0.template.0.spec.0.container.0.args.#": "3",

În general, dacă cineva dorește o problemă de programare pentru un interviu, cereți-i să scrie un parser pentru această sarcină :)
După multe încercări de a scrie un parser fără erori, am găsit o parte din el în codul terraform și cea mai importantă parte. Și totul părea să funcționeze bine

Încercați trei
Furnizorii terraform sunt binare care conțin cod cu toate resursele și logica pentru lucrul cu API-ul cloud. Fiecare nor are propriul său furnizor și terraform însuși îi apelează doar prin protocolul său RPC între două procese.
Acum am decis să contactez furnizorii terraform direct prin apeluri RPC. A ieșit frumos și a făcut posibilă schimbarea furnizorilor de terraform cu alții mai noi și obținerea de noi funcții fără a schimba codul. De asemenea, se dovedește că nu toate câmpurile din tfstate ar trebui să fie în tf, dar cum poți afla? Întrebați-vă furnizorul despre acest lucru. Apoi a început o altă pornografie recursivă de asamblare a expresiilor regulate, căutând câmpuri în interiorul tfstate la toate nivelurile în profunzime.

În cele din urmă, am primit un instrument CLI util care are o infrastructură comună pentru toți furnizorii de terraform și puteți adăuga cu ușurință una nouă. De asemenea, adăugarea de resurse necesită puțin cod. Plus tot felul de bunătăți, cum ar fi conexiunile între resurse. Desigur, au existat multe probleme diferite care nu pot fi descrise toate.
Am numit animalul Terrafomer.

final

Folosind Terrafomer, am generat 500-700 de mii de linii de cod tf + tfstate din doi nori. Am putut să luăm lucruri vechi și să începem să le atingem doar prin terraform, ca în cea mai bună infrastructură ca idei de cod. Este doar magie atunci când iei un nor uriaș și îl primești printr-o echipă sub formă de fișiere de lucrător terraform. Și apoi grep/replace/git și așa mai departe.

L-am pieptănat și l-am pus în ordine, am primit permisiunea. Lansat pe GitHub pentru toată lumea joi (02.05.19/XNUMX/XNUMX). github.com/GoogleCloudPlatform/terraformer
Am primit deja 600 de stele, 2 solicitări pull pentru adăugarea de suport pentru openstack și kubernetes. Feedback bun. În general, proiectul este util oamenilor
Îi sfătuiesc pe toți cei care doresc să înceapă să lucreze cu Terraform și să nu rescrie totul pentru asta.
Voi fi bucuros să trag cereri, probleme, stele.

Demo
Terraformer - Infrastructură pentru a codifica

Sursa: www.habr.com

Adauga un comentariu