Terraformer – infrastruktuur kodeerimiseks

Terraformer – infrastruktuur kodeerimiseks
Tahaksin teile rääkida uuest CLI tööriistast, mille kirjutasin vana probleemi lahendamiseks.

probleem

Terraform on juba pikka aega olnud Devopsi/Cloudi/IT kogukonna standard. Asi on väga mugav ja kasulik infrastruktuuri kui koodi käsitlemisel. Terraformis on palju naudinguid, samuti palju kahvleid, teravaid nuge ja rehasid.
Terraformiga on väga mugav luua uusi asju ja neid siis hallata, muuta või kustutada. Mida peaksid tegema need, kellel on pilves tohutu infrastruktuur, mis pole loodud Terraformi kaudu? Kogu pilve ümberkirjutamine ja uuesti loomine on kuidagi kallis ja ebaturvaline.
Selle probleemiga puutusin kokku kahel töökohal, kõige lihtsam näide on see, kui soovite, et kõik oleks Gitis terraformfailide kujul, kuid teil on 2+ ämbrit ja neid käsitsi terraformis kirjutada on palju.
On probleem aastast 2014 terrafomis mis suleti 2016. aastal lootusega, et tuleb importi.

Üldiselt on kõik nagu pildil ainult paremalt vasakule

Hoiatused: autor ei ela pooltki oma elust Venemaal ja kirjutab vähe vene keeles. Hoiduge õigekirjavigade eest.

Lahendused

1. AWS-i jaoks on valmis ja vanad lahendused terraformeerimine. Kui proovisin oma 250+ ämbrit sealt läbi saada, sain aru, et seal on kõik halvasti. AWS on juba pikka aega tutvustanud palju uusi võimalusi, kuid terraforming ei tea neist midagi ja üldiselt on see rubiin mall näeb hõre välja. Peale kella 2 õhtul saatsin Tõmbetaotlus et sinna veel funktsioone lisada ja sain aru, et selline lahendus ei sobi üldse.
Terraforming töötab: see võtab andmeid AWS SDK-st ja genereerib malli kaudu tf ja tfstate.
Siin on 3 probleemi:
1. Uuendustes esineb alati viivitust
2. tf failid tulevad mõnikord katki
3. tfstate kogutakse tf-st eraldi ja see ei lähe alati kokku
Üldiselt on raske saada tulemust, kus `terraformi plaan` ütleb, et muudatusi pole

2. Terraform import on terraformi sisseehitatud käsk. Kuidas see töötab?
Kirjutate tühja TF-faili koos ressursi nime ja tüübiga, seejärel käivitate terraformi importimise ja edastate ressursi ID. terraform võtab teenusepakkujaga ühendust, võtab andmed vastu ja teeb tfstate faili.
Siin on 3 probleemi:
1. Saame ainult tfstate faili ja tf on tühi, peate selle käsitsi kirjutama või tfstate'ist teisendama
2. Saab töötada ainult ühe ressursiga korraga ja ei toeta kõiki ressursse. Ja mida ma peaksin uuesti tegema 250+ ämbriga?
3. Peate teadma ressursside ID-d – see tähendab, et peate selle pakkima koodi, mis saab ressursside loendi
Üldjuhul on tulemus osaline ja ei skaleeru hästi

Minu otsus

nõuded:
1. Võimalus luua ressursside jaoks tf ja tfstate faile. Näiteks laadige alla kõik ämbrid/turvarühm/koormuse tasakaalustaja ja see `terraform plan` tagastas, et muudatusi pole
2. Teil on vaja 2 GCP + AWS pilve
3. Globaalne lahendus, mida on lihtne iga kord uuendada ja mis ei raiska aega iga ressursi peale 3 päeva tööks
4. Tee see avatud lähtekoodiga – kõigil on sama probleem

Go keel on põhjus, miks see mulle meeldib ja sellel on teek terraformis kasutatavate HCL-failide loomiseks + palju terraformaadis koodi, mis võib olla kasulik

Tee

Esimene katse
Alustasin lihtsa versiooniga. Pilvega ühenduse võtmine SDK kaudu vajaliku ressursi saamiseks ja selle teisendamine terraformi väljadeks. Katse suri turvagrupis kohe ära, sest mulle ei meeldinud 1.5 päeva ainult turvagrupi teisendamiseks (ja ressursse on palju). Kaua ja siis saab välju muuta/lisa

