Бих искал да ви разкажа за новия CLI инструмент, който написах за решаване на стар проблем.
проблем
Terraform отдавна е стандарт в Devops/Cloud/IT общността. Нещото е много удобно и полезно за работа с инфраструктура като код. В Terraform има много изкушения, както и много вилици, остри ножове и гребла.
С Terraform е много удобно да създавате нови неща и след това да ги управлявате, променяте или изтривате. Какво трябва да направят тези, които имат огромна инфраструктура в облака и не са създадени чрез Terraform? Пренаписването и повторното създаване на целия облак е някак скъпо и опасно.
Срещнах този проблем при 2 задачи, най-простият пример е, когато искате всичко да е в Git под формата на terraform файлове, но имате 250+ кофи и е много да ги пишете в terraform на ръка.
Има
Като цяло всичко е като на снимката само от дясно на ляво
Предупреждения: Авторът не живее половината си живот в Русия и пише малко на руски. Пазете се от правописни грешки.
Решения
1. Има готови и стари решения за AWS
Как работи тераформирането: взема данни от 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. Трябва да знаете идентификационния номер на ресурсите - тоест трябва да го обвиете в код, който получава списъка с ресурси
Като цяло резултатът е частичен и не се мащабира добре
Моето решение
Изисквания:
1. Възможност за създаване на tf и tfstate файлове за ресурси. Например, изтеглете всички кофи/група за сигурност/балансиране на натоварването и този `terraform plan` върна, че няма промени
2. Имате нужда от 2 GCP + AWS облака
3. Глобално решение, което лесно се актуализира всеки път и не губи време за всеки ресурс за 3 дни работа
4. Направете го с отворен код - всеки има същия проблем
Езикът Go е причината, поради която го харесвам и има библиотека за създаване на HCL файлове, която се използва в terraform + много код в terraform, който може да бъде полезен
Път
Опитайте се първо
Започнах с проста версия. Свързване с облака чрез SDK за необходимия ресурс и преобразуването му в полета за terraform. Опитът умря незабавно в групата за сигурност, защото не ми харесаха 1.5 дни за конвертиране само на групата за сигурност (и има много ресурси). За дълго време и след това могат да се променят/добавят полета
Втори опит
Въз основа на описаната идея
Сега нека направим рекурсивната порнография за писане на конвертор за 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. spec - хеш с размер 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 и то най-важната част. И изглеждаше, че всичко работи добре
Опит три
доставчиците на terraform са двоични файлове, които съдържат код с всички ресурси и логика за работа с облачния API. Всеки облак има свой собствен доставчик и самият terraform ги извиква само чрез своя RPC протокол между два процеса.
Сега реших да се свържа директно с доставчиците на terraform чрез RPC повиквания. Получи се прекрасно и направи възможно смяната на доставчиците на terraform с по-нови и получаването на нови функции без промяна на кода. Оказва се също, че не всички полета в tfstate трябва да са в tf, но как можете да разберете? Просто попитайте вашия доставчик за това. След това започна друга рекурсивна порнография на сглобяване на регулярни изрази, търсейки полета в tfstate на всички нива в дълбочина.
В крайна сметка получихме полезен CLI инструмент, който има обща инфраструктура за всички доставчици на terraform и можете лесно да добавите нова. Освен това добавянето на ресурси отнема малко код. Плюс всякакви екстри като връзки между ресурси. Разбира се, имаше много различни проблеми, които не могат да бъдат описани всички.
Нарекох животното Терафомер.
финал
Използвайки Terrafomer, генерирахме 500-700 хиляди реда tf + tfstate код от два облака. Успяхме да вземем наследени неща и да започнем да ги докосваме само чрез тераформа, както в най-добрата инфраструктура като идеи за код. Просто е магия, когато вземете огромен облак и го получите чрез екип под формата на тераформирани работни файлове. И след това grep/replace/git и така нататък.
Разресах го и го подредих, получих разрешение. Пуснат в GitHub за всички в четвъртък (02.05.19/XNUMX/XNUMX).
Вече получи 600 звезди, 2 заявки за изтегляне за добавяне на поддръжка за openstack и kubernetes. Добра обратна връзка. Като цяло проектът е полезен за хората
Съветвам всички, които искат да започнат работа с Terraform и да не пренаписват всичко за това.
Ще се радвам да изтегля заявки, проблеми, звезди.
демонстрация
Източник: www.habr.com