Grafana-налог $2000 в год: реальная история про стоимость мониторинга на AWS

Grafana-налог $2000 в год: реальная история про стоимость мониторинга на AWS

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


Контекст

Стартап пришёл к нам с типичным запросом: продукт работает, клиенты есть, пора делать всё по-человечески. IaC, безопасность, автоматизация, воспроизводимость.

Стандартный стек: несколько Lambda-функций, пара EC2, RDS, с десяток S3-бакетов, Cognito, DynamoDB, Glue, Amplify, API Gateway. Ничего экзотического.

Мы сделали Terraform, GitHub Actions пайплайны, чистое разделение окружений. Всё развернули в dev, проверили, выглядит хорошо.

Потом дошли до метрик.


“Нам нужна Grafana”

У них были стандартные Lambda-метрики в CloudWatch - invocations, duration, errors, throttles, стандартный набор из документации AWS. Никаких кастомных метрик, ничего необычного.

Мы начали строить CloudWatch-дашборды. Разумный выбор: данные уже там, никакой лишней инфраструктуры, нативная интеграция с AWS.

Потом на созвоне:

«Нам нужна Grafana. Я привык к Grafana, мне там удобнее, давайте сделаем в Grafana.»

Это сказал проджект-менеджер.

Ну… окей. Раз уж это так важно…


Что значит “просто Grafana” на ECS

Дело в том, что запустить Grafana-стек на AWS ECS - это не “просто Grafana”. Нужна вся экосистема.

В итоге получилось:

  • Victoria Metrics - TSDB для хранения метрик, Prometheus-совместимая, отличное сжатие
  • VMAlert - движок алертинга поверх Victoria Metrics
  • Loki - агрегация логов, данные хранятся в S3, индексируются только лейблы
  • Grafana - визуализация, подключается к Victoria Metrics и Loki
  • Blackbox Exporter - probe-мониторинг HTTP/TCP эндпоинтов
  • Yet Another CloudWatch Exporter (YACE) - про него отдельно

Почему YACE, а не нативный CloudWatch datasource?

У Grafana есть встроенный плагин для CloudWatch, но он не подошёл. Нативный плагин делает запросы в CloudWatch при каждом обновлении дашборда - то есть API-затраты и задержки при каждой загрузке панели. И главное - он возвращает метрики в формате CloudWatch, без лейблов, нужных для нормальных Prometheus-стиль дашбордов.

YACE решает это правильно: собирает метрики CloudWatch по расписанию, обогащает нужными лейблами (имя функции, окружение, сервис - что угодно), и пушит всё в Victoria Metrics. Оттуда Grafana запрашивает PromQL, как с любым другим Prometheus-источником. Чисто, быстро, консистентно.

Пайплайн приёма логов

Для логов нужны два отдельных пайплайна:

CloudWatch Logs: Мы прикрепили subscription filter к каждой лог-группе. Это триггерит Lambda при каждом обновлении логов - без поллинга, без API-вызовов по расписанию. Terraform-код не самый элегантный (for_each по каждой лог-группе с Lambda permission и subscription filter на каждую группу), но надёжно и экономично.

CloudTrail: CloudTrail пишет в S3, поэтому мы использовали S3 bucket notifications для триггера отдельной Lambda, которая парсит и шлёт события в Loki.

Обе Lambda распаковывают, парсят, обогащают лейблами и форвардят в Loki. Разделённый подход сохранял чистоту и не заставлял одну Lambda обрабатывать два совершенно разных формата данных и типа триггеров.

Вспомогательная инфраструктура:

  • 3x EFS-тома (дашборды/плагины Grafana, индексы Loki, данные Victoria Metrics)
  • 2x S3-бакета (хранение логов Loki, источник CloudTrail)
  • ECR (кастомные Docker-образы - подробнее ниже)
  • GitHub Actions пайплайны для сборки образов
  • S3 VPC endpoint (трафик Loki в S3 НЕ должен идти через NAT Gateway)
  • Service discovery, SSM Parameter Store для секретов

Проблема ConfigMap в ECS

