Принцип 'You build It, You Run It' при разработке современного ПО

За последние годы требования к скорости доставки программного обеспечения существенно выросли, при этом заказчики ожидают все то же высочайшее качество и максимально частую интеграцию изменений в продукт.

Поставщики вынуждены менять подходы к разработке, чтобы соответствовать ожиданиям клиентов об эффективном поставщике и оправдывать ожидание сотрудников об инновационной и прогрессивной организации. Традиционные подходы к разработке, в которых команды разработки состоят из обособленных подразделений с узкоспециализированными инженерами, работающими конвейерно (develop - test - deploy - run) под влиянием данных тенденций начинают трансформироваться в более универсальные юниты смешанной специализации.

Появилась целая когорта подходов и практик, которая решает проблемы, связанные с новыми потребностями клиентов - CI/CD, DevOps, Agile-методологии и т.п. Однако, мы часто наблюдаем, что попытка внедрить какую-то новую практику терпит фиаско или превращается в профанацию, в “сертификат соответствия” (да-да ISO9001, CMMI), которым размахивают перед лицом клиента, при организация все работает без каких-либо изменений. Помните тот анекдот, в котором разговаривают два приятеля:

П1: Я теперь профессиональный фотограф.
П2: Да ты что? Как ты этого добился?
П1: Да вот, профессиональную фотокамеру купил.

Все помнят как пять-семь лет назад каждый второй человек в возрасте до 30 был “профессиональным” фотографом. Так и сейчас, администраторы внезапно стали DevOps-инженерами, компании стали применять DevOps-подходы, хотя на основании общения, участия в конференциях, чтения форумов за последние два года, у меня складывается впечатление, что большинство людей просто услышали про новую модную плюшку и начали эксплуатировать ее для самопрезентации.

Когда я задумал данный материал, то планировал написать подробную статью о том, как использовать CI/CD и другие практики быстрой разработки для улучшения результатов деятельности команд, но после восьми страниц введения вдруг понял, что материала слишком много, и стоит начать с чего-то простого. В этой статье я хочу рассказать об идее “You build it, you run it”, которую, можно обобщить до “If you do it, you are responsible for it”.

Данный манифест сформулирован компаниями, которые разрабатывают действительно серьезное программное обеспечение и являются высококонкурентными, в частности его продвигают Amazon и Netflix. Впервые я услышал эту формулировку на конференции JAX в августе 2017 года на мастер-классе о Chaos Engineering и доставке микросервисов. Тогда я понял, что это именно та емкая фраза, которая необходима для переосмысления подхода к разработке.

Итак, начнем с примера. Рассмотрим типичный цикл доставки очередной версии программного обеспечения. Как правило, он будет состоять из нескольких крупных фаз:

  1. Разрабатываем код;
  2. Тестируем код (тестирование, регрессионное тестирование);
  3. Исправляем ошибки;
  4. Повторяем шаги 2-3 до достижения требуемого уровня качества;
  5. Разрабатываем процедуры миграции;
  6. Делаем тестовое развертывание на данных клиента;
  7. Доставляем код клиенту для эксплуатации.

Скорость доставки продукта зависит от того, сколько времени займет данный цикл. Его продолжительность определяется тем, сколько времени занимает каждый из шагов, особое влияние оказывают шаги 2-4. Практика показывает, что продолжительность тестирования кода в случае месячного цикла разработки может составлять 1-2 недели для команды размером 10-20 человек, а совместная продолжительность шагов 2-4 легко может занимать 2-3 недели. Причем, сохраняя процесс разработки в долгосрочном периоде, затраты на выполнение этого процесса будут линейно увеличиваться, а у клиента будет складываться впечатление, что команда стала работать медленно. В процессе такого способа доставки происходит наслоение деятельностей, в ходе которого разработчики занимаются как созданием новых функций, так и исправлением ошибок в текущей функциональности, которые были найдены отделом QA в ходе тестирования кода.

Данная проблема может быть решена тем, что специальность “Инженер QA” трансформируется в “Developer in Test”, QA инженеры присоединяются к команде разработки, создают интеграционные и e2e тесты, учат разработчиков писать лучшие тесты, выполняют аудит кода и исправляют найденные ошибки, идентифицируют сценарии, которые требуют ручного тестирования и автоматизируют их, на каждую найденную ошибку создается автоматизированный тест. В чистой форме, роль QA полностью сливается с ролью разработчика, в результает чего возникает новый подход к доставке, который полностью отвечает парадигме “You build it, you run it” (You build it, you test it, you guarantee the quality of it).

