Terraformer - Infrastructuur om te coderen

Terraformer - Infrastructuur om te coderen
Ik wil je graag vertellen over de nieuwe CLI-tool die ik heb geschreven om een ​​oud probleem op te lossen.

probleem

Terraform is al lang een standaard in de Devops/Cloud/IT-gemeenschap. Het ding is erg handig en nuttig voor het omgaan met infrastructuur als code. Er zijn veel lekkernijen in Terraform, evenals veel vorken, scherpe messen en harken.
Met Terraform is het erg handig om nieuwe dingen aan te maken en deze vervolgens te beheren, wijzigen of verwijderen. Wat moeten degenen die een enorme infrastructuur in de cloud hebben en niet via Terraform is gecreëerd, doen? Het herschrijven en opnieuw creëren van de hele cloud is op de een of andere manier duur en onveilig.
Ik kwam dit probleem tegen bij 2 banen, het eenvoudigste voorbeeld is wanneer je alles in Git wilt hebben in de vorm van terraform-bestanden, maar je hebt meer dan 250 buckets en het is veel om ze met de hand in terraform te schrijven.
Er is kwestie sinds 2014 in terrafom dat in 2016 werd gesloten in de hoop dat er import komt.

Over het algemeen is alles zoals op de foto, alleen van rechts naar links

Waarschuwingen: de auteur woont niet de helft van zijn leven in Rusland en schrijft weinig in het Russisch. Pas op voor spelfouten.

Ð ÐμÑÐμниÑ

1. Er zijn kant-en-klare en oude oplossingen voor AWS terravorming. Toen ik mijn 250+ emmers er doorheen probeerde te krijgen, besefte ik dat daar alles slecht was. AWS introduceert al lang veel nieuwe opties, maar terraforming kent ze niet en over het algemeen is het robijn de sjabloon ziet er schaars uit. Na 2 uur 's avonds stuurde ik Pull-verzoek om daar meer functies toe te voegen en besefte dat een dergelijke oplossing helemaal niet geschikt is.
Hoe terraforming werkt: het haalt gegevens uit de AWS SDK en genereert tf en tfstate via een sjabloon.
Er zijn hier 3 problemen:
1. Updates zullen altijd vertraging oplopen
2. tf-bestanden komen soms kapot uit
3. tfstate wordt afzonderlijk van tf verzameld en convergeert niet altijd
Over het algemeen is het moeilijk om een ​​resultaat te verkrijgen waarin het 'terraformplan' zegt dat er geen veranderingen zijn

2. `terraform import` is een ingebouwd commando in terraform. Hoe werkt het?
U schrijft een leeg TF-bestand met de naam en het type van de bron, voert vervolgens `terraform import` uit en geeft de bron-ID door. terraform neemt contact op met de provider, ontvangt de gegevens en maakt een tfstate-bestand aan.
Er zijn hier 3 problemen:
1. We krijgen alleen een tfstate-bestand en de tf is leeg, je moet het handmatig schrijven of converteren van tfstate
2. Kan slechts met één bron tegelijk werken en ondersteunt niet alle bronnen. En wat moet ik nu weer doen met 250+ emmers?
3. U moet de ID van de bronnen weten - dat wil zeggen dat u deze in code moet verpakken die de lijst met bronnen ophaalt
Over het algemeen is het resultaat gedeeltelijk en schaalt het niet goed

Mijn beslissing

vereisten:
1. Mogelijkheid om tf- en tfstate-bestanden voor bronnen te maken. Download bijvoorbeeld alle buckets/beveiligingsgroep/load balancer en dat `terraform plan` retourneert dat er geen wijzigingen zijn
2. Je hebt 2 GCP + AWS-clouds nodig
3. Globale oplossing die elke keer gemakkelijk kan worden bijgewerkt en geen tijd verspilt aan elke bron voor 3 dagen werk
4. Maak het Open Source - iedereen heeft hetzelfde probleem

De Go-taal is waarom ik er dol op ben, en het heeft een bibliotheek voor het maken van HCL-bestanden die worden gebruikt in terraform + veel code in terraform die nuttig kan zijn

Pad

