Перейти до вмісту

Зберігання

У будь-якій системі є дані, які мають пережити віртуальну машину. Це завантажені користувачами файли, журнали, резервні копії, дані бази. Хмара пропонує для них три різні сховища, і різниця між ними визначає і надійність, і рахунок.

Диск віртуальної машини описується двома числами, які ви платите окремо: скільки IOPS і скільки мегабайтів за секунду ви замовили. Об’єктне сховище описується довговічністю у «11 дев’яток» і чотирма статтями рахунку: місце, запити, вилучення з холодних класів і вихідний трафік. Довговічність гарантує, що провайдер не втратить ваші об’єкти. Вона нічого не каже про те, що станеться, коли об’єкти видалите ви самі, а видалення й помилкові права доступу належать до типових причин втрат і витоків.

Тому модуль розбирає механізми: як влаштована консистентність, що саме означає довговічність, звідки беруться мінімальні строки зберігання, як працює тимчасове посилання і чому диск у хмарі оплачується за продуктивність.

Передумови. Регіони й зони доступності (модуль 1), акаунти й бюджети (модуль 2), політики й ролі (модуль 3), вихідний трафік і приватні ендпоінти (модуль 5). Як влаштовано блочний рівень, IOPS і черги запитів, розібрано в курсі ОС, а файлові системи, inode і журналювання в наступному модулі того курсу. Тут ці поняття вважаються відомими.

Блочне сховище (block storage) віддає віртуальній машині масив блоків за номерами, як фізичний диск. Файлову систему на ньому створюєте ви, тож із боку машини це звичайний /dev/nvme1n1. Диск підключається до однієї машини в межах однієї зони доступності (availability zone).

Файлове сховище (file storage) віддає готову файлову систему по мережі за протоколом NFS або SMB. Її одночасно монтують багато машин, а каталоги, права й блокування підтримує провайдер.

Об’єктне сховище (object storage) не має файлової системи взагалі. Воно зберігає об’єкти в бакетах (buckets), кожен об’єкт має ключ, тіло й метадані, а працюють з ним HTTP-запитами PUT, GET, DELETE і LIST.

Блочне, файлове й об’єктне сховище: інтерфейс, який бачить застосунок, і хто будує файлову системублочнезастосунокблоки за номеромфайлову системустворюєте виEBS · Managed DisksPersistent Disk · Hyperdiskодна ВМ, одна зонафайловезастосунокфайли й каталогифайлову системутримає провайдерEFS · Azure FilesFilestoreбагато ВМ по NFS або SMBоб’єктнезастосунокключ → об’єктфайлової системинемаєS3 · Blob StorageCloud StorageHTTP-запити звідки завгодно
Три види сховища. Різниця в тому, який інтерфейс бачить застосунок, і від нього випливають і ціна, і межі застосування.

Об’єктне сховище влаштоване інакше, ніж файлова система з курсу ОС, і це має практичні наслідки:

  • «Папок» немає. Ключ reports/2026/09/a.csv є одним рядком, а слеш у ньому лише договір між клієнтами. «Каталог» є префіксом, який LIST уміє фільтрувати.
  • Об’єкт не змінюють частково. Щоб виправити один байт, завантажують об’єкт цілком. Дописати в кінець можна лише там, де сховище має окремий тип об’єкта для дописування.
  • Перейменування не існує. Воно виконується як копіювання під новим ключем і видалення старого, тому для великого «каталогу» це мільйони запитів. Щоб мати справжні каталоги, Azure і Google Cloud пропонують ієрархічний простір імен, а Amazon S3 має для цього directory buckets.
  • Блокувань немає. Два клієнти, які пишуть в один ключ, дадуть результат за правилом «останній записав виграв». Для безпечного створення без перезапису S3 підтримує умовні записи: заголовок If-None-Match у PutObject відхиляє запис, якщо ключ уже існує.

Дані, які пишуть один раз і читають цілком, найкраще лягають на об’єктне сховище. Диск, на якому працює база, потребує блочного.

Консистентність об’єктного сховища

Section titled “Консистентність об’єктного сховища”

Консистентність (consistency) відповідає на питання: якщо запис завершився успішно, чи побачить наступне читання нові дані.

Amazon S3 до 1 грудня 2020 року давав таку гарантію лише частково. Новий об’єкт було видно відразу, але після перезапису або видалення читання й LIST могли ще якийсь час повертати старий стан. Щоб із цим жити, Hadoop-екосистема тримала обхідні шляхи на кшталт S3Guard та EMRFS Consistent View, які зберігали власний індекс у DynamoDB. Від грудня 2020 року S3 дає строгу консистентність читання після запису (strong read-after-write) для PUT, DELETE і LIST в усіх регіонах без додаткової плати й без втрати продуктивності.

