Terraformer - Infrastruktura za kodo

Terraformer - Infrastruktura za kodo
Rad bi vam povedal o novem orodju CLI, ki sem ga napisal za rešitev stare težave.

problem

Terraform je že dolgo standard v skupnosti Devops/Cloud/IT. Zadeva je zelo priročna in uporabna za obravnavo infrastrukture kot kode. V Terraformu je veliko užitkov ter veliko vilic, ostrih nožev in grabelj.
S Terraformom je zelo priročno ustvarjati nove stvari in jih nato upravljati, spreminjati ali brisati. Kaj naj storijo tisti, ki imajo ogromno infrastrukturo v oblaku in niso ustvarjeni prek Terraforma? Ponovno pisanje in ponovno ustvarjanje celotnega oblaka je nekako drago in nevarno.
Na to težavo sem naletel pri dveh opravilih, najenostavnejši primer je, ko želite, da je vse v Gitu v obliki terraform datotek, vendar imate 2+ veder in jih je veliko, če jih ročno pišete v terraform.
Obstaja vprašanje od leta 2014 v terafomu, ki so ga leta 2016 zaprli z upanjem, da bo prišlo do uvoza.

Na splošno je vse kot na sliki le od desne proti levi

Opozorila: Avtor polovico svojega življenja ne živi v Rusiji in malo piše v ruščini. Pazite se črkovalnih napak.

Rešitve

1. Obstajajo že pripravljene in stare rešitve za AWS teraformiranje. Ko sem poskušal svojih 250+ veder spraviti skozenj, sem ugotovil, da je tam vse slabo. AWS že dolgo uvaja veliko novih možnosti, ki pa jih terraforming ne pozna in na splošno je ruby predloga je videti redka. Po 2 zvečer sem poslal Zahteva za poteg dodati več funkcij in ugotovil, da takšna rešitev sploh ni primerna.
Kako deluje teraformiranje: vzame podatke iz AWS SDK in ustvari tf in tfstate prek predloge.
Tukaj so 3 težave:
1. Pri posodobitvah bo vedno prišlo do zamika
2. datoteke tf so včasih pokvarjene
3. tfstate se zbira ločeno od tf in ne konvergira vedno
Na splošno je težko dobiti rezultat, v katerem `terraform plan` pravi, da ni sprememb

2. `terraform import` je vgrajen ukaz v terraform. Kako deluje?
Napišete prazno datoteko TF z imenom in vrsto vira, nato zaženete `terraform import` in posredujete ID vira. terraform vzpostavi stik s ponudnikom, prejme podatke in naredi datoteko tfstate.
Tukaj so 3 težave:
1. Dobimo samo datoteko tfstate, tf pa je prazna, napisati jo morate ročno ali jo pretvoriti iz tfstate
2. Lahko deluje samo z enim virom hkrati in ne podpira vseh virov. In kaj naj spet naredim z 250+ vedri?
3. Poznati morate ID virov – to pomeni, da ga morate zaviti v kodo, ki dobi seznam virov
Na splošno je rezultat delen in se ne meri dobro

Moja odločitev

Zahteve:
1. Sposobnost ustvarjanja datotek tf in tfstate za vire. Na primer, prenesite vsa vedra/varnostno skupino/izravnalnik obremenitve in ta `teraformni načrt` je vrnil, da ni sprememb
2. Potrebujete 2 oblaka GCP + AWS
3. Globalna rešitev, ki jo je enostavno posodobiti vsakič in ne izgublja časa na vsakem viru za 3 dni dela
4. Naj bo odprtokoden - vsi imajo enak problem

Všeč mi je jezik Go, ki ima knjižnico za ustvarjanje datotek HCL, ki se uporablja v terraformu + veliko kode v terraformu, ki je lahko uporabna

Pot

Najprej poskušaj
Začel sem s preprosto različico. Vzpostavljanje stika z oblakom prek SDK za zahtevani vir in njegovo pretvorbo v polja za terraform. Poskus je takoj umrl na varnostni skupini, ker mi ni bilo všeč 1.5 dni za pretvorbo samo varnostne skupine (in virov je veliko). Dolgo časa, potem pa je mogoče polja spremeniti/dodati

