M'agradaria parlar-vos de la nova eina CLI que vaig escriure per resoldre un problema antic.
problema
Terraform ha estat durant molt de temps un estàndard a la comunitat Devops/Cloud/IT. La cosa és molt convenient i útil per tractar la infraestructura com a codi. Hi ha moltes delícies a Terraform, així com moltes forquilles, ganivets afilats i rasclets.
Amb Terraform és molt convenient crear coses noves i després gestionar-les, canviar-les o eliminar-les. Què haurien de fer aquells que tenen una gran infraestructura al núvol i no es creen a través de Terraform? Reescriure i tornar a crear tot el núvol és d'alguna manera car i insegur.
Em vaig trobar amb aquest problema en 2 treballs, l'exemple més senzill és quan voleu que tot estigui a Git en forma de fitxers terraform, però teniu més de 250 cubs i és molt escriure-los a terraform a mà.
Hi
En general, tot és com a la imatge només de dreta a esquerra
Advertències: l'autor no viu a Rússia durant la meitat de la seva vida i escriu poc en rus. Compte amb les faltes d'ortografia.
Solucions
1. Hi ha una solució antiga i preparada per a AWS
Com funciona la terraformació: pren dades de l'SDK d'AWS i genera tf i tfstate mitjançant una plantilla.
Aquí hi ha 3 problemes:
1. Sempre hi haurà un retard en les actualitzacions
2. Els fitxers tf de vegades surten trencats
3. tfstate es recull per separat de tf i no sempre convergeix
En general, és difícil obtenir un resultat en què el `pla terraforma` digui que no hi ha canvis
2. `terraform import` és una ordre integrada a terraform. Com funciona?
Escriviu un fitxer TF buit amb el nom i el tipus de recurs, després executeu `terraform import` i passeu l'ID del recurs. terraform contacta amb el proveïdor, rep les dades i crea un fitxer tfstate.
Aquí hi ha 3 problemes:
1. Només obtenim un fitxer tfstate, i el tf està buit, cal escriure-lo manualment o convertir-lo des de tfstate
2. Només pot treballar amb un recurs alhora i no és compatible amb tots els recursos. I què he de tornar a fer amb més de 250 galledes?
3. Heu de conèixer l'identificador dels recursos, és a dir, l'heu d'embolicar en codi que obtingui la llista de recursos.
En general, el resultat és parcial i no s'escala bé
La meva decisió
Requisits:
1. Capacitat de crear fitxers tf i tfstate per als recursos. Per exemple, descarregueu tots els cubs/grup de seguretat/equilibrador de càrrega i aquest "pla de terraform" va indicar que no hi ha canvis
2. Necessites 2 núvols GCP + AWS
3. Solució global que és fàcil d'actualitzar cada vegada i que no perd temps en cada recurs durant 3 dies de treball
4. Feu que sigui de codi obert: tothom té el mateix problema
L'idioma Go és per això que m'encanta, i té una biblioteca per crear fitxers HCL que s'utilitza a terraform + molt de codi a terraform que pot ser útil
Camí
Intenta primer
Vaig començar amb una versió senzilla. Contactar amb el núvol mitjançant l'SDK per obtenir el recurs necessari i convertir-lo en camps per a terraform. L'intent va morir immediatament al grup de seguretat perquè no m'agradaven els 1.5 dies per convertir només el grup de seguretat (i hi ha molts recursos). Durant molt de temps i després es poden canviar/afegir camps
Segon intent
A partir de la idea descrita
Ara fem la pornografia recursiva d'escriure un convertidor de tfstate a tf. Per a aquells que no han llegit mai tfstate, és JSON, però especial.
Aquí hi ha els seus atributs de part important
"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",
Hi ha:
1. id - cadena
2. metadades: una matriu de mida 1 i en ella un objecte amb camps que es descriu a continuació
3. spec - hash de mida 1 i clau, valor en ella
En resum, un format divertit, tot pot tenir diversos nivells de profunditat
"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",
En general, si algú vol un problema de programació per a una entrevista, només cal demanar-li que escrigui un analitzador per a aquesta tasca :)
Després de molts intents d'escriure un analitzador sense errors, n'he trobat part al codi terraform i la part més important. I semblava que tot funcionava bé
Intent tres
Els proveïdors de terraform són binaris que contenen codi amb tots els recursos i la lògica per treballar amb l'API del núvol. Cada núvol té el seu propi proveïdor i terraform només els crida mitjançant el seu protocol RPC entre dos processos.
Ara vaig decidir contactar amb els proveïdors de terraform directament mitjançant trucades RPC. Va resultar meravellós i va fer possible canviar els proveïdors de terraform per nous i obtenir noves funcions sense canviar el codi. També resulta que no tots els camps de tfstate haurien d'estar en tf, però com ho pots esbrinar? Només cal que pregunteu al vostre proveïdor sobre això. Aleshores va començar una altra pornografia recursiva d'acoblament d'expressions regulars, cercant camps dins de tfstate a tots els nivells en profunditat.
Al final, tenim una eina CLI útil que té una infraestructura comuna per a tots els proveïdors de terraform i podeu afegir-ne una de nova fàcilment. A més, afegir recursos requereix poc codi. A més de tot tipus de llaminadures, com ara connexions entre recursos. Per descomptat, hi havia molts problemes diferents que no es poden descriure tots.
Vaig anomenar l'animal Terrafomer.
Final
Amb Terrafomer, vam generar 500-700 mil línies de codi tf + tfstate a partir de dos núvols. Vam poder agafar coses heretades i començar a tocar-les només a través de terraform, com a la millor infraestructura com a idees de codi. És màgic quan agafeu un núvol enorme i el rebeu a través d'un equip en forma de fitxers de terraform worker. I després grep/replace/git i així successivament.
El vaig pentinar i ho vaig posar en ordre, vaig obtenir permís. Publicat a GitHub per a tothom el dijous (02.05.19/XNUMX/XNUMX).
Ja s'han rebut 600 estrelles, 2 sol·licituds d'extracció per afegir suport per a openstack i kubernetes. Bon feedback. En general, el projecte és útil per a la gent
Aconsello a tothom que vulgui començar a treballar amb Terraform i no reescriure-ho tot per a això.
Estaré encantat de treure sol·licituds, problemes, estrelles.
Demostració
Font: www.habr.com