Azure Blob Storage і Cloud Storage мали строгу консистентність із самого початку. Тож для трьох провайдерів сьогодні правило однакове: успішний запис видно всім наступним читанням і переліками.

Чого консистентність не дає:

  • Атомарності між ключами. Транзакція з двох об’єктів не існує, тому застосунок, який пише «дані» й «індекс» окремо, має продумати порядок запису і що робити, якщо упаде посередині.
  • Захисту від конкурентних записів. Два одночасні PUT в один ключ залишать той, що прийшов пізніше. Для оптимістичного блокування є умовні запити: If-None-Match і If-Match в S3, ETag у Azure, передумови на generation у Cloud Storage.
  • Миттєвих змін конфігурації бакета. Налаштування бакета в S3 мають кінцеву консистентність: після першого ввімкнення версіонування документація радить почекати близько 15 хвилин, перш ніж писати й видаляти об’єкти.

Довговічність і чого вона не гарантує

Section titled “Довговічність і чого вона не гарантує”

Довговічність (durability) вимірює ймовірність, що об’єкт не буде втрачений. Про доступність (availability), тобто чи відповість сховище зараз, вона нічого не каже. Ці два числа плутають найчастіше.

«Одинадцять дев’яток», 99.999999999%, означають розрахункову річну ймовірність втрати одного об’єкта, що дорівнює 10−11. За арифметикою, якщо зберігати 10 мільйонів об’єктів, чекати першої втрати доведеться близько 10 000 років. Механізм за цією цифрою простий: кілька копій даних у різних пристроях, стійкість до втрати цілої зони доступності, постійна перевірка контрольних сум і відновлення пошкоджених копій.

Числа в провайдерів такі:

Сховище Довговічність за рік Доступність (задум)
S3 Standard, Standard-IA, Glacier 99.999999999% (11 дев’яток) 99.99% для Standard, 99.9% для Standard-IA
S3 One Zone-IA ті самі 11 дев’яток, але одна зона 99.5%; втрата зони може знищити дані
Azure Blob, LRS щонайменше 11 дев’яток щонайменше 99.9% на читання
Azure Blob, ZRS щонайменше 12 дев’яток щонайменше 99.9% на читання
Azure Blob, GRS і GZRS щонайменше 16 дев’яток 99.9%; читання з другого регіону лише в RA-варіантах
Cloud Storage 11 дев’яток залежить від типу розташування
EBS gp3 (диск, не об’єкти) 99.8–99.9% за рік окремий SLA; річна частка відмов тому до 0.2%

Останній рядок важливий. Диск EBS має довговічність на вісім порядків нижчу за S3: до двох відмов на 1000 томів за рік. Тому знімки (snapshots) є не «додатковою» опцією, а способом отримати довговічність, якої сам диск не має.

Ці цифри є проєктним показником (designed for), а не гарантією: у договорі про рівень послуги (SLA) провайдери обіцяють кредити за недоступність, а не компенсацію за втрату даних. До того ж вони описують стан, який ви залишили в сховищі, а не те, що ви з ним зробили.

Довговічність не захищає від видалення: втрачену копію відновлюють з двох інших, а команда DELETE прибирає всі три; версіонування залишає стару версію за маркером видаленняЗбій диска або сервераКоманда DELETE або перезапископія 1копія 2копію втраченокопія 3система відновлює її з двох іншихдовговічність працюєкопія 1видаленокопія 2видаленокопія 3видаленоусі копії зникають разомдовговічність тут не допоможеЗ версіонуванням або soft deleteмаркер видаленняпопередня версіяGET дає «не знайдено», але стару версію можна повернути
Довговічність ремонтує апаратні збої. Команда DELETE виконується на всіх копіях одразу, бо вони мають відображати один стан.

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

  • команда rm --recursive або цикл із помилкою в префіксі;
  • правило життєвого циклу з помилковим префіксом, яке видаляє те, що не мало;
  • зламані облікові дані, якими атакувальник видаляє або шифрує об’єкти;
  • закритий акаунт або підписка. У травні 2024 року в австралійського фонду UniSuper через помилку в конфігурації Google Cloud видалив підписку на приватну хмару, і, за спільною заявою компаній, видалення зачепило обидві геолокації. Відновленню допомогли копії в іншого провайдера (детальніше в модулі 7).

