Terraformer — Infrastruktur till Kod

Terraformer — Infrastruktur till Kod
Jag skulle vilja berÀtta om det nya CLI-verktyget som jag har skrivit för att lösa ett gammalt problem.

Problemet

Terraform har lÀnge blivit standarden inom DevOps/Cloud/IT-gemenskapen. Det Àr ett mycket praktiskt och anvÀndbart verktyg för att arbeta med infrastruktur som kod. Det finns mÄnga fördelar med Terraform, men Àven mÄnga fallgropar.
Med Terraform Àr det mycket enkelt att skapa nya resurser och sedan hantera, Àndra eller ta bort dem. Men vad ska man göra om man har en stor infrastruktur i molnet som inte har skapats med Terraform? Att skriva om och Äterskapa hela molnet kÀnns bÄde dyrt och osÀkert.
Jag har stött pÄ ett sÄdant problem pÄ tvÄ jobb, det enklaste exemplet Àr nÀr man vill ha allt i git som Terraform-filer, men man har 250+ buckets och det kÀnns som att skriva dem för Terraform för hand Àr alldeles för mycket.
Det finns problem Redan sedan 2014 har det funnits ett Terraform-problem som stÀngdes 2016 i hopp om att det skulle bli en importfunktion.

Allt Àr i princip som pÄ bilden, men frÄn höger till vÀnster.

Varningar: Författaren har bott större delen av sitt liv utanför Ryssland och skriver sÀllan pÄ ryska. Var försiktig med stavfel.

Lösningar

1. Det finns gamla och fÀrdiga lösningar för AWS. terraforming. NÀr jag försökte fÄ mina 250+ buckets genom det insÄg jag att allt inte fungerade som det skulle. AWS har lÀnge lagt till mÄnga nya alternativ, men terraforming Àr inte medveten om dem och det Àr dessutom skrivet i Ruby. mallarna ser skrala ut. Efter tvÄ kvÀllar skickade jag Pull request för att lÀgga till fler möjligheter dÀr och insÄg att sÄdana lösningar inte fungerar överhuvudtaget.
Hur terraforming fungerar Àr att det hÀmtar data frÄn AWS SDK och genererar tf och tfstate genom en mall.
Det finns tre problem:
1. Det kommer alltid att finnas en fördröjning i uppdateringarna.
2. tf-filerna blir ibland trasiga.
3. tfstate samlas separat frÄn tf och stÀmmer inte alltid överens.
Det Àr generellt svÄrt att fÄ ett resultat dÀr `terraform plan` sÀger att det inte finns nÄgra Àndringar.

2. `terraform import` — ett inbyggt kommando i Terraform. Hur fungerar det?
Du skriver en tom TF-fil med namnet och typen pÄ resursen, sedan kör du `terraform import` och skickar ID:t för resursen. Terraform kontaktar leverantören, fÄr data och skapar en tfstate-fil.
Det finns tre problem:
1. Vi fÄr bara tfstate-filen, medan tf-filen Àr tom och mÄste skrivas för hand eller konverteras frÄn tfstate.
2. Kan endast fungera med en resurs i taget och stöder inte alla resurser. Och vad ska jag göra med 250+ buckets?
3. Man mĂ„ste veta ID:t för resurserna — det innebĂ€r att man mĂ„ste slĂ„ in det i kod som hĂ€mtar listan över resurser.
Generellt Àr resultatet delvis och skalas inte bra.

Mina lösningar

Krav:
1. Möjlighet att skapa tf- och tfstate-filer utifrÄn resurser. Till exempel ladda ner alla buckets/security groups/load balancers och vad `terraform plan` returnerade som inga förÀndringar.
2. TvÄ moln GCP + AWS
3. En global lösning som Àr lÀtt att uppdatera varje gÄng och som inte krÀver tre dagar arbete per resurs.
4. Göra det open source — detta Ă€r ett problem som alla har.

SprĂ„k Go — dĂ€rför Ă€lskar jag det, och det finns ett bibliotek för att skapa HCL-filer som anvĂ€nds i terraform + mycket kod i terraform som kan vara anvĂ€ndbar.

VĂ€g

