Налаштування AWS ECR для production: IAM, lifecycle, CI/CD

Реєстр образів ламається на проді тихо: доступи видані зайвим людям, старі шари накопичуються, розгортання тримається на ручних кроках. Ми налаштовуємо AWS ECR під ключ — політики доступу, життєвий цикл образів і автоматичну публікацію. Команда отримує передбачуване розгортання, а час випуску версії скорочується в рази.
Часті запитання

Чому налаштування AWS ECR ламається на проді

Налаштування AWS ECR зазвичай минає гладко, поки реєстр контейнерних образів торкається один інженер з однієї машини.

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

Ручна публікація образів ламає відтворюваність найраніше. Поки образ збирається на ноутбуці й надсилається однією командою, між «зібрав» і «залив» залишається вікно, у якому середовище, залежності та змінні оточення встигають розійтися.

Відкат на попередній реліз у такій схемі перетворюється на пошук — потрібного образу може просто не бути в реєстрі, бо його перезаписали.

Права доступу до реєстру — друге джерело відмов. Політики, видані широко, «щоб не заважати роботі», дають право на запис усім, хто має лише читати: теги перезаписуються чужими збірками, а розібратися постфактум нема чим.

Зворотна крайність — доступи, роздані вручну конкретним людям: новий агент або підрядник тиждень чекає на ключ, і команда повертається до ручної публікації.

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

Розбираємо, як це закривається: де ставляться межі прав, як автоматизується публікація і що чистить реєстр без втрати можливості відкотитися.

Що дає керований реєстр образів в ECR

Керований реєстр — це не склад образів, а контур із політиками доступу та зберігання. Ролі IAM розділяють pull для середовищ виконання і push для конвеєра збірки, тому агент збірки фізично не може перезаписати тег, який уже розгортався в production.

Додатково вмикаємо незмінність тегів: артефакт під цим тегом залишається тим самим, а спроба повторної публікації відхиляється на рівні Amazon ECR.

Правило життєвого циклу тримає останні кілька образів на тег і чистить решту за віком — реєстр перестає зростати лінійно, але відкат на попередній реліз залишається доступним.

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

Автоматизація публікації прибирає ручні кроки: збірка, тегування за ідентифікатором коміту, публікація, оновлення опису служби. Час публікації скорочується з десятків хвилин, де половина — узгодження тегів і перемикання руками, до кількох хвилин передбачуваного процесу.

Відкат стає перемиканням на попередній незмінний тег, тому час відновлення після збою вимірюється хвилинами і не залежить від того, хто з інженерів на зв'язку.

Відтворюваність збірок закриває окремий клас відмов — розбіжність артефактів між середовищами. Той самий образ за дайджестом проходить перевірки на стенді й потрапляє в production, а не збирається заново «приблизно з того самого коду».

Частка ручних операцій падає, і разом із нею зникають інциденти через людський фактор під час випуску.

Варіанти публікації образів: порівняння підходів

Спосіб публікації визначає, що опиниться на стенді за наступного розгортання й чи вдасться повернутися до попереднього стану. Тег зручний як читабельне посилання, але під час перезапису два різні стани системи вказують на одне ім'я — порівняти збірки між собою вже не можна.

Посилання на незмінний ідентифікатор прив'язує розгортання до конкретного вмісту образу, тому відкат відтворюваний.

Другий вибір — єдиний реєстр або розділення за середовищами. У спільному реєстрі права доступу й правила зберігання розводяться за префіксами імен, і помилка в одному правилі зачіпає всі контури одразу.

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

Варіант Коли підходить Обмеження
Публікація за тегом Ручні прогони, швидкі перевірки Перезапис тега ламає відтворюваність і порівняння збірок
Публікація за незмінним ідентифікатором Промислове розгортання, аудит, відкат Нечитабельно вручну, потрібна дисципліна в конвеєрі збірки
Єдиний реєстр для всіх середовищ Один контур, невелика команда Спільні права й правила очищення, тести впливають на промисловий контур
Реєстри, розділені за середовищами Кілька контурів, вимоги до ізоляції доступу Дублювання образів, складніше синхронізувати правила
Автоматична політика очищення Регулярні релізи, багато гілок Без точного налаштування видаляється потрібний для відкату образ

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

Як ми вибудовуємо впровадження: етапи роботи

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

Приводимо це до схеми, яку команда замовника підтримує сама — порядок етапів однаковий і для нового контуру, і для розбору успадкованого.

  1. Аудит прав доступу та поточної схеми. Дивимося, які репозиторії та теги живуть насправді, хто публікує образи і звідки беруться облікові дані. На виході — карта надлишкових привілеїв, дублів і місць без ротації.

  2. Проєктування схеми реєстру. Розбиваємо сховище за оточеннями й командами, фіксуємо правила іменування образів і тегів. Схема залишається в описі інфраструктури, а не в ручних налаштуваннях консолі.

  3. Налаштування політик доступу. Ролі з мінімально достатніми правами: запис — лише з конвеєра збірки, читання — точково для стендів. Довгоживучі ключі замінюємо тимчасовими обліковими даними з ротацією.

  4. Політики зберігання образів. Автовидалення старих збірок із збереженням останніх релізних тегів, сканування на вразливості, захист релізних тегів від перезапису. Реєстр перестає зростати, відкат на попередню версію залишається доступним.

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

  6. Передавання інфраструктури. Віддаємо опис реєстру, ролей і політик у вигляді коду плюс регламент роботи з тегами. Розбираємо з командою типові операції: новий репозиторій, доступ підряднику, відкат релізу.