Захист працює шарами, і кожен шар закриває свою причину:

Причина втрати Що допомагає
Випадкове видалення чи перезапис Версіонування (S3, Blob), soft delete (Blob, Cloud Storage)
Зловмисне видалення або шифрування Object Lock в S3, immutable storage в Azure, retention policy і Bucket Lock у Cloud Storage: об’єкт не можна змінити до кінця строку, навіть адміністратору
Втрата зони Класи з кількома зонами: S3 Standard, Azure ZRS, багаторегіональні бакети
Втрата регіону Реплікація в інший регіон: S3 replication, Azure GRS, dual-region у Cloud Storage
Втрата акаунта або компрометація адміністратора Копія в окремому акаунті або в іншого провайдера

Реплікація в інший регіон не є резервною копією: вона повторює зміни, зокрема видалення, якщо вони входять у її налаштування. Що саме вона повторює, треба перевіряти окремо.

Класи зберігання і життєвий цикл

Section titled “Класи зберігання і життєвий цикл”

Дані з часом охолоджуються: файл, якого вчора торкалися десять разів на день, через рік читають раз на квартал. Провайдери відповідають на це класами зберігання (storage classes): що холодніший клас, то дешевше тримати гігабайт, але дорожче його читати. Крім того, холодні класи мають мінімальний строк зберігання і платні запити.

Ціна зберігання проти плати за вилучення для класів S3, Blob Storage і Cloud Storage: чим дешевше тримати дані, тим дорожче їх читати00.0050.0100.0150.0200.02500.020.040.06зберігання, $ за ГБ на місяцьвилучення, $ за ГБгарячі класи: дорожче тримати, читати безкоштовнохолодні класи: дешево тримати, дорого читатиAWS S3Azure BlobGCS
Кожна точка є одним класом. Чим лівіше точка, тим дешевше зберігання, і тим вище вона, тим дорожче вилучення. Ціни з розділу «Скільки це коштує». Glacier Flexible Retrieval і Deep Archive не показано, бо їхнє вилучення залежить від швидкості.

Класи в трьох провайдерів:

Провайдер Клас Зберігання, $/ГБ на міс. Мін. строк Вилучення, $/ГБ
AWS S3 Standard 0.023 немає 0
AWS S3 Standard-IA 0.0125 30 діб 0.01
AWS S3 Glacier Instant Retrieval 0.004 90 діб 0.03
AWS S3 Glacier Flexible Retrieval 0.0036 90 діб залежить від швидкості, дані «офлайн»
AWS S3 Glacier Deep Archive див. прайс 180 діб залежить від швидкості, години
Azure Hot 0.0208 немає 0
Azure Cool 0.0152 30 діб 0.01
Azure Cold 0.0036 90 діб 0.03
Azure Archive 0.00099 180 діб 0.02, до 15 годин на розморожування
GCP Standard 0.020 немає 0
GCP Nearline 0.010 30 діб 0.01
GCP Coldline 0.004 90 діб 0.02
GCP Archive 0.0012 365 діб 0.05

Ціни станом на вересень 2026, регіони us-east-1, eastus і us-central1. Мінімальний строк Cool і Cold в Azure застосовується в акаунтах general-purpose v2.

Рахунок за холодний клас складається з чотирьох частин:

  1. Зберігання за гігабайт на місяць. Це єдина частина, яку показує реклама.
  2. Запити. Вони теж дорожчають із охолодженням: PUT у S3 Standard коштує $0.005 за тисячу, у Standard-IA $0.01, у Glacier Instant Retrieval $0.02. Читання з Archive у Cloud Storage коштує $0.05 за тисячу запитів проти $0.0004 у Standard.
  3. Вилучення за гігабайт, прочитаний із класу.
  4. Дострокове видалення. Якщо видалити, перезаписати або перемістити об’єкт раніше за мінімальний строк, платите за решту строку так, ніби він лежав до кінця.

Два приклади показують, як це б’є по гаманцю.

Короткоживучі дані в холодному класі. 100 ГБ переклали в S3 Glacier Instant Retrieval і видалили через 10 днів. Ви заплатите за мінімальні 90 днів: 100 × $0.004 × 3 місяці = $1.20. У S3 Standard за ті самі 10 днів було б 100 × $0.023 × 10/30 ≈ $0.77.