Сравните с тем, что было раньше: разработчики не отвечали за качество, они отвечали за разработку (build), QA инженеры отвечали за качество (test), таким образом у разработчиков была модель мышления “баги найдут QA инженеры, а мы их исправим”. Изменение отношения привело к тому, что теперь каждый участник отвечает как за создание программного обеспечения так и за уровень его качества.

Могут существовать и более успешные модели взаимодействия QA и разработчиков, которые позволяют сократить время на доставку, относительно примера выше. Например, внедрение CI/CD с возможностью тестирования каждой функции значительно сокращает стадию тестирования и отдел QA выполняет только регрессионное тестирование за пределами итерации разработки. Однако, сама идея того, что ответственность за качество лежит на QA, а не на разработчиках ведет к тому, что разработчики могут перекладывать ответственность за поиски проблем с качеством на отдел QA, что приводит к снижению темпов разработки за счет повторной проработки задач, в которых были найдены ошибки.

Аналогично, мы можем рассмотреть и взаимоотношения разработки (R&D) и службы эксплуатации (ITSM). Обычный подход заключается в том, что разработчик создает ПО в своей песочнице, а служба эксплуатации отвечает за внедрение, проверку производительности, эксплуатацию, обработку заявок от пользователей. Разработчики, как правило, совершенно не задумываются о том, как их продукт будет работать в реальной среде до тех пор, пока не случилось внедрение в тестовую эксплуатацию, где были найдены множественные проблемы, и продукт отправляется на доработку.

Как и в предыдущем примере, здесь возникает разделение “мы - вы”. Например, “наша СУБД работает хорошо, но ваш код тормозит” или “настройте вашу СУБД так, чтобы наш код мог работать, у меня локально все прекрасно работает”. Это порождает прения и отсутствие консенсуса по поводу ответственности за конечный результат между подразделениями. Практики DevOps созданы, чтобы устранить данную проблему за счет того, что разработчики более глубоко вовлекаются в эксплуатацию и начинают нести ответственность за разработку производственной среды (Infrastructure as a Code, Continuous Configuration Automation). Служба ITSM превращается в партнерскую команду для R&D, и она больше не отвечает за результат того, чтобы переданный продукт волшебным образом заработал в производственной среде. Вместо этого она помогает разработчикам создать правильно работающий в производственной среде продукт.

В качестве примера такой трансформации можно рассмотреть следующий кейс. Представим, что Иван Петров - опытный администратор, а Николай Сидоров - разработчик, который создает ПО, работающее с базой данных. Сидоров не в полной мере обладает опытом анализа производительности СУБД на определенных операциях, и он просит Петрова проконсультировать его в этом вопросе: “Иван, я написал запрос, который использует json-поле MySQL, а он не выдает требуемой производительности на реальных данных. Я бы хотел, чтобы ты помог мне разобраться в этом, чтобы я добавил правильные конфигурационные директивы в сценарий развертывания приложения”.

Это пример изменившихся отношений. Во-первых, Петров больше не отвечает только за эксплуатацию, которая случится после внедрения, а отвечает за решение вполне конкретной проблемы (участвует в разработке), а Сидоров теперь отвечает не только за реализацию, но и за то, чтобы эта реализация работала эффективно на реальных данных. В итоге, Петров начинает понимать как работает часть ПО, которая может быть проблемной на этапе эксплуатации, а Сидоров приобретает знания по администрированию, которые помогут в будущем решать задачи эффективнее.

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

Очень важно, чтобы этот момент прочувствовала вся команда, чтобы от разделения сфер деятельности произошел переход к личной ответственности за конечный результат и взаимопомощи, совместному процессу создания. В идеальном процессе каждый участник начинает полностью управлять всей цепочкой: “разработка - тестирование - документирование - развертывание - работа с пользователями” программного обеспечения. Все в команде начинают развивать дополнительные специализации и воспринимать создаваемый продукт более целостно.

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

Внедрение принципа “You build it, you run it” не может быть осуществлено без внедрения других важных практик, таких как CI/CD, TDD, Integration Testing, Continuous Configuration Automation и IaC, которые позволяют сделать процесс разработки по-настоящему эффективным и экономически выгодным. Помимо Dev & QA, Dev & Ops возможно распространить данный подход и на другие роли, которые есть в команде, например, на технических писателей и службу поддержки клиентов.

PS: Эта трансформация может стать чем-то большим чем задумывается. К примеру, Вы можете пойти еще дальше и превратить QA из функции, которая осуществляет контроль качества продукта, в функцию, осуществляющую контроль качества деятельности сотрудников, команды, компании.

Читайте еще по этой теме:

Если вам понравился этот пост, поделитесь им с друзьями.