Eerste poging
Ik begon met een eenvoudige versie. Via de SDK contact opnemen met de cloud voor de benodigde resource en deze omzetten in velden voor terraform. De poging mislukte onmiddellijk bij de beveiligingsgroep omdat ik de 1.5 dag niet leuk vond om alleen de beveiligingsgroep te converteren (en er zijn veel bronnen). Voor een lange tijd en dan kunnen er velden gewijzigd/toegevoegd worden

Tweede poging
Gebaseerd op het beschreven idee hier. Neem gewoon tfstate en converteer het naar tf. Alle gegevens zijn aanwezig en de velden zijn hetzelfde. Hoe krijg ik volledige tfstate voor veel bronnen? Dit is waar het `terraform refresh`-commando te hulp kwam. terraform neemt alle bronnen in tfstate en haalt er, per ID, gegevens over op en schrijft alles naar tfstate. Dat wil zeggen, maak een lege tfstate met alleen namen en ID's, voer `terraform refresh` uit en dan krijgen we volledige tfstates. Hoera!
Laten we nu de recursieve pornografie doen door een converter voor tfstate naar tf te schrijven. Voor degenen die nog nooit tfstate hebben gelezen: het is JSON, maar dan speciaal.
Hier zijn de belangrijke onderdeelattributen

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

Er bestaat:
1. id - tekenreeks
2. metadata - een array van grootte 1 en daarin een object met velden dat hieronder wordt beschreven
3. spec - hash van maat 1 en sleutel, waarde erin
Kortom een ​​leuk format, alles kan meerdere niveaus diep zijn

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

Als iemand een programmeerprobleem voor een interview wil, vraag hem dan in het algemeen om een ​​parser voor deze taak te schrijven :)
Na vele pogingen om een ​​parser zonder bugs te schrijven, vond ik een deel ervan in de terraform-code, en het belangrijkste deel. En alles leek goed te werken

Poging drie
Terraform-providers zijn binaire bestanden die code bevatten met alle bronnen en logica voor het werken met de cloud-API. Elke cloud heeft zijn eigen provider en terraform zelf belt deze alleen via zijn RPC-protocol tussen twee processen.
Nu besloot ik rechtstreeks contact op te nemen met terraform-providers via RPC-oproepen. Het bleek prachtig en maakte het mogelijk om terraform-providers te veranderen naar nieuwere en nieuwe functies te krijgen zonder de code te veranderen. Het blijkt ook dat niet alle velden in tfstate in tf zouden moeten staan, maar hoe kom je daar achter? Vraag dit gerust aan uw provider. Toen begon een nieuwe recursieve pornografie over het samenstellen van reguliere expressies, waarbij op alle diepgaande niveaus naar velden binnen tfstate werd gezocht.

Uiteindelijk hebben we een handige CLI-tool gekregen die een gemeenschappelijke infrastructuur heeft voor alle terraform-providers en die je eenvoudig kunt toevoegen aan een nieuwe. Bovendien kost het toevoegen van bronnen weinig code. Plus allerlei lekkers zoals verbindingen tussen hulpbronnen. Natuurlijk waren er veel verschillende problemen die niet allemaal kunnen worden beschreven.
Ik noemde het dier Terrafomer.

slotstuk

Met behulp van Terrafomer hebben we 500-700 duizend regels tf + tfstate-code gegenereerd uit twee clouds. We waren in staat om oude dingen te nemen en ze alleen via terraform aan te raken, zoals in de beste infrastructuur als code-ideeën. Het is gewoon magisch als je een enorme wolk neemt en deze via een team ontvangt in de vorm van terraform-werkbestanden. En dan grep/replace/git enzovoort.

Ik kamde het uit en bracht het in orde, kreeg toestemming. Donderdag (02.05.19/XNUMX/XNUMX) voor iedereen vrijgegeven op GitHub. github.com/GoogleCloudPlatform/terraformer
Al 600 sterren ontvangen, 2 pull-verzoeken voor het toevoegen van ondersteuning voor openstack en kubernetes. Goede feedback. Over het algemeen is het project nuttig voor mensen
Ik raad iedereen die met Terraform aan de slag wil gaan, aan om hier niet alles voor te herschrijven.
Ik zal graag verzoeken, problemen, sterren opvragen.

Демо
Terraformer - Infrastructuur om te coderen

Bron: www.habr.com

Voeg een reactie