Дрібні об’єкти. У Standard-IA і Glacier Instant Retrieval мінімальний розмір, за який виставляють рахунок, становить 128 КБ. Мільйон об’єктів по 10 КБ в IA оплачується як 128 000 000 КБ, тобто близько 122 ГіБ, а це близько $1.53 за місяць. У Standard ті самі 9.5 ГіБ коштують близько $0.22. Для дрібних об’єктів холодніший клас дорожчий.

Тому S3 за замовчуванням і не переносить у нові класи об’єкти менші за 128 КБ: кожен перехід є платним запитом ($0.02 за тисячу переходів у Glacier Instant Retrieval), і для дрібних об’єктів він коштує більше, ніж економія. Перенесення 10 мільйонів об’єктів у цей клас коштувало б $200 лише за запити.

Правила, які переносять і видаляють об’єкти самі, називаються життєвим циклом (lifecycle). Кожен провайдер має власні особливості:

  • AWS. Класи утворюють «водоспад»: з Standard можна у все, а назад правилом не повернеш. Glacier Deep Archive є пасткою в один бік: з нього можна лише розморозити копію запитом на відновлення. Плата за перехід нараховується від дати, коли виконалася умова правила, а не від фізичного переміщення.
  • Azure. Політика керування життєвим циклом (lifecycle management policy) не вміє розморожувати з Archive. Archive не підтримується для ZRS і GZRS акаунтів, тож вибір резервування в одному місці забороняє архів в іншому. Якщо ввімкнено soft delete, блоб вважається видаленим лише після закінчення строку утримання, тож штраф за дострокове видалення в цей період не діє.
  • GCP. Штраф за дострокове видалення не нараховується, якщо клас змінив сам життєвий цикл, і не нараховується в бакетах із Autoclass. Тож правила життєвого циклу тут безпечніші, ніж ручна зміна класу.

Коли патерн доступу невідомий, є автоматичні варіанти: S3 Intelligent-Tiering (без плати за вилучення, але з платою за моніторинг кожного об’єкта, а об’єкти менші за 128 КБ не моніторяться), Autoclass у Cloud Storage і smart tier в Azure Blob.

Версіонування (versioning) зберігає кожну версію об’єкта. Коли ви перезаписуєте ключ, нова версія стає поточною, а стара лишається з власним ідентифікатором. Коли ви видаляєте ключ, сховище не стирає нічого, а додає маркер видалення (delete marker). Запит GET без версії тепер повертає «не знайдено», але кожну стару версію можна повернути.

Що це коштує. Кожна версія тримається за повну ціну зберігання. Бакет, у який щодня перезаписують файл 1 ГБ, за рік накопичить 365 ГБ версій. Тож версіонування завжди йде в парі з правилом, яке видаляє неактуальні (noncurrent) версії через певний строк.

У трьох провайдерів відповідні механізми не збігаються:

  • S3 вмикає версіонування на бакеті й окремо має Object Lock для незмінності. Версіонування можна лише призупинити, але не вимкнути.
  • Azure Blob Storage має три окремі перемикачі з окремими строками: версіонування, soft delete блобів і soft delete контейнерів.
  • Cloud Storage має версіонування і soft delete, який увімкнено в усіх бакетах за замовчуванням із утриманням на 7 діб. Тож захист від випадкового видалення тут є вже без вашої участі.

У бакетах з важливими даними захист від видалення вмикають одразу під час створення, а не після першого інциденту.

Доступ: публічні бакети та тимчасові посилання

Section titled “Доступ: публічні бакети та тимчасові посилання”

Усі три сховища за замовчуванням приватні. Публічність нового об’єкта є результатом того, що хтось її свідомо ввімкнув. Захисти теж посилилися: із квітня 2023 року S3 для нових бакетів автоматично вмикає Block Public Access і вимикає ACL. Azure-акаунт не дозволяє публічних контейнерів, якщо не ввімкнути allow_nested_items_to_be_public. У Cloud Storage є public_access_prevention, який забороняє публічний доступ на рівні бакета.

Публічний доступ усе одно з’являється і призводить до витоків. Типові шляхи такі:

  • політика бакета з "Principal": "*", додана «на хвилинку», щоб застосунок запрацював;
  • контейнер із рівнем доступу blob або container;
  • прив’язка ролі для allUsers чи allAuthenticatedUsers у Cloud Storage (у другому випадку «автентифікований» означає будь-кого з обліковим записом Google);
  • вимкнений Block Public Access на рівні акаунта «для одного проєкту»;
  • посилання, у яке вбудовано право доступу, потрапило туди, де його прочитають сторонні.

