IaC на практике: ревью, политики, секреты
Три замера из этой темы складываются в одну картину. Инструмент описания инфраструктуры сам заметил ручную правку и вернул описанное состояние. Сценарий настройки на втором прогоне дал одно изменение вместо четырёх. А пароль, положенный в описание ресурса, нашёлся в файле состояния открытым текстом. Первые два - про то, ради чего всё затевалось; третий - про цену.
Стержень: описание инфраструктуры даёт воспроизводимость и историю, но добавляет свои чувствительные файлы и свои правила просмотра изменений.
// Формулировки: «что такое неизменяемая инфраструктура?», «как ревьюить изменения инфраструктуры?», «где хранить секреты?»
Неизменяемость вместо донастройки
Изменяемый подход: машина живёт годами, её обновляют, донастраивают, чинят. Со временем каждая такая машина становится уникальной - на одной остался старый пакет, на другой правка в конфиге, о которой знал уволившийся коллега. Воспроизвести такую машину с нуля невозможно, а значит, и восстановить после потери тоже.
Неизменяемый подход: машина или контейнер собирается из образа - неизменяемой заготовки со всем нужным внутри - и больше не меняется. Нужна новая версия - собирается новый образ, поднимаются новые экземпляры, старые гасятся. Отсюда и одинаковость всех экземпляров, и простой откат: вернуть предыдущий образ.
// Плата честная. Нужна быстрая и надёжная сборка образов, иначе каждое мелкое изменение становится дорогим. Нужно место для хранения версий. И нужно вынести все данные наружу - в тома (хранилища, живущие отдельно от контейнера) и в базы, - потому что при пересоздании локальные данные исчезают. Это ровно то, что я показывал раньше: слой записи контейнера умирает вместе с ним.
- неизменяемая инфраструктура
- экземпляры не донастраиваются, а пересоздаются из нового образа
- уникальная машина
- сервер с накопленными ручными правками, который невозможно воспроизвести
Просмотр изменений и защитные проверки
Изменение инфраструктуры смотрят не как код, а как ПЛАН. Сам текст описания может выглядеть безобидно, а план при этом содержать уничтожение базы. Поэтому конвейер - набор шагов, через который проходит каждое изменение, - публикует план прямо в изменение комментарием, и обсуждают именно его.
Дальше ставят автоматические проверки. Форматирование и синтаксис - самое дешёвое. Политики: запрет публичных сетевых доступов, обязательные метки владельца, разрешённые типы машин, обязательное шифрование дисков. Отдельная проверка на уничтожение: если в плане есть удаление ресурсов с данными, нужно второе одобрение.
// И организационная часть, без которой всё это не работает. Право применять изменения на проде выдаётся конвейеру, а не людям: тогда каждое изменение проходит через просмотр и остаётся в истории. Людям оставляют аварийный доступ - с записью, оповещением и обязательным возвратом изменения в описание тем же днём.
- просмотр плана
- обсуждают не текст описания, а разницу, которую он даст
- политики
- автоматические запреты: публичный доступ, отсутствие меток, нешифрованные диски
Секреты в описании инфраструктуры
Тут две отдельные проблемы, и вторую обычно не замечают. Первая очевидна: пароль в тексте описания попадает в репозиторий. Вторая - я проверил её замером: значение попадает ещё и в файл состояния, причём открытым текстом, независимо от того, откуда оно взялось.
Значит, состояние - такой же чувствительный объект, как сам пароль. Отсюда требования: хранилище состояния с шифрованием, доступ по ролям, включённое версионирование и журнал обращений. И понимание, что «мы взяли пароль из хранилища секретов» не отменяет того, что он лёг в состояние.
// Практические варианты. Не создавать секреты через описание инфраструктуры вовсе: создать пустой ресурс, а значение положить отдельным процессом. Либо генерировать значение прямо в облаке и никогда не выносить наружу. Либо принять, что состояние чувствительно, и защитить его как таковое. Худший вариант - считать, что раз пароль пришёл из хранилища, то в состоянии его нет.
- чувствительный файл состояния
- содержит значения ресурсов открытым текстом, включая пароли
Как отвечать: «Как ревьюить изменения инфраструктуры, чтобы не уронить прод?»
Смотреть надо не текст описания, а план, который он даёт: текст бывает безобидным, а план при этом содержит уничтожение базы. Поэтому конвейер публикует план комментарием прямо в изменение, и обсуждают именно его, причём в первую очередь итоговую строку про уничтожения. Дальше три уровня защиты. Автоматические проверки формата и синтаксиса - самое дешёвое. Политики: запрет публичного доступа, обязательные метки владельца, шифрование дисков - они ловят целые классы ошибок. И отдельное правило: если в плане есть удаление ресурсов с данными, нужно второе одобрение. Организационно право применять на проде отдаю конвейеру, а не людям, чтобы каждое изменение проходило просмотр и оставалось в истории; людям остаётся аварийный доступ с оповещением и обязанностью вернуть правку в описание тем же днём.
Ответ ставит план в центр процесса и выстраивает защиту по уровням. Разделение прав между конвейером и людьми - то, что отличает выстроенный процесс от набора благих намерений.
На чём валятся
- −Смотрят текст описания вместо плана и пропускают уничтожение ресурсов.
- −Считают, что секрет из хранилища не попадает в состояние. Попадает, открытым текстом.
- −Раздают людям право применять изменения на проде мимо конвейера.
- −Донастраивают долгоживущие машины руками и получают набор неповторимых серверов.
- −Переходят на неизменяемые экземпляры, не вынеся наружу состояние, и теряют данные при пересоздании.
Проверьте себя
Пять вопросов из банка по этой подтеме. Всего их 6, остальные разбираются в тренажёре.
- В чём смысл неизменяемой инфраструктуры вместо донастройки живых машин?A)Новая версия — новый образ и новая машина, старую гасимB)Обновления ставятся автоматически по расписанию на всех хостахC)Конфигурация хранится в одном месте и раздаётся агентомD)Машины перестают требовать мониторинга после сборки образа
показать ответ и разбор
+A)Новая версия — новый образ и новая машина, старую гасим// разбор: Долгоживущий сервер накапливает историю: ручные правки, разные версии пакетов, забытые эксперименты — два «одинаковых» хоста расходятся, и воспроизвести падение невозможно. Неизменяемый подход заменяет донастройку заменой: собрали образ, раскатали новые машины, старые погасили. Плата — нужна сборка образов и быстрая замена, зато состояние предсказуемо, а откат сводится к запуску прошлого образа.
- Как ревьюить пул-реквест, который меняет инфраструктуру?A)Смотреть только диф кода: план проверит дежурный при примененииB)Применить в тестовом окружении и сравнить консоли облака вручнуюC)Публиковать план в пул-реквест и гонять проверки политикD)Требовать, чтобы автор приложил скриншот успешного локального применения
показать ответ и разбор
+C)Публиковать план в пул-реквест и гонять проверки политик// разбор: Диф в коде не показывает последствия: строчка про параметр может означать пересоздание базы. Потому CI на каждый пул-реквест публикует план как комментарий или артефакт, а рядом гоняет проверки политик — запрет публичных бакетов, обязательные теги, ограничения по типам машин. Применяет тоже CI: локальный apply лишает всех истории изменений и обходит ревью.
- Пароль от базы передан в Terraform переменной и помечен sensitive. Где он окажется?A)Только в памяти процесса на время примененияB)В зашифрованном виде внутри самого состоянияC)В логах CI, но не в состоянии — его отфильтруютD)В состоянии открытым текстом, поэтому его и защищают
показать ответ и разбор
+D)В состоянии открытым текстом, поэтому его и защищают// разбор: Пометка sensitive прячет значение в выводе плана и в логах, но в состояние ресурс сохраняется как есть — вместе с паролем. Отсюда требования к бэкенду: шифрование хранилища, узкие права, версионирование и аудит доступа. Более здоровый путь — не передавать секрет через IaC вовсе: генерировать его в хранилище (Vault и аналоги) и отдавать приложению на рантайме, а в коде держать ссылку.
- Хочется ловить типичные ошибки IaC (открытый наружу порт, забытый тег) до применения. Что поставить в пайплайн?A)Ревьюера, который вручную вычитывает каждый diffB)Прод-мониторинг, он заметит проблему после выкатаC)Линтер/сканер IaC (tflint, checkov) в пайплайнеD)Юнит-тесты приложения — они покроют и инфраструктуру
показать ответ и разбор
+C)Линтер/сканер IaC (tflint, checkov) в пайплайне// разбор: Типичные ошибки конфигурации ловят статическим анализом IaC в пайплайне: tflint (валидность и best practices Terraform), checkov/tfsec/kics (безопасность — публичные бакеты, открытые порты, отсутствие шифрования). Гейт срабатывает до apply, на этапе проверки PR. Ручное ревью и прод-мониторинг — не замена: одно устаёт, другое ловит уже по факту.
- Нужно жёстко запретить мержить инфраструктуру, нарушающую правила (публичный бакет, обязательные теги), автоматически. Чем?A)Policy as code: OPA/Conftest/Sentinel в пайплайне как гейтB)Пункт в вики с правилами, которые все должны помнитьC)Устная договорённость команды на код-ревьюD)Ограничить права в облаке, чтобы бакет не создался
показать ответ и разбор
+A)Policy as code: OPA/Conftest/Sentinel в пайплайне как гейт// разбор: Автоматический запрет задают через policy as code: OPA/Conftest, Sentinel, checkov-политики описывают правила («бакет не публичный», «обязательны теги owner/env») кодом и проверяют terraform plan в пайплайне — нарушение валит проверку и блокирует merge. Это жёсткий, повторяемый гейт, в отличие от вики и устных договорённостей. Облачные guardrails (SCP) — хорошее дополнение, но не покрывают всё.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.