Управление расходами: бюджеты, алерты аномалий и неожиданный счёт
Счёт AWS приходит через месяц после трат, поэтому сбежавший ресурс тихо жжёт деньги неделями. Управление бьёт оптимизацию: Budgets и Anomaly Detection превращают задержку в сигнал того же дня, теги аллокации дают владельца, а SCP-ограждения гасят траты до их начала.
Третьего числа финансы пересылают счёт, который на сорок тысяч долларов выше плана. Никто не узнаёт эту строку. Ты копаешь: три недели назад ML-инженер поднял парк GPU-инстансов для «быстрого эксперимента», эксперимент закончился, а парк — нет. Он работал круглосуточно в забытом аккаунте, жёг тысячи в день, и так девятнадцать дней — пока счёт не сделал это видимым. Бага не было. Инстансы делали ровно то, что им сказали. Сбой структурный: AWS выставляет счёт постфактум, поэтому единственным местом, где этим тратам вообще суждено было проявиться, был счёт, приходящий через месяц после того, как счётчик закрутился. Уменьшить парк сейчас не сэкономит ничего — деньги уже потеряны. Следующий неожиданный счёт получит та команда, у которой всё ещё нет ни алерта бюджета, ни монитора аномалий, ни тега, который назвал бы владельца в первый же день.
После урока ты сможешь поднять контроли, которые поймали бы GPU-парк из Hook за сутки, — и объяснить, почему одна только оптимизация на это не способна.
Неожиданный счёт: месячная слепая зона, а не ошибка биллинга
Самое дорогое свойство биллинга AWS — его задержка. Тебя тарифицируют непрерывно, но счёт месячный и приходит постфактум — поэтому петля обратной связи между «ресурс начал стоить денег» и «человек видит это в счёте» растягивается до 30+ дней. Cost Explorer обновляется чаще счёта, но пока никто активно не смотрит, ничто не подталкивает сигнал к тебе. Этот разрыв и есть вся проблема. Забытое dev-окружение, рекурсивная Lambda, вызывающая саму себя, межаккаунтная петля egress-трафика, утёкший access-ключ, поднимающий инстансы для майнинга, или простаивающий GPU-парк из Hook — у всех одна форма: устойчивое прожигание, которое никто не атрибутировал, идущее неделями, прежде чем число станет видимым.
Математика жестока, потому что облачные траты — это скорость, а не разовый платёж. Один неправильно подобранный ресурс по $2000/день — это $60 000 к тому моменту, как месячный счёт его обнажит. Утёкший ключ, запускающий крупнейшие GPU-инстансы в каждом регионе, способен выбить пятизначную сумму за день. Оптимизация — рычаги из урока 01, Savings Plans, rightsizing и гигиена egress — здесь неверный инструмент, потому что оптимизация ретроспективна: она снижает стоимость того, что ты уже знаешь, что запускаешь. Она ничего не делает с тем, о чём ты не знаешь, что оно запущено. Лекарство от неожиданного счёта — это не более дешёвый ресурс; это более короткая петля обратной связи плюс ограждения, блокирующие траты до того, как они случатся. Всё ниже — одно из этих двух.
▸Почему это работает
Почему задержка счёта в облаке бьёт намного сильнее, чем в дата-центре? В колокации ты купил железо один раз; забытый сервер тратит уже вложенный капитал, но маргинальная стоимость оставить его включённым — это лишь электричество. В облаке каждая работающая секунда — это свежий платёж против счёта следующего месяца, и ты можешь зарезервировать почти неограниченную ёмкость за секунды одним вызовом API — поэтому радиус поражения от «забыл выключить» масштабируется с тем, сколько ты мог запустить, а не сколько собирался. Задержка превращает маленькую ошибку (забытый запуск) в большую (забытый запуск, помноженный на 30 дней, помноженный на тот размер инстанса, что API охотно выдал). Скорость провижининга — это фича; запаздывающий счёт — это неучтённый риск, который едет вместе с ней.
Budgets и Anomaly Detection: сжать 30 дней в один
Первая задача управления — сделать траты видимыми в день их начала, а не в день выставления счёта. Это делают два сервиса.
AWS Budgets позволяет задать бюджет по стоимости, использованию, покрытию RI/Savings Plans или утилизации и слать алерты, когда фактические или прогнозные траты пересекают порог — стандартный паттерн: сигналы на 80% (предупреждение), 100% (превышение) и алерт прогноза-к-превышению, предупреждающий в середине месяца, что тренд пробьёт лимит, хотя ты до него ещё не дошёл. Именно прогнозный алерт выигрывает больше всего времени. Критично, что бюджет может нести и budget action: при срабатывании порога AWS автоматически применяет IAM-политику, SCP или целевое действие (остановить EC2/RDS) — превращая бюджет из пассивного уведомления в проведённый в жизнь потолок.
{
"Budget": {
"BudgetName": "team-payments-monthly",
"BudgetType": "COST",
"TimeUnit": "MONTHLY",
"BudgetLimit": { "Amount": "8000", "Unit": "USD" },
"CostFilters": { "TagKeyValue": ["user:team$payments"] }
},
"NotificationsWithSubscribers": [
{
"Notification": { "NotificationType": "FORECASTED", "ComparisonOperator": "GREATER_THAN", "Threshold": 100 },
"Subscribers": [{ "SubscriptionType": "SNS", "Address": "arn:aws:sns:us-east-1:111122223333:cost-alerts" }]
}
]
}Budgets отвечают на порог, который ты задал. AWS Cost Anomaly Detection отвечает на траты, которые ты не предсказал: он строит ML-базовую линию нормальных трат по сервису, по аккаунту или по измерению тега аллокации и алертит, когда дневные траты сервиса резко отклоняются от этой линии — ловя рекурсивную Lambda или новый GPU-парк примерно в течение суток после всплеска, без порога, который нужно поддерживать. Используй оба: Budgets проводят в жизнь известные лимиты; anomaly detection ловит неизвестные неизвестные. Острый компромисс — гранулярность. Один бюджет на весь аккаунт, срабатывающий на «ты потратил слишком много в этом месяце», не говорит ничего действенного — ни сервиса, ни команды, ни владельца. Чтобы быть полезными, бюджеты и мониторы аномалий должны быть нарезаны по команде или сервису, что возможно только если твои траты атрибутированы — а это следующий раздел.
Аллокация и подотчётность: нельзя управлять тем, что нельзя атрибутировать
Алерт «траты выросли на $40k» бесполезен, если никто не может ответить «чьи это $40k?». Атрибуция — несущая предпосылка для любого другого контроля управления. Её строят три механизма. Теги аллокации стоимости (team, env, service, cost-center) дают нарезать счёт по тому, кто чем владеет, в Cost Explorer. Консолидированный биллинг AWS Organizations сворачивает множество аккаунтов-участников в один платёжный, сохраняя разбивку по аккаунтам — поэтому аккаунт каждой команды и есть измерение стоимости. Вместе они дают showback (видимость трат — каждая команда видит свои расходы в отчёте) и, на шаг дальше, chargeback (обратный биллинг — траты каждой команды списываются в её собственную книгу, так что они попадают в её бюджет, а не в общий котёл).
Слепая зона — нетегированные ресурсы: они падают в неатрибутируемую корзину и тихо размывают покрытие аллокации, пока «прочее» не станет самой большой строкой счёта. Лекарство — проводить в жизнь тегирование, а не просить о нём: tag policy в Organizations задаёт обязательные ключи и допустимые значения, а SCP может прямо запретить создание ресурса при отсутствии обязательного тега, так что аллокация остаётся близкой к 100%, потому что нетегированный ресурс не может существовать. Компромисс между showback и chargeback — культурный, не технический: chargeback даёт самую жёсткую подотчётность (реальные деньги в бюджете каждой команды), но добавляет финансовый процесс и трение; showback легче и политически проще, но полагается на то, что команды решат действовать по увиденному.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyRunInstancesWithoutTeamTag",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": { "Null": { "aws:RequestTag/team": "true" } }
}]
}Превентивные ограждения и гигиена обязательств: гаси траты до начала
Самый быстрый сигнал всё равно отстаёт от трат на сутки. Самый дешёвый доллар — тот, что никогда не был списан, поэтому верхний слой управления превентивен: общеорганизационные Service Control Policies, блокирующие дорогое до того, как оно сможет запуститься. SCP может запретить запуск негабаритных или GPU-семейств инстансов вне одобренного allow-листа, запретить работу в неиспользуемых регионах (сжимая радиус поражения утёкшего ключа до нуля в этих регионах) и запретить создание публичных S3-бакетов или публичных AMI. Ограждение строго лучше алерта для известно-плохих паттернов: алерт говорит, что GPU-парк жжёт деньги; SCP означает, что его вообще не дали запустить.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyExpensiveAndGpuInstanceTypes",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"ForAnyValue:StringLike": { "ec2:InstanceType": ["p4d.*", "p5.*", "x2*", "u-*"] }
}
}]
}Вторая половина гигиены — постоянный обзор обязательств, введённых уроком 01. Урок 01 учил, какой вариант покупки брать; управление — это рутина, которая держит эти покупки зарабатывающими свою скидку, отслеживаемая через две различные метрики. Покрытие (coverage) спрашивает «какая доля приемлемого использования покрыта обязательством?» — низкое покрытие значит, что ты платишь On-Demand за постоянную базу, которую мог бы закоммитить (переплата). Утилизация (utilization) спрашивает «какую долю того, что я закоммитил, я реально использую?» — низкая утилизация значит, что ты купил ёмкость, которую не потребляешь (потери). Классический режим отказа — купить 3-летний Savings Plan или RI, а затем сменить архитектуру — уйти с того семейства инстансов, переехать на Fargate или урезать парк — и каждый месяц платить за закоммиченную ёмкость, уже не соответствующую реальности. Отчёты Compute Optimizer и покрытия/утилизации в Cost Explorer превращают это в месячный ритм: и недопокрытие, и недоутилизация — оба триггеры обзора, и ни один не виден, пока кто-то не владеет этой проверкой.
Organization из 60 аккаунтов раз за разом получает неожиданные счета спустя недели после старта сбежавшего ресурса — в прошлом месяце забытый GPU-парк, в этом рекурсивная Lambda. Тебе нужен максимально ранний сигнал на следующий случай, нарезанный достаточно, чтобы назвать владельца. Выбери основной контроль, который поднимешь первым.
Утёкший access-ключ запускает крупные GPU-инстансы. У команды один общеаккаунтный месячный бюджет стоимости, выставленный на 100% от прошлого месяца. Когда сбежавший ресурс наиболее правдоподобно станет видимым и что поймало бы его раньше?
- 01Почему сбежавший ресурс AWS жжёт деньги неделями, прежде чем кто-то заметит, и какие два вида контроля это чинят?
- 02Пройди, как аллокация, подотчётность и превентивные ограждения складываются вместе в управлении расходами.
AWS выставляет счёт постфактум, поэтому самое дорогое свойство счёта — его задержка: тебя тарифицируют каждую секунду, но счёт месячный и приходит после факта, оставляя слепую зону в 30+ дней, в которой забытый GPU-парк, рекурсивная Lambda, egress-петля или утёкший ключ для майнинга жгут с устойчивой скоростью — ресурс по $2000/день — это $60 000 ко времени, как кто-то это увидит. Оптимизация не поможет, потому что лишь снижает стоимость того, что ты уже знаешь, что запускаешь; неожиданному счёту нужны более короткая петля и ограждения. Теперь, когда заводишь новый аккаунт или проект, ещё до первой строки кода спроси себя: есть ли бюджет с прогнозным алертом и несёт ли каждый ресурс тег с владельцем? Сократи петлю через AWS Budgets (бюджеты по стоимости, использованию, покрытию или утилизации с алертами на 80%, 100% и прогноз-к-превышению, опционально с budget action, авто-применяющим IAM/SCP-ограничение или останавливающим ресурс) и AWS Cost Anomaly Detection (ML-линии по сервису, аккаунту или тегу, помечающие всплеск примерно за сутки без порога для поддержки) — Budgets проводят известные лимиты, anomaly detection ловит неизвестные неизвестные, и оба должны быть нарезаны по команде/сервису через теги, чтобы быть действенными, а не просто «потратил слишком много». Сделай их действенными, атрибутировав траты первым делом: теги аллокации плюс консолидированный биллинг Organizations дают showback и chargeback, нетегированные ресурсы — слепая зона, а tag policy плюс SCP, запрещающий создание-без-тегов, держат аллокацию близкой к 100%. Затем предотврати худшие траты напрямую SCP, блокирующими дорогие и GPU-семейства инстансов, неиспользуемые регионы и публичные ресурсы по всей организации, и держи обязательства зарабатывающими скидку через постоянный обзор покрытия (низкое = переплата) и утилизации (низкая = потери) — потому что купить 3-летнее обязательство и потом сменить архитектуру, или жить вовсе без бюджета и монитора аномалий, — ровно так неожиданный счёт и возвращается.
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.