Останній шлях стосується тимчасових посилань. Presigned URL в AWS, SAS (shared access signature) в Azure і signed URL у Google Cloud діють однаково: сервіс, у якого є доступ до об’єкта, підписує посилання своїми обліковими даними, а клієнт без облікових даних скачує чи завантажує об’єкт напряму, не проходячи через ваш сервер.

Це зручно для завантаження великих файлів, бо трафік не йде через ваш застосунок. Але тимчасове посилання є bearer-токеном: усі, хто його має, діють від імені того, хто підписав, у межах наданих прав і строку. Дізнатися, хто ним користується, майже неможливо.

Що варто знати про кожного провайдера:

AWS Azure GCP
Назва presigned URL SAS: user delegation, service, account signed URL
Хто підписує ключ IAM-користувача або тимчасові облікові дані ролі ключ делегування Entra ID (user delegation SAS) або ключ облікового запису (service, account SAS) акаунт служби або HMAC-ключ
Максимальний строк 7 діб для ключа IAM-користувача; для ролі не довше за сесію ролі (для EC2 зазвичай близько 6 годин); у консолі від 1 хв до 12 год задається під час створення; для SAS без збереженої політики радять короткі строки 7 діб; у gcloud без файлу ключа --duration обмежено 12 годинами
Як відкликати посилання перестає діяти, коли відкликано облікові дані, якими його підписано збережена політика доступу (для service SAS) або ротація ключа облікового запису відкликання ключа підписувача

Ще три властивості з документації Azure, які треба знати. Microsoft рекомендує user delegation SAS, бо він захищений обліковими даними Entra, а не ключем облікового запису. Storage не відстежує видані SAS, тому їхню кількість з боку сервісу дізнатися неможливо. І створення SAS не аудитується: хто має право його підписати, той може зробити це непомітно для власника акаунта.

Виходить така схема: користувач автентифікується у вашому застосунку, ваш бекенд перевіряє права й видає посилання на 5–15 хвилин на один об’єкт з мінімальною дією (GET або PUT), а не на весь бакет.

Блочні диски: IOPS і пропускна здатність як оплачувані параметри

Section titled “Блочні диски: IOPS і пропускна здатність як оплачувані параметри”

Блочний диск у хмарі не лежить у сервері. Він підключається по мережі, тому працює за законами з курсу ОС: IOPS, пропускна здатність (throughput) і глибина черги є окремими числами, і кожне має стелю.

Історично продуктивність диска зростала з його розміром: щоб отримати більше IOPS, треба було купити більший диск. EBS gp2 давав 3 IOPS на гібібайт, а маленькі томи мали «кредити на сплеск» до 3000 IOPS, які закінчувалися. Нове покоління розв’язало це так: ємність, IOPS і пропускна здатність оплачуються окремо. У AWS це gp3, в Azure Premium SSD v2, у Google Cloud Hyperdisk Balanced. У всіх трьох закладено базові 3000 IOPS (Azure: 3000 IOPS і 125 МБ/с, gp3: 3000 і 125 МіБ/с, Hyperdisk Balanced: 3000 і 140 МБ/с), а понад базу ви платите за кожну одиницю.

Що це змінює на практиці. Базі даних на 500 ГіБ потрібно 10 000 IOPS і 250 МБ/с:

  • gp2: IOPS прив’язано до розміру, тож потрібен диск на 3334 ГіБ, і за $0.10 за гібібайт це близько $333 на місяць.
  • gp3: 500 ГіБ × $0.08 + 7000 додаткових IOPS × $0.005 + 125 додаткових МіБ/с × $0.04 = $80 на місяць. Швидкість і розмір змінюються окремо і без зупинки диска.

Кілька правил, які випливають із цього:

  • Замовляйте IOPS за виміром, а не «про запас». Кожен IOPS понад базу коштує щомісяця, навіть якщо ви ним не користуєтеся.
  • Стеля є й у самої віртуальної машини. Кожен тип інстансу має власну межу пропускної здатності до дисків, і замовлені IOPS, які машина не може прийняти, ви оплачуєте марно (модуль 4).
  • Диск прив’язаний до зони. EBS-том і Premium SSD v2 живуть в одній зоні доступності, тож втрата зони робить диск недоступним. Пережити втрату зони допомагають знімки, регіональні диски (у Google Cloud) чи реплікація рівнем вище, наприклад у базі даних (модуль 7).
  • Знімки є вашою довговічністю. Знімок інкрементальний і зберігає лише змінені блоки. У EBS знімки лежать в S3 і коштують $0.05 за гібібайт на місяць.
  • Локальні NVMe-диски інстансу тимчасові. Вони швидкі й дешеві, але зникають разом із машиною, тож для кешів і тимчасових файлів вони підходять, а для даних, які треба зберегти, ні.