Drugi poskus
Na podlagi opisane ideje tukaj. Samo vzemite in pretvorite tfstate v tf. Vsi podatki so tam in polja so enaka. Kako pridobiti polno tfstate za veliko virov?? Tu je na pomoč priskočil ukaz `terraform refresh`. terraform prevzame vse vire v tfstate in z ID-jem izvleče podatke o njih ter vse zapiše v tfstate. To pomeni, ustvarite prazno tfstate samo z imeni in ID-ji, zaženite `terraform refresh` in nato dobimo polna tfstate. Hura!
Zdaj pa naredimo rekurzivno pornografijo pisanja pretvornika za tfstate v tf. Za tiste, ki še nikoli niste brali tfstate, je JSON, vendar poseben.
Tu so njegove pomembne lastnosti

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

Tukaj je:
1. id - niz
2. metapodatki - niz velikosti 1 in v njem objekt s polji, ki je opisan spodaj
3. spec - hash velikosti 1 in ključ, vrednost v njem
Skratka, zabaven format, vse je lahko globoko na več nivojih

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

Na splošno, če kdo želi programski problem za intervju, ga prosi, naj napiše razčlenjevalnik za to nalogo :)
Po mnogih poskusih, da bi napisal razčlenjevalec brez napak, sem našel del tega v kodi terraform in to najpomembnejši del. In vse je delovalo dobro

Tretji poskus
ponudniki terraform so binarne datoteke, ki vsebujejo kodo z vsemi viri in logiko za delo z API-jem v oblaku. Vsak oblak ima svojega ponudnika in sam terraform jih kliče samo prek svojega protokola RPC med dvema procesoma.
Zdaj sem se odločil, da kontaktiram ponudnike terraform neposredno prek klicev RPC. Izkazalo se je čudovito in omogočilo zamenjavo ponudnikov terraform z novejšimi in pridobitev novih funkcij brez spreminjanja kode. Izkazalo se je tudi, da vsa polja v tfstate ne bi smela biti v tf, ampak kako lahko to ugotovite? Vprašajte svojega ponudnika o tem. Nato se je začela še ena rekurzivna pornografija sestavljanja regularnih izrazov, ki je poglobljeno iskala polja znotraj tfstate na vseh ravneh.

Na koncu smo dobili uporabno orodje CLI, ki ima skupno infrastrukturo za vse ponudnike terraform in enostavno lahko dodate novo. Poleg tega dodajanje virov zahteva malo kode. Plus vse vrste dobrot, kot so povezave med viri. Seveda je bilo veliko različnih težav, ki jih vseh ni mogoče opisati.
Žival sem poimenoval Terrafomer.

Končno

Z uporabo Terrafomerja smo ustvarili 500–700 tisoč vrstic kode tf + tfstate iz dveh oblakov. Lahko smo vzeli podedovane stvari in se jih začeli dotikati samo prek terraforme, kot v najboljši infrastrukturi kot ideje kode. Prav čarobno je, ko vzamete ogromen oblak in ga prejmete prek ekipe v obliki delovnih datotek terraform. In potem grep/replace/git in tako naprej.

Prečesal sem ga in spravil v red, dobil dovoljenje. Objavljeno na GitHubu za vse v četrtek (02.05.19. XNUMX. XNUMX). github.com/GoogleCloudPlatform/terraformer
Prejeli smo že 600 zvezdic, 2 zahtevi za vlečenje za dodajanje podpore za openstack in kubernetes. Dobra povratna informacija. Na splošno je projekt koristen za ljudi
Svetujem vsem, ki želijo začeti delati s Terraformom in ne prepisati vsega za to.
Z veseljem bom potegnil zahteve, težave, zvezdice.

Demo
Terraformer - Infrastruktura za kodo

Vir: www.habr.com

Dodaj komentar