FinOps на практике. Серия 2: от пилота к регламентам, или как удержать экономию на облаке

от автора

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

А порядок-то надолго?

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

В инфраструктуре это выглядит так: команда нашла забытые ресурсы, выключила лишнее, показала экономию, получила одобрение бизнеса и выдохнула. Через пару месяцев dev-окружения снова живут круглосуточно, старые диски остаются после удаленных ВМ, снапшоты копятся «на всякий случай», а новые ресурсы создаются без владельца.

Разовая уборка не превращается в порядок сама по себе. Чтобы экономия не расползалась обратно, пилот нужно довести до правил: кто владеет ресурсом, как проверяется временная инфраструктура, какие данные нужны для аллокации, что считается отклонением и кто принимает решение по оптимизации.

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

Эта серия про фазу, которую в FinOps обычно называют Crawl. Мы еще не бежим и даже не идем. Мы учимся собирать данные, связывать ресурсы с владельцами, отличать потенциальную экономию от реализованной и выносить из пилота правила, которые потом можно закрепить в регламентах.

Как мы выбирались из этой стадии, с граблями и находками, я частями разбирал в Telegram-канале «Практики FinOps». Там же часто появляются практики, которые уже прошли этот путь: иногда чужой ответ действительно экономит месяц собственных экспериментов.

Пилот FinOps: почему стартуют с одного провайдера

Когда первые данные уже на руках, появляется соблазн сразу пройтись по всей инфраструктуре. Взять всех провайдеров, все проекты, все окружения, все команды и одним большим рывком навести порядок.

Лучше так не делать.

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

Для пилота лучше выбрать один понятный контур:

  • одного облачного провайдера

  • один крупный бизнес-юнит

  • один набор ресурсов

  • один тип проблемы, например idle resources, dev/test или storage

  • один период, по которому можно быстро проверить результат

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

Что запросили в биллинге

Для пилота не подходит месячная сводка в духе «compute столько-то, storage столько-то». Она полезна для общего понимания, но почти бесполезна для действий.

Нужна выгрузка на уровне ресурсов, максимально похожая на CUR-подобную детализацию. Минимальный набор полей для первого разбора:

  • период потребления

  • сервис или категория сервиса

  • SKU или тарифная единица

  • resource_id или имя ресурса

  • проект, folder, account или другой контейнер

  • регион или зона

  • usage amount

  • cost до и после скидок

  • валюта

  • теги или labels

  • дата создания ресурса, если доступна

  • связанный владелец или команда, если уже есть в данных

Если каких-то полей нет, это тоже результат пилота. Значит, в будущий регламент попадет не только «как оптимизировать», но и «какие данные должны появляться при создании ресурса».

Например, если у ресурса нет owner, environment и project, его невозможно нормально аллоцировать. Можно вручную найти владельца один раз. Но если после этого правило не закрепить, через месяц появятся новые ресурсы с той же проблемой.

Как размечали ресурсы

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

Для каждого ресурса фиксировали:

  • владелец или команда

  • проект или направление

  • окружение: prod, stage, dev, test, sandbox

  • назначение ресурса

  • критичность

  • статус: используется, кандидат на удаление, требует проверки, владелец не найден

  • возможное действие: удалить, выключать по расписанию, уменьшить, перенести, зарезервировать, оставить без изменений

  • срок решения

  • ответственный за подтверждение

Самая полезная категория в такой таблице, это не «дорого». Самая полезная категория, это «непонятно».

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

Первые находки: где обычно лежит быстрый эффект

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

Остановленные ВМ с живыми дисками

Для бизнеса это часто выглядит странно: машина же выключена, почему она продолжает стоить денег?

Но compute и storage биллятся по-разному. Если виртуальная машина остановлена, вычислительная часть может не потребляться, но attached disk, snapshot, образ, публичный IP или балансировщик рядом с ней могут продолжать жить и попадать в счет.

Поэтому в пилоте важно смотреть не только на статус ВМ, а на весь хвост связанных ресурсов. Иначе команда удалит очевидное, но оставит то, что продолжает создавать регулярный расход.

Снапшоты и образы «на всякий случай»

Снапшоты редко выглядят как главная проблема, пока не посмотреть на их возраст, объем и владельцев. В нормальном процессе у снапшота должна быть причина существования: backup policy, миграция, rollback window, требование безопасности или конкретная заявка.

