Terraformer - Infrastructure To Code

Terraformer - Infrastructure To Code
Би сакал да ви кажам за новата алатка CLI што ја напишав за да решам стар проблем.

проблем

Terraform одамна е стандард во заедницата Devops/Cloud/IT. Работата е многу погодна и корисна за справување со инфраструктурата како код. Има многу задоволства во Terraform, како и многу вилушки, остри ножеви и гребла.
Со Terraform е многу погодно да се создаваат нови работи и потоа да се управуваат, менуваат или бришат. Што треба да прават оние кои имаат огромна инфраструктура во облакот и не се создадени преку Terraform? Препишувањето и повторното создавање на целиот облак е некако скапо и небезбедно.
Наидов на овој проблем на 2 работни места, наједноставниот пример е кога сакате сè да биде во Git во форма на тераформски датотеки, но имате 250+ кофи и многу е да ги напишете рачно во тераформ.
Постои прашање од 2014 година во терафом кој беше затворен во 2016 година со надеж дека ќе има увоз.

Во принцип, сè е како на сликата само од десно кон лево

Предупредувања: Авторот не живее во Русија половина од својот живот и малку пишува на руски. Пазете се од правописни грешки.

Решенија

1. Постои готово и старо решение за AWS тераформирање. Кога се обидов да ги протнам моите 250+ кофи, сфатив дека таму сè е лошо. AWS одамна воведува многу нови опции, но тераформирањето не знае за нив и воопшто е рубин шаблонот изгледа редок. После 2 навечер пратив Барање за повлекување да додадете повеќе функции таму и сфатив дека таквото решение воопшто не е соодветно.
Како функционира тераформирањето: зема податоци од AWS SDK и генерира tf и tfstate преку шаблон.
Тука има 3 проблеми:
1. Секогаш ќе има задоцнување во ажурирањата
2. tf датотеките понекогаш излегуваат скршени
3. tfstate се собира одделно од tf и не секогаш се спојува
Генерално, тешко е да се добие резултат во кој „тераформниот план“ вели дека нема промени

2. `terraform import` е вградена команда во terraform. Како работи?
Пишувате празна TF-датотека со името и типот на ресурсот, потоа извршите `terraform import` и го пренесувате ID-то на ресурсот. terraform контактира со провајдерот, ги прима податоците и прави датотека tfstate.
Тука има 3 проблеми:
1. Добиваме само tfstate датотека, а tf е празна, треба да ја напишете рачно или да ја конвертирате од tfstate
2. Може да работи само со еден ресурс во исто време и не ги поддржува сите ресурси. И што да правам пак со 250+ кофи?
3. Треба да го знаете ID на ресурсите - односно треба да го завиткате во код што ја добива листата на ресурси
Во принцип, резултатот е делумен и не се скалира добро

Моја одлука

Барања:
1. Способност да креирате tf и tfstate датотеки за ресурси. На пример, преземете ги сите кофи/безбедносна група/балансер на оптоварување и тој `terraform plan` врати дека нема промени
2. Потребни ви се 2 облаци GCP + AWS
3. Глобално решение кое лесно се ажурира секој пат и не губи време на секој ресурс за 3 дена работа
4. Направете го со отворен код - сите го имаат истиот проблем

Јазикот Go е причината зошто го сакам и има библиотека за креирање HCL-датотеки што се користи во terraform + многу код во terraform што може да биде корисен

Пат

Прв обид
Почнав со едноставна верзија. Контактирање на облакот преку SDK за потребниот ресурс и негово претворање во полиња за тераформа. Обидот веднаш почина на групата за безбедност бидејќи не ми се допаднаа 1.5 дена да ја конвертирам само групата за безбедност (и има многу ресурси). Долго време, а потоа полињата може да се менуваат/додадат

Втор обид
Врз основа на опишаната идеја тука. Само земете и претворете го tfstate во tf. Сите податоци се таму и полињата се исти. Како да добиете целосна tfstate за многу ресурси?? Еве каде командата `terraform refresh` дојде на помош. terraform ги зема сите ресурси во tfstate и, со ID, вади податоци за нив и запишува сè на tfstate. Односно, креирајте празна tfstate само со имиња и ID, извршете `terraform refresh` и потоа добиваме целосни tfstates. Ура!
Сега да ја направиме рекурзивната порнографија за пишување конвертор за tfstate во tf. За оние кои никогаш не прочитале tfstate, тоа е JSON, но посебно.
Еве ги неговите важен дел атрибути

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

Ете го:
1. id - стринг
2. метаподатоци - низа со големина 1 и во неа објект со полиња што е опишано подолу
3. спец - хаш со големина 1 и клуч, вредност во него
Накратко, забавен формат, сè може да биде длабоко неколку нивоа

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

Во принцип, ако некој сака програмски проблем за интервју, само замолете го да напише парсер за оваа задача :)
После многу обиди да напишам парсер без бубачки, дел од него најдов во тераформскиот код и најважниот дел. И се чинеше дека сè функционира добро

Обид три
Terraform провајдерите се бинарни датотеки кои содржат код со сите ресурси и логика за работа со Cloud API. Секој облак има свој провајдер и самиот terraform ги повикува само преку својот RPC протокол помеѓу два процеси.
Сега решив да контактирам со провајдерите на terraform директно преку повици RPC. Се покажа прекрасно и овозможи да се сменат провајдерите на тераформи на понови и да се добијат нови функции без да се менува кодот. Исто така, излегува дека не сите полиња во tfstate треба да бидат во tf, но како можете да дознаете? Само прашајте го вашиот провајдер за ова. Потоа започна уште една рекурзивна порнографија на составување редовни изрази, барајќи полиња во tfstate на сите нивоа во длабочина.

На крајот, добивме корисна алатка CLI која има заедничка инфраструктура за сите провајдери на тераформи и лесно можете да додадете нова. Исто така, додавањето ресурси бара малку код. Плус секакви добрини како што се врските помеѓу ресурсите. Се разбира, имаше многу различни проблеми кои не можат да се опишат сите.
Животното го нареков Терафомер.

Финале

Користејќи го Terrafomer, генериравме 500-700 илјади линии tf + tfstate код од два облаци. Успеавме да земеме наследени работи и да почнеме да ги допираме само преку тераформи, како во најдобрата инфраструктура како идеи за кодови. Тоа е само магија кога ќе земете огромен облак и ќе го примите преку тим во форма на тераформни работнички датотеки. А потоа grep/replace/git и така натаму.

Го исчешлав и го средив, добив дозвола. Објавено на GitHub за сите во четврток (02.05.19). github.com/GoogleCloudPlatform/terraformer
Веќе примени 600 ѕвезди, 2 pull барања за додавање поддршка за openstack и kubernetes. Добри повратни информации. Во принцип, проектот е корисен за луѓето
Ги советувам сите што сакаат да почнат да работат со Terraform и да не препишуваат сè за ова.
Ќе ми биде драго да повлечам барања, проблеми, ѕвезди.

Демо
Terraformer - Infrastructure To Code

Извор: www.habr.com

Додадете коментар