Terraformer - Infrastrukturo Por Kodigi

Terraformer - Infrastrukturo Por Kodigi
Mi ŝatus rakonti al vi pri la nova CLI-ilo, kiun mi skribis por solvi malnovan problemon.

problemo

Terraform longe estas normo en la komunumo Devops/Cloud/IT. La afero estas tre oportuna kaj utila por trakti infrastrukturon kiel kodon. Estas multaj ĝojoj en Terraform same kiel multaj forkoj, akraj tranĉiloj kaj rastiloj.
Kun Terraform estas tre oportune krei novajn aferojn kaj poste administri, ŝanĝi aŭ forigi ilin. Kion devas fari tiuj, kiuj havas grandegan infrastrukturon en la nubo kaj ne kreitaj per Terraform? Reskribi kaj rekrei la tutan nubon estas iel multekosta kaj nesekura.
Mi renkontis ĉi tiun problemon ĉe 2 laborpostenoj, la plej simpla ekzemplo estas kiam vi volas, ke ĉio estu en Git en formo de terraformaj dosieroj, sed vi havas 250+ sitelojn kaj estas multe skribi ilin en terraform permane.
Ekzistas temo ekde 2014 en terrafom kiu estis fermita en 2016 kun la espero ke estos importo.

Ĝenerale ĉio estas kiel en la bildo nur de dekstre al maldekstre

Avertoj: La aŭtoro ne loĝas en Rusio dum duono de sia vivo kaj skribas malmulte en la rusa. Atentu pri literumaj eraroj.

Solvoj

1. Estas preta kaj malnova solvo por AWS terformado. Kiam mi provis trapasi miajn 250+ sitelojn, mi rimarkis, ke ĉio estas malbona tie. AWS delonge enkondukas multajn novajn eblojn, sed teraformado ne scias pri ili kaj ĝenerale ĝi estas rubena. la ŝablono aspektas malabunda. Post la 2-a vespere mi sendis Tiru peton aldoni pliajn funkciojn tie kaj rimarkis, ke tia solvo tute ne taŭgas.
Kiel teraformado funkcias: ĝi prenas datumojn de la AWS SDK kaj generas tf kaj tfstate per ŝablono.
Estas 3 problemoj ĉi tie:
1. Ĉiam estos malfruo en ĝisdatigoj
2. tf-dosieroj foje eliras rompitaj
3. tfstate estas kolektita aparte de tf kaj ne ĉiam konverĝas
Ĝenerale, estas malfacile akiri rezulton, en kiu `teraforma plano` diras, ke ne estas ŝanĝoj

2. `terraform import` estas enkonstruita komando en terraform. Kiel ĝi funkcias?
Vi skribas malplenan TF-dosieron kun la nomo kaj speco de rimedo, poste rulu `terraform import` kaj transdonas la rimedan ID. terraform kontaktas la provizanton, ricevas la datumojn kaj faras tfstate-dosieron.
Estas 3 problemoj ĉi tie:
1. Ni ricevas nur tfstate-dosieron, kaj la tf estas malplena, vi devas skribi ĝin permane aŭ konverti ĝin de tfstate
2. Povas labori nur per unu rimedo samtempe kaj ne subtenas ĉiujn rimedojn. Kaj kion mi faru denove kun 250+ siteloj?
3. Vi devas scii la ID de la rimedoj - tio estas, vi devas envolvi ĝin en kodo kiu ricevas la liston de rimedoj
Ĝenerale, la rezulto estas parta kaj ne bone skalas

Mia decido

Postuloj:
1. Kapablo krei tf kaj tfstate dosierojn por rimedoj. Ekzemple, elŝutu ĉiujn sitelojn / sekurecan grupon / ŝarĝan ekvilibron kaj tiu `teraformplano` resendis, ke ne estas ŝanĝoj.
2. Vi bezonas 2 GCP + AWS-nuboj
3. Tutmonda solvo, kiu estas facile ĝisdatigebla ĉiufoje kaj ne malŝparas tempon pri ĉiu rimedo dum 3 tagoj da laboro
4. Faru ĝin Malferma Kodo - ĉiuj havas la saman problemon

La Go-lingvo estas kial mi amas ĝin, kaj ĝi havas bibliotekon por krei HCL-dosierojn, kiuj estas uzataj en terraform + multe da kodo en terraform kiu povas esti utila.

padon

