Search
Write a publication
Pull to refresh
4
0
Игорь Гербылев @gersp

User

Send message

очень хочется посмотреть процесс, как с нуля собирается yaml для нетривиального API хотя бы на пять полноценных сущностей?

В этом процессе нет ничего особенно, по сравнению даже с тем, что описано в этой статье.
На практике (проектов среднего размера) скажу, что в API first подходе определённо есть ряд проблем:

  • несовершенство генераторов порой не позволяет описать спеку так, как хочется, потому что генератор чего-то не поддерживает. Иногда приходится править спеку, а иногда коммитить в генератор.

  • могут быть сложности с описанием правил валидации. В спеке не описать всех проверок, которые можно описать в коде. Но такие проверки надо и оставить в коде. Так что это не существенная проблема.

  • могут быть сложности с добавлением кастомных аннотаций (декораторов) к сгенерированным классам. Но мне такой необходимости удавалось избегать.

Но при Code first будет ряд других проблем связанных с построением процессов интеграции изменений в генерируемой спеке между несколькими компонентами. И на мой субъективный взгляд, проблем настройки CI в случае code-first - больше.

Противоестественность вижу только в использовании конкретного инструмента, FastAPI

Что ж тут противоестественного. Возможность генерации спеки из кода никак не запрещает генерить из спеки код.

Ознакомьтесь со списоком генераторов. Тут есть минимум три генератора, которые создают pydantic модели из swagger-спеки:
https://openapi-generator.tech/docs/generators
Зачем-то ведь люди это делают.

И вот ещё по теме:
https://github.com/fastapi/fastapi/issues/519
Обратите внимание на реакцию сообщества на первый комментарий.

С ног на голову перевёрнуто

Не с ног на голову, а API first. Вот, например, статья объясняющая различия принципов code first и api first: https://habr.com/ru/companies/axenix/articles/694340/
И тот и другой принцип имеет свои плюсы и минусы и оба используются в разных проектах. Как мне кажется, code first даже более распространён в виду простоты реализации. Но ничего противоестественного в API first нет.

этот подход (API first) не что иное, как воплощение классических этапов разработки, о которых всё время твердят олды, но шарахаются Agile адепты: проектирование и системный анализ.

Мне очень понравился комментарий пользователя @lebedecиз статьи, что я привёл выше в этом комменте. Потому перепечатаю его здесь и посоветую прочитать статью, если тема вам кажется интересной.

Любой. Вам нужно открыть только один порт для подключения по ssh к контейнеру telekube.

Компонент - это абстракция, улучшающая (на мой взгляд) структурирование кода, причём большого объёма кода. Как и любой стайл-гайд, Компонент не является чем-то таким, без чего нельзя обойтись (если бы это было так, то эта методика появилась бы лет на 20 раньше).

Сдвиг парадигмы разработки, который предлагает компонентный подход - очень не большой. Можно его ещё раз сформулировать так: в стандартном подходе - у вас есть Роли, поверх которых вы пишите Плейбук(код)+Инвентарь(данные), а в нашем Компонентном - у нас есть библиотека Компонентов, поверх которых мы пишем только Инвентарь. Т.е. чуть меньше императивщины в ежедневных операциях.

Но мне кажется важным ещё один момент. В Компонентном подходе я "нанизываю" на понятие Компонента много дополнительных best practies: от нейминга и правил работы с переменными до CI/CD. Эти правила у меня плохо клеились в единую картину без понятия Компонента.

Буду признателен, если читатели покидают в комментарии ссылки аналогичные руководства-методики-бест-практисы по "стандартному" ансибл.

Собственно мне и интересно как вы реализуете проект

  1. Один репозиторий, два vault-ключа - один общедоступный для test и stage, другой для prod, доступный только прод-админам. И два CI-раннера, один с доступом к прод-серверам, другой без.

  2. 3х2 инвентаря, чтобы разделить инфру и апп. Делается это для того, чтобы разделить ответственность между разработкой и девопсами.

  3. Соответственно два корневых плейбука plays/infra.yml, plays/app.yml. Оба они стоят под CI/CD и периодически прогоняются с -C, если обнаруживаются чейнджы, что в чат отправляется алерт. Оба этих плейбука можно запускать из CI/CD. Эти корневые плейбуки состоят только из набора import_playbook.

  4. Кроме "простых" корневых плейбуков, обеспечивающих раскатку, могут быть и дополнительные, предназначенные для типовых процедур обслуживания. Например: перенос дампа с прода на стейдж, промоут версий со стейджа на прод с расстановкой нужных тэгов в гите и т.п. Подобные действия можно реализовать и в виде CI-пайплайнов, но этот вопрос я считаю делом личных предпочтений. На практике у нас бывает и так и так.

  5. Рядом с корневыми плейбуками лежит папка cmp с плейбуками компонентов (если у нас много схожих проектов, то эта папка выносится в отдельный реп и подтягивается с помощью ansible-collection). Компоненты разделены по плейбукам в соответствии с правилами из статьи. Некоторые плейбуки, могут использовать говотовые роли, обеспечивая только их "привязку" к нашему типовому инвентарю и к общим правилам. Обычно, таких ролей не много и используются они только для особо сложных компонентов (kubespray например).

  6. Будет ли отдельный плейбук-компонент на каждый golang-сервис зависит от того, насколько они типовые. Если все сервисы +-одинаковы с точки зрения развёртывания и конфигурации - то у нас будет компонент GoLang-Приложение и много его инстансов. Если сервисы сильно разные, то будут отдельные компоненты типа Приложение1, Приложение2 и т.п.


