Želio bih vam reći o novom CLI alatu koji sam napisao da riješim stari problem.
problem
Terraform je dugo bio standard u Devops/Cloud/IT zajednici. Stvar je vrlo zgodna i korisna za bavljenje infrastrukturom kao kodom. Mnogo je užitaka u Terraformu, kao i mnogo vilica, oštrih noževa i grabulja.
Sa Terraformom je vrlo zgodno kreirati nove stvari, a zatim ih upravljati, mijenjati ili brisati. Šta da rade oni koji imaju ogromnu infrastrukturu u oblaku, a ne kreiranu kroz Terraform? Ponovno pisanje i ponovno kreiranje cijelog oblaka je nekako skupo i nesigurno.
Susreo sam se s ovim problemom na 2 posla, najjednostavniji primjer je kada želite da sve bude u Gitu u obliku terraform fajlova, ali imate 250+ bucketa i puno je pisati ih u terraformu rukom.
Postoje
Generalno, sve je kao na slici samo s desna na lijevo
Upozorenja: Autor ne živi u Rusiji pola života i malo piše na ruskom. Čuvajte se pravopisnih grešaka.
Rešenja
1. Postoje gotova i stara rješenja za AWS
Kako funkcioniše terraformiranje: uzima podatke iz AWS SDK-a i generiše tf i tfstate kroz šablon.
Ovdje postoje 3 problema:
1. Uvijek će biti kašnjenja u ažuriranjima
2. tf fajlovi ponekad izlaze pokvareni
3. tfstate se prikuplja odvojeno od tf i ne konvergira uvijek
Generalno, teško je dobiti rezultat u kojem `terraformni plan` kaže da nema promjena
2. `terraform import` je ugrađena komanda u terraform. Kako to radi?
Napišete praznu TF datoteku s imenom i tipom resursa, zatim pokrenete `terraform import` i proslijedite ID resursa. terraform kontaktira provajdera, prima podatke i pravi tfstate fajl.
Ovdje postoje 3 problema:
1. Dobijamo samo tfstate fajl, a tf je prazan, morate ga napisati ručno ili ga konvertovati iz tfstate
2. Može raditi samo s jednim resursom u isto vrijeme i ne podržava sve resurse. I šta da radim opet sa 250+ kanti?
3. Morate znati ID resursa - to jest, trebate ga umotati u kod koji dobija listu resursa
Općenito, rezultat je djelomičan i nije dobro skaliran
Moja odluka
Uslovi:
1. Mogućnost kreiranja tf i tfstate datoteka za resurse. Na primjer, preuzmite sve kante/sigurnosne grupe/balansator opterećenja i taj `terraform plan` je vratio da nema promjena
2. Potrebna su vam 2 GCP + AWS oblaka
3. Globalno rješenje koje je lako ažurirati svaki put i ne gubi vrijeme na svaki resurs za 3 dana rada
4. Neka bude otvorenog koda – svi imaju isti problem
Go jezik je razlog zašto ga volim, i ima biblioteku za kreiranje HCL datoteka koje se koriste u terraformu + puno koda u terraformu koji može biti koristan
putanja
Prvi pokušaj
Počeo sam sa jednostavnom verzijom. Kontaktiranje oblaka preko SDK-a za traženi resurs i pretvaranje u polja za terraform. Pokušaj je odmah propao na sigurnosnoj grupi jer mi se nije svidjelo 1.5 dana za pretvaranje samo sigurnosne grupe (a ima puno resursa). Dugo vremena, a zatim polja se mogu mijenjati/dodavati
Drugi pokušaj
Na osnovu opisane ideje
Sada napravimo rekurzivnu pornografiju pisanja pretvarača za tfstate u tf. Za one koji nikada nisu čitali tfstate, to je JSON, ali poseban.
Evo njegovih važnih atributa
"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",
Tu je:
1. id - string
2. metapodaci - niz veličine 1 iu njemu objekat sa poljima koji je opisan u nastavku
3. spec - hash veličine 1 i ključ, vrijednost u njemu
Ukratko, zabavan format, sve može biti duboko na nekoliko nivoa
"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",
Generalno, ako neko želi programski problem za intervju, samo ga zamolite da napiše parser za ovaj zadatak :)
Nakon mnogo pokušaja da napišem parser bez grešaka, našao sam dio u terraform kodu, i to najvažniji dio. I činilo se da sve dobro funkcionira
Treći pokušaj
Terraform provajderi su binarni fajlovi koji sadrže kod sa svim resursima i logikom za rad sa cloud API-jem. Svaki oblak ima svog provajdera i sam terraform ih poziva samo preko svog RPC protokola između dva procesa.
Sada sam odlučio da kontaktiram terraform provajdere direktno putem RPC poziva. Ispalo je prekrasno i omogućilo je promjenu terraform provajdera na novije i dobijanje novih funkcija bez promjene koda. Takođe se ispostavilo da ne bi sva polja u tfstate trebala biti u tf, ali kako to možete saznati? Samo pitajte svog provajdera o ovome. Zatim je počela još jedna rekurzivna pornografija sastavljanja regularnih izraza, tražeći polja unutar tfstate na svim nivoima u dubinu.
Na kraju smo dobili koristan CLI alat koji ima zajedničku infrastrukturu za sve terraform provajdere i lako možete dodati novi. Takođe, dodavanje resursa zahteva malo koda. Plus sve vrste dobrota kao što su veze između resursa. Naravno, bilo je mnogo različitih problema koji se ne mogu sve opisati.
Životinju sam nazvao Terrafomer.
Finale
Koristeći Terrafomer, generisali smo 500-700 hiljada linija tf + tfstate koda iz dva oblaka. Uspjeli smo uzeti naslijeđene stvari i početi ih dodirivati samo kroz terraformu, kao u najboljoj infrastrukturi kao kod ideja. Prava je magija kada uzmete ogroman oblak i primite ga preko tima u obliku terraformskih datoteka radnika. A onda grep/replace/git i tako dalje.
Očešljao sam ga i doveo u red, dobio dozvolu. Objavljeno na GitHubu za sve u četvrtak (02.05.19/XNUMX/XNUMX).
Već sam dobio 600 zvjezdica, 2 pull zahtjeva za dodavanje podrške za openstack i kubernetes. Dobra povratna informacija. Generalno, projekat je koristan za ljude
Savjetujem svima koji žele da počnu raditi sa Terraformom i ne prepisuju sve za ovo.
Bit će mi drago povući zahtjeve, probleme, zvijezde.
Demo
izvor: www.habr.com