Комплект документації, політики та схеми реєстру

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

  • Ролі IAM і політики доступу — права за принципом мінімально необхідних: публікація з конвеєра, читання із середовищ виконання й адміністративні операції розведені за різними ролями, плюс явні межі між проєктами.
  • Схема іменування образів — репозиторій на сервіс, незмінний тег на реліз, окремі теги для середовищ перевірки; за іменем одразу видно, що і звідки розгорнуто.
  • Регламент очищення — lifecycle-правила з порогами: скільки останніх образів тримати на тег, коли видаляти проміжні збірки і з якою періодичністю переглядати пороги.
  • Конфігурація реєстру як код — репозиторії, перевірки під час завантаження й шифрування описані файлами й застосовуються автоматично, без ручних правок у консолі.
  • Інструкції для інженерів — як опублікувати образ, як відкотитися на попередній реліз, що робити в разі відмови публікації та як запросити розширення прав.
  • Схема зв'язків із конвеєром і середовищами — де збирається образ, куди публікується, хто його читає і які перевірки проходять на кожному кроці.
  • Порядок ревізії — хто і з якою періодичністю переглядає політики, щоб права не накопичувалися, а терміни зберігання відповідали вимогам.

Комплект передаємо у ваш репозиторій із коротким розбором — черговий інженер розбереться з реєстром без звернення до нас.

Кейс: скоротили час публікації та прибрали ручні кроки

Замовник — продуктова команда, яка збирала образи й публікувала їх у реєстр AWS ECR вручну: інженер тегував збірку, заливав її та правив конфігурацію оточення перед кожним випуском.

За 12–14 публікацій на тиждень це давало до 14 ручних дій у релізному циклі — і майже кожне друге відхилення на проді було пов'язане з тим, що в оточення йшов не той тег.

Що було до

Публікація займала 25–30 хвилин: збірка, очікування завантаження, ручна перевірка, що образ справді потрапив у реєстр. Реєстр зростав без правил — образи накопичувалися всіма тегами, включно з проміжними збірками гілок, і пошук актуального артефакту перетворювався на перебір. Відкат на попередню збірку сягав години, бо потрібного образу під рукою не було.

Що змінили і що вийшло

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

Публікація скоротилася до 5–7 хвилин, ручних операцій у релізі залишилося дві: підтвердження й перевірка метрик. Обсяг реєстру зменшився втричі за повного збереження історії релізів, а відкат виконується поверненням попереднього тега за пару хвилин. Частка випусків, які відкочували через неправильний артефакт, упала до нуля.

Чим відрізняється публікація за тегом від публікації за хешем

Тег — це змінне посилання на маніфест: app:release сьогодні вказує на одну збірку, а завтра конвеєр перепризначить його іншій. Сам по собі тег не гарантує, що за ним розгорнеться той самий код, що вчора, — звідси й ростуть розбіжності між стендом і продуктивним контуром.

Хеш (дайджест) маніфесту обчислюється з вмісту образу, тому переписати його непомітно не можна: під одним ідентифікатором завжди лежать ті самі шари й та сама конфігурація. Незмінність артефакту забезпечує саме адресація за вмістом, а не обіцянка не перевикористовувати тег.

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

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

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

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

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

Часті питання щодо доступів і життєвого циклу образів

Доступи й чистка реєстру лякають тим, що «зламають робочий реліз». На практиці обидві операції вводяться без простою: правило життєвого циклу спочатку програється в попередньому перегляді — видно, які теги потраплять під видалення, — а ролі видаються окремо на читання й на запис. Ключова розвилка в тому, за якою ознакою чистити і як видавати права, не відкриваючи зайвого.

Теги релізів позначаємо незмінними, тому під видалення йдуть лише проміжні збірки та образи без тега, старші за заданий термін.

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

Увімкнемо чистку — чи не видалить вона образ, потрібний для відкату?

Ні, якщо правило будується на тегах, а не на даті. Схема «тримати останні N образів на кожен тег» зберігає попередні релізи, а під видалення потрапляють лише проміжні збірки та образи без тега, на які не посилається жодне розгортання.

Як видати доступ зовнішнім підрядникам, не віддаючи ключі від усього реєстру?

Роль на читання образів плюс дозвіл забирати їх із конкретного репозиторію — без прав на видалення й зміну.

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

Що станеться з уже працюючим розгортанням?

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

Обговоримо задачу і повернемося з оцінкою та планом

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

Уточнюємо, перш ніж рахувати терміни:

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

За відповідями збираємо склад робіт щодо реєстру, розкладаємо його на етапи й називаємо терміни впровадження — окремо те, що робимо наші інженери, окремо те, що залишається на вашому боці. Так у середині проєкту не з'являється «несподіваних» пунктів.

Опишіть задачу — повернемося з оцінкою та планом.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    815
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139