Пример инвентарей

https://github.com/vitabaks/postgresql_cluster - это не наш модуль) Этот пример я привёл в другом контексте. У нас скрипты деплоя постгреса выглядят немного по другому.

Специфика задач у нас чуть-чуть другая, но не принципиально. Возможно у нас более тесная интеграция с разработкой, в том смысле что разработка порой сама вносит правки, например, в балансировщик или пробует поставить новую версию базы, чтобы проверить работоспособность. Не говоря уже о правках конфигурации на тестовых стендах. Над таким задачами удобнее работать из консоли, а не через CI/CD. Но это утверждение субъективно и зависит уровня компетенции по девопс-скриптам.

По тому коду что я вижу выше мне кажется у вас не совсем "декларативный подход" и не совсем "IaC". Ну и общее впечатление - "слишком усложнено"

Тут каждое утверждение требует пояснения. Что не декларативно, что не не IaC и как должно быть проще?

> зачастую вся инфраструктура - одним плейбуком

Здорово, если у вас так получается. Но рискну предположить, что система у вас на порядок проще. На моём опыте, подход с одним плейбуком изживает себя примерно на уровне 10 серверов и 20 программных компонент, которые требуют установки и настройки.

> я лично предпочитаю

Если эта фраза акцентирует внимание на индивидуальной работе, то это много объясняет. При отсутствии большого количества внутри- и меж-командных коммуникаций многие из этих "сложностей" действительно не нужны.

Пользуется ли вашим "единственным плейбуком" кто-нибудь ещё? Пользуются ли им разработчики того приложения, которое вы сетапите? У нас пользуются.

И надо оговориться, что Компонентый подход не противоречит использованию ролей. Роли можно использовать внутри Компонентов. Т.е. довольно типовой вариант, то что Компонент просто перевызывает внутри себя Роль с определёнными параметрами. По сути, определяя лишь Имя компонента, определяемое как имя хост-группы на которую он нацелен. На моей практике, такой подход можно применять если в сети уже есть готовая подходящая роль. Новые же скрипты, как мне кажется, проще сразу писать в Компонентной архитектуре.

Это самый важный вопрос) И весьма холиварный.

  1. Началось всё с необходимости установить несколько однотипных компонентов на один хост. Т.е. как бы применить одну роль к одному хосту несколько раз. Чтобы сделать это с ansible придётся извернуться и мы придумали свой способ.

  2. Мне хотелось создать абстракцию, которая сделает инвентарь самодостаточным. Для того, чтобы "пристегнуть" Роль к Инвентарю, вам понадобится написать плейбук, который, как минимум, определит привязку роли к имени хост-группы. А это означает, что читателю не достаточно прочитать инвентарь, а нужно ещё изучать что же делается в соответствующем плейбуке. А если мы поверх роли пишем плейбук, то со временем он будет разрастаться начнёт вбирать в себя всё больше вспомогательной логики.
    Напротив: плейбук-компонент это атомарная единица конфигурации, которая прицепляется только лишь добавлением строчки в инвентарь (и в корневой плейбук, если это совсем новый компонент). На мой взгляд это удобнее для чтения и поддержки.

  3. Я смотрю на инвентарь, в первую очередь (как разработчик), со стороны архитектуры системы, т.е. программных компонентов, которые он описывает. Стандартный подход с ролями как бы говорит нам о том, что сначала есть Сервера, а потом они выполняют определённые Роли. Компонентный подход говорит о том, что сначала есть Система (окружение, инвентарь), она состоит из набора Компонентов, которые мы потом распределяем по Серверам.

  1. Потому что подобный сетап баш-скриптом автоматизировать довольно сложно - https://github.com/vitabaks/postgresql_cluster.

  2. Ради единства инструментов и стандартизации управления конфигурацией. Даже если у вас найдётся подходящий баш-скрипт, который ещё и обеспечивает идемпотентность и корректно показывает changes, то обернуть его в плейбук не составит проблем. И это вполне нормальный путь с точки зрения нашего Компонентного подхода. Потому что не важно, как плейбук выполняет свою работу, а важно чтобы он её выполнял качественно и с соблюдением принятых стандартов.

В ансибл можно удалять записи из инвентаря не сразу, а путём добавления аттрибута remove: true. Но это конечно не так удобно как при работе с terraform. И обработку этого аттрибута придётся писать самостоятельно

