
Szeretnék mesélni egy új CLI eszközről, amelyet írtam egy régi probléma megoldására.
Probléma
A Terraform már régóta standard a DevOps / Cloud / IT közösségben. Nagyon kényelmes és hasznos az infrastruktúra kód formájában való kezelésére. Sok szépsége van a Terraformnak, de sok villa, éles kés és csapda is.
A Terraformmal nagyon kényelmes új dolgokat létrehozni, majd ezeket kezelni, módosítani vagy törölni. De mi a helyzet azokkal, akiknek hatalmas felhőinfrastruktúrájuk van, és nem Terraformon keresztül készült? Az egész felhő újraírása és újrarendelése elég drága és nem biztonságos.
Két munkahelyen találkoztam ilyen problémával. A legegyszerűbb példa, amikor szeretném, hogy minden a Gitben terrafom fájlok formájában legyen, de van 250+ tárolóm, és kézzel megírni őket a Terraformhoz túl sok.
Van Már 2014 óta létezik a terrafom, amely 2016-ban zárult be, remélve, hogy lesz importálás.
Minden, mint a képen, csak jobbról balra.
Figyelmeztetések: A szerző élete felét nem Oroszországban tölti és csak keveset ír oroszul. Óvatosan az helyesírási hibákkal.
Megoldások
1. Léteznek kész és régi megoldások az AWS-hez. . Amikor megpróbáltam vele megszerezni a 250+ tárolómat, akkor rájöttem, hogy nagyon rossz. Az AWS már régóta sok új lehetőséget bevezetett, de a terraforming nem tud róluk, és egyébként is Ruby. . Két este után elküldtem. hogy több lehetőséget adjak hozzá, és rájöttem, hogy az ilyen megoldás egyáltalán nem megfelelő.
A terraforming úgy működik, hogy az AWS SDK-tól beszerzi az adatokat, és tf és tfstate fájlokat generál sablon alapján.
Itt három probléma van:
1. Mindig lesz késés a frissítésekben.
2. A tf fájlok néha sérültek.
3. A tfstate külön készült a tf-től, és nem mindig egyezik meg.
Általában nehéz elérni, hogy a `terraform plan` azt mondja, hogy nincsenek változások.
2. `terraform import` — beépített parancs a terraformhoz. Hogyan működik?
Írsz egy üres TF fájlt az erőforrás nevével és típusával, majd elindítod a `terraform import`-t, és átadod az erőforrás ID-t. A terraform a szolgáltatóhoz fordul, megkapja az adatokat, és létrehozza a tfstate fájlt.
Itt három probléma van:
1. Csak a tfstate fájl készül el, a tf üres, azt manuálisan kell írni vagy a tfstate-ből konvertálni.
2. Csak egy erőforrással tud dolgozni egyszerre, és nem támogat minden erőforrást. És mit csináljak újra a 250+ tárolómmal?
3. Ismerni kell az erőforrások ID-ját — tehát be kell burkolni ezt egy kódba, amely lekérdezi az erőforrások listáját.
Általában az eredmény részleges és nem méretezhető jól.
Az én megoldásom
Elvárások:
1. Lehetőség tf és tfstate fájlokat létrehozni erőforrások alapján. Például letölteni az összes tárolót/security csoportot/terheléselosztót, és hogy a `terraform plan` azt adja vissza, hogy nincs változás.
2. Kell 2 felhő: GCP + AWS.
3. Globális megoldás, amelyet könnyen frissíteni lehet, és nem kell minden erőforrással napi 3 napot eltölteni.
4. Nyílt forráskódúvá tenni — ez mindenkinek problémája.
Go nyelv — ezért szeretem, és van egy könyvtár benne HCL fájlok létrehozására, amelyet a terraform használ + sok kód a terraform-ben, amely hasznos lehet.
Út
Első kísérlet
Egyszerű változattal kezdtem. Hívások a felhőn keresztül az SDK-val a szükséges erőforráshoz és annak konvertálása mezőkké a terraform számára. A kísérlet azonnal elhalt a security csoportnál, mert nem tetszett, hogy 1,5 napot töltöttem el csak a security csoport konvertálásával (mivel sok erőforrás van). Hosszú és azután a mezők változhatnak/hozzáadhatók.
Második kísérlet
Az ötlet alapján, amit leírtam, . Egyszerűen át kell venni és konvertálni a tfstate-t tf-be. Minden adat ott van és a mezők is ugyanazok. Hogyan lehet teljes tfstate-t kapni sok erőforráshoz?? Itt segített a `terraform refresh` parancs. A terraform az összes erőforrást veszi a tfstate-ből és ID alapján kinyeri az adatokat, és mindet írja a tfstate-be. Tehát létrehozni egy üres tfstate-t csak nevekkel és ID-kkal, végrehajtani a `terraform refresh`-t, így megkapjuk a teljes tfstate-t. Hurrá!
Most foglalkozzunk a rekurtív pornográfiával, a tfstate-t tf-re konvertáló írásával. Azok számára, akik soha nem olvastak tfstate-t, ez JSON, de különleges.
Itt az fontos részlete: attributes
"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",
Itt van:
1. id — string
2. metadata — 1 méretű tömb, amelyben az alábbi mezőkkel rendelkező objektum található
3. spec — 1 méretű hash, amelyben kulcs-érték pár van
Röviden, vidám formátum, minden mélységbe mehet több szinten is.
"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", Általában, aki programozási feladatot keres interjúra, az csak kérje meg, hogy írjon egy parser-t erre a dologra 🙂
Hosszú próbálkozások után, hogy hibák nélküli parser-t írjak, felfedeztem a terraform kódjában a legfontosabb részét. És úgy tűnik, minden rendben működött.
Harmadik kísérlet
A terraform provider olyan bináris fájlok, amelyek tartalmazzák a kódot az összes erőforrással és logikával az API-k felhőkkel való használatához. Minden felhőnek megvan a saját providere, és a terraform csak ezeket hívja meg az RPC protokollján keresztül két folyamat között.
Most úgy döntöttem, közvetlenül a terraform providerekkel fogok dolgozni RPC hívásokon keresztül. Ez szépen alakult, és lehetőséget adott arra, hogy frissítsem a terraform providereket anélkül, hogy módosítani kellene a kódot. Kiderült, hogy nem minden mezőnek kell benne lennie a tfstate-ben, de hogyan tudom ezt? Csak meg kell kérdezni a providert erről. Aztán egy újabb rekurzív „pornózás” kezdődött a reguláris kifejezések összeszerelésével a mezők keresésére a tfstate minden szintjén belül.
A végén egy hasznos CLI eszközt készítettem, amely közös infrastruktúrával rendelkezik az összes terraform provider számára, és könnyen hozzá lehet adni újat. Emellett az erőforrások hozzáadása kevés kódot igényel. Plusz mindenféle apróság, mint az erőforrások közötti kapcsolatok. Természetesen sok különböző probléma merült fel, amelyeket mind nem lehet leírni.
Terrafomer-nek neveztem el a kis szörnyet.
Döntő
A Terrafomer segítségével 500-700 ezer sor tf + tfstate kódot generáltunk két felhőben. Képessé váltunk régi dolgokat elővenni és csak terraform segítségével kezdhettünk el foglalkozni velük, ahogy a legjobb infrastructure as code ötletekben. Egyszerű varázslat, amikor egy hatalmas felhőt veszel, és parancs segítségével terraform fájlok formájában kapod meg. Aztán grep/replace/git és így tovább.
Kiszámoltam és rendbe raktam, megkaptam az engedélyeket. Csütörtökön (2019.05.02.) kiadtam a GitHub-ra mindenki számára.
Már 600 csillagot kaptam, 2 pull request, amelyek az openstack és kubernetes támogatását adják hozzá. Jó visszajelzések. A projekt igazán hasznos az emberek számára.
Ajánlom mindenkinek, aki elkezdene dolgozni a Terraform-mal és nem akar mindent átírni emiatt.
Örömmel fogadom a pull requesteket, a problémákat és a csillagokat.
Demos
Forrás: habr.com
