Модуль 1.4: Amazon S3 та об'єктне сховище
Складність: [MEDIUM] | Час на виконання: 2.5 год | Передумови: Модуль 1.1
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»У 2017 році оборонний підрядник випадково розкрив особисту інформацію, дані про допуски до секретності та паролі тисяч державних службовців. Дані не були викрадені через складний мережевий злом. Вони знаходилися в бакеті Amazon S3 під назвою defense-contractor-internal-data. Дозволи бакета були необачно змінені розробником, який намагався виправити скрипт розгортання, ненавмисно надавши доступ READ групі AllUsers — фактично зробивши його публічним для всього інтернету. Будь-хто, хто міг вгадати URL, міг завантажити файли. Дані залишалися відкритими протягом декількох місяців, поки їх не знайшов дослідник з безпеки.
Amazon Simple Storage Service (S3) — це фундаментальний рівень зберігання даних у хмарі. Він безмежно масштабований, надзвичайно надійний і обслуговує трильйони об’єктів по всьому світу. Завдяки своїй доступності та простоті використання, він став стандартним місцем для зберігання ресурсів додатків, бекапів баз даних, величезних озер даних (data lakes) та хостингу статичних веб-сайтів.
Однак ця доступність — палиця з двома кінцями. S3 за замовчуванням знаходиться прямо в публічному інтернеті (з точки зору мережевої маршрутизації, а не прав доступу). Одна неправильно налаштована політика бакета може миттєво перетворити приватне сховище даних на публічний витік. У цьому модулі ви вивчите механіку об’єктного зберігання на відміну від традиційного файлового. Ви опануєте рівні безпеки, що захищають дані в S3, впровадите правила життєвого циклу для автоматизації економних стратегій архівування та навчитеся створювати безпечні тимчасові механізми доступу для обміну об’єктами без відкриття всього бакета.
Об’єктне сховище vs Файлове сховище
Розділ «Об’єктне сховище vs Файлове сховище»Якщо ви користувалися традиційною операційною системою або мережевим накопичувачем (NAS), ви знайомі з Файловим сховищем. Дані організовані в ієрархічне дерево вкладених директорій та папок. Модифікація великого файлу зазвичай передбачає оновлення лише змінених блоків на диску.
S3 — це Об’єктне сховище. Воно працює за принципово іншою логікою:
- Плоска структура: В S3 немає справжніх директорій або папок. Усе зберігається у величезному пласкому контейнері, який називається Бакет (Bucket).
- Ключі та Об’єкти: Дані зберігаються як Об’єкт, що складається з самих даних файлу та його метаданих. Кожен об’єкт ідентифікується унікальним Ключем (Key — фактично шлях/ім’я файлу). Коли ви бачите шлях на кшталт
images/2023/photo.jpgв S3,images/2023/не є папкою; увесь рядокimages/2023/photo.jpg— це просто довге ім’я ключа. Консоль візуально імітує папки для вашої зручності. - Незмінність (Immutability): Об’єкти в S3 незмінні. Ви не можете відкрити відеофайл на 10 ГБ в S3, відредагувати метадані і зберегти тільки зміни. Якщо ви змінюєте об’єкт, S3 повністю перезаписує існуючий об’єкт новою версією.
Швидке порівняння
Розділ «Швидке порівняння»| Функція | Файлове сховище (EFS/NFS) | Блочне сховище (EBS) | Об’єктне сховище (S3) |
|---|---|---|---|
| Структура | Ієрархічна (папки/файли) | Сирі блоки на диску | Плоский простір (ключі) |
| Доступ | Протокол NFS/SMB | Приєднано до однієї EC2 | HTTP REST API |
| Зміна на місці | Так | Так | Ні (повне перезаписування) |
| Макс. розмір | Обмежено диском | Обмежено томом | 5 ТБ на об’єкт |
| Метадані | Базові (права, час) | Немає (сирі блоки) | Багаті кастомні пари ключ-значення |
| Типове використ. | Спільні папки, CMS | Бази даних, диски ОС | Бекапи, озера даних, статика |
| Надійність | Залежить від конфігу | 99.999% (у межах AZ) | 99.999999999% (11 дев’яток) |
Думайте про це так: EBS — це жорсткий диск, прикручений болтами до одного сервера; EFS — це мережева папка, яку монтують усі; а S3 — це величезний склад, де ви віддаєте пакунки комірнику і отримуєте квитанцію (ключ), щоб забрати їх пізніше.
Безпека S3: Рівні захисту
Розділ «Безпека S3: Рівні захисту»Оскільки бакети S3 існують у глобальному просторі імен і доступні через HTTP-ендпоінти, їх захист потребує кількох рівнів авторизації, що накладаються один на одного. S3 оцінює дозволи за допомогою комбінації політик IAM та політик ресурсів.
Ось як працює повний потік оцінки доступу, коли запит потрапляє до S3:
┌──────────────────────┐ │ Вхідний запит │ │ (GET /my-bucket/obj)│ └──────────┬───────────┘ │ ▼ ┌────────────────────────────────┐ │ S3 Block Public Access (BPA) │ │ Це публічний запит? │ │ Чи ввімкнено BPA? │ └───────────┬───────┬────────────┘ │ │ BPA блокує BPA пропускає (DENY) (не публіч. або BPA вимкн) │ │ ▼ ▼ ВІДМОВЛЕНО ┌──────────────────────┐ │ Політика бакета │ │ Явна заборона? │ └──┬─────────┬─────────┘ │ │ Явна Немає явної ЗАБОРОНА заборони │ │ ▼ ▼ ВІДМОВЛЕНО ┌──────────────────────┐ │ Політика бакета │ │ Явний дозвіл? │ └──┬─────────┬─────────┘ │ │ Явний Немає збігу ДОЗВІЛ в політиці │ │ ▼ ▼ ДОЗВОЛЕНО ┌──────────────────┐ (якщо │ Політика IAM │ той самий │ запитувача │ акаунт) └──┬──────┬────────┘ │ │ IAM Дозвіл Немає IAM │ Дозволу ▼ ▼ ДОЗВОЛЕНО ВІДМОВЛЕНО
Ключові правила: - Явна ЗАБОРОНА завжди перемагає, незалежно від місця в ланцюжку. - Крос-акаунт: і політика бакета, і IAM запитувача ПОВИННІ дозволяти. - Один акаунт: достатньо АБО політики бакета, АБО IAM дозволу. - BPA — це головний запобіжник від спроб публічного доступу.1. S3 Block Public Access (BPA)
Розділ «1. S3 Block Public Access (BPA)»Це ваш головний вимикач. BPA працює на рівні акаунта або бакета, щоб скасувати будь-яку політику, яка намагається зробити дані публічними. Якщо BPA увімкнено (а він увімкнений за замовчуванням для всіх нових бакетів), навіть якщо адміністратор напише політику бакета, яка явно надає s3:GetObject групі * (усім), S3 заблокує такий запит. Ніколи не вимикайте Block Public Access, якщо ви не хостите публічні веб-ресурси навмисно.
BPA має чотири незалежні налаштування:
| Налаштування | Що воно блокує |
|---|---|
BlockPublicAcls | Відхиляє запити PUT, що містять публічний ACL |
IgnorePublicAcls | Ігнорує будь-які існуючі публічні ACL на бакеті/об’єктах |
BlockPublicPolicy | Відхиляє політики бакета, що надають публічний доступ |
RestrictPublicBuckets | Обмежує доступ до бакетів із публічними політиками тільки сервісами AWS та авторизованими користувачами |
Найкраща практика: увімкніть усі чотири на рівні акаунта, щоб жоден бакет у всьому акаунті не міг випадково стати публічним.
# Увімкнення BPA на рівні АКАУНТА (рекомендовано)aws s3control put-public-access-block \ --account-id $(aws sts get-caller-identity --query Account --output text) \ --public-access-block-configuration \ "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"2. Політики IAM
Розділ «2. Політики IAM»Як ми розбирали в Модулі 1.1, політики IAM приєднуються до ідентифікатора, який робить запит (користувача або ролі). Якщо екземпляр EC2 має IAM-роль, що дозволяє s3:PutObject у конкретний бакет, він зможе завантажувати файли.
Приклад: дозволити ролі читати тільки з певного префікса:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::my-data-bucket", "arn:aws:s3:::my-data-bucket/reports/*" ], "Condition": { "StringEquals": { "s3:prefix": "reports/" } } } ]}Зверніть увагу на два ARN: один для самого бакета (потрібен для ListBucket) і один для об’єктів всередині (потрібен для GetObject). Забути ARN рівня бакета — одна з найпоширеніших помилок при відлагодженні IAM.
3. Політики бакета (Bucket Policies)
Розділ «3. Політики бакета (Bucket Policies)»Політика бакета приєднується безпосередньо до ресурсу (самого бакета). Це JSON-документ, який діє як вишибала на вході до бакета.
- Крос-акаунт доступ: Політики бакета необхідні для того, щоб дозволити користувачам з інших акаунтів AWS читати або писати у ваш бакет.
- Примусове шифрування: Ви можете написати політику, яка відхиляє всі
s3:PutObject, якщо запит не містить заголовка, що вимагає шифрування на стороні сервера (напр., AES256). - Обмеження за IP: Ви можете заборонити доступ до бакета, якщо запит надходить не з діапазону IP-адрес вашого корпоративного VPN.
Приклад: вимога шифрування для всіх завантажень:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyUnencryptedUploads", "Effect": "Deny", "Principal": "*", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::my-secure-bucket/*", "Condition": { "StringNotEquals": { "s3:x-amz-server-side-encryption": "aws:kms" } } } ]}4. Списки контролю доступу (ACL)
Розділ «4. Списки контролю доступу (ACL)»ACL — це застарілий механізм контролю доступу ще з часів до появи IAM. Вони застосовуються до окремих об’єктів або бакета. AWS наполегливо рекомендує повністю вимикати ACL (встановлюючи бакет у режим “Bucket Owner Enforced”) і покладатися виключно на IAM та політики бакета.
Політика бакета vs ACL vs IAM — коли що використовувати?
Розділ «Політика бакета vs ACL vs IAM — коли що використовувати?»| Аспект | Політика IAM | Політика бакета | ACL |
|---|---|---|---|
| Приєднано до | Ідентичності (user/role) | Ресурсу (bucket) | Бакета або об’єкта |
| Крос-акаунт | Тільки на стороні запитувача | Можна давати зовнішнім принципалам | Можна іншим акаунтам |
| Макс. розмір | 6 144 симв. (вбудована) | 20 КБ | Фіксований список |
| Гранулярність | Будь-яка дія AWS | Тільки дії S3 | Тільки Read/Write/Full |
| Умови | Повний блок Condition | Повний блок Condition | Немає |
| Рекомендація AWS | Основний механізм | Для крос-акаунт + обмежень | Вимкнути (legacy) |
| Коли використ. | Керування діями ваших юзерів | Керування доступом до бакета | Майже ніколи |
Емпіричне правило: Використовуйте політики IAM для контролю доступу всередині акаунта. Використовуйте політики бакета для крос-акаунт доступу, обмежень за IP та вимог до шифрування. Вимикайте ACL.
Підписані URL-адреси (Pre-Signed URLs): Тимчасовий безпечний доступ
Розділ «Підписані URL-адреси (Pre-Signed URLs): Тимчасовий безпечний доступ»Уявіть, що ви будуєте додаток для обміну фотографіями. Користувачі завантажують приватні фото, а додаток їх відображає.
Поганий шлях: Веб-сервер завантажує фото з S3 і пересилає його клієнту. Це створює “пляшкове горло” для мережі та пам’яті сервера. Небезпечний шлях: Ви робите бакет S3 публічним, щоб браузер клієнта міг завантажити фото за прямим посиланням. Тепер будь-хто може вкрасти ці фото.
Шлях S3: Підписані URL (Pre-Signed URLs). Ваш бекенд-додаток (який має IAM-роль із доступом до S3) використовує AWS SDK для генерації тимчасової, криптографічно підписаної URL-адреси. Ця URL надає доступ до завантаження конкретного об’єкта на конкретний період (наприклад, 5 хвилин). Бекенд передає цю URL фронтенду. Браузер користувача використовує її для завантаження фото безпосередньо з S3. Як тільки 5 хвилин минають, посилання стає недійсним.
Генерація підписаних URL
Розділ «Генерація підписаних URL»# Генеруємо посилання, дійсне 300 секунд (5 хвилин)aws s3 presign s3://my-bucket/private/report.pdf --expires-in 300
# Приклад виводу:# https://my-bucket.s3.amazonaws.com/private/report.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Expires=300&X-Amz-Signature=abc123...
# Генеруємо посилання для ЗАВАНТАЖЕННЯ (PUT)aws s3 presign s3://my-bucket/uploads/user-photo.jpg \ --expires-in 3600
# Будь-хто з цим посиланням зможе завантажити файл за цим ключем протягом 1 годиниВажливі деталі про підписані URL:
- Посилання успадковує дозволи того IAM-ідентифікатора, який його створив. Якщо цей ідентифікатор втратить доступ, посилання миттєво перестануть працювати.
- Максимальний термін дії: 7 днів, якщо підписано IAM-користувачем; 36 годин, якщо підписано через тимчасові креденшали (STS ролі).
- Працюють як для завантаження (GET), так і для передачі файлів на сервер (PUT).
Класи зберігання та правила життєвого циклу
Розділ «Класи зберігання та правила життєвого циклу»S3 пропонує різні класи зберігання, розроблені під різні патерни доступу. Навіщо платити преміальну ціну за дані, якими ви користуєтеся раз на рік?
Порівняння класів зберігання
Розділ «Порівняння класів зберігання»| Клас зберігання | Доступність | Мін. термін зберіг. | Мін. розмір об’єкта | Час отримання | Ціна $/ГБ/міс | Вартість отрим. | Найкраще для |
|---|---|---|---|---|---|---|---|
| S3 Standard | 99.99% | Немає | Немає | Миттєво | ~$0.023 | Немає | Активні дані, сайти |
| S3 Intelligent-Tiering | 99.9% | Немає | Немає | Миттєво* | ~$0.023 + збір | Немає | Невідомі патерни |
| S3 Standard-IA | 99.9% | 30 днів | 128 КБ | Миттєво | ~$0.0125 | $0.01/ГБ | Бекапи, копії DR |
| S3 One Zone-IA | 99.5% | 30 днів | 128 КБ | Миттєво | ~$0.01 | $0.01/ГБ | Дані, що можна відновити |
| S3 Glacier Instant | 99.9% | 90 днів | 128 КБ | Миттєво | ~$0.004 | $0.03/ГБ | Архіви з миттєвим дост. |
| S3 Glacier Flexible | 99.99% | 90 днів | Немає | 1 хв - 12 год | ~$0.0036 | $0.01-0.03/ГБ | Довготривалі архіви |
| S3 Glacier Deep Archive | 99.99% | 180 днів | Немає | 12-48 годин | ~$0.00099 | $0.02/ГБ | Комплаєнс (7-10 років) |
Примітка: Ціни орієнтовні для регіону us-east-1 станом на 2025 рік. Актуальні дані завжди на сторінці цін S3.
S3 Intelligent-Tiering заслуговує на особливу увагу. Він автоматично переміщує об’єкти між рівнем частого та нечастого доступу на основі реального використання. Він стягує невелику місячну плату за моніторинг об’єктів (~$0.0025 за 1000 об’єктів), але може значно заощадити на великих наборах даних із непередбачуваним доступом. Плати за отримання даних немає.
Приклад економії
Розділ «Приклад економії»Припустимо, ви зберігаєте 10 ТБ логів додатків:
| Стратегія | Приблизна вартість/міс |
|---|---|
| Все у S3 Standard | $235 |
| Все у S3 Standard-IA | $128 |
| Все у Glacier Deep Archive | $10 |
| Розумне шарування (30/90/365 днів) | ~$40-80 (залежно від доступу) |
Використання правил життєвого циклу дозволяє скоротити витрати на 75-95%.
Правила життєвого циклу (Lifecycle Rules)
Розділ «Правила життєвого циклу (Lifecycle Rules)»Ви не хочете вручну переміщувати дані між цими рівнями. Lifecycle Rules в S3 автоматизують цей процес.
Ви можете налаштувати правило, яке каже:
- Коли створюються лог-файли, зберігай їх у S3 Standard.
- Через 30 днів перемісти їх у S3 Standard-IA.
- Через 90 днів перемісти їх у S3 Glacier Flexible Retrieval.
- Через 365 днів остаточно Видали об’єкти.
Таке автоматичне шарування радикально зменшує витрати на зберігання історичних даних.
# Перегляд існуючих правил життєвого циклу на бакетіaws s3api get-bucket-lifecycle-configuration --bucket my-bucket
# Видалення всіх правил життєвого циклу (обережно!)aws s3api delete-bucket-lifecycle --bucket my-bucketОбмеження правил життєвого циклу
Розділ «Обмеження правил життєвого циклу»Існують правила черговості при переході між класами зберігання. S3 впроваджує принцип “водоспаду” — ви можете переходити тільки “вниз”:
S3 Standard ├──► S3 Intelligent-Tiering ├──► S3 Standard-IA (мін. 30 днів після створення) ├──► S3 One Zone-IA (мін. 30 днів після створення) ├──► S3 Glacier Instant Retrieval (мін. 90 днів після створення) ├──► S3 Glacier Flexible Retrieval └──► S3 Glacier Deep ArchiveВи не можете перейти з Glacier назад у Standard-IA через правило життєвого циклу. Щоб підняти дані “вгору”, ви повинні відновити їх і скопіювати вручну.
Основні команди S3 CLI
Розділ «Основні команди S3 CLI»AWS CLI надає дві групи команд для S3:
aws s3— Команди високого рівня (cp, sync, ls, mv, rm). Вони автоматично обробляють багатопотокове завантаження, повтори та паралелізм.aws s3api— Низькорівневі API-виклики (put-object, get-object, put-bucket-policy). Повний контроль, ввід/вивід у JSON.
Копіювання файлів
Розділ «Копіювання файлів»# Завантаження одного файлуaws s3 cp backup.tar.gz s3://my-bucket/backups/backup.tar.gz
# Скачування файлуaws s3 cp s3://my-bucket/backups/backup.tar.gz ./backup.tar.gz
# Копіювання між бакетамиaws s3 cp s3://source-bucket/data.csv s3://dest-bucket/archive/data.csv
# Завантаження з конкретним класом зберіганняaws s3 cp archive.tar.gz s3://my-bucket/archives/ --storage-class GLACIER
# Завантаження із шифруванням (KMS)aws s3 cp report.pdf s3://my-bucket/confidential/ --sse aws:kms --sse-kms-key-id alias/my-key
# Копіювання цілої папки (рекурсивно)aws s3 cp ./logs/ s3://my-bucket/logs/ --recursive
# Копіювання з фільтром — тільки .log файлиaws s3 cp ./logs/ s3://my-bucket/logs/ --recursive --exclude "*" --include "*.log"Синхронізація директорій
Розділ «Синхронізація директорій»aws s3 sync — основний інструмент для бекапів. Він копіює тільки нові або змінені файли (на основі розміру та часу модифікації), подібно до rsync.
# Синхронізація локальної папки в S3aws s3 sync ./website/ s3://my-website-bucket/
# Синхронізація з S3 на локальну машинуaws s3 sync s3://my-bucket/data/ ./local-data/
# Синхронізація з ВИДАЛЕННЯМ файлів у цілі, яких немає в джерелі# (робить ціль точною копією — використовуйте обережно!)aws s3 sync ./website/ s3://my-website-bucket/ --delete
# Dry run — подивитися, що БУЛО Б зроблено, без реальних змінaws s3 sync ./website/ s3://my-website-bucket/ --dryrunПерегляд та перевірка
Розділ «Перегляд та перевірка»# Список усіх бакетів в акаунтіaws s3 ls
# Список об'єктів у бакеті ("папки" верхнього рівня)aws s3 ls s3://my-bucket/
# Рекурсивний список усіх об'єктів із розмірамиaws s3 ls s3://my-bucket/ --recursive --human-readable --summarize
# Отримання детальних метаданих конкретного об'єктаaws s3api head-object --bucket my-bucket --key reports/q4-summary.pdfУправління бакетами
Розділ «Управління бакетами»# Створення бакетаaws s3 mb s3://my-new-bucket --region us-west-2
# Видалення ПОРОЖНЬОГО бакетаaws s3 rb s3://my-empty-bucket
# Видалення бакета РАЗОМ із вмістом (деструктивно!)aws s3 rb s3://my-bucket --force
# Увімкнення версійностіaws s3api put-bucket-versioning \ --bucket my-bucket \ --versioning-configuration Status=Enabled
# Увімкнення шифрування за замовчуванням (SSE-S3)aws s3api put-bucket-encryption \ --bucket my-bucket \ --server-side-encryption-configuration '{ "Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}] }'Відновлення з Glacier
Розділ «Відновлення з Glacier»Об’єкти в класах Glacier не можна завантажити миттєво. Спочатку треба ініціювати відновлення (restore).
# Ініціація відновлення (Expedited = 1-5 хв, Standard = 3-5 год, Bulk = 5-12 год)aws s3api restore-object \ --bucket my-archive-bucket \ --key old-logs/app-2023.tar.gz \ --restore-request '{"Days": 7, "GlacierJobParameters": {"Tier": "Standard"}}'
# Перевірка статусу відновленняaws s3api head-object --bucket my-archive-bucket --key old-logs/app-2023.tar.gz
# Заголовок "Restore" покаже:# ongoing-request="true" → ще відновлюється# ongoing-request="false", expiry-date="..." → готово до завантаженняШифрування в S3
Розділ «Шифрування в S3»S3 пропонує кілька варіантів шифрування. З січня 2023 року всі нові об’єкти шифруються за замовчуванням за допомогою SSE-S3 (AES-256), навіть якщо ви не вказали налаштування.
| Тип шифрування | Ким керується ключ | Коли використовувати |
|---|---|---|
| SSE-S3 (AES-256) | AWS (повністю керований) | За замовчуванням, найпростіший варіант |
| SSE-KMS | AWS KMS (ви керуєте політиками) | Аудит, ротація ключів, крос-акаунт |
| SSE-C | Вами (надаєте ключ у кожному запиті) | Регуляторна вимога тримати ключі у себе |
| Client-side | Вами (шифруєте перед завантаж.) | Zero-trust, наскрізне шифрування |
SSE-KMS — найпопулярніший вибір для корпорацій, оскільки він інтегрується з CloudTrail (кожне використання ключа логується) та підтримує автоматичну щорічну ротацію ключів.
Глибоке занурення у версійність (Versioning)
Розділ «Глибоке занурення у версійність (Versioning)»Коли версійність увімкнена, кожне перезаписування або видалення створює нову версію замість знищення даних.
Ключ: reports/q4.pdf
Стек версій (нові зверху):┌─────────────────────────────────────────┐│ Delete Marker (немає даних) │ ← поточний стан = "видалено"├─────────────────────────────────────────┤│ Version: abc789 (Фінальна версія) │├─────────────────────────────────────────┤│ Version: def456 (Друга чернетка) │├─────────────────────────────────────────┤│ Version: ghi123 (Перше завантаж.) │└─────────────────────────────────────────┘
Звичайний GET поверне 404 (через delete marker).GET з ?versionId=abc789 поверне Фінальну версію.ВИДАЛЕННЯ delete marker → повертає abc789 у статус поточної версії.Важливі особливості версійності:
- Версійність не можна вимкнути після ввімкнення. Її можна тільки призупинити (suspended).
- Призупинена версійність зберігає існуючі версії, але нові об’єкти отримують
nullяк ID версії. - Ви платите за кожну збережену версію. Файл 1 ГБ, перезаписаний 100 разів = 100 ГБ у рахунку.
- MFA Delete може вимагати двофакторну аутентифікацію для видалення версій.
Чи знали ви?
Розділ «Чи знали ви?»-
S3 забезпечує консистентність “read-after-write” для всіх операцій PUT та DELETE. Якщо ви записали новий об’єкт і миттєво спробували його прочитати — S3 поверне нові дані. (До грудня 2020 року S3 був “eventually consistent”, тобто миттєве читання могло повернути 404 або стару версію).
-
S3 підтримує хостинг статичних сайтів. Додавши файл
index.html, вимкнувши BPA та додавши публічну політику бакета, ви отримуєте глобально доступний, високонадійний веб-сервер без жодної віртуальної машини EC2. -
S3 може обробляти дані на місці за допомогою S3 Select та S3 Object Lambda. S3 Select дозволяє виконувати SQL-запити безпосередньо до файлів CSV або JSON у бакеті — замість того, щоб скачувати CSV на 10 ГБ і фільтрувати його локально, ви надсилаєте запит
SELECT * FROM s3object WHERE status = 'error', і S3 повертає тільки потрібні рядки. Це економить 80-90% трафіку. -
S3 спроєктований для надійності 99.999999999% (11 дев’яток). Це означає: якщо ви зберігаєте 10 мільйонів об’єктів, статистично ви можете втратити один раз на 10 000 років. Це досягається автоматичною реплікацією кожного об’єкта мінімум у 3 зонах доступності в межах регіону.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому це стається | Як виправити |
|---|---|---|
| Витік даних через публічні бакети | Вимкнення BPA, бо “програма видає 403 і так воно запрацювало”. | Ніколи не вимикайте BPA для приватних даних. Виправте IAM-політики або використовуйте підписані URL. |
| Оплата за мільйони дрібних файлів в IA | Перенесення величезної кількості логів по 5 КБ у Standard-IA для “економії”. | Standard-IA має мінімальний оплачуваний розмір 128 КБ. За файл 5 КБ ви заплатите як за 128 КБ. Об’єднуйте дрібні файли в архіви перед шаруванням. |
| Використання S3 як бази даних | Оскільки є API і можна зберігати JSON, розробники пробують робити тисячі транзакцій на секунду. | S3 не оптимізований для частих мілісекундних транзакційних записів. Використовуйте DynamoDB або RDS. |
| Ігнорування витрат на версійність | Увімкнення версійності на бакеті, що постійно оновлюється, без правил очищення. | S3 бере гроші за кожну стару версію. Якщо вмикаєте версійність — ОБОВ’ЯЗКОВО налаштуйте Lifecycle Rule для видалення старих версій через певний час. |
| Конфлікти імен бакетів | Спроба створити бакет з назвою test-bucket. | Імена бакетів S3 мають бути унікальними у всьому світі серед усіх акаунтів AWS. Використовуйте префікс компанії та ID акаунта. |
| Забування обох ARN в IAM політиках | Написання політики тільки з ARN бакета (arn:aws:s3:::my-bucket) або тільки об’єктів (.../*). | ListBucket потребує ARN бакета. GetObject/PutObject потребують ARN об’єктів з /*. Завжди вказуйте обидва. |
| Відсутність правил для незавершених завантажень | Великі файли, що не завантажилися до кінця, залишають невидимі фрагменти, за які ви платите вічно. | Додайте правило життєвого циклу “Abort incomplete multipart uploads” через 7 днів. Це безкоштовна економія для кожного бакета. |
Тест
Розділ «Тест»Питання 1: Аудитор вимагає, щоб компанія зберігала логи додатків рівно 7 років для дотримання регуляторних норм. Логи ніколи не відкриваються, якщо немає перевірки, при якій затримка у 24 години на отримання даних є цілком прийнятною. Як зберігати ці логи максимально економно?
Завантажуйте логи в S3 і використовуйте Lifecycle Rule для негайного переведення їх у клас зберігання S3 Glacier Deep Archive, який має найнижчу ціну. Налаштуйте правило на видалення об’єктів через 2 555 днів (7 років).
Питання 2: Ви намагаєтеся додати політику бакета (Bucket Policy), що надає публічний доступ на читання до префікса `images/`. Консоль AWS видає помилку і відмовляється зберігати політику. Яка найбільш імовірна причина?
На бакеті (або на рівні акаунта) увімкнено S3 Block Public Access (BPA). BPA працює як головний запобіжник, який активно блокує спроби застосувати будь-яку політику або ACL, що відкриває публічний доступ.
Питання 3: Стороння компанія з аналізу даних має щодня завантажувати CSV-файл у бакет у вашому акаунті AWS. Вони надали вам ARN своєї IAM-ролі. Як надати їм доступ, не створюючи для них IAM-користувача у вашому акаунті?
Створіть політику ресурсу (Bucket Policy) на вашому бакеті. У ній вкажіть Effect: Allow, Action: s3:PutObject, Resource: ARN вашого бакета/*, а в полі Principal вкажіть наданий ними ARN IAM-ролі. Для крос-акаунт доступу важливо, щоб дозвіл був і у вашій політиці бакета, і в їхній політиці IAM.
Питання 4: Ви видалили відеофайл розміром 1 ГБ із бакета, на якому увімкнена версійність. Ви зрозуміли, що це помилка. Чи видалено файл назавжди і як його відновити?
Ні, файл не видалено. При ввімкненій версійності звичайне видалення просто вставляє “Delete Marker” поверх об’єкта, приховуючи його зі списків. Щоб відновити файл, перейдіть у перегляд версій об’єкта і видаліть цей “Delete Marker” — це поверне попередню версію файлу в статус поточної.
Питання 5: Команда зберігає 50 мільйонів дрібних JSON-файлів (в середньому по 2 КБ кожен) у S3 Standard. Перевірка витрат пропонує перенести їх у S3 Standard-IA для економії. Чи допоможе це заощадити гроші?
Ні, це, швидше за все, збільшить витрати. Клас Standard-IA має мінімальний оплачуваний розмір об’єкта 128 КБ. За кожен файл у 2 КБ ви платитимете як за 128 КБ, тобто за 6.4 ТБ замість реальних 100 ГБ. Також Standard-IA стягує плату за отримання кожного ГБ даних. Правильний підхід: об’єднати дрібні файли у великі архіви (напр., .tar.gz) перед зміною класу зберігання.
Практична вправа: Продуктовий бакет для бекапів із управлінням життєвим циклом
Розділ «Практична вправа: Продуктовий бакет для бекапів із управлінням життєвим циклом»У цій вправі ви створите бакет для бекапів промислового рівня: із посиленою безпекою, версійністю, автоматизацією життєвого циклу та потренуєте основні команди CLI.
Завдання 1: Створення та захист бакета
Розділ «Завдання 1: Створення та захист бакета»# Генеруємо унікальне ім'я бакетаexport MY_BUCKET="dojo-backup-$(openssl rand -hex 6)"echo "Bucket name: $MY_BUCKET"
# Створюємо бакетaws s3 mb s3://$MY_BUCKET
# Вмикаємо Block Public Access (усі чотири налаштування)aws s3api put-public-access-block \ --bucket $MY_BUCKET \ --public-access-block-configuration \ "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
# Вмикаємо шифрування за замовчуванням (SSE-S3)aws s3api put-bucket-encryption \ --bucket $MY_BUCKET \ --server-side-encryption-configuration '{ "Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}] }'
# Вмикаємо версійністьaws s3api put-bucket-versioning \ --bucket $MY_BUCKET \ --versioning-configuration Status=Enabled
# Перевірка налаштуваньaws s3api get-bucket-versioning --bucket $MY_BUCKETЗавдання 2: Завантаження бекапів та робота з версіями
Розділ «Завдання 2: Завантаження бекапів та робота з версіями»Симулюємо щоденний бекап бази даних, який перезаписує той самий файл.
mkdir -p ./backup-exercise
# День 1echo '{"date": "2025-01-01", "status": "healthy"}' > ./backup-exercise/db-dump.jsonaws s3 cp ./backup-exercise/db-dump.json s3://$MY_BUCKET/backups/daily/db-dump.json
# День 2 (перезаписує файл, але версійність збереже День 1)echo '{"date": "2025-01-02", "status": "healthy"}' > ./backup-exercise/db-dump.jsonaws s3 cp ./backup-exercise/db-dump.json s3://$MY_BUCKET/backups/daily/db-dump.json
# День 3 (зіпсований бекап!)echo '{"date": "2025-01-03", "status": "CORRUPTED"}' > ./backup-exercise/db-dump.jsonaws s3 cp ./backup-exercise/db-dump.json s3://$MY_BUCKET/backups/daily/db-dump.json
# Список УСІХ версій — зверніть увагу на VersionIdaws s3api list-object-versions \ --bucket $MY_BUCKET \ --prefix backups/daily/db-dump.json \ --query 'Versions[].{Key:Key,VersionId:VersionId,LastModified:LastModified}'Завдання 3: Відновлення зіпсованого бекапа
Розділ «Завдання 3: Відновлення зіпсованого бекапа»Повернемося до здорового бекапа за День 2, завантаживши конкретну версію.
# Отримуємо ID версії за День 2 (другий у списку, індекс [1])DAY2_VERSION=$(aws s3api list-object-versions \ --bucket $MY_BUCKET \ --prefix backups/daily/db-dump.json \ --query 'Versions[1].VersionId' --output text)
# Завантажуємо саме цю версіюaws s3api get-object \ --bucket $MY_BUCKET \ --key backups/daily/db-dump.json \ --version-id $DAY2_VERSION \ ./backup-exercise/restored.json
# Перезаписуємо поточний файл здоровою версієюaws s3 cp ./backup-exercise/restored.json s3://$MY_BUCKET/backups/daily/db-dump.jsonecho "Бекап відновлено."Завдання 4: Синхронізація та підписані URL
Розділ «Завдання 4: Синхронізація та підписані URL»# Створюємо кілька лог-файлівfor i in 1 2 3; do echo "Log $i" > ./backup-exercise/log-$i.txt; done
# Синхронізація папки в S3 (копіюються тільки нові файли)aws s3 sync ./backup-exercise/ s3://$MY_BUCKET/logs/ --exclude "*.json"
# Генерація підписаного посилання на 10 хвилинSIGNED_URL=$(aws s3 presign s3://$MY_BUCKET/logs/log-1.txt --expires-in 600)echo "Тимчасове посилання: $SIGNED_URL"
# Перевірка (має вивести вміст лога)curl -s "$SIGNED_URL"Завдання 5: Налаштування правил життєвого циклу
Розділ «Завдання 5: Налаштування правил життєвого циклу»Створимо комплексну політику автоматизації.
cat << 'EOF' > lifecycle.json{ "Rules": [ { "ID": "ArchiveOldLogs", "Filter": {"Prefix": "logs/"}, "Status": "Enabled", "Transitions": [ {"Days": 30, "StorageClass": "STANDARD_IA"}, {"Days": 90, "StorageClass": "GLACIER"} ], "Expiration": {"Days": 365} }, { "ID": "CleanupIncompleteUploads", "Filter": {"Prefix": ""}, "Status": "Enabled", "AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 7} } ]}EOF
# Застосовуємо конфігураціюaws s3api put-bucket-lifecycle-configuration \ --bucket $MY_BUCKET \ --lifecycle-configuration file://lifecycle.jsonОчищення
Розділ «Очищення»Оскільки бакет з версійністю містить приховані дані, звичайне видалення через CLI може бути складним. Використаємо Python-скрипт для повного очищення.
cat << EOF > empty_bucket.pyimport boto3import sysbucket_name = sys.argv[1]s3 = boto3.resource('s3')bucket = s3.Bucket(bucket_name)print(f"Видалення всіх версій у {bucket_name}...")bucket.object_versions.delete()print(f"Видалення бакета {bucket_name}...")bucket.delete()EOF
python3 empty_bucket.py $MY_BUCKETrm -rf ./backup-exercise lifecycle.json empty_bucket.pyКритерії успіху
Розділ «Критерії успіху»- Я створив бакет із увімкненим Block Public Access, шифруванням та версійністю.
- Я завантажив кілька версій одного файлу і переглянув історію версій.
- Я відновив конкретну попередню версію після симуляції псування даних.
- Я синхронізував локальну папку з S3 і згенерував робоче підписане посилання.
- Я застосував правила життєвого циклу для архівації та очищення.
- Я успішно очистив усі ресурси.
Наступний модуль
Розділ «Наступний модуль»Тепер, коли ви опанували обчислення та зберігання, час навчитися направляти користувачів до ваших додатків. Переходьте до Модуля 1.5: Route 53 та DNS.