Terraformer - Infrastruktura za kodiranje

Terraformer - Infrastruktura za kodiranje
Htio bih vam reći o novom CLI alatu koji sam napisao za rješavanje starog problema.

problem

Terraform je dugo bio standard u Devops/Cloud/IT zajednici. Stvar je vrlo zgodna i korisna za rad s infrastrukturom kao kodom. U Terraformu ima mnogo užitaka kao i mnogo vilica, oštrih noževa i grablji.
S Terraformom je vrlo zgodno stvarati nove stvari i zatim njima upravljati, mijenjati ih ili brisati. Što trebaju učiniti oni koji imaju ogromnu infrastrukturu u oblaku, a nije stvorenu kroz Terraform? Prepisivanje i ponovno stvaranje cijelog oblaka nekako je 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 datoteka, ali imate 250+ kanti i puno je ručno ih pisati u terraform.
Tu je izdanje od 2014. u terrafom koji je zatvoren 2016. s nadom da će biti uvoza.

Općenito, sve je kao na slici samo s desna na lijevo

Upozorenja: Autor pola života ne živi u Rusiji i malo piše na ruskom. Čuvajte se pravopisnih pogrešaka.

rješenja

1. Postoje gotova i stara rješenja za AWS teraformiranje. Kad sam pokušao provući svojih 250+ kanti kroz njega, shvatio sam da je tamo sve loše. AWS već dugo uvodi puno novih opcija, ali terraforming ne zna za njih i općenito je rubin predložak izgleda oskudno. Poslije 2 navečer poslao sam Zahtjev za povlačenjem dodati više značajki i shvatio da takvo rješenje uopće nije prikladno.
Kako radi terraforming: uzima podatke iz AWS SDK-a i generira tf i tfstate putem predloška.
Ovdje postoje 3 problema:
1. Uvijek će postojati kašnjenje u ažuriranjima
2. tf datoteke ponekad izađu pokvarene
3. tfstate se prikuplja odvojeno od tf i ne konvergira uvijek
Općenito, teško je dobiti rezultat u kojem `terraform plan` kaže da nema promjena

2. `terraform import` je ugrađena naredba u terraformu. Kako radi?
Napišete praznu TF datoteku s nazivom i vrstom resursa, zatim pokrenete `terraform import` i proslijedite ID resursa. terraform kontaktira pružatelja, prima podatke i stvara tfstate datoteku.
Ovdje postoje 3 problema:
1. Dobivamo samo tfstate datoteku, a tf je prazan, morate ga napisati ručno ili pretvoriti iz tfstate
2. Može raditi samo s jednim resursom u isto vrijeme i ne podržava sve resurse. I što da opet radim s 250+ kanti?
3. Morate znati ID resursa - to jest, trebate ga zamotati u kod koji dobiva popis resursa
Općenito, rezultat je djelomičan i ne mjeri se dobro

Moja odluka

Zahtjevi:
1. Sposobnost stvaranja tf i tfstate datoteka za resurse. Na primjer, preuzmite sve kante/sigurnosnu grupu/balanser opterećenja i taj `terraform plan` je vratio da nema promjena
2. Potrebna su vam 2 GCP + AWS oblaka
3. Globalno rješenje koje se lako ažurira svaki put i ne gubi vrijeme na svaki resurs za 3 dana rada
4. Neka bude Open Source - svi imaju isti problem

Go jezik je razlog zašto ga volim, a ima biblioteku za stvaranje HCL datoteka koje se koriste u terraformu + puno koda u terraformu koji može biti koristan

Put

Pokušaj najprije
Počeo sam s jednostavnom verzijom. Kontaktiranje oblaka putem SDK-a za traženi resurs i njegovo pretvaranje u polja za terraform. Pokušaj je odmah umro na sigurnosnoj grupi jer mi se nije sviđalo 1.5 dana za konverziju samo sigurnosne grupe (a ima puno resursa). Dugo vremena, a zatim se polja mogu mijenjati/dodavati

Drugi pokušaj
Na temelju opisane ideje ovdje. Samo uzmite i pretvorite tfstate u tf. Svi podaci su tu i polja su ista. Kako dobiti puno tfstate za mnoge resurse?? Tu je u pomoć priskočila naredba `terraform refresh`. terraform uzima sve resurse u tfstate i, pomoću ID-a, izvlači podatke o njima i zapisuje sve u tfstate. Odnosno, stvorite prazan tfstate sa samo imenima i ID-ovima, pokrenite `terraform refresh` i tada ćemo dobiti puna tfstatea. hura!
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",

Tamo je:
1. id - niz
2. metapodaci - polje veličine 1 iu njemu objekt s 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 razina

                   "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",

Općenito, ako netko želi programski problem za intervju, samo ga zamolite da napiše parser za ovaj zadatak :)
Nakon mnogih pokušaja da napišem parser bez grešaka, pronašao sam dio toga u terraform kodu, i to najvažniji dio. I činilo se da sve radi dobro

Pokušaj treći
terraform provideri su binarne datoteke koje sadrže kod sa svim resursima i logikom za rad s API-jem u oblaku. Svaki oblak ima svog pružatelja usluga, a sam terraform ih poziva samo preko svog RPC protokola između dva procesa.
Sada sam odlučio kontaktirati pružatelje terraforma izravno putem RPC poziva. Ispalo je prekrasno i omogućilo je promjenu pružatelja terraforma na novije i dobivanje novih značajki bez promjene koda. Također se ispostavlja da ne bi sva polja u tfstate trebala biti u tf, ali kako možete saznati? Samo pitajte svog pružatelja usluga o ovome. Zatim je počela još jedna rekurzivna pornografija sastavljanja regularnih izraza, dubinski tražeći polja unutar tfstate-a na svim razinama.

Na kraju smo dobili koristan CLI alat koji ima zajedničku infrastrukturu za sve terraform providere i možete jednostavno dodati novu. Također, dodavanje resursa zahtijeva malo koda. Plus sve vrste dobrih stvari 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, generirali smo 500-700 tisuća linija tf + tfstate koda iz dva oblaka. Uspjeli smo uzeti naslijeđene stvari i početi ih dodirivati ​​samo kroz teraformu, kao u najboljoj infrastrukturi kao ideje koda. Prava je magija kada uzmete ogroman oblak i primite ga kroz tim u obliku terraform worker datoteka. I onda grep/replace/git i tako dalje.

Počešljao sam ga i doveo u red, dobio dopuštenje. Objavljeno na GitHubu za sve u četvrtak (02.05.19.). github.com/GoogleCloudPlatform/terraformer
Već je primljeno 600 zvjezdica, 2 zahtjeva za povlačenje za dodavanje podrške za openstack i kubernetes. Dobra povratna informacija. Općenito, projekt je koristan za ljude
Savjetujem svima koji žele početi raditi s Terraformom i ne prepisivati ​​sve za ovo.
Bit će mi drago povući zahtjeve, probleme, zvjezdice.

demo
Terraformer - Infrastruktura za kodiranje

Izvor: www.habr.com

Dodajte komentar