Terraformer - Infrastruktura za kodiranje

Terraformer - Infrastruktura za kodiranje
Ž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 problem od 2014 godine u terrafomu koji je zatvoren 2016 godine sa nadom da će biti uvoza.

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 terraformiranje. Kada sam pokušao da prođem kroz to svojih 250+ kanti, shvatio sam da je tu sve loše. AWS već dugo uvodi puno novih opcija, ali terraforming ne zna za njih i općenito je rubin šablon izgleda oskudno. Poslao sam posle 2 uveče Zahtjev za povlačenjem da dodam više mogućnosti tamo i shvatio da takvo rješenje uopće nije prikladno.
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 ovdje. Samo uzmite i pretvorite tfstate u tf. Svi podaci su tu i polja su ista. Kako dobiti punu tfstate za mnoge resurse?? Ovdje je u pomoć priskočila komanda `terraform refresh`. terraform uzima sve resurse u tfstate i, po ID-u, izvlači podatke o njima i sve zapisuje u tfstate. Odnosno, kreirajte prazno stanje tfstate samo sa imenima i ID-ovima, pokrenite `terraform refresh` i tada ćemo dobiti pune tfstate. Ura!
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). github.com/GoogleCloudPlatform/terraformer
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
Terraformer - Infrastruktura za kodiranje

izvor: www.habr.com

Dodajte komentar