Как же это удобно! Хочешь что-то от Инфры — написал в Service Desk, тебя тегнули в TiMe в треде под уведомлением о создании задачи в Жире. А через несколько минут в том же треде тегнули ещё раз, чтобы сообщить, что задача выполнена.
Как было раньше?
Идёшь в канал #infra
в Slack. Пишешь свободным текстом, что нужно. Типа: «Дайте доступ в БД» — «В какую БД?» — «Не помню название, БД такого-то проекта». Через час кто-то откликнется: «У нас нет такой БД. Попробуй спросить того парня, может, он знает». Вернулся с точным названием, чтобы через час получить следующий вопрос: нужно читать или писать?
У инженера Инфры таких запросов пара десятков в день. Где-то ответил, а про что-то забыл. Чтобы не потеряться, мы ставили эмодзи на запросах:
✅ — запрос обработан.
? — не будем делать.
? — работаем прямо сейчас.
Ставили ждуна, если запрос отложили.
Если запрос не удавалось выполнить в течение дня, то создавали задачу в Жире. Чтобы решить позже. Половину. Может быть ?
Как сейчас?
Есть Service Desk с формами запросов и поиском по ним. Есть CMDB с данными по инфраструктуре. Нужен доступ в БД? Выбери её в меню. Нет в списке — у нас такого нет. Юзер не сможет сделать ошибку, если у него не будет свободы их делать. Меню — это закрытый список.
Что ещё нужно для доступа в БД, что стоит спросить у юзера сразу же? Уровень доступа: только чтение или чтение/запись. Список таблиц, к которым нужен доступ.
И здесь юзеры дают волю своей фантазии. В списке таблиц могут написатьвсе
, или*
, или поставить прочерк. Потом бот посмотрит на эту писанину, проверит, какие таблицы есть в БД на самом деле, и исключит из задачи те, которых нет. Напишет об этом юзеру, после чего спросит одобрение у владельца БД, давать ли доступ.
По отправке запроса в Service Desk появляется задача в Жире со всей информацией по задаче. Service Desk — это фронт. Задача в Жире — это бэк. В TiMe появится уведомление о создании задачи, в треде под уведомлением бот тегнет юзера: «Э-э-эй, здесь можно следить за выполнением твоей задачи! Будут вопросы — пиши сюда».
Шрек
Наш зелёный друг (его зовут Шрек, почему так — отдельная тема) увидит задачу в Жире и пойдёт по ней работать. Шрек написан на Ансибле — плейбук и роль. По факту создания или изменения задачи Жира отправляет хук в GitLab, где запускается Ансибл со Шреком и номером задачи. Иногда хуки теряются, так что Шрек также запускается по расписанию, получает JQL запросом список подходящих задач и идёт по ним работать. В цикле по каждой из списка.
Получив задачу, Шрек смотрит по типу задачи, что вообще по ней надо сделать. Шрек — рукастый парень: у него есть 70+ обработчиков для разных задач. По большинству задач нужно выполнить один обработчик, по некоторым несколько. Например, сделать БД, добавить БД в Графану.
Infrastructure as Code
Мы придерживаемся IaC-подхода. Это значит, что большая часть инфраструктуры описана в справочниках Ансибла, а типичный обработчик Шрека состоит из пары шагов:
- Внести изменения в репозиторий (обычно Ансибла, иногда в какой-то другой).
- Раскатать изменения на прод.
- Отписаться о проделанной работе.
Каждый обработчик лежит в своём каталоге и может выглядеть в коде как-то так:
- name: Do something
include_tasks: edit-repo.yml
vars:
shrek_edit_tasks: edit.yml
shrek_edit_files:
- vars/something.yml
shrek_apply_tasks: apply.yml
Здесь edit-repo.yml
:
- Склонирует репу во временный каталог.
- Внесёт изменения, вызвав
edit.yml
. - Изменения в
vars/something.yml
отправит в отдельную ветку на Gitlab. - Сделает MR по этой ветке и самостоятельно его одобрит (свой человек, ему можно).
- Подождёт, пока Gitlab выполнит пайплайн по MR.
- Сольёт MR в мастер.
- Вызовёт
apply.yml
, чтобы раскатать изменения на прод.
Чтобы редактировать YAML-ы, я широко использую yq. Как sed для текста или jq для JSON, так yq — потоковый редактор YAML.
Чтобы раскатать изменения, обычно нужно выполнить какую-то роль Ансибла. Так как Шрек сам написан на Ансибле, то он запросто может вызвать какую-нибудь роль с нужными параметрами. Если эта часть инфраструктуры ещё не описана в Ансибле, то Шрек вполне может сходить куда-нибудь по API.
localhost
Шрек — это плейбук, который работает на localhost
. Где бы он ни был: AWX, GitLab, Jenkins, мой рабочий комп или ноутбук коллеги. Запусти его с ключом задачи — и он сделает всё, что нужно по этой задаче. Детерминированный конечный автомат, у которого состояние хранится снаружи. Обработчики идемпотентные. Если что-то пошло не так (например, конфликт при мёрдже), просто запусти ещё раз.
На первых порах этого хватало — выполнить одну или несколько ролей. Но в Ансибле, помимо ролей, ещё есть плейбуки. В плейбуке можно ограничить область выполнения роли. У нас 300+ БД. При создании БД нужно выполнить роль управления БД только на одном хосте, а не на всех наших 40+ хостах с БД. Плейбук databases.yml
выполняет роль databases
на хостах с БД, а не на localhost
. Это проблема №1.
Транзакционность изменений
Шрек внёс изменения в код, раскатил изменения на прод… А если что-то пошло не так и не удалось раскатить? Изменения уже в мастере, но на проде их нет. Получаем configuration drift. Что делать дальше? Откатить изменения? Как-то сложно. Притом что в мастер уже могли прилететь другие изменения. Это проблема №2.
Другой источник изменений
Ещё один источник изменений в инфраструктуре, помимо запросов юзеров через Service Desk, — это мои коллеги по Инфре. I like to move it, move it! ? Например, они постоянно двигают БД между хостами. Дальше по чек-листу должны бы обновить данные в CMDB, но не всегда это делают. Человеку свойственно ошибаться. Было бы здорово, чтобы изменения в Ансибле сами залетали в CMDB. Это проблема №3.
?
Нам нужно что-то, что:
- Запускало бы плейбуки (а не роли).
- Работало бы самостоятельно (а не по задачам).
- Можно сравнительно легко перезапустить.
Иногда запускать плейбуки нужно в определённом порядке. Например, прилетел MR, в котором появляется новый хост, и существующая БД сразу переезжает на него. Здесь нужно, во-первых, добавить новый хост в CMDB, во-вторых, обновить БД (ссылку на хост) в CMDB — строго в таком порядке.
И тут на сцену выходит...
Харольд
CI/CD, коллега Шрека, прошу любить и жаловать. ? Если Шрек трудится в поте лица вносит изменения по задачам, то Харольд по факту изменений командует, что делать доставляет их на прод. И ещё может выполнять что-то по расписанию. Или по запросу, если сильно нужно прямо сейчас. Харольд, как и Шрек, тоже написан на Ансибле. Gitlab запускает Харольда по факту изменений в справочниках Ансибла. Его также можно запустить вручную — пайплайн со списком джоб в переменной.
У Харольда есть кучка джоб, которые он может выполнить.
- Каждая джоба — это плейбук плюс параметры: теги, дополнительные переменные, артефакты, против каких хостов выполнять, зависимости между джобами.
- Для каждой джобы записано, когда её выполнять: «Изменения в таких-то файлах». Плюс есть фильтр на изменения.
Например, в справочнике юзеров около 7000 файлов типа такого:
vasya.pupkin:
databases:
crm:
timetable:
ldap:
givenName: Vasya
sn: Pupkin
email: vasya.pupkin@skyeng.ru
Если у юзера поменялась секция databases
, то нужно выполнить плейбук databases.yml
с ограничением на этого юзера и БД, которая добавилась. Если поменялась секция ldap
, то надо обновить этого юзера в LDAP и только его, а БД трогать вообще не надо. При наших объёмах инкрементальные изменения — наше всё.
Харольд смотрит прежде всего, что от него хотят:
- Возможно, ему передали список джоб на выполнение.
- Если списка джоб нет, то ему можно передать коммит в качестве базы. Он вычислит изменения относительно этой базы.
- Можно передать два коммита. Он вычислит изменения от и до.
- По комментарию к коммиту определяет задачу Жиры, по которой были внесены эти изменения.
- В Gitlab-е настроено требование, что комментарий к любому коммиту должен начинаться с номера задачи. Ещё коммиты должны быть с корпоративной почтой. Gitlab не принимает пуши с коммитами, не подходящими под эти правила.
- По изменениям вычисляет джобы для запуска.
Например, у нас есть прокси для тестингов. Тестинги доступны только через VPN, но некоторые endpoint-ы можно выставить наружу для получени хуков от социальных сетей или платёжных систем. При добавлении тестинга на прокси нужно получить SSL сертификат с именем тестинга и затем можно сконфигурить сам прокси. Так как изменилось описание прокси в инвентаре Ансибла, то этот хост также обновляется в CMDB.
Для фильтрации YAML я широко использую JMESPath. Это как SQL для реляционных БД, но для JSON.
Вычислив список джоб, Харольд генерирует динамический пайплайн Gitlab-а с джобами и зависимостями между ними и триггерит этот пайплайн. В каждой джобе один плейбук Ансибла. Запуск плейбука обёрнут в шелле таким образом, что Харольд (другим плейбуком) пишет в тред под задачей отчёт со списком джоб, которые он собирается запустить. Когда джоба завершилась, Харольд изменяет в отчёте эмоджи соответственно статусу выполнения джобы: успех, провал.
Новое Symfony приложение
На картинке в начале статьи создание Шреком нового Symfony приложения. Раньше разработчики самостоятельно занимались таким делами. От Инфры они могли получить инструкцию в духе:
- Сходи в канал
#infra
, попроси их сделать новую БД. - Разверни Symfony, поменяй такие-то параметры.
- Попроси Инфру сделать новую репу.
- Задеплой приложение на тестинг.
На всё про всё запросто уходил месяц. Теперь требуется час, включая ручную проверку, что приложение отдаёт 200.
Итого
Взгляд извне Инфры:
- Отправил заявку в Service Desk и через несколько минут получил, что хотел.
- В CMDB всегда актуальная инфа. Можно получить нужные данные IQL запросами.
С точки зрения инженера Инфры:
Скучаю, положив ноги на стол.- На канбан-доске задачи. Присматриваю одним глазом, чтобы не было зависших задач. Это задачи, где что-то пошло не так, или которые трудно формализировать, и они всё ещё выполняются вручную.
С точки зрения тимлида:
- Задачи на доске, в задачах ссылки на обсуждение.
- Time to market сократился сократился на порядок. Местами на два ?
Ext_Art
Какой то поток сознания.