Unua provo
Mi komencis per simpla versio. Kontakti la nubon per la SDK por la bezonata rimedo kaj konverti ĝin en kampojn por terraform. La provo tuj mortis sur la sekureca grupo ĉar mi ne ŝatis la 1.5 tagojn por konverti nur la sekurecan grupon (kaj estas multaj rimedoj). Dum longa tempo kaj tiam kampoj povas esti ŝanĝitaj/aldonitaj

Dua provo
Surbaze de la priskribita ideo tie. Nur prenu kaj konverti tfstate al tf. Ĉiuj datumoj estas tie kaj la kampoj estas la samaj. Kiel akiri plenan tfstate por multaj rimedoj?? Jen kie la komando `terraform refresh` venis al la savo. terraform prenas ĉiujn rimedojn en tfstate kaj, per ID, eltiras datumojn pri ili kaj skribas ĉion al tfstate. Tio estas, kreu malplenan tfstate kun nur nomoj kaj identigiloj, rulu `terraform refresh` kaj tiam ni ricevas plenajn tfstates. Hura!
Nun ni faru la rekursivan pornografion verki konvertilon por tfstate al tf. Por tiuj, kiuj neniam legis tfstate, ĝi estas JSON, sed speciala.
Jen ĝiaj gravaj partaj atributoj

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

Estas:
1. id - ĉeno
2. metadatenoj - tabelo de grandeco 1 kaj en ĝi objekto kun kampoj, kiu estas priskribita malsupre
3. spec - hash de grandeco 1 kaj ŝlosilo, valoro en ĝi
Resume, amuza formato, ĉio povas esti pluraj niveloj profunda

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

Ĝenerale, se iu volas programan problemon por intervjuo, simple petu ilin skribi analizilon por ĉi tiu tasko :)
Post multaj provoj skribi analizilon sen cimoj, mi trovis parton de ĝi en la teraforma kodo, kaj la plej gravan parton. Kaj ĉio ŝajnis funkcii bone

Provo tri
terraform-provizantoj estas binaroj kiuj enhavas kodon kun ĉiuj rimedoj kaj logikon por labori kun la nuba API. Ĉiu nubo havas sian propran provizanton kaj terraform mem nur vokas ilin per sia RPC-protokolo inter du procezoj.
Nun mi decidis kontakti terraform-provizantoj rekte per RPC-vokoj. Ĝi rezultis bele kaj ebligis ŝanĝi teraformajn provizantojn al pli novaj kaj akiri novajn funkciojn sen ŝanĝi la kodon. Rezultas ankaŭ, ke ne ĉiuj kampoj en tfstate devus esti en tf, sed kiel vi povas ekscii? Nur demandu vian provizanton pri tio. Tiam komenciĝis alia rekursiva pornografio de kunvenado de regulaj esprimoj, serĉante kampojn ene de tfstate ĉe ĉiuj niveloj profunde.

Fine, ni ricevis utilan CLI-ilon, kiu havas komunan infrastrukturon por ĉiuj terformaj provizantoj kaj vi povas facile aldoni novan. Ankaŭ aldoni rimedojn bezonas malmulte da kodo. Plie ĉiaj bonaĵoj kiel ligoj inter rimedoj. Kompreneble, estis multaj malsamaj problemoj kiuj ne povas esti priskribitaj ĉiuj.
Mi nomis la beston Terrafomer.

Fino

Uzante Terrafomer, ni generis 500-700 mil liniojn de tf + tfstate-kodo el du nuboj. Ni povis preni heredaĵaĵojn kaj komenci tuŝi ilin nur per terraform, kiel en la plej bona infrastrukturo kiel kodaj ideoj. Estas nur magio kiam vi prenas grandegan nubon kaj ricevas ĝin per teamo en la formo de teraformaj laboristoj. Kaj tiam grep/replace/git kaj tiel plu.

Mi elkombis ĝin kaj metis ĝin en ordo, ricevis permeson. Eldonita en GitHub por ĉiuj ĵaŭdon (02.05.19/XNUMX/XNUMX). github.com/GoogleCloudPlatform/terraformer
Jam ricevis 600 stelojn, 2 tirajn petojn por aldoni subtenon por openstack kaj kubernetes. Bonaj rimarkoj. Ĝenerale, la projekto estas utila por homoj
Mi konsilas ĉiujn, kiuj volas komenci labori kun Terraform kaj ne reverki ĉion por ĉi tio.
Mi ĝojos tiri petojn, aferojn, stelojn.

Demo
Terraformer - Infrastrukturo Por Kodigi

fonto: www.habr.com

Aldoni komenton