Amazon EFS, Azure Files і Google Cloud Filestore дають спільну файлову систему по NFS чи SMB для багатьох машин: спільні каталоги, вебконтент, домашні каталоги, застосунки, які очікують POSIX. Провайдер тримає масштабування, резервування між зонами й блокування.

Гігабайт тут коштує помітно дорожче, ніж в об’єктному сховищі, а кожна операція з метаданими (stat, відкриття файлу) іде по мережі й повільніша, ніж на локальному диску. Тому файлове сховище обирають, коли застосунок не може працювати з об’єктами й потребує саме файлової семантики.

Функція AWS Azure GCP
Об’єктне сховище Amazon S3 Azure Blob Storage Cloud Storage
Контейнер об’єктів бакет контейнер у storage account бакет
Блочне сховище EBS (gp3, io2) Managed Disks (Premium SSD v2) Persistent Disk, Hyperdisk
Файлове сховище EFS, FSx Azure Files Filestore
Строга консистентність з 2020 року завжди завжди
Захист від видалення versioning, Object Lock, MFA Delete versioning, soft delete, immutable storage versioning, soft delete (7 діб), retention policy
Тимчасове посилання presigned URL SAS signed URL
Заборона публічного доступу Block Public Access allow_nested_items_to_be_public public_access_prevention
Зона чи регіон об’єкта бакет у регіоні, класи з ≥3 зонами резервування LRS, ZRS, GRS, GZRS на акаунті тип розташування: регіон, dual-region, multi-region

Чим відрізняється і що з цього випливає.

  • В Azure налаштування живуть в акаунті, а не в контейнері. Резервування, ключі доступу й мережеві правила storage account спільні для всіх його блобів, файлів, черг і таблиць. Різні вимоги до резервування означають різні акаунти. Ключі акаунта дають повний доступ, тому в продуктивних середовищах їх вимикають (shared_access_key_enabled = false) і працюють через Entra ID.
  • У Google Cloud розташування є властивістю бакета. Регіон, dual-region і multi-region обирають під час створення бакета, і резервування між регіонами вбудовано в цей вибір.
  • У S3 «більше зон» є властивістю класу. Standard і Standard-IA живуть у щонайменше трьох зонах, а One Zone-IA в одній і не переживе втрату зони.
  • Archive в Azure несумісний із ZRS. Архівувати можна лише в акаунтах LRS, GRS і RA-GRS, тож вибір між стійкістю до втрати зони й архівом ухвалюється в одному налаштуванні.
  • Імена бакетів у S3 і Cloud Storage та імена storage account в Azure глобально унікальні, тож вигадана назва може бути вже зайнята.

Приватний бакет із захистом від видалення

Section titled “Приватний бакет із захистом від видалення”
variable "bucket_name" {
type = string
}
resource "aws_s3_bucket" "data" {
bucket = var.bucket_name
}
resource "aws_s3_bucket_public_access_block" "data" {
bucket = aws_s3_bucket.data.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_s3_bucket_versioning" "data" {
bucket = aws_s3_bucket.data.id
versioning_configuration {
status = "Enabled"
}
}

Життєвий цикл: охолодження і видалення

Section titled “Життєвий цикл: охолодження і видалення”

Правило однакове в трьох варіантах: через 30 діб перенести в клас для рідкісного доступу, через 120 діб у холодніший, через два роки видалити.

variable "bucket_name" {
type = string
}
resource "aws_s3_bucket" "logs" {
bucket = var.bucket_name
}
resource "aws_s3_bucket_lifecycle_configuration" "logs" {
bucket = aws_s3_bucket.logs.id
rule {
id = "cool-then-expire"
status = "Enabled"
filter {
prefix = "logs/"
}
transition {
days = 30
storage_class = "STANDARD_IA"
}
transition {
days = 120
storage_class = "GLACIER_IR"
}
expiration {
days = 730
}
noncurrent_version_expiration {
noncurrent_days = 30
}
}
}

У версії для AWS об’єкти менші за 128 КБ у клас IA не потраплять: це типова поведінка S3. Якщо в бакеті багато дрібних файлів, простіше зберігати їх у Standard, а перед архівуванням збирати в більші.

Тимчасове посилання на 15 хвилин

Section titled “Тимчасове посилання на 15 хвилин”
Terminal window
aws s3 presign s3://my-bucket/reports/2026-09.pdf --expires-in 900