Kubernetes позволяет монтировать конфиг-файлы как ConfigMaps прямо в контейнеры. В ECS такого понятия нет - поэтому любое изменение конфига означает пересборку и перезапуск.

Любое изменение конфига - datasource Grafana, политика ретеншена Loki, правило VMAlert - требует:

  1. Обновить конфиг
  2. Пересобрать Docker-образ
  3. Запушить в ECR
  4. Обновить task definition в ECS
  5. Передеплоить сервис и ждать, пока задачи перезапустятся

Альтернативы есть. Можно монтировать конфиги через EFS - но чтобы положить файлы на EFS, нужно поднять EC2-инстанс в нужном VPC с правильными security groups и IAM. Работает, но автоматизировать это на удивление сложно, особенно в IaC-first подходе. Мы пробовали вариант с S3-at-startup (entrypoint-скрипт тянет конфиг при старте контейнера), но это добавляет IAM-разрешения и движущихся частей. В итоге конфиги, зашитые в образ, с циклом пересборки оказались наиболее предсказуемым вариантом - пусть и не самым изящным.

Итого времени на сборку, настройку и “чтобы красиво”: примерно месяц инженерной работы.

Хотя красиво получилось.


Бонус: страница статуса

Заодно попросили сделать статус-страницу.

Мы написали Python Lambda, которая каждые 5 минут берёт предрасчитанные метрики из Victoria Metrics, генерирует HTML-страницу и загружает её в S3 за CloudFront. Просто, надёжно, стоит почти ничего - при условии, что Victoria Metrics уже работает.

Это последнее условие станет важным позже.


Шесть месяцев спустя

PM, которому “нужна была Grafana”, ушёл из проекта.

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

Решение было очевидным: мигрировать обратно на CloudWatch-дашборды.

А та Lambda статус-страницы, которая тянула данные из Victoria Metrics? Поскольку Victoria Metrics уходила, её тоже надо было переписать - под CloudWatch. Ещё одна вещь для миграции, следствие плотной связности.

В итоге статус-страницу заменили бесплатным внешним сервисом. Проще.

Чисто. Готово. $2k в год сэкономлено.


Но это провал?

Вот где история становится интереснее, чем просто “дорогая ошибка, урок извлечён”.

Это не был провал.

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

Исправили. Быстрее Lambda - дешевле Lambda. Улучшения производительности почти наверняка отбили больше $2 000 в год на compute-затратах.

Но - и это главное - те же самые выводы были доступны в CloudWatch всё это время.

Узкие места не требовали Grafana для обнаружения. Они требовали смотреть, а смотреть начали, потому что появились дашборды. CloudWatch-дашборды дали бы тот же импульс к расследованию.


Реальное сравнение стоимостей

Давайте поставим реальные цифры для похожего стека: 50 Lambda-функций, 2 EC2, 1 RDS, 10 S3-бакетов, 1 EFS. Регион: us-east-1.

CloudWatch: ~$35–40 в месяц

  • Lambda-метрики (стандартные): $0 (бесплатно)
  • EC2 detailed monitoring: ~$5
  • RDS + S3 метрики: ~$3
  • Lambda-логи (~20 ГБ/мес): ~$8
  • EC2 + RDS логи (~10 ГБ/мес): ~$3
  • CloudTrail ingestion: ~$2
  • Алерты (40 alarms): ~$4
  • Дашборды (2 дополнительных): ~$6
  • Хранение/архив логов: ~$1

Grafana на ECS: ~$105–145 в месяц

  • Lambda-метрики: $0 (через YACE)
  • EC2 + RDS + S3 метрики: $0
  • Lambda-логи (~20 ГБ/мес): ~$1 (S3 через Loki)
  • EC2 + RDS логи (~10 ГБ/мес): ~$0.3 (S3)
  • CloudTrail ingestion: ~$1 (Lambda + S3)
  • Алерты: $0 (VMAlert)
  • Дашборды: $0
  • Хранение/архив логов: ~$0.7 (S3)
  • Инфраструктура ECS: ~$80–120
  • EFS-тома: ~$15
  • ECR-хранилище: ~$2
  • API-вызовы YACE в CloudWatch: ~$1