Если причина неизвестна, снапшот превращается в вечную страховку от неизвестного риска. А вечная страховка всегда стоит денег.

Dev/test, который живет как production

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

Здесь не всегда нужно сразу все выключать. Но нужно задать вопрос: действительно ли этому окружению нужен режим 24/7? Если нет, появляются варианты: расписание, автоматическое выключение, уменьшение конфигурации, пересборка окружения по запросу.

Когда ручное выключение превращается в технический гардрейл

В пилоте часто начинают с простого: нашли dev/test-окружение, договорились с владельцем, выключили на ночь. Это уже дает эффект, но само по себе не решает проблему.

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

Например, для Kubernetes-workloads с непостоянной нагрузкой можно использовать событийное или расписанное масштабирование. Очередь пустая, рабочее окно закончилось, трафика нет, значит сервис уходит в минимальное состояние или в scale-to-zero. Когда нагрузка возвращается, workload поднимается обратно.

Подробно эту механику разбирали в отдельной статье: KEDA как финансовый гардрейл: scale-to-zero, лимиты реплик и автоскейлинг по событиям в Kubernetes.

Ниже упрощенный пример ScaledObject для сценария, где внутренний сервис нужен только в рабочее время. В рабочем окне KEDA держит 3 реплики, вне окна workload может уйти в 0.

apiVersion: keda.sh/v1alpha1kind: ScaledObjectmetadata:  name: internal-service-office-hours  namespace: devspec:  scaleTargetRef:    name: internal-service  minReplicaCount: 0  maxReplicaCount: 5  cooldownPeriod: 300  triggers:    - type: cron      metadata:        timezone: Europe/Moscow        start: "50 8 * * 1-5"        end: "0 19 * * 1-5"        desiredReplicas: "3"

FinOps-смысл здесь простой: команда платит не за ожидание, а за обработку нагрузки. Но важно не переобещать. Scale-to-zero не делает нулевым счет за весь кластер: остаются control plane, системные компоненты, ноды, диски, логи и сеть. Зато для конкретного workload это может убрать холостой простой.

Именно поэтому в регламенте важно фиксировать не только «что можно выключить», но и «как это должно выключаться»:

  • по расписанию

  • по событию

  • по метрике

  • с ограничением верхней границы реплик

  • с проверкой SLA

  • с rollback-планом

  • с понятным владельцем настройки

Инстансы «на вырост»

Ресурс когда-то брали с запасом: под будущую нагрузку, миграцию, крупный релиз или неопределенность. Потом проект изменился, нагрузка не пришла, но конфигурация осталась.

Такие случаи нельзя резать автоматически. Сначала нужно проверить фактическую нагрузку, пики, зависимости, SLA и риски. Но именно они часто дают хороший оптимизационный потенциал.

Потенциальная экономия и реализованная экономия, это разные вещи

После первого разбора мы получили цифру порядка миллиона рублей в год оптимизационного потенциала на одном провайдере.

Важно: потенциал, это еще не экономия.

Потенциальная экономия появляется, когда команда видит ресурс и может посчитать, сколько он стоит в текущей конфигурации. Реализованная экономия появляется только после цепочки действий:

  • найден ресурс или группа ресурсов

  • определен владелец

  • подтверждено назначение

  • согласовано действие

  • ресурс удален, уменьшен, переведен на расписание или перенастроен

  • изменение не сломало сервис

  • эффект подтвердился в следующем биллинговом периоде

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

Поэтому в отчете по пилоту мы разделяли:

  • найденный потенциал

  • согласованный потенциал

  • реализованную экономию

  • отложенные действия

  • ресурсы, которые оставили с обоснованием

  • риски, из-за которых действие нельзя выполнить сразу

Для бизнеса это честнее. Для инженерной команды безопаснее.

Как проверять эффект технической оптимизации

Техническая оптимизация должна закрываться не ощущением «стало дешевле», а набором метрик до и после.

Для workload, который перевели на расписание, autoscaling или scale-to-zero, нужно заранее зафиксировать baseline:

  • сколько pod-hours или instance-hours было до изменения

  • сколько стоил workload в месяц

  • сколько часов в сутки ресурс реально обрабатывал нагрузку

  • какая была средняя и пиковая утилизация

  • какие SLA или SLO нельзя нарушить

  • какие ошибки, latency и очереди нужно отслеживать

  • сколько времени занимает scale up

  • есть ли риск cold start для пользователей или внутренних потребителей

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