Кожна з трьох команд повертає URL із підписом у параметрах запиту. Його можна відкрити в браузері без облікових даних, і він перестане працювати через 15 хвилин. Варіант для Azure використовує user delegation SAS, тому для нього потрібна роль із правом на ключ делегування.

Диск із замовленою продуктивністю

Section titled “Диск із замовленою продуктивністю”

500 ГіБ, 10 000 IOPS, 250 МБ/с:

resource "aws_ebs_volume" "db" {
availability_zone = "us-east-1a"
size = 500
type = "gp3"
iops = 10000
throughput = 250
encrypted = true
}

Ціни станом на вересень 2026, з офіційних прайс-листів і сторінок цін; регіони us-east-1, eastus, us-central1, Linux, оплата за фактом.

Об’єкти: 1 ТБ (1000 ГБ) у стандартному класі за місяць, 1 млн записів і 10 млн читань.

AWS S3 Standard Azure Blob Hot, LRS GCP Standard
Зберігання 1000 ГБ $23.00 $20.80 $20.00
1 млн записів $5.00 $5.00 $5.00
10 млн читань $4.00 $4.00 $4.00
Разом $32.00 $29.80 $29.00

Ціни запитів збіглися: $0.005 за тисячу записів і $0.004 за десять тисяч читань у AWS та Azure, $0.0004 за тисячу читань у GCP.

Вихідний трафік з сервісу в інтернет (модуль 5 розбирає його детально). AWS бере $0.09 за гігабайт за перші 10 ТБ на місяць, перші 100 ГБ на місяць безкоштовні. Azure бере $0.087 за гігабайт після безкоштовних 100 ГБ (маршрут через мережу Microsoft). Читання 1 ТБ на місяць обійдеться приблизно в $81 в AWS і $78 в Azure. Для GCP вартість залежить від рівня мережі і напрямку.

Що ще додається. Вилучення з холодних класів: читання 1 ТБ із S3 Glacier Instant Retrieval коштує $30 понад зберігання. Тимчасові посилання оплачуються як звичайні запити. Плата за вихідний трафік лягає на власника акаунта, навіть коли посилання відкрив сторонній користувач: Azure у своїй документації прямо попереджає, що завантаження 200 ГБ десять разів через SAS дасть 2 ТБ вихідного трафіку в рахунку власника.

Блочні диски: 500 ГіБ, 10 000 IOPS, 250 МБ/с на місяць.

AWS gp3 Azure Premium SSD v2 GCP Hyperdisk Balanced
Ємність $0.08 за ГіБ $0.0803 за ГіБ $0.08 за ГіБ
IOPS понад базові 3000 $0.005 за IOPS $0.0051 за IOPS $0.005 за IOPS
Пропускна здатність понад базову $0.04 за МіБ/с (база 125) $0.04 за МБ/с (база 125) $0.04 за МБ/с (база 140)
Разом $80.00 $80.94 $79.40

Розрахунок для gp3: ємність $40 + 7000 додаткових IOPS × $0.005 = $35 + 125 додаткових МіБ/с × $0.04 = $5. Ціни трьох провайдерів майже збіглися, бо всі три перейшли на одну модель оплати. gp2 за тієї ж потреби IOPS коштував би $333.

Про що забувають. Неприєднані диски й знімки лишаються в рахунку, версії об’єктів без правила очищення ростуть без меж, а незавершені багаточастинні завантаження в S3 оплачуються, поки їх не прибере правило abort_incomplete_multipart_upload.

Розбір: SAS-токен, який відкрив 38 ТБ

Section titled “Розбір: SAS-токен, який відкрив 38 ТБ”

Що сталося. Дослідники Microsoft AI опублікували в GitHub репозиторій robust-models-transfer з відкритим кодом і моделями розпізнавання зображень. У репозиторії був URL для завантаження моделей із Azure Blob Storage з токеном SAS. Компанія Wiz Research виявила, що токен видано на весь storage account з повним контролем (читання, запис, видалення), хоча потрібне було лише читання окремих файлів. Строк дії токена стояв до 6 жовтня 2051 року.

Що було доступно. За даними Wiz, разом із моделями через токен було видно 38 ТБ приватних даних, зокрема резервні копії робочих станцій двох колишніх співробітників, у яких були секрети, приватні ключі й паролі, та понад 30 000 внутрішніх повідомлень Microsoft Teams від 359 співробітників. Microsoft у своєму повідомленні уточнила, що дані клієнтів не постраждали і що інші внутрішні сервіси не були під загрозою.