Grafana Cloud: ~$31–35 в месяц

  • Lambda-метрики (стандартные): $0 (включено)
  • EC2 + RDS + S3 метрики: $0
  • Lambda-логи (~20 ГБ/мес): ~$6
  • EC2 + RDS логи (~10 ГБ/мес): $0 (в бесплатном тире)
  • CloudTrail ingestion: ~$2 (Lambda + S3)
  • Алерты: $0 (Grafana Alerting)
  • Дашборды: $0
  • Хранение логов: включено
  • Pro-план: $19/мес
  • YACE / CloudWatch plugin: ~$1–5

Несколько важных нюансов:

Затраты на CloudWatch обманчиво переменчивы. Оценка $35–40 предполагает, что вы не используете кастомные метрики активно. Включите Container Insights на ECS - и получите ~150 кастомных метрик на кластер, это $45/мес, добавленных незаметно. Используете Lambda EMF в масштабе - легко получить тысячи кастомных метрик до того, как осознаете. По $0.30/метрика/мес это накапливается быстро.

Grafana на ECS имеет фиксированный нижний порог стоимости, который не растёт с объёмом данных. Если вы генерируете 400+ кастомных метрик, математика переворачивается - $120/мес только на кастомные метрики CloudWatch против той же инфраструктурной стоимости ECS вне зависимости от количества метрик.

Grafana Cloud выигрывает по цене для этого масштаба - но стоимость растёт линейно, как только превысите 10k активных серий или 50 ГБ логов/мес. Для стартапа такого размера это, вероятно, наиболее экономичный управляемый вариант.

Data transfer в основном не проблема, если планировать заранее. У S3 есть бесплатный Gateway VPC Endpoint. С ним трафик Loki в S3 не стоит ничего дополнительно. YACE обращается к CloudWatch API через NAT Gateway (у CloudWatch нет Gateway Endpoint), но фактический объём данных небольшой - если NAT Gateway уже существует по другим причинам, это фактически бесплатно.


“Я хочу X” - и что с этим делать

В инфраструктурном консалтинге часто слышишь: “нам нужна Grafana”, “надо переходить на Kubernetes”, “давайте всё разобьём на микросервисы”.

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

Работа не в том, чтобы говорить нет. Работа в том, чтобы спросить:

Какую проблему мы на самом деле решаем? В данном случае: видимость производительности приложения. И CloudWatch, и Grafana решают это. Разница - в стоимости, времени настройки и операционной сложности.

Кто владеет этим долгосрочно? Система, построенная вокруг предпочтений одного человека - это риск, когда этот человек уходит. Это не критика кого-либо - просто реальный фактор в совокупной стоимости владения, который редко попадает в архитектурное обсуждение.

Какой самый простой путь к результату? Иногда скучное решение - правильное решение. Иногда заплатить больше за что-то лучшее абсолютно оправдано - лучший UX ведёт к лучшим привычкам наблюдаемости, что ведёт к реальным улучшениям производительности. Хитрость в том, чтобы знать, какая ситуация до того, как провести месяц за созданием.

В данном случае Grafana-стек не был неправильным. Он принёс реальную ценность. Просто был оптимизирован под неправильное ограничение.


Скрытые затраты

$2 000 в год на инфраструктуру были видны в AWS-счёте. Что не было видно:

  • Месяц инженерного времени на создание изначального стека
  • Постоянное обслуживание: изменения конфигов требовали пересборки образов и передеплоя
  • Lambda статус-страницы, которую пришлось переписывать при уходе Victoria Metrics - тесная связность, которая не была очевидна до момента миграции
  • Институциональные знания, которые ушли вместе с PM и инженером, который это строил

Ни одно из этого не отображается строчкой. Все они - реальные затраты.


Перед следующим инфраструктурным решением

Самые дорогие инфраструктурные ошибки, которые я вижу - не очевидные. Не случайно оставленный большой EC2-инстанс, не забытые lifecycle-политики S3, не включённый Container Insights в CloudWatch, который неожиданно генерирует сотни кастомных метрик.

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

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

Иногда находишь Grafana-налог $2 000 в год.

Иногда находишь что-то значительно дороже.


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