Terraformer - Infrastructure To Code

Terraformer - Infrastructure To Code
Gusto kong sabihin sa iyo ang tungkol sa bagong CLI tool na isinulat ko upang malutas ang isang lumang problema.

problema

Matagal nang naging pamantayan ang Terraform sa komunidad ng Devops/Cloud/IT. Ang bagay ay napaka-maginhawa at kapaki-pakinabang para sa pagharap sa imprastraktura bilang code. Maraming kasiyahan sa Terraform pati na rin ang maraming tinidor, matutulis na kutsilyo at kalaykay.
Sa Terraform, napakaginhawang lumikha ng mga bagong bagay at pagkatapos ay pamahalaan, baguhin o tanggalin ang mga ito. Ano ang dapat gawin ng mga may malaking imprastraktura sa cloud at hindi nilikha sa pamamagitan ng Terraform? Ang muling pagsulat at muling paggawa ng buong cloud ay mahal at hindi ligtas.
Naranasan ko ang problemang ito sa 2 trabaho, ang pinakasimpleng halimbawa ay kapag gusto mong ang lahat ay nasa Git sa anyo ng mga terraform file, ngunit mayroon kang 250+ bucket at napakaraming isulat ang mga ito sa terraform sa pamamagitan ng kamay.
Mayroon problema mula noong 2014 sa terrafom na isinara noong 2016 na may pag-asa na magkakaroon ng import.

Sa pangkalahatan, ang lahat ay tulad ng nasa larawan lamang mula kanan hanggang kaliwa

Mga Babala: Ang may-akda ay hindi nakatira sa Russia sa kalahati ng kanyang buhay at nagsusulat ng kaunti sa Russian. Mag-ingat sa mga pagkakamali sa spelling.

Solusyon

1. May mga handa at lumang solusyon para sa AWS terraforming. Nang sinubukan kong ipasa ang aking 250+ na mga balde, napagtanto kong masama ang lahat doon. Matagal nang nagpapakilala ang AWS ng maraming bagong opsyon, ngunit hindi alam ng terraforming ang tungkol sa mga ito at sa pangkalahatan ito ay ruby mukhang kalat ang template. After 2 in the evening nagpadala ako Hiling ng hilahin upang magdagdag ng higit pang mga tampok doon at natanto na ang gayong solusyon ay hindi angkop sa lahat.
Paano gumagana ang terraforming: kumukuha ito ng data mula sa AWS SDK at bumubuo ng tf at tfstate sa pamamagitan ng isang template.
Mayroong 3 problema dito:
1. Palaging may lag sa mga update
2. tf files minsan lumalabas na sira
3. Ang tfstate ay kinokolekta nang hiwalay mula sa tf at hindi palaging nagtatagpo
Sa pangkalahatan, mahirap makakuha ng resulta kung saan sinasabi ng `terraform plan` na walang mga pagbabago

2. Ang `terraform import` ay isang built-in na command sa terraform. Paano ito gumagana?
Sumulat ka ng walang laman na TF file na may pangalan at uri ng mapagkukunan, pagkatapos ay patakbuhin ang `terraform import` at ipasa ang resource ID. Nakikipag-ugnayan ang terraform sa provider, natatanggap ang data at gumagawa ng tfstate file.
Mayroong 3 problema dito:
1. Nakakakuha lang kami ng tfstate file, at walang laman ang tf, kailangan mong isulat ito nang manu-mano o i-convert ito mula sa tfstate
2. Maaari lamang gumana sa isang mapagkukunan sa isang pagkakataon at hindi sumusuporta sa lahat ng mga mapagkukunan. At ano ang dapat kong gawin muli sa 250+ bucket?
3. Kailangan mong malaman ang ID ng mga mapagkukunan - ibig sabihin, kailangan mong balutin ito sa code na nakakakuha ng listahan ng mga mapagkukunan
Sa pangkalahatan, ang resulta ay bahagyang at hindi maayos ang sukat

Ang aking desisyon

Mga Kinakailangan:
1. Kakayahang lumikha ng mga tf at tfstate na file para sa mga mapagkukunan. Halimbawa, i-download ang lahat ng bucket/security group/load balancer at ang `terraform plan` ay bumalik na walang mga pagbabago
2. Kailangan mo ng 2 GCP + AWS cloud
3. Global na solusyon na madaling i-update sa bawat oras at hindi nag-aaksaya ng oras sa bawat mapagkukunan para sa 3 araw ng trabaho
4. Gawin itong Open Source - lahat ay may parehong problema

Ang wika ng Go ang dahilan kung bakit gusto ko ito, at mayroon itong library para sa paglikha ng mga HCL file na ginagamit sa terraform + maraming code sa terraform na maaaring maging kapaki-pakinabang

ΠŸΡƒΡ‚ΡŒ