Поэтому в пилоте мы считаем эффект в двух плоскостях:

  • финансовой: сколько стоило до, сколько стало после, что реально подтвердилось в биллинге

  • инженерной: что произошло с SLA, latency, очередями, ошибками, утилизацией и операционной поддержкой

Результаты пилота: что дали три месяца ручной работы

У нас на пилот ушло примерно три месяца. Да, не быстро. Но почти все делалось руками, а цель была не только сэкономить, но и понять, как этот процесс должен работать дальше.

Деньги оказались не единственным результатом.

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

Во-вторых, появились первые сценарии работы с публичным облаком: что туда выносим, где используем on-demand, где потенциально имеет смысл смотреть в сторону резервирования, какие окружения должны жить постоянно, а какие могут работать по расписанию.

В-третьих, начал собираться общий словарь между финансами и инженерами.

Финансисты лучше понимают, почему кластер, диск, база данных и балансировщик не являются одной строкой «инфраструктура». Инженеры начинают видеть разницу между техническим ресурсом, финансовым учетом, амортизацией, аллокацией и бюджетным планированием.

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

Пример платформенного подхода: когда FinOps растет снизу

Иногда FinOps появляется не как отдельная функция, а как часть платформенной инженерии.

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

Название компании здесь не так важно. Важнее принцип: платформенная команда видит, что ресурсы забронированы, но используются слабо, и начинает задавать вопросы не из финансовой логики, а из инженерной. Зачем держать емкость, которая не работает на продукт?

В таком подходе важны три вещи.

Первая: каждый workload должен быть связан с командой или сервисом. Если нельзя определить владельца, ресурс не должен бесконечно жить в общей зоне.

Вторая: командам нужна видимость потребления. Не обязательно сразу строить chargeback, но showback должен показывать, сколько потребляет команда, как меняется динамика, где requests сильно расходятся с фактом.

Третья: на отклонения кто-то должен реагировать. Если команда запросила много, а использует мало, это не повод автоматически резать ресурс. Но это повод обсудить конфигурацию, профиль нагрузки и возможность оптимизации.

В Kubernetes эта история особенно заметна. Pod может фактически использовать меньше CPU и memory, чем указано в requests. Но завышенные requests занимают емкость кластера и влияют на capacity planning. Поэтому для внутреннего showback можно показывать фактическое потребление, но для управления емкостью нужно смотреть и requests, и limits, и утилизацию node pool.

Главный вывод из такого примера простой: FinOps начинается не с покупки платформы. Он начинается со связи «ресурс → владелец → потребление → решение».

FinOps-созвон: как удержать экономию после пилота

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

Поэтому после пилота нужен ритуал. Не ради календарной дисциплины, а ради повторяемости.

Главный ритуал у нас, ежемесячный расширенный FinOps-созвон. На него приходят инженерные команды и финансы. Вместо общего счета на всех обсуждаются конкретные разрезы:

  • расходы по бизнес-юнитам

  • динамика к прошлому периоду

  • топ отклонений

  • ресурсы без владельца

  • dev/test, который выглядит как production

  • кандидаты на удаление или изменение конфигурации

  • статус решений по прошлому месяцу

  • новые риски и крупные изменения

Такой созвон быстро меняет качество разговора. Пока счет общий, он ничей. Когда команда видит свой кусок инфраструктуры, вопросы появляются сами:

  • почему dev столько стоит

  • нужен ли еще этот балансировщик

  • можно ли выключать окружение ночью

  • почему storage растет быстрее плана

  • кто владелец ресурса без тега

  • что изменилось после релиза

Важно, что созвон не должен превращаться в разнос. Если команда воспринимает FinOps как наказание за расход, процесс не взлетит. Нормальная логика другая: рост затрат не является проблемой сам по себе. Проблема, это рост без объяснения.

Если расходы выросли на 20%, а нагрузка на 25%, возможно, все нормально. Если расходы выросли на 20%, а никто не понимает почему, это уже предмет для разбора.

Ответственный за косты в продуктовой команде

Один из главных результатов регулярных созвонов, появление ответственных за косты внутри продуктовых команд.

Это не отдельный финансист и не человек, который запрещает создавать ресурсы. Скорее технический owner, который держит в голове несколько вопросов:

  • какие ресурсы принадлежат команде

  • какие расходы являются нормальными

  • какие изменения запланированы

  • какие отклонения требуют объяснения

  • какие ресурсы можно пересмотреть

  • какие оптимизации рискованны

  • где нужна помощь инфраструктурной команды