Спасибо за внимательные комментарии!

Было бы интересно услышать мнение насчёт вопроса "зачем на ансибл, если есть террафом") Теоретически я слышал о том, что терраформ можно применять гораздо шире, чем только для создания серверов, но на практике мы не пробовали.

зачем людям terraform, если у них есть ansible?

Довольно интересный вопрос. Я тоже было придерживался такого мнения и пару раз писал управление инфраструктурой (читай как создание VPC в hetzner), а потом пытался применить похожий подход на других провайдерах. Но потом отказался от этой затеи.

Вместо долгих рассуждений - попробуйте создать вирутальный сервер в Selectel (указав кастомный базовый образ и подключив пару сетевых дисков) с помощью ансибл. Думаю вопросы быстро отпадут.

Более рациональный ответ - у терраформа другая модель выполнения, терраформ поддерживает некое внутреннее состояние и при каждом запуске вычисляет план действий, которые надо применить к инфраструктуре. Наличие такого планировщика 1. снимает часть сложности с разработчика, на ансибл вам придётся чекать изменения самостоятельно, 2. делает выполнение скрипта быстрее, потому что в результате построения правильного плана будут применены только те действия, которые действительно необходимы.

у вас получится километровый инветарь

У нас отдельные инвентарь на каждое окружение, у каждого окружения (и соответственно инвентаря) есть владелец. Про один общий инвентарь я вроде бы не писал.
Есть ещё пара простых трюков касаемо инвентарей: один инвентарь можно разбивать на отдельные файлы и инвентари можно как-бы наследовать друг от друга с помощью симлинков.

При таком подходе мне всё равно как выглядят инвентари моих коллег.

А это вот деструктивное утверждение. А как же обмен опытом и взаимозаменяемость сотрудников? А если ваш коллега заболет на долго или уволится, кто будет разбирать его код, до которого никому не было дела?
Практики код-ревью и совместного владения кодом не просто так придумали. Они верны при любом подходе, если только речь не о личном пет-проекте.

многие вещи в принципе не надо автоматизировать

Приведите пример?

IaC сильно добавляет сложности в работе и требует найма более дорогих инженеров

Я всё же адресовал это высказывание к ранней фазе внедрения IaC, когда ещё не все практики изучены и не все процессы налажены (а руки растут там где вырасли, а не там где надо). Сейчас мы не мыслим своей жизни без IaC и этот код не то чтобы экономит нам время, но делает возможным поддержание работоспособного состояния всех систем в принципе.

  1. Количество окружений у нас значительно уменьшить не получится. Как минимум есть окружения для некоторых заказчиков, выделенные отдельно по соображениям ИБ. Плюс каждой команде разработки нужен хотя бы один свой интеграционный стенд. Мы решаем эту сложность путём стандартизации конфигов и плейбуков и распределением ответственности по владению окружениями.

  2. С этим утверждением сложно не согласится. Но можно. Во первых, если девопс-разработчик хорошо умеет писать скрипты автоматизации, то написать, а главное отладить скрипт становится гораздо проще, чем отладить инструкцию. Инструкцию надо выполнять руками, а скрипт можно прогнать автоматически за секунды или минуты на тестовом сервере. Во вторых, при автоматизации возникают дополнительные сложности. В основном связанные с тем, что скрипт не может применить "экспертное знание" системного администратора, если оно в него не закодировано. А инструкция какие-то "очевидные всем" шаги может пропускать. В третьих, инструкция будет устаревать со временем и на поддержку 100 инструкций вам ни хватит ни сил ни желания (мне точно не хватит). Так что моё мнение - можно и нужно сразу писать плейбуки и сразу выводить их на CI стенды.
    Но, на этапе обучения работе с автоматизацией, инструкции конечно придётся делать.

Даже если сторонние ансибл-модули не умеют сами корректно обрабатывать change'ы, мы почти всегда можем сделать это сами, расставляя правильные changed_when, а иногда и создавая более сложные конструкции. Например:

  1. сначала запросить текущую конфигурацию

  2. потом сравнить её с той конфигурацией, которую мы собираемся применить.

  3. и если она отличается, то выполнить обновление

  4. а если нет, то ничего не менять, чтобы не было changes.

В более интересных случаях, мы можем даже специальным образом дизайнить API сервисов так, чтобы сервис возвращал разные коды ответа в случае если изменения были применены или если дифа не было. Можно ещё создавать отдельные ветки в плейбуках для dry run режима.

В этом пункте правил, я хотел обратить внимание на то, что проверкой наличия изменений, диагностируемой по changes=0, можно пользоваться только если все используемые плейбуки и роли будут придерживаться этого правила. Достичь этого не так то просто, но можно. А польза и удобство от идемпотентности весьма большие.

Information

Rating
Does not participate
Location
Санкт-Петербург и область, Россия
Works in
Registered
Activity