Teine katse
Kirjeldatud idee põhjal siin. Lihtsalt võtke ja teisendage tfstate tf-ks. Kõik andmed on olemas ja väljad on samad. Kuidas saada paljude ressursside jaoks täielik tfstate? Siin tuli appi käsk `terraform refresh`. terraform võtab kõik tfstate'i ressursid ja ID järgi tõmbab nende kohta andmed välja ja kirjutab kõik tfstate'i. See tähendab, et looge tühi tfstate ainult nimede ja ID-dega, käivitage "terraform refresh" ja siis saame täielikud tf-olekud. Hurraa!
Nüüd teeme rekursiivse pornograafia, kirjutades tfstate to tf konverteri. Neile, kes pole kunagi tfstate'i lugenud, on see JSON, kuid eriline.
Siin on selle olulised atribuudid

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

Seal on:
1. id - string
2. metaandmed - massiiv suurusega 1 ja selles objekt väljadega, mida kirjeldatakse allpool
3. spetsifikatsioon - räsi suurus 1 ja võti, väärtus selles
Ühesõnaga lõbus formaat, kõik võib olla mitme tasandi sügavus

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

Üldiselt, kui keegi soovib intervjuuks programmeerimisprobleemi, siis paluge tal selle ülesande jaoks parser kirjutada :)
Pärast mitmeid katseid kirjutada parser ilma vigadeta, leidsin osa sellest terraformi koodist ja kõige olulisema osa. Ja kõik näis toimivat hästi

Katse kolm
terraformi pakkujad on kahendfailid, mis sisaldavad koodi koos kõigi ressursside ja loogikaga pilve API-ga töötamiseks. Igal pilvel on oma pakkuja ja terraform ise helistab neile ainult oma RPC-protokolli kaudu kahe protsessi vahel.
Nüüd otsustasin võtta ühendust terraformi pakkujatega otse RPC kõnede kaudu. See tuli ilusti välja ja võimaldas vahetada terraformi pakkujaid uuemate vastu ja saada uusi funktsioone ilma koodi muutmata. Samuti selgub, et kõik väljad tfstate'is ei peaks olema tf-is, aga kuidas seda teada saada? Küsige selle kohta lihtsalt oma teenusepakkujalt. Seejärel algas järjekordne regulaaravaldiste kokkupanemise rekursiivne pornograafia, mis otsis tfstate'i seest välju kõigil tasanditel sügavuti.

Lõpuks saime kasuliku CLI-tööriista, millel on kõigi terraformi pakkujate jaoks ühine infrastruktuur ja saate hõlpsalt uue lisada. Samuti võtab ressursside lisamine vähe koodi. Lisaks veel kõikvõimalikud headused, näiteks ressurssidevahelised seosed. Muidugi oli palju erinevaid probleeme, mida ei saa kõiki kirjeldada.
Panin loomale nimeks Terrafomer.

Lõplik

Terrafomeri abil genereerisime kahest pilvest 500-700 tuhat rida tf + tfstate koodi. Saime võtta pärandasju ja hakata neid puudutama ainult terraformi kaudu, nagu parimas infrastruktuuris koodiideedena. See on lihtsalt maagiline, kui võtate tohutu pilve ja võtate selle vastu meeskonna kaudu terraform-töötaja failide kujul. Ja siis grep/replace/git ja nii edasi.

Kammisin välja ja tegin korda, sain loa. Avaldasime selle GitHubis kõigile neljapäeval (02.05.19/XNUMX/XNUMX). github.com/GoogleCloudPlatform/terraformer
Juba saadud 600 tärni, 2 tõmbetaotlust openstacki ja kubernetese toe lisamiseks. Hea tagasiside. Üldiselt on projekt inimestele kasulik
Soovitan kõigil, kes soovivad alustada tööd Terraformiga ja mitte kõike selle jaoks ümber kirjutada.
Võtan hea meelega taotlusi, probleeme, tähti.

Demo
Terraformer – infrastruktuur kodeerimiseks

Allikas: www.habr.com

Lisa kommentaar