Subukan muna
Nagsimula ako sa isang simpleng bersyon. Pakikipag-ugnayan sa cloud sa pamamagitan ng SDK para sa kinakailangang mapagkukunan at pag-convert nito sa mga field para sa terraform. Namatay kaagad ang pagtatangka sa pangkat ng seguridad dahil hindi ko nagustuhan ang 1.5 araw na i-convert lamang ang pangkat ng seguridad (at maraming mapagkukunan). Sa loob ng mahabang panahon at pagkatapos ay maaaring baguhin/idagdag ang mga patlang

Ikalawang pagtatangka
Batay sa ideyang inilarawan dito. Kunin lang at i-convert ang tfstate sa tf. Ang lahat ng data ay naroroon at ang mga patlang ay pareho. Paano makakuha ng buong tfstate para sa maraming mapagkukunan?? Dito nagligtas ang utos na `terraform refresh`. kinukuha ng terraform ang lahat ng mapagkukunan sa tfstate at, sa pamamagitan ng ID, kumukuha ng data sa mga ito at isinusulat ang lahat sa tfstate. Iyon ay, lumikha ng isang walang laman na tfstate na may mga pangalan at ID lamang, patakbuhin ang `terraform refresh` at pagkatapos ay makakakuha tayo ng buong tfstates. Hooray!
Ngayon gawin natin ang recursive pornography ng pagsulat ng converter para sa tfstate sa tf. Para sa mga hindi pa nakakabasa ng tfstate, ito ay JSON, ngunit espesyal.
Narito ang mahalagang bahaging katangian nito

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

mayroong:
1. id - string
2. metadata - isang array ng laki 1 at sa loob nito ay isang bagay na may mga field na inilalarawan sa ibaba
3. spec - hash ng laki 1 at key, halaga sa loob nito
Sa madaling salita, isang masayang format, lahat ay maaaring maging ilang mga antas ng malalim

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

Sa pangkalahatan, kung may gustong magkaroon ng problema sa programming para sa isang panayam, hilingin lamang sa kanila na magsulat ng parser para sa gawaing ito :)
Pagkatapos ng maraming pagtatangka na magsulat ng isang parser nang walang mga bug, nakita ko ang bahagi nito sa terraform code, at ang pinakamahalagang bahagi. At tila maayos ang lahat

Subukan ang tatlo
Ang mga provider ng terraform ay mga binary na naglalaman ng code kasama ang lahat ng mga mapagkukunan at lohika para sa pagtatrabaho sa cloud API. Ang bawat cloud ay may sariling provider at ang terraform mismo ay tumatawag lamang sa kanila sa pamamagitan ng RPC protocol nito sa pagitan ng dalawang proseso.
Ngayon ay nagpasya akong direktang makipag-ugnayan sa mga provider ng terraform sa pamamagitan ng mga tawag sa RPC. Ito ay naging maganda at naging posible na baguhin ang mga provider ng terraform sa mga mas bago at makakuha ng mga bagong feature nang hindi binabago ang code. Lumalabas din na hindi lahat ng field sa tfstate ay dapat nasa tf, ngunit paano mo malalaman? Tanungin lang ang iyong provider tungkol dito. Pagkatapos ay nagsimula ang isa pang recursive pornography ng pag-assemble ng mga regular na expression, na naghahanap ng mga field sa loob ng tfstate sa lahat ng antas nang malalim.

Sa huli, nakakuha kami ng kapaki-pakinabang na tool ng CLI na may karaniwang imprastraktura para sa lahat ng provider ng terraform at madali kang makakapagdagdag ng bago. Gayundin, ang pagdaragdag ng mga mapagkukunan ay nangangailangan ng kaunting code. Dagdag pa sa lahat ng uri ng goodies tulad ng mga koneksyon sa pagitan ng mga mapagkukunan. Siyempre, mayroong maraming iba't ibang mga problema na hindi mailarawan ang lahat.
Pinangalanan ko ang hayop na Terrafomer.

Huling

Gamit ang Terrafomer, nakabuo kami ng 500-700 libong linya ng tf + tfstate code mula sa dalawang ulap. Nakuha namin ang mga legacy na bagay at nagsimulang hawakan ang mga ito sa pamamagitan lang ng terraform, tulad ng sa pinakamagandang imprastraktura bilang mga ideya sa code. Isa lang itong magic kapag kumuha ka ng malaking ulap at natanggap ito sa pamamagitan ng isang team sa anyo ng mga terraform worker file. At pagkatapos ay grep/replace/git at iba pa.

Sinuklay ko ito at inayos, kumuha ng pahintulot. Inilabas sa GitHub para sa lahat noong Huwebes (02.05.19/XNUMX/XNUMX). github.com/GoogleCloudPlatform/terraformer
Nakatanggap na ng 600 bituin, 2 pull request para sa pagdaragdag ng suporta para sa openstack at kubernetes. Magandang feedback. Sa pangkalahatan, ang proyekto ay kapaki-pakinabang para sa mga tao
Pinapayuhan ko ang lahat na gustong magsimulang magtrabaho sa Terraform at huwag muling isulat ang lahat para dito.
Ikalulugod kong hilahin ang mga kahilingan, isyu, bituin.

Demo
Terraformer - Infrastructure To Code

Pinagmulan: www.habr.com

Magdagdag ng komento