Terraform vs Pulumi: выбор IaC для ИБ и разделения окружений
Terraform vs Pulumi: как выбрать IaC под требования ИБ, разделить dev test prod, настроить контроль прав и аудит изменений инфраструктуры.

Почему выбор IaC упирается в ИБ и управление изменениями
К Infrastructure as Code обычно приходят не из-за любви к «красивому коду», а потому что инфраструктурные изменения со временем превращаются в хаос. Кто-то поправил настройку вручную на сервере, другой забыл задокументировать правило в сети, и система работает «как-то» ровно до первого сбоя или проверки.
В этот момент становится ясно: проблема не в синтаксисе, а в управлении. Как безопасно вносить изменения и как доказать, что все сделано по правилам. Поэтому сравнение Terraform vs Pulumi почти всегда упирается в требования ИБ, аудит и процесс согласований, а не в то, какой язык или формат удобнее.
«Контроль изменений» на практике означает простые вещи: должно быть понятно, кто и когда предложил правку; что именно изменится еще до применения; что изменение прошло ревью и было одобрено; и что можно восстановить прошлое состояние, объяснив причину (тикет, инцидент, запрос).
Представьте типичную ситуацию: в тестовом контуре нужно открыть доступ к сервису. Инженер делает правку вручную, а через неделю такая же правка случайно попадает в prod. Без следа, кроме «так получилось». IaC делает изменения повторяемыми и проверяемыми, но только если инструмент и процесс поддерживают ваши правила доступа и аудита.
На практике чаще всего выбирают между Terraform (или его форком OpenTofu для IaC) и Pulumi. Дальше важнее не «что легче написать», а «как это впишется в ваши контуры, роли, ревью, хранение состояния и требования к отчетности».
Какие требования ИБ стоит зафиксировать до выбора инструмента
Спор «Terraform vs Pulumi» часто начинается слишком рано. Сначала полезно договориться о требованиях ИБ к самому процессу изменений. Тогда выбор инструмента станет почти техническим, а не политическим.
Минимальный набор обычно включает:
- управляемость (понятно, кто и что меняет);
- аудит (можно восстановить цепочку решений);
- повторяемость (одинаковый результат при одинаковом входе);
- предсказуемость отката.
Если это не закрепить заранее, IaC быстро превращается в набор скриптов, а не в контролируемый процесс.
Где нужны точки контроля
Заранее определите, где изменение должно «остановиться» и дождаться проверки. Практичный базовый контур выглядит так:
- План: есть ли понятный список того, что изменится, до применения.
- Ревью: кто обязан проверить изменения и по каким критериям.
- Применение: кто имеет право запускать
applyи из какого окружения. - Откат: что считается откатом и кто его запускает.
Такой контур важен и для облака, и для on-prem инфраструктуры (например, в дата-центре на серверах и рабочих станциях), потому что риск один и тот же: неконтролируемые изменения.
Почему опасны изменения «из-под администратора»
Когда правки делаются вручную, без истории и согласования, теряются сразу три вещи: объяснимость (зачем), воспроизводимость (как повторить) и ответственность (кто сделал). В организациях с аудитом это заканчивается простым вопросом: «Покажите, на основании чего вы изменили правила сети или параметры сервера». Если ответа нет, проблема уже не техническая.
Чтобы не спорить на внедрении, заранее зафиксируйте правила: как оформляются изменения, кто утверждает, какие есть исключения для аварий, и что считается нарушением. После этого любой инструмент IaC оценивают по тому, насколько хорошо он поддерживает эти правила, а не «заменяет» их.
Terraform и OpenTofu простыми словами: что вы получаете
Terraform (и близкий к нему OpenTofu для IaC) позволяет описывать инфраструктуру как набор правил: что должно быть создано и с какими параметрами. Вы описываете желаемое состояние, а инструмент рассчитывает, какие действия нужны, чтобы привести реальность к этому описанию.
Типовой процесс строится вокруг двух шагов. Сначала вы делаете plan: инструмент показывает, что изменится, что будет создано или удалено. Потом apply: изменения применяются. Для ИБ это удобно тем, что plan можно сделать обязательным этапом ревью и согласования, а apply выполнять только из контролируемого места (например, из CI/CD).
OpenTofu появился как форк Terraform и часто рассматривается рядом с ним, потому что подход и язык конфигураций очень похожи. Для команд это обычно означает более мягкий переход: можно сохранить привычные практики, структуру репозиториев и большую часть модулей. При выборе смотрят на модель сопровождения, темп обновлений и то, как закрываются требования по аудиту и контролю зависимостей.
Отдельная ценность Terraform/OpenTofu - модули и реестры. Модуль - это переиспользуемый шаблон (например, «типовой сервер», «VPC/сеть», «набор IAM-ролей»). Когда команда стандартизирует модули, ручного труда становится меньше, а ошибок - тоже: вместо сотен строк каждый раз используется проверенная сборка.
Риски чаще всего не в самом инструменте, а вокруг него. Основные источники проблем - провайдеры (они выполняют реальные изменения), «плавающие» версии (инструментов, провайдеров, модулей) и командные привычки (обход plan, отсутствие ревью, слишком широкие права на apply).
Поэтому спор «Terraform vs Pulumi» на практике часто сводится к вопросу: готовы ли вы выстроить дисциплину вокруг версий, модулей и процесса plan/review/apply. Если да, Terraform/OpenTofu дают понятный фундамент, который легко связать с требованиями ИБ и аудита.
Pulumi простыми словами: чем отличается подход
Pulumi часто описывают как «инфраструктура как обычный код». Это значит, что вы описываете облако, сети, кластеры и доступы не в отдельном DSL, а на привычном языке программирования (например, TypeScript, Python, Go, C#). Для команды это меняет не только синтаксис, но и привычки: IaC живет рядом с приложениями, в тех же репозиториях, с теми же практиками.
Ключевое отличие Pulumi в том, что он сильнее опирается на подходы из разработки. Это дает больше гибкости там, где инженерная культура уже выстроена.
Что дает команде «обычный код»
Можно использовать типизацию, модульность и тесты. Это помогает ловить ошибки раньше и поддерживать единый стиль. На практике ценность чаще всего в трех вещах: меньше случайных ошибок с параметрами (за счет типов и автодополнения), возможность проверять важные правила тестами (например, «публичный доступ запрещен») и переиспользовать общие библиотеки стандартов (сети, роли, логирование) без копирования.
Риски для ИБ и управления изменениями
Обратная сторона свободы в том, что ошибиться тоже проще. В IaC на обычном языке можно незаметно добавить небезопасную логику, обойти согласованные шаблоны или спрятать критичное изменение внутри вспомогательной функции.
Поэтому для ИБ важнее не «какой инструмент», а правила вокруг него: обязательные ревью, запрет прямых применений с ноутбуков, проверка политик в CI/CD, фиксированные версии зависимостей.
Pulumi обычно хорошо приживается там, где команда уже живет по разработческим правилам и все изменения проходят через пайплайны. Например, если в организации параллельно строят инфраструктуру для разных контуров и нужен единый набор проверенных модулей для серверов, рабочих мест и системных компонентов, такой подход часто оказывается удобнее.
Разделение окружений dev test prod: практичные варианты
Разделять dev, test и prod нужно не ради «порядка», а ради управления рисками. В dev изменения частые и иногда грубые. В prod цена ошибки выше: простой сервисов, утечки данных, нарушение регламентов ИБ. Поэтому у окружений должны отличаться права, темп изменений и уровень контроля.
Самый надежный подход - разделение на уровне облачных аккаунтов, подписок или отдельных проектов (в зависимости от платформы). Тогда даже неверная переменная или ошибочная команда не сможет «дотянуться» до продовых ресурсов. Когда такой изоляции нет, компенсацией становятся ограничения по сети и IAM, но это заметно слабее.
Практичные схемы, которые одинаково применимы и в Terraform/OpenTofu, и в Pulumi:
- отдельные аккаунты/подписки для dev, test, prod и отдельные CI-пайплайны под каждое окружение;
- отдельные проекты или ресурсные группы внутри одного аккаунта, но с жесткими политиками и запретом на создание ресурсов «вне своей зоны»;
- отдельный state на каждое окружение (и на каждый крупный компонент), чтобы dev не мог затронуть prod через общий state.
Чтобы dev и prod не смешивались, помогают простые правила гигиены: одинаковая структура каталогов, префиксы в именах (например, prd-, tst-), теги окружения и владельца, плюс запреты на ручные изменения в prod. Если организация проходит аудит (например, в госсекторе или финансах), эти правила лучше закрепить в стандарте и проверять автоматически.
Доступ удобно строить по принципу «меньше прав в prod». Разработчики могут применять изменения в dev, в test - по запросу, а в prod - только через ревью и отдельную роль. Минимальный набор ролей можно описать так: apply в dev без доступа к prod; оператор test, который применяет изменения по согласованию; оператор prod, который применяет только из CI и после одобрения; и наблюдатель (read-only) для ИБ, аудита и владельцев систем.
Так разделение окружений dev test prod становится понятными границами ответственности, а не «договоренностью на словах».
Контроль прав на изменения: роли, ревью и политики
В IaC самый чувствительный вопрос не в том, кто умеет писать конфиги, а в том, кто может применить изменения к реальной инфраструктуре. Код можно обсудить и исправить. А один неосторожный apply способен открыть доступ в сеть, удалить диск или поднять дорогие ресурсы.
Чаще всего хватает четырех ролей (даже для небольшой команды): автор изменений (готовит код и описание, прикладывает обоснование), ревьюер (проверяет безопасность и соответствие стандартам), оператор применения (запускает план и применение в нужном контуре) и аудитор (смотрит журнал: кто и что менял, и почему).
Главный принцип: права на применение отделяются от прав на разработку. Автор может создавать ветки и pull request, но не должен иметь доступа к ключам/токенам, которыми выполняется применение в test и особенно в prod. Это снижает риск и упрощает расследования.
Процесс через pull request
Хорошая базовая схема строится вокруг pull request и обязательных проверок. Важно, чтобы проверка была не «на словах», а технически неизбежной:
- обязательное ревью (минимум 1-2 человека) и запрет прямых пушей в основную ветку;
- автоматический plan/preview в CI с сохранением результата как артефакта;
- отдельное подтверждение применения для prod (ручной шаг, окно изменений);
- логи: кто утвердил, кто применил, какой план применили.
Политики и ограничения
Политики помогают запретить опасные настройки еще до применения. Типовые правила: запрет публичных IP по умолчанию, запрет открытых security group (0.0.0.0/0 на админские порты), ограничение регионов и типов ресурсов, требование шифрования дисков и обязательных тегов для учета.
В организациях с жесткими требованиями (например, госсектор или финансы в Казахстане) удобно закрепить политики как код. Тогда не важно, используете вы Terraform/OpenTofu или Pulumi: правила остаются одинаковыми и проверяются на каждом PR.
State и секреты: где чаще всего прячутся риски
State (состояние) - это файл или хранилище, где IaC-инструмент держит «правду» о том, что уже создано: ID ресурсов, связи, параметры и часто фрагменты конфигурации. Если злоумышленник получает доступ к state, он видит устройство инфраструктуры и иногда - доступы к ней. Поэтому безопасность IaC почти всегда начинается не с кода, а со state.
Где хранить state и какие требования важны
Главное правило: state должен быть удаленным, с контролем доступа и журналированием. Локальный файл на ноутбуке разработчика - частая причина утечек и потери контроля.
Проверьте базовые вещи: кто может читать state и кто может менять; включено ли шифрование; есть ли блокировка на время применения (чтобы два человека не «накатили» изменения одновременно); как делаются резервные копии и как быстро можно восстановиться.
Простой пример: команда настраивает контуры dev/test/prod для кластера на серверах в дата-центре. Если state prod лежит рядом с dev и доступен тем же людям, одна ошибка в правах открывает путь к изменениям в бою без нужного согласования.
Секреты: не в коде и по возможности не в state
Секреты (пароли, токены, ключи) нельзя хранить в репозитории. Но важнее другое: секреты часто «случайно» попадают в state через параметры ресурсов. В Terraform/OpenTofu и в Pulumi это возможно, даже если вы не планировали.
Меры, которые действительно снижают риск:
- раздельные учетные данные и ключи для dev/test/prod;
- минимальные права для IaC (только то, что нужно для создания и изменения ресурсов);
- шифрование state на хранении и при передаче, плюс ограничение чтения;
- регулярная ротация ключей и токенов, особенно для prod;
- проверки в CI: не допускать секреты в переменных и файлах конфигурации.
Если инструмент поддерживает «секреты» на уровне движка (например, шифрование значений), это полезно, но не отменяет главного: проектируйте так, чтобы секреты не оказывались в state без необходимости.
Пошагово: как выбрать инструмент и не ошибиться с процессом
Выбор IaC часто «ломается» не на сравнении Terraform vs Pulumi, а на том, что процесс изменений не описан. Сначала договоритесь о правилах, а уже потом сравнивайте инструменты по удобству.
Начните с короткого документа на 1-2 страницы. Зафиксируйте требования ИБ и эксплуатации: где можно выполнять apply, какие журналы и артефакты нужно хранить и как долго, кто имеет право одобрять изменения, какие есть запреты (например, публичные IP или открытые порты без исключения).
Дальше определите модель окружений и владение ресурсами. Частая ошибка - когда dev, test и prod живут «как получится», а потом невозможно доказать, кто и зачем поменял сеть или правила доступа. Решите заранее: отдельные аккаунты или проекты, отдельные state, отдельные ключи и бюджеты, и кто является владельцем каждого слоя (сеть, вычисления, базы, мониторинг).
Практичный порядок действий:
- собрать требования ИБ и эксплуатации в один короткий документ и согласовать его;
- описать окружения и границы ответственности;
- зафиксировать процесс изменений: план, ревью, условия допуска к применению, окно работ, откат;
- сделать пилот на одном сервисе и проверить аудит, права, повторяемость, реакцию на инцидент;
- утвердить стандарты: структура репозитория, модули, именование, версии провайдеров и правил.
Пилот лучше делать на чем-то «настоящем», но не критичном: например, типовой сервис для внутреннего портала с сетью, несколькими VM и секретами. Если организация работает с госзаказом или строгим аудитом, сразу проверьте, что вы можете показать проверяющим: кто сделал изменение, кто одобрил, какой был план, и что именно применилось.
Финальная проверка простая: новый человек в команде должен уметь понять структуру, безопасно внести изменение через ревью и не иметь возможности случайно затронуть prod без явного допуска.
Пример сценария: организация с тремя контурами и обязательным аудитом
Представьте организацию с тремя контурами: dev, test и prod. Внутренние правила требуют локального контроля над изменениями, а аудит должен показывать: кто инициировал правку, кто одобрил, что именно изменилось и когда это попало в production. Дополнительно есть требование, чтобы доступ к облаку или виртуализации не раздавался разработчикам напрямую.
Процесс можно выстроить так, чтобы ручных действий в prod было минимум, а след для аудита - максимальный. Здесь важнее не синтаксис Terraform vs Pulumi, а то, как вы закрепите правила внесения и применения изменений.
Как выглядит поток изменений
Обычно работает схема, где изменения проходят через код-ревью и применяются только автоматикой:
- заявка на изменение с описанием цели, риска и плана отката;
- pull request в репозиторий IaC и обязательные ревью от эксплуатации и ИБ;
- автопроверки в CI: формат, линтеры, plan/preview и сохраненный отчет;
- apply только из CI по ручному подтверждению (approval) и только для нужного контура;
- сохранение отчета о применении и привязка к заявке для аудита.
Ключевой момент: у людей не должно быть привычки «быстро поправить руками, а потом перенести в код». В IaC это почти всегда заканчивается расхождением между тем, что описано, и тем, что реально работает.
Типовые ошибки при внедрении IaC
Самая частая ошибка - начинать писать Terraform или Pulumi-код, пока не договорились о правилах: кто может менять инфраструктуру, как проходит ревью, что считается «применением», где хранится состояние и кто его видит. Потом эти правила приходится встраивать на ходу, и команда быстро устает от конфликтов и ручных исключений.
Вторая боль - смешивание окружений. Когда dev, test и prod живут в одном state или в одном наборе учетных данных, любой промах превращается в инцидент. Это особенно опасно там, где обязателен аудит: сложно доказать, что изменения в prod делались контролируемо.
Часто встречается и проблема с секретами. Пароли, токены и ключи случайно оказываются в репозитории, в переменных CI или в файлах tfvars. Даже если репозиторий приватный, это риск: секреты копируются, попадают в логи и остаются в истории.
Еще один класс ошибок - «плавающие» изменения из-за версий. Не зафиксировали версии провайдеров, модулей и зависимостей, и один и тот же код на разных машинах или в разное время дает разные планы. В спорах «Terraform vs Pulumi» это часто забывают: проблема не в инструменте, а в дисциплине управления версиями.
Обычно внедрение ломают быстрее всего пять вещей: прямой доступ к prod без обязательного ревью и понятных ролей; один state на несколько окружений или команд; секреты в репозитории, в таск-трекере или в логах CI; отсутствие pinned-версий провайдеров и модулей; отсутствие проверенного пути отката и восстановления state.
Чтобы снизить риск, полезно заранее поставить минимальные «рельсы» процесса и проверить их на небольшом проекте: разделить окружения по отдельным state и учетным данным; включить обязательное ревью и запрет на ручные правки в prod; хранить секреты в специализированном хранилище, а не в коде; зафиксировать версии и добавить проверку plan в CI; провести тренировку восстановления state и отката после неудачного apply.
Чеклист перед запуском и следующие шаги
Перед стартом IaC важно убедиться, что процесс безопасен не только на бумаге. Даже если вы выбрали Terraform vs Pulumi, риски чаще всего появляются из-за настроек окружений, прав и хранения секретов.
Чеклист готовности перед первым боевым изменением:
- окружения dev, test, prod разделены (аккаунты, подписки, проекты или хотя бы отдельные state и сети);
- прямой apply в prod ограничен: только через CI/CD, по ролям, с обязательным ревью;
- включен аудит: логи действий, история планов и применений, понятный след «кто и зачем менял»;
- секреты защищены: нет паролей в репозитории и в логах, есть ротация и контроль доступа;
- есть план отката: как быстро вернуть прошлую конфигурацию и кто это делает.
Дальше проверьте, что эксплуатация действительно готова. Кто дежурит, если после изменения упал сервис в 02:00? Где лежит runbook с простыми шагами диагностики и восстановления? Как вы поймете, что причина именно в IaC-изменении, а не во внешнем факторе? Эти ответы лучше закрепить до запуска.
Через 1-2 месяца успех обычно видно по простым признакам: меньше ручных правок в консоли и больше изменений через код; инфраструктурные релизы стали предсказуемыми по времени и результату; любое изменение можно объяснить и воспроизвести по истории; количество аварий из-за конфигурации снизилось.
Следующие шаги: выберите небольшой пилот (например, типовой сервис и его сеть), соберите ИБ, инфраструктуру и разработку на совместный разбор требований, затем зафиксируйте роли, политики и правила разделения окружений.
Если нужна помощь на старте, GSE.kz может подключиться как системный интегратор: спроектировать контуры и доступы, собрать инфраструктуру (в том числе серверы и решения для ЦОД) и помочь выстроить поддержку эксплуатации с понятными регламентами."}
FAQ
С чего начать выбор между Terraform/OpenTofu и Pulumi, если важна ИБ?
Сначала зафиксируйте требования ИБ к процессу изменений: кто имеет право предлагать правки, кто обязан ревьюить, где можно выполнять применение, какие артефакты для аудита нужно сохранять и как устроен откат. Когда этот контур понятен, выбор Terraform/OpenTofu или Pulumi обычно сводится к тому, какой инструмент проще встроить в ваш CI/CD, роли и хранение состояния.
Зачем делать plan/preview обязательным этапом перед apply?
План нужен как обязательная «витрина изменений» до применения: вы заранее видите, что будет создано, изменено или удалено, и можете отправить это на ревью и согласование. Если разрешить применять без плана, вы теряете предсказуемость и усложняете аудит, потому что сложно доказать, что именно собирались менять и что в итоге изменилось.
Почему ручные изменения «в консоли» считаются риском для ИБ?
Потому что ручные правки почти не оставляют проверяемого следа: непонятно, кто изменил, что именно и по какой причине, а воспроизвести состояние потом трудно. В результате dev-эксперимент легко «протечет» в prod, а на аудите вы не сможете показать цепочку согласований и обоснование изменения.
Как правильно разделять dev/test/prod, чтобы dev не ломал prod?
Самый надежный вариант — физическая изоляция на уровне отдельных аккаунтов, подписок или проектов, чтобы ошибочная команда технически не могла достучаться до prod. Если такой изоляции нет, компенсируйте отдельными state, раздельными учетными данными и жесткими IAM/сетевыми ограничениями, но это обычно слабее и сложнее в сопровождении.
Какие роли минимально нужны, чтобы контролировать изменения в IaC?
Часто хватает модели, где автор готовит изменения и описывает цель, ревьюер проверяет безопасность и соответствие стандартам, оператор запускает применение из контролируемого окружения, а аудитору доступен журнал и артефакты. Ключевой принцип — отделить право писать код от права применять изменения в test и особенно в prod.
Как организовать процесс через pull request, чтобы он был «аудитопригодным»?
В PR-процессе важно запретить прямые пуши в основную ветку, сделать ревью обязательным, а plan/preview выполнять автоматически и сохранять результат. Для prod полезно требовать отдельное подтверждение применения и фиксировать, кто одобрил и кто применил, чтобы аудит мог восстановить всю цепочку решений.
Почему state — одна из главных точек риска в IaC и как его защитить?
State часто содержит идентификаторы ресурсов, связи и чувствительные детали конфигурации, поэтому его компрометация раскрывает устройство инфраструктуры и иногда доступы. Храните state удаленно, с шифрованием, строгим контролем чтения, журналированием и блокировкой на время применения, а для dev/test/prod держите разные state, чтобы исключить случайные пересечения.
Как не допустить утечку секретов при Terraform/OpenTofu или Pulumi?
Секреты нельзя хранить в репозитории, но важно помнить, что они могут «случайно» попасть в state через параметры ресурсов и в логи CI. Используйте отдельные учетные данные для окружений, минимальные права для IaC-ролей, регулярную ротацию и проверки в пайплайне, чтобы секреты не оказывались в конфигурационных файлах и переменных.
Какие политики безопасности стоит проверять автоматически при IaC-изменениях?
Политики помогают отлавливать опасные настройки до применения, например запрет открытых правил доступа или требование шифрования и обязательных тегов. Важно, чтобы проверки были автоматическими в CI/CD и одинаково работали для всех команд и окружений, тогда инструмент IaC становится деталью реализации, а правила остаются неизменными.
Когда Pulumi лучше, а когда логичнее Terraform/OpenTofu?
Если у вас сильная разработческая культура, общие языки программирования, тестирование и единые библиотеки стандартов, Pulumi может быть удобнее для масштабирования практик. Если важна предсказуемая декларативность, зрелая экосистема модулей и привычная модель plan/apply с простым ревью, чаще выбирают Terraform/OpenTofu; в любом случае решающим будет не синтаксис, а дисциплина версий, прав и пайплайнов.