Так ответственность перестает быть абстрактной. Не «инфраструктура стала дорогой», а «вот направление, вот сервисы, вот потребление, вот владелец, вот решение».

Именно это превращает FinOps из разовой уборки в управляемый процесс.

Метрики FinOps: исполнение бюджета, аллокация, утилизация

Пилот нужно закрывать не презентацией «мы молодцы», а отчетом, из которого понятно, что делать дальше.

В финальном отчете мы зафиксировали:

  • базовую стоимость до пилота

  • найденный оптимизационный потенциал

  • реализованную экономию

  • отложенные действия и причины

  • ресурсы без владельцев

  • качество аллокации

  • список правил, которые нужно закрепить

  • метрики для следующего периода

  • roadmap на квартал, полгода и год

Дальше договорились смотреть на три основные группы метрик.

Процент исполнения бюджета

Это про предсказуемость. Планировали одну сумму, потратили примерно столько же, значит, для бизнеса инфраструктура становится управляемой.

Важно не путать это с задачей «потратить ровно бюджет». Хороший результат, это объяснимое отклонение. Плохой результат, это сюрприз в конце месяца.

Процент аллокации

Это про качество данных. Если большая часть затрат уверенно привязана к командам, проектам и направлениям, значит, у процесса есть основа.

Если заметная часть расходов висит в категории «непонятно», это не просто проблема отчета. Это слепая зона управления.

Полезная нагрузка

Это про то, работают ли оплаченные ресурсы или просто занимают емкость.

Но здесь важно не скатиться в примитивное «низкая утилизация, значит режем». CPU, RAM, disk, IOPS, network и latency нужно смотреть вместе. Иногда низкий CPU не означает переразмеренность. Например, размер инстанса может быть связан с дисковой производительностью, профилем нагрузки, maintenance-процессами или требованиями к отказоустойчивости.

Поэтому полезная нагрузка, это не кнопка «уменьшить». Это сигнал для инженерной проверки.

Низкий CPU не всегда означает «уменьшаем»

Отдельно стоит проговорить одну техническую ловушку.

На графике видно, что CPU у группы машин большую часть времени загружен слабо. Первый вывод: можно уменьшить инстансы.

Но у ресурса может быть другая причина текущего размера: дисковая производительность, IOPS, сетевой профиль, maintenance-процессы, резерв под пики или требования к восстановлению.

Если принять решение только по CPU, можно получить красивую экономию в отчете и инцидент в production.

Поэтому в пилоте мы разделяли два вопроса:

  • где есть подозрение на переразмеренность

  • где можно безопасно уменьшать

Первый вопрос решается через FinOps-дашборд. Второй, только через инженерную проверку.

Итоги Crawl: когда пилот превращается в правила

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

Но это еще не зрелый FinOps-процесс.

Пока порядок держится на ручном труде, личной памяти и регулярном внимании одного-двух людей, он остается хрупким. Если ответственный отвлекся на квартал, инфраструктура быстро возвращается к старому состоянию: временные окружения становятся постоянными, теги заполняются по-разному, ресурсы создаются без понятного владельца, а dev/test снова начинает жить как production.

Поэтому главный результат Crawl, не найденная экономия сама по себе. Главный результат, набор правил, которые можно превратить в регламенты.

После пилота у нас начали складываться такие правила:

  • ресурс создается только с владельцем

  • временный ресурс создается с датой пересмотра

  • dev/test не работает 24/7 без обоснования

  • снапшоты и диски старше заданного срока попадают в ревью

  • reserved capacity покупается только под подтвержденный стабильный профиль

  • отклонения от бюджета разбираются с владельцем, а не остаются общей проблемой инфраструктуры

  • потенциальная экономия считается отдельно от реализованной

  • ресурс без понятной аллокации попадает в отдельный список разбора

  • workloads с событийной нагрузкой масштабируются по очереди, расписанию или внешней метрике

  • для autoscaling задается верхняя граница роста

  • scale-to-zero применяется только там, где допустим cold start

  • перед включением технического гардрейла фиксируются baseline, SLA и rollback-план

  • после изменения эффект проверяется по биллингу и техническим метрикам

Так Crawl заканчивается не красивым отчетом и не разовой уборкой, а переходом к управляемому процессу.

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

_______________________________________

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

ссылка на оригинал статьи https://habr.com/ru/articles/1059076/