Акаунти, ієрархія ресурсів і рахунок
Навіщо це
Section titled “Навіщо це”У 2020 році засновник стартапу Milkie Way виставив у Google Cloud бюджет $7 для тесту, а за кілька годин отримав рахунок близько $72 000. Бюджет не зупинив нічого: він лише надсилає листи. Цей модуль стоїть у курсі другим, щоб ви прочитали його до першого створеного ресурсу, а не після першого рахунку.
Тут ми з’ясуємо, де проходять межі доступу й білінгу, як поставити бюджет і чому він усе одно не вимикач, чим небезпечні безкоштовні рівні і як виникають рахунки на тисячі доларів.
Передумови. Модуль 1: моделі обслуговування й спільна відповідальність. Доступи й ролі докладно розібрано в модулі 3; тут ми лише позначаємо, де вони живуть.
Акаунт як межа
Section titled “Акаунт як межа”Кожен ресурс у хмарі належить контейнеру верхнього рівня, і той є одночасно межею ресурсів, доступу, квот і білінгу: витрати збираються по ньому, а ліміти рахуються на нього.
У кожного з провайдерів контейнер називається по-різному:
- в AWS це акаунт (account), який створюють на унікальну адресу пошти;
- в Azure це підписка (subscription);
- в GCP це проєкт (project).
Одного контейнера на все замало з двох причин. Перша: радіус ураження (blast radius): ключ, викрадений у тестовому акаунті, не дає доступу до продакшену. Друга: облік: витрати на розробку й продакшен у різних контейнерах видно без тегів. Звідси стандартна практика: окремий контейнер на середовище, а часто й на команду чи застосунок.
Ієрархія ресурсів
Section titled “Ієрархія ресурсів”Кілька десятків контейнерів потребують структури, на яку можна повісити спільні правила. Усі три провайдери будують її як дерево з успадкуванням: правило, задане вгорі, діє на все, що нижче.
AWS. Дерево будує сервіс AWS Organizations. У його корені стоїть організація з єдиним root, а керує нею керівний акаунт (management account). Під root лежать організаційні одиниці (OU), до п’яти рівнів углиб, а в них акаунти. На OU й акаунти накладають політики керування сервісами (SCP): вони задають стелю дозволів, яку не перевищить навіть адміністратор акаунта. За замовчуванням в організації можна мати 10 акаунтів, ліміт піднімається через Service Quotas до 50 000.
Azure. Тут дві незалежні структури. Тенант (tenant) є окремим каталогом Microsoft Entra ID, у якому лежать користувачі й групи. Ресурси лежать у дереві груп керування (management groups): до шести рівнів, кожна підписка й група мають рівно одного батька. Найвищою є коренева група Tenant root group, у яку за замовчуванням потрапляють нові підписки. Підписка є контейнером ресурсів і білінгу, а всередині неї є група ресурсів (resource group), у яку кладуть ресурси одного життєвого циклу. Видалення групи видаляє все, що в ній лежить.
GCP. Організація (organization) є коренем, під нею папки (folders), у папках проєкти. Проєкт має три ідентифікатори: ім’я, що змінюється, ID, який ви обираєте один раз, і номер, який призначає система. Політики й ролі успадковуються вниз. Без організації проєкти можуть існувати лише в користувачів безкоштовної програми Google Cloud, а для частини функцій керування організація потрібна.
Одна політика на вершині діє на сотню контейнерів, але й помилка там зачепить усе, тому на корені Azure чи GCP доступ і політики лишають мінімальними.
Рахунок живе окремо
Section titled “Рахунок живе окремо”Рахунок (billing) формується не там, де лежать ресурси, і в різних провайдерів зв’язок між ними влаштований по-різному.
| AWS | Azure | GCP | |
|---|---|---|---|
| Хто платить | management-акаунт організації (об’єднаний рахунок, consolidated billing) | білінг-акаунт, до якого прив’язана підписка | окремий Cloud Billing account |
| Зв’язок із ресурсами | акаунт входить в організацію | підписка належить білінгу | проєкт посилається на білінг-акаунт |
У GCP Cloud Billing account є окремою сутністю, і проєкт можна перепідключити до іншого. Це зручно для поділу рахунків між замовниками, але витрати проєкту відв’язуються від його дерева доступу.
Бюджети й алерти до першого ресурсу
Section titled “Бюджети й алерти до першого ресурсу”Бюджет (budget) задає суму за період і поріг, при якому надсилається сповіщення. Він не зупиняє ресурсів. Так влаштовано в усіх трьох:
- AWS Budgets оновлюється до трьох разів на добу з інтервалом 8–12 годин, і документація прямо попереджає, що між витратою й сповіщенням є затримка, а витрати можуть перевищити поріг раніше, ніж прийде лист. Опціональні дії бюджету можуть застосувати політику IAM чи SCP або зупинити конкретні інстанси EC2 і RDS у власному акаунті.
- Azure Cost Management отримує дані за 8–24 години і перевіряє бюджет раз на добу, а лист надсилається зазвичай протягом години після перевірки. Один бюджет має до п’яти порогів і п’яти адрес; є сповіщення і про прогноз витрат. Ресурси при цьому не зачіпаються, споживання не зупиняється. Дії через групу дій (action group) працюють лише на рівні підписки чи групи ресурсів, а в щойно створеній підписці бюджети можуть з’явитися не одразу: документація радить очікувати до 48 годин.
- GCP Budgets створює порогові правила за замовчуванням на 50 %, 90 % і 100 %, і документація каже, що бюджет лише з алертами не обмежує використання й витрат. Для автоматичної реакції сповіщення можна надіслати в Pub/Sub і запустити код.
Сама реакція має жорсткіший вигляд, ніж здається. Приклад Google з «вимиканням» білінгу проєкту через Pub/Sub попереджає: усі ресурси проєкту зупиняються, можуть бути безповоротно видалені, а через затримку витрати між сповіщенням і зупинкою все одно накопичаться. Тому Google радить ставити бюджет із запасом нижче за реальну стелю, наприклад $85–90 при реальному ліміті $100.
Окремий інструмент AWS: Cost Anomaly Detection використовує моделі машинного навчання й шукає незвичні витрати за сервісом, акаунтом, регіоном чи типом використання. Він оновлюється приблизно три рази на добу, а виявлення може відстати до 24 годин, бо працює на даних Cost Explorer.
Бюджет працює як сигналізація, а обмежувач доводиться будувати самому. Мінімум для нового акаунта: невелика сума, два пороги (наприклад 80 % реальних витрат і 100 % прогнозованих) і лист на адресу, яку ви справді читаєте.
У Terraform кожен блок нижче створює бюджет на $20 на місяць з двома сповіщеннями.
variable "alert_email" { type = string}
resource "aws_budgets_budget" "monthly" { name = "monthly-total" budget_type = "COST" limit_amount = "20" limit_unit = "USD" time_unit = "MONTHLY"
notification { comparison_operator = "GREATER_THAN" threshold = 80 threshold_type = "PERCENTAGE" notification_type = "ACTUAL" subscriber_email_addresses = [var.alert_email] }
notification { comparison_operator = "GREATER_THAN" threshold = 100 threshold_type = "PERCENTAGE" notification_type = "FORECASTED" subscriber_email_addresses = [var.alert_email] }}variable "alert_email" { type = string}
data "azurerm_subscription" "current" {}
resource "azurerm_consumption_budget_subscription" "monthly" { name = "monthly-total" subscription_id = data.azurerm_subscription.current.id amount = 20 time_grain = "Monthly"
time_period { start_date = "2026-10-01T00:00:00Z" }
notification { enabled = true threshold = 80 operator = "GreaterThan" threshold_type = "Actual" contact_emails = [var.alert_email] }
notification { enabled = true threshold = 100 operator = "GreaterThan" threshold_type = "Forecasted" contact_emails = [var.alert_email] }}variable "alert_email" { type = string}
variable "billing_account" { type = string}
variable "project_number" { type = string}
resource "google_monitoring_notification_channel" "email" { display_name = "Budget alerts" type = "email"
labels = { email_address = var.alert_email }}
resource "google_billing_budget" "monthly" { billing_account = var.billing_account display_name = "monthly-total"
budget_filter { projects = ["projects/${var.project_number}"] }
amount { specified_amount { currency_code = "USD" units = "20" } }
threshold_rules { threshold_percent = 0.8 }
threshold_rules { threshold_percent = 1.0 spend_basis = "FORECASTED_SPEND" }
all_updates_rule { monitoring_notification_channels = [google_monitoring_notification_channel.email.id] disable_default_iam_recipients = true }}В AWS бюджет належить акаунту, в Azure підписці, а в GCP білінг-акаунту з фільтром за проєктами, і потрібен ще окремий канал сповіщень.
Теги й мітки
Section titled “Теги й мітки”Бюджет на весь акаунт каже, що гроші витрачаються. Щоб побачити хто, потрібні
теги: пари ключ і значення на ресурсах, за якими рахунок можна розрізати. Ключі
типу env, owner, team і project достатні для початку.
- AWS. Тег на ресурсі ще не є тегом для рахунку. Його треба активувати як cost allocation tag у консолі білінгу, і тільки management-акаунт організації має до цього доступ; до появи в Cost Explorer може пройти до 24 годин.
- Azure. Ресурси не успадковують тегів групи ресурсів чи підписки, тож для успадкування використовують Azure Policy. Теги ставляться на ресурси, групи ресурсів і підписки, але не на групи керування. Ключ регістронезалежний, значення регістрозалежне.
- GCP. Тег тут називається міткою (label). В ієрархії мітки підтримують лише проєкти, а не папки чи організацію, і мітка проєкту не поширюється на ресурси автоматично. Мітки потрапляють в експорт білінгу.
Секретів у тегах не тримають: AWS і Azure прямо попереджають, що вони потрапляють у звіти й журнали.
Безкоштовні рівні і їхні пастки
Section titled “Безкоштовні рівні і їхні пастки”Умови акцій найшвидше застарівають у курсі, тож ось стан на вересень 2026 року.
| AWS Free plan | Azure Free account | Azure for Students | GCP Free Trial | |
|---|---|---|---|---|
| Кредити | $100 при реєстрації і до $100 додатково за виконання завдань | $200 | $100 | $300 |
| Строк | 6 місяців або до вичерпання кредитів | 30 днів | 12 місяців | 90 днів |
| Що після строку | акаунт закривається; 90 днів дані зберігаються, далі видалення | рішення: перейти на pay-as-you-go чи ні; без переходу рахунок і сервіси вимикаються | сповіщення; перехід на платний або вимкнення підписки | 30 днів пільгового періоду, потім ресурси видаляються |
| Захист від витрат | без переходу на Paid рахунків немає | витрати обмежено кредитом | картки немає, списувати нема з чого | до переходу на платний акаунт рахунків немає |
Azure Free account вимагає перевірки телефоном і карткою, Azure for Students картки не вимагає. Головні пастки такі.
Тихий перехід на платний план. AWS Free plan автоматично стає Paid, якщо ви вступаєте в AWS Organizations, налаштовуєте Control Tower, приєднуєтеся до партнерської програми чи позначаєте акаунт як HIPAA або SEC. Тобто структура з цього модуля, з кількома акаунтами, сама переводить безкоштовний акаунт на платний. Free plan також не дає доступу до сервісів, які швидко вичерпують кредити (Savings Plans, Reserved Instances, частина пропозицій Marketplace).
Що відбувається після строку. AWS закриває акаунт (дані зберігаються 90 днів), Azure вимикає підписку, поки ви не оберете pay-as-you-go, GCP дає 30 днів пільгового періоду і видаляє ресурси. Небезпека виникає, коли ви переходите на платний план, щоб «врятувати» роботу: усе, що працює, з цього моменту оплачується за звичайним тарифом.
Обмеження пробного режиму. Пробний GCP не дає додавати GPU, користуватися Marketplace, підвищувати квоти й створювати ВМ із Windows Server.
Безкоштовне на 12 місяців. В Azure 20+ сервісів безкоштовні перші 12 місяців, потім виставляють рахунок, а 65+ «завжди безкоштовних» лишаються. В AWS понад 30 сервісів безкоштовні в межах місячних лімітів на будь-якому плані.
Для студента найпростіший варіант Azure for Students: кредит $100 без картки, відновлюється щороку, поки триває статус студента.
Розбір: рахунки, яких ніхто не чекав
Section titled “Розбір: рахунки, яких ніхто не чекав”Три випадки з першоджерелами. Їх поєднує те, що ніхто не збирався витрачати такі суми, а бюджет або не допоміг, або його не було.
$72 000 за кілька годин (Google Cloud, 2020)
Section titled “$72 000 за кілька годин (Google Cloud, 2020)”Стартап Milkie Way тестував скрапер на Firebase і Cloud Run і виставив бюджет $7. Помилка в коді створила нескінченну рекурсію: сторінки посилалися одна на одну. За даними The Register, набігло понад 116 мільярдів читань Firestore, 33 мільйони записів і 16 000 годин процесорного часу Cloud Run.
Механізм складається з кількох частин. Безкоштовний план Firebase автоматично перейшов на платний, коли активність зросла, і лист про це прийшов, коли власник спав. Cloud Run за замовчуванням дозволяє до 1 000 інстансів із 80 одночасними запитами, тож платформа охоче масштабувала витрати. Бюджет нічого не зупиняє, а білінгові дані приходять із затримкою близько доби. Google списав рахунок як одноразовий жест, але видання зауважило, що на це не можна розраховувати.
$1 300 за порожній бакет (AWS, 2024)
Section titled “$1 300 за порожній бакет (AWS, 2024)”Розробник Maciej Pocwierz створив приватний порожній бакет S3 і за два дні побачив рахунок понад $1 300: за його описом, консоль показувала майже 100 мільйонів запитів PUT за добу. Причиною стало типове налаштування популярного відкритого засобу резервного копіювання: назва бакета в прикладі конфігурації збіглася з назвою його бакета, і кожна інсталяція з типовими значеннями слала запити саме туди. Запити відхилялися, але оплачувалися як запити запису, за $0,005 за 1 000.
Спочатку Jeff Barr написав, що клієнти не мають платити за неавторизовані запити, яких вони не ініціювали. А 13 травня 2024 року AWS оголосила, що S3 перестає нараховувати плату за відповіді HTTP 403 (Access Denied) від запитувачів поза акаунтом чи організацією, і застосувала зміну ретроспективно (The Register). Урок для вас: назва ресурсу теж може бути вектором, а платити можна за запити, яких ви не робили.
$82 314 за 48 годин (Gemini API, 2026)
Section titled “$82 314 за 48 годин (Gemini API, 2026)”У лютому 2026 року в команди з трьох розробників із Мексики вкрали ключ Google Cloud API з доступом до Gemini. За 48 годин (11–12 лютого) набігло $82 314,44 замість звичайних близько $180 на місяць, переважно за моделі Gemini 3 Pro. За звітом The Register, представник Google послався на модель спільної відповідальності й дав зрозуміти, що рахунок доведеться сплатити. Про результат спору публікації не повідомляють. За повідомленнями інших видань, алерти в команди були, але надійшли, коли основні витрати вже сталися.
Що спільного
Section titled “Що спільного”- Стелі немає. Жодна квота чи бюджет не зупинили витрат вчасно.
- Затримка. Алерти приходять, коли основна частина рахунку вже набігла.
- Автоматика підсилює помилку. Автомасштабування, відкриті запити чи ключ із широкими правами перетворюють одну помилку на тисячі викликів.
- Пільг не можна очікувати. Google списав рахунок у 2020 році, AWS змінила правила у 2024, а в 2026 позиція Google була інша.
Що зробити до першого ресурсу:
-
Створіть бюджет. Мала сума, два пороги, справжня пошта.
-
Обмежте масштабування. Максимум інстансів у Cloud Run, ліміти одночасності функцій, квоти на API-ключі: такі обмеження діють одразу, а не після оновлення білінгу.
-
Обмежте ключі. Прив’язуйте API-ключі до сервісів і адрес, а довгоживучі ключі замінюйте ролями (модуль 3).
-
Увімкніть виявлення аномалій. Наприклад, AWS Cost Anomaly Detection.
-
Ставте теги з першого дня. Через місяць з’ясовувати, чиї це ресурси, пізно.
-
Знайте, як усе вимкнути. Запишіть заздалегідь, як видалити проєкт чи групу ресурсів і хто має на це право.
Як це в трьох хмарах
Section titled “Як це в трьох хмарах”| AWS | Azure | GCP | |
|---|---|---|---|
| Контейнер | акаунт | підписка | проєкт |
| Група контейнерів | OU | management group | папка (folder) |
| Ще рівень | немає | група ресурсів | немає |
| Політики зверху вниз | SCP | Azure Policy, Azure RBAC | Organization Policy, IAM |
| Бюджет | AWS Budgets | Cost Management budgets | Cloud Billing budgets |
| Дії за бюджетом | політика IAM / SCP, зупинка EC2 і RDS | групи дій (action groups) | Pub/Sub і власний код |
| Теги | теги (треба активувати для білінгу) | теги (без успадкування) | мітки (лише проєкти) |
Чим відрізняється і що з цього випливає. По-перше, кількість рівнів: в Azure контейнером білінгу є підписка, але робочою групою є ще група ресурсів, і видаляти й розподіляти права зручно на обох рівнях. У AWS і GCP групування ресурсів усередині контейнера роблять тегами чи мітками. По-друге, рахунок: AWS збирає рахунок на management-акаунті, GCP відділяє білінг від дерева, а Azure прив’язує підписку до білінг-акаунта. Наслідок: змінити, хто платить, у GCP можна перепідключенням проєкту до іншого білінг-акаунта, а в AWS це означає перевести акаунт в іншу організацію. По-третє, Free plan AWS перестає бути безкоштовним, коли ви створюєте організацію.
Подивитися свою структуру й бюджети можна командами, які лише читають дані:
# хто я і в якому акаунтіaws sts get-caller-identity
# чи є організація і хто її management-акаунтaws organizations describe-organization
# бюджети акаунтаaws budgets describe-budgets \ --account-id "$(aws sts get-caller-identity --query Account --output text)"# підписки, доступні меніaz account list --query '[].{name:name, id:id, state:state}' -o table
# бюджети поточної підпискиaz consumption budget list -o table# організації та проєкти, які я бачуgcloud organizations listgcloud projects list --format='table(projectId,name,parent.id)'
# бюджети білінг-акаунта (потрібне право на перегляд)gcloud billing budgets list --billing-account=BILLING_ACCOUNT_IDТепер сама ієрархія в Terraform. Кожен блок створює гілку «workloads» і один контейнер під нею з тегами. Він показує, скільки сутностей потрібно кожному провайдерові.
variable "dev_email" { type = string}
resource "aws_organizations_organization" "this" { feature_set = "ALL"}
resource "aws_organizations_organizational_unit" "workloads" { name = "workloads" parent_id = aws_organizations_organization.this.roots[0].id}
resource "aws_organizations_account" "dev" { name = "shop-dev" email = var.dev_email parent_id = aws_organizations_organizational_unit.workloads.id
tags = { env = "dev" owner = "platform" }}data "azurerm_subscription" "current" {}
resource "azurerm_management_group" "workloads" { display_name = "workloads"}
resource "azurerm_management_group_subscription_association" "dev" { management_group_id = azurerm_management_group.workloads.id subscription_id = data.azurerm_subscription.current.id}
resource "azurerm_resource_group" "shop_dev" { name = "rg-shop-dev" location = "germanywestcentral"
tags = { env = "dev" owner = "platform" }}variable "org_id" { type = string}
variable "billing_account" { type = string}
variable "project_id" { type = string}
resource "google_folder" "workloads" { display_name = "workloads" parent = "organizations/${var.org_id}"}
resource "google_project" "shop_dev" { name = "shop-dev" project_id = var.project_id folder_id = google_folder.workloads.name billing_account = var.billing_account auto_create_network = false
labels = { env = "dev" owner = "platform" }}Нову підписку в Azure зазвичай оформлюють у білінг-акаунті, тому в прикладі ми приєднуємо наявну. Стан і дрейф цих ресурсів розібрано в модулі 10.
Типові помилки розуміння
Section titled “Типові помилки розуміння”«Бюджет зупинить витрати». Бюджет лише надсилає сповіщення. Автоматична зупинка, де вона є, будується окремо й працює із затримкою.
«Алерт прийде вчасно». Дані білінгу оновлюються за години, а не секунди. Швидкий захист дають квоти й ліміти масштабування.
«Безкоштовний рівень не може коштувати грошей». Може, якщо ви перейшли на платний план, вийшли з ліміту, чи умови змінилися: наприклад, Free plan AWS стає платним, коли ви створюєте організацію.
«Один акаунт достатньо». Тоді помилка у тесті зачепить продакшен, а рахунок не розділити без тегів.
«Теги на групі ресурсів дістануться ресурсам». В Azure й GCP вони не успадковуються без політик чи окремого налаштування.
Перевір себе
Джерела
Section titled “Джерела”- AWS: Free Tier plans, AWS Budgets, budget actions, Cost Anomaly Detection, cost allocation tags, квоти AWS Organizations
- Microsoft Learn: management groups, budgets, tags; Azure free account FAQ, Azure for Students
- Google Cloud: resource hierarchy, budgets, disable billing with notifications, free trial, labels, Firebase: avoid surprise bills
- Maciej Pocwierz, How an empty S3 bucket can make your AWS bill explode, 2024
- The Register: $72 000 у Google Cloud (10.12.2020), порожній бакет S3 (01.05.2024), ключ Gemini на $82 314 (03.03.2026)