Хронологія.

Дата Подія
20 липня 2020 Токен уперше потрапив у GitHub, тоді його строк був до 5 жовтня 2021
6 жовтня 2021 Строк продовжили до 6 жовтня 2051
22 червня 2023 Wiz повідомила Microsoft Security Response Center
24 червня 2023 Microsoft відкликала токен і закрила зовнішній доступ

Механізм. Три налаштування, які легко ввімкнути, склалися в проблему:

  1. Обсяг. Токен видано на весь акаунт, хоча потрібен був один контейнер для читання.
  2. Права. Повний контроль замість читання. Це давало змогу не лише зчитати, а й перезаписати файли, зокрема моделі, які інші люди завантажують і запускають.
  3. Строк. 30 років замість годин. Посилання, яке живе довше за проєкт, фактично є постійним ключем.

За повідомленням MSRC, сканування секретів у GitHub помітило цей URL, але результат помилково позначили хибним спрацюванням. Після інциденту Microsoft розширила виявлення SAS-токенів із надмірними правами.

Що з цього випливає. SAS не можна відстежити: сервіс не веде обліку виданих токенів, а їх створення не аудитується. Тому єдина система захисту складається з правил, які застосовуються до створення:

  • видавати user delegation SAS, а не підписаний ключем облікового запису;
  • обмежувати обсяг одним блобом чи контейнером, права мінімальні, строк у хвилинах чи годинах;
  • вимкнути доступ за ключем облікового запису, щоб токени, які він підписує, не могли існувати;
  • для публічних даних використовувати окремий акаунт без приватних даних.

Так само в AWS і Google Cloud: presigned URL і signed URL підписуються обліковими даними сервісу, тож надмірні права ролі, що підписує, стають надмірними правами в кожному посиланні.

Класичний публічний бакет. У 2017 році дослідник UpGuard знайшов відкритий для скачування бакет S3 із записами клієнтів Verizon, який налаштував підрядник NICE Systems. UpGuard оцінила витік у 14 мільйонів записів, Verizon у 6 мільйонів акаунтів. Виявлено 8 червня, Verizon повідомили 13 червня, доступ закрили 22 червня.

Типові помилки розуміння

Section titled “Типові помилки розуміння”
  • «11 дев’яток означає, що дані не зникнуть». Це проєктний показник проти апаратних збоїв. Видалення, перезапис і скомпрометовані облікові дані він не покриває.
  • «Реплікація в інший регіон є бекапом». Вона повторює й помилкове видалення. Бекап має бути окремою копією, недосяжною для тих облікових даних, які можуть зіпсувати основну.
  • «S3 має кінцеву консистентність». Це було правдою до грудня 2020 року. Старі статті й обхідні шляхи на кшталт S3Guard тепер не потрібні.
  • «Холодний клас завжди дешевший». Він дешевший лише для даних, які лежать довго, читаються рідко і не є дрібними. Для короткоживучих і дрібних об’єктів він дорожчий.
  • «Тимчасове посилання безпечне, бо тимчасове». Воно діє для всіх, хто його має, і 7 діб чи 30 років є суто налаштуванням.
  • «Диск у хмарі швидкий, бо це SSD». Швидкість диска є параметром, який ви замовляєте й оплачуєте, і його обмежує ще й тип віртуальної машини.
  • «У бакеті немає папок, отже це не важливо». Це важливо для ціни: перейменування каталогу означає копіювання й видалення кожного об’єкта.

Перевір себе

1. Розробник виконав `aws s3 rm --recursive` на префікс у бакеті без версіонування, реплікації та Object Lock. Документація обіцяє 11 девʼяток довговічності. Що з даними?
2. Застосунок записує новий обʼєкт у S3 і одразу викликає LIST по префіксу. Чого очікувати?
3. Бакет S3 має 5 мільйонів обʼєктів по 20 КБ. Правило життєвого циклу переносить їх у Standard-IA через 30 діб, бо IA дешевший за гігабайт. Що станеться?
4. Блоб переклали в Azure Cool і видалили на 10-й день. Що вкаже рахунок?
5. База даних на gp2 500 ГіБ потребує 9000 IOPS. Який варіант дешевший і чому?
6. Бекенд генерує presigned URL із `--expires-in 604800` (7 діб), використовуючи облікові дані ролі з EC2-профілю. Коли посилання перестане працювати?
7. У публічному репозиторії знайшли SAS на весь storage account із повним доступом і строком до 2051 року, підписаний ключем облікового запису. Що найдієвіше?