Första försöket
Jag började med en enkel variant. Anrop till molnet via SDK för att hÀmta den resurs som behövs och konvertera den till fÀlt för terraform. Försöket dog direkt pÄ security group eftersom jag inte gillade att det tog 1,5 dagar att konvertera bara security group (det finns mÄnga resurser). LÄngsamt och sedan kan fÀlten Àndras/lÀggas till.

Andra försöket
Baserat pÄ idén som beskrivs ). Ett typiskt exempel pÄ anvÀndning:. Att helt enkelt ta och konvertera tfstate till tf. Alla data finns dÀr och fÀlten Àr desamma. Hur fÄr man en fullstÀndig tfstate för mÄnga resurser?? HÀr kom kommandot `terraform refresh` till hjÀlp. Terraform hÀmtar alla resurser i tfstate och drar ut data för dem baserat pÄ ID och skriver allt till tfstate. SÄ skapa en tom tfstate bara med namn och ID, köra `terraform refresh`, och dÄ fÄr vi fullstÀndiga tfstate. Hurra!
Nu ska vi syssla med den rekursiva pornografin att skriva en konverterare för tfstate till tf. För dem som aldrig har lÀst tfstate, sÄ Àr det JSON, men speciellt.
HÀr Àr dess viktiga del egenskaper

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

HĂ€r finns:
1. id — string
2. metadata — array av storlek 1 och den innehĂ„ller ett objekt med fĂ€lten som beskrivs nedan
3. spec — hash av storlek 1 och den innehĂ„ller key,value
En kort, underhÄllande format dÀr allt kan gÄ djupare, Àven pÄ flera nivÄer.

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

I allmĂ€nhet, den som vill ha en programmeringsuppgift för en intervju kan helt enkelt be om att fĂ„ skriva en parser för detta 🙂
Efter mÄnga försök att skriva en parser utan buggar, hittade jag en del av den i terraform-koden, nÀmligen den mest kritiska delen. Och allt verkade fungera bra.

Försök tre.
Terraform provider Àr binÀrer som innehÄller kod med alla resurser och logik för att arbeta med moln-API:er. Varje moln har sin egen provider och terraform anropar dem enbart genom sitt RPC-protokoll mellan tvÄ processer.
Nu har jag beslutat att kontakta terraform-providers direkt via RPC-anrop. Det blev vackert och gav möjlighet att byta terraform-providers mot nyare versioner och fÄ nya funktioner utan att Àndra koden. Det visade sig ocksÄ att inte alla fÀlt i tfstate mÄste vara i tf, men hur vet man detta? Man mÄste bara frÄga provider om det. Sedan började en annan rekursiv process med att bygga regelbundna uttryck och söka efter fÀlt inom tfstate pÄ alla nivÄer.

I slutÀndan blev det ett anvÀndbart CLI-verktyg med en gemensam infrastruktur för alla terraform-leverantörer, och det Àr enkelt att lÀgga till nya. Dessutom tar tillÀgg av resurser lite kod. Plus olika finesser som kopplingar mellan resurser. Det fanns förstÄs mÄnga olika problem som inte gÄr att beskriva alla.
Jag döpte lilla djuret till Terrafomer.

Finalen

Med hjÀlp av Terrafomer genererade vi 500-700 tusen rader tf + tfstate-kod frÄn tvÄ moln. Vi kunde ta tag i legacy-grejer och börja arbeta med dem genom terraform som i de bÀsta idéerna för infrastruktur som kod. Ren magi nÀr man tar ett stort moln och fÄr det som terraform-filer med ett kommando. Och sedan grep/replace/git och sÄ vidare.

Jag rÀknade ut och organiserade, fick tillstÄnd. SlÀppte det pÄ GitHub för alla pÄ torsdag (02.05.19). github.com/GoogleCloudPlatform/terraformer
Har redan fÄtt 600 stjÀrnor, 2 pull requests för att lÀgga till stöd för openstack och kubernetes. Bra recensioner. Generellt sett Àr projektet anvÀndbart för mÀnniskor.
Jag rekommenderar det till alla som vill börja arbeta med Terraform och inte skriva om allt för detta.
Jag ser fram emot pull requests, problem, stjÀrnor.

Demo
Terraformer — Infrastruktur till Kod

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster