25 сент. 2025 г.·8 мин чтения

Бэкенд для Terraform state: GitLab, S3 или Terraform Cloud

Сравните GitLab, S3 и Terraform Cloud для небольшой команды. Узнайте, как выбор Terraform state backend влияет на блокировки, доступ, резервные копии и восстановление.

Бэкенд для Terraform state: GitLab, S3 или Terraform Cloud

Почему хранение state становится командной задачей

Локальный файл state кажется удобным, когда всё делает один человек. Это меняется, как только второй человек запускает plan или apply. В этот момент Terraform state backend перестаёт быть личным удобством и становится общей инфраструктурой.

Файл state — это память Terraform. Он показывает, что уже существует, и как реальная инфраструктура соотносится с вашим кодом. Обычно там есть ID ресурсов, отслеживаемые атрибуты, сведения о зависимостях, outputs, а иногда и чувствительные значения.

Это важно, потому что облачная инфраструктура не любит путаницу. Если Terraform теряет связь с базой данных, load balancer или VPC ID, следующий apply может попытаться заменить то, что должно остаться на месте.

Небольшие команды сталкиваются с этим быстрее, чем ожидают. Один инженер меняет security group. Другой обновляет размер инстанса, опираясь на устаревший state. Второй apply может перезаписать первое изменение или завершиться на полпути с ошибкой. После этого никто не доверяет результату, а разбор занимает больше времени, чем сама работа.

State тоже нужно защищать тщательнее, чем думают многие команды. Данные провайдера, сгенерированные пароли, приватные endpoints, account ID и внутренние имена ресурсов могут попасть в файл или в резервные копии рядом с ним. Даже если Terraform скрывает часть значений в выводе, сохранённый state всё равно заслуживает такого же отношения, как и другие чувствительные операционные данные.

Поэтому выбор backend на самом деле — это вопрос командных правил. Вам нужен один общий источник правды, блокировка, которая не даёт запускать два apply одновременно, и контроль доступа, который соответствует тому, кто должен читать production или менять его. Ещё нужен скучный план восстановления: где лежат резервные копии, кто может их восстановить и как команда проверяет этот процесс до того, как что-то сломается.

Для небольшой команды простота побеждает. Один источник правды, понятные права доступа и отработанное восстановление избавляют от большего количества проблем, чем любой хитрый workflow.

Что сравнить перед выбором

Файлы state кажутся скучными, пока два человека не запустят apply одновременно или кто-то не раскроет секрет. Для небольшой команды лучший backend — обычно тот, который делает ошибки труднее и восстановление максимально спокойным.

Начните с блокировок. Если один человек начинает изменение, может ли backend сразу заблокировать вторую запись? Если блокировка зависнет, понимает ли команда, как безопасно её снять? Слабая блокировка кажется допустимой ровно до того момента, пока длинный вечер пятницы не докажет обратное.

Потом посмотрите на доступ простыми словами. Кто может читать state, кто может писать в него и кто может удалять старые версии? State часто содержит достаточно деталей, чтобы создать серьёзные проблемы, поэтому слишком широкий доступ — плохая привычка. Если можно разделить права на чтение и запись, так и сделайте.

История версий важнее, чем думают многие команды. Вам нужны старые снимки, понятный audit trail и резервные копии, которые не зависят от одного ноутбука или от того, что один администратор не забудет ручной шаг. Автоматическое versioning может спасти после неудачного import, force-unlock или поспешного ручного редактирования state.

Восстановление должно быть настоящим процессом, а не расплывчатой идеей. Задайте прямой вопрос: если кто-то повредит state сегодня, как вы восстановите версию за вчера? Ответ должен объяснять, кто утверждает восстановление, где лежит более старая копия и как команда проверяет, что восстановленный state всё ещё соответствует реальной инфраструктуре.

Будьте честны и насчёт администрирования. S3 обычно означает дополнительную настройку IAM, versioning, encryption и locking. GitLab может быть проще, если команда уже использует GitLab CI и уже хорошо делает резервные копии. Terraform Cloud снимает большую часть настройки, но нужно быть готовыми к его модели доступа и к тому, как он запускает изменения.

Хороший Terraform state backend — не тот, у которого больше всего функций. Это тот, который ваша команда сможет спокойно использовать и через шесть месяцев, с понятными правилами доступа и планом восстановления, который не держится на памяти одного человека.

GitLab как backend

Для небольшой команды GitLab часто оказывается самым удобным backend, если вы уже храните там код и CI. Не нужен ещё один аккаунт, ещё один счёт и ещё одна модель прав доступа. State остаётся привязанным к тому же проекту, где люди смотрят merge requests и запускают pipelines.

GitLab хранит state в своём управляемом хранилище. В GitLab.com GitLab обслуживает это хранилище за вас. В self-managed setup state живёт там, где хранит его ваш GitLab instance: на локальном диске или в object storage за instance. Эта деталь важна, потому что ваш план восстановления зависит не только от Terraform, но и от того, как админы GitLab делают backup этого хранилища.

Доступ и блокировки

GitLab довольно прост в управлении доступом. Большинство команд уже понимают роли в проекте, и эти роли обычно достаточно хорошо ложатся на доступ к state. При этом всё равно нужно проверить, кто может запускать apply и кто может видеть чувствительные outputs.

Блокировки работают хорошо для обычной повседневной работы. Если один pipeline или пользователь выполняет terraform apply, GitLab может заблокировать state, чтобы второй запуск не записывал данные одновременно. Уже этого достаточно, чтобы уберечь маленькие команды от классической путаницы "два человека применили изменения одновременно". Но плохие привычки это не исправляет. Если кто-то убьёт job на середине, команде всё равно нужен понятный порядок проверки и снятия зависших блокировок.

Резервные копии и восстановление

Прежде чем стандартизировать GitLab state, ответьте на несколько практических вопросов. Кто делает backup хранилища GitLab, где лежит state? Как часто команда проверяет восстановление, а не просто создаёт копии? Можно ли быстро экспортировать current state, если позже вы захотите перейти на S3 или Terraform Cloud? Кто может снять блокировку после неудачного pipeline? Где лежат заметки по восстановлению, чтобы вся команда могла ими воспользоваться?

GitLab лучше всего подходит, когда команда небольшая, GitLab уже обслуживает репозиторий и CI, и вам нужно одно место для управления доступом. Это разумный выбор по умолчанию для стартапа с двумя–восьмью инженерами. Если у вас уже есть self-hosted GitLab с CI/CD, что часто бывает у компактных команд, хранение state там убирает ещё один лишний элемент без усложнения повседневной работы.

S3 как backend

S3 даёт небольшой команде много контроля. Это полезно, когда большая часть инфраструктуры уже работает в AWS, но это также значит, что ранние решения лучше принять сразу, а не пытаться исправлять их потом.

Первое правило простое: отделите доступ к state от доступа к Git. Разработчику может понадобиться читать репозиторий GitLab и смотреть merge requests, но это не значит, что он должен читать или менять production state. Используйте AWS IAM roles для людей и CI jobs и относитесь к S3 bucket как к production-инфраструктуре, а не как к очередному файлу проекта.

Настройте правила bucket в первый же день. Команды, которые откладывают это на потом, обычно продолжают работать на слабых настройках по умолчанию. Включите versioning, запретите public access, включите server-side encryption, ограничьте доступ именованными ролями и убедитесь, что audit logs действительно существуют.

Versioning важнее, чем кажется многим командам. State меняется часто, и плохая запись, сломанная миграция или поспешная ручная правка могут оставить после себя беспорядок. С object versioning восстановление обычно сводится к контролируемому откату, а не к ночной пересборке.

S3 также заставляет задуматься о блокировках. Само хранилище не мешает двум apply записывать данные одновременно. Многие команды используют S3 вместе с DynamoDB locking, чтобы параллельные запуски быстро завершались ошибкой вместо повреждения state. Если ваша команда использует GitLab CI, это ещё важнее, потому что retry или второй pipeline может стартовать раньше, чем кто-то заметит проблему.

Кто-то должен отвечать за IAM roles, настройки encryption и audit logs. В небольшой команде это часто senior engineer или человек, который выполняет роль fractional CTO. Если ответственного нет, права расползаются, временные исключения становятся постоянными, и никто не знает, кто и что поменял.

S3 больше всего подходит, когда вам нужен более жёсткий контроль доступа, шифрование под вашим управлением или понятные шаги восстановления внутри AWS. Команда, которая работает с AWS workloads и GitLab CI, часто приходит именно к этому варианту: GitLab управляет кодом, AWS IAM управляет доступом к state, S3 хранит файл, DynamoDB отвечает за блокировки, а история версий даёт практичный путь восстановления.

Terraform Cloud как backend

Безопасно настройте S3
Получите помощь с IAM, versioning, encryption и DynamoDB locking для Terraform state.

Terraform Cloud даёт небольшой команде самый быстрый путь к общему state. Вы создаёте workspace, подключаете репозиторий, если хотите remote runs, добавляете переменные и начинаете plan и apply, не строя своё хранилище, блокировки и правила доступа.

Это особенно важно, как только одним и тем же infrastructure пользуется больше одного человека. Terraform Cloud хранит файл state в workspace и выполняет планы у себя. Один workspace обрабатывает один запуск за раз, так что два инженера не записывают state одновременно. Для небольшой команды это убирает одну из самых частых причин повреждения state почти без настройки.

Права доступа здесь тоже проще, чем в большинстве self-managed вариантов. Можно дать одной группе доступ на чтение, другой разрешить ставить план в очередь и ограничить право apply теми, кто отвечает за production. Такой раздельный доступ хорошо работает, когда founder, один инженер и внешний advisor должны иметь разные уровни контроля.

История state тоже понятна. Terraform Cloud хранит старые версии state, поэтому если неудачный apply всё же прошёл, можно посмотреть, что изменилось, сравнить версии и вернуть более ранний state. Безопасная привычка простая: восстановить старую версию, запустить новый plan и убедиться, что Terraform показывает только ожидаемые изменения, прежде чем кто-либо снова запустит apply.

Самое большое преимущество — экономия времени на настройке. Вам не нужно настраивать S3, DynamoDB, bucket policies, параметры encryption или правила хранения state в GitLab. Плюс вы получаете remote runs, variables, run history и policy controls в одном месте. Если команде нужен аккуратный процесс как можно быстрее, Terraform Cloud трудно превзойти.

Но есть и компромисс — меньше контроля. Ваш workflow зависит от другого сервиса, и некоторым командам это не нравится. По мере роста использования могут расти и расходы. Remote runs могут казаться ограничивающими, если вам нужен нестандартный сетевой доступ, особые инструменты или жёсткие правила о том, где хранятся state и secrets.

Для небольшой команды, которая хочет меньше движущихся частей, Terraform Cloud часто оказывается наименее болезненным выбором. Для команды, которая уже хорошо выстроила AWS или GitLab-инфраструктуру и хочет большего контроля, он может показаться слишком ограничивающим.

Простой путь выбора для небольшой команды

Для небольшой команды правильный backend обычно тот, который не создаёт лишнего шума. Если хранение, блокировки и восстановление зависят от памяти одного человека, стандартом это ещё не стало.

Сначала разберитесь, кто вообще запускает Terraform. Размер команды важен, но привычки важнее. Возможно, один инженер всё ещё запускает планы и apply вручную. Возможно, код проверяют несколько человек, но apply делает только один или два. Возможно, CI запускает apply после approval. Возможно, подрядчикам нужен доступ только на чтение, а кому-то вне engineering — доступ к audit logs. Эти детали важнее, чем страницы маркетинга.

Когда станет понятно, кто что делает, задайте одно понятное правило для записей. Простое правило работает хорошо: многие могут читать state, очень немногие могут его менять, а backend принимает записи только от утверждённых CI jobs или от назначенных операторов. Это уменьшает число случайных apply и сильно упрощает разбор инцидентов.

Затем выберите минимально сложную схему, которую команда действительно сможет поддерживать. Если ваша команда каждый день работает в GitLab и понимает его модель прав, GitLab может оказаться самым удобным вариантом. Если основная инфраструктура уже в AWS, S3 может ощущаться естественнее. Если никто не хочет обслуживать plumbing для backend, Terraform Cloud может сэкономить время. Выбирайте вариант, который команда уже понимает.

Не переносите сразу все workspace. Сначала протестируйте один низкорисковый проект, например staging-среду или внутренний сервис. Пройдите несколько обычных изменений, один неудачный запуск и одну ошибку с блокировкой или доступом намеренно. Маленькие тесты быстро вскрывают неудобные детали.

Перед полноценным запуском опишите шаги восстановления простыми словами и храните их там, где команда их найдёт. В документе должны быть пять быстрых ответов: кто может снять блокировку, где лежит резервная копия, как проверить последнюю рабочую версию, когда нужно остановить apply и проверить drift, и кто принимает финальное решение во время восстановления.

Если команда не может ответить на эти вопросы за две минуты, лучше не спешить со стандартом. Спокойная настройка всегда лучше хитрой.

Реалистичный пример

Выберите правильный backend
Получите практичное второе мнение по GitLab, S3 или Terraform Cloud для вашей команды.

Представьте стартап из четырёх человек с одним AWS account. Founder рано настроил Terraform и держал state-файл на ноутбуке. Сначала это работает. Один человек вносит изменения, один человек помнит, что произошло, и ничего не пересекается.

Это перестаёт работать, когда приходит второй инженер. Теперь два человека могут запускать plan и apply с разных машин и с разными копиями одного и того же state. Один инженер добавляет SQS queue. Через несколько часов другой меняет ECS service, опираясь на старый локальный state-файл. Команда начинает спрашивать в чате: "Ты уже применил это?" Вот в этот момент локальный state перестаёт быть удобным и становится рискованным.

В такой ситуации GitLab часто оказывается разумным выбором, если стартап уже хранит там код и CI. Он даёт команде одно место для репозитория, pipelines и state под контролем доступа. S3 тоже может работать хорошо, но для небольшой команды это обычно означает больше настройки вокруг bucket, IAM и locking. Terraform Cloud тоже надёжный вариант, но он добавляет ещё один инструмент ещё до того, как у команды появится чёткая причина так делать.

На этом этапе достаточно простого правила. Только GitLab CI должен запускать apply в main branch. Инженеры могут запускать plan в feature branches. Только два человека должны иметь возможность снимать блокировку state или менять credentials backend.

Одно это правило убирает большую часть проблем формата "кто это поменял?" одним движением.

Команде также стоит регулярно проводить восстановление по сценарию. Раз в месяц берите staging stack и тренируйтесь восстанавливаться после плохого изменения state. Сохраните последний рабочий снимок state, убедитесь, что живые AWS resources ему по-прежнему соответствуют, затем воспроизведите восстановление этого снимка и запустите новый plan. Если plan показывает неожиданные удаления, остановитесь и исправьте несоответствие до того, как production вообще увидит проблему.

Позже они смогут перейти на другой вариант, если setup перерастёт текущую форму. Типичные причины — второй AWS account, несколько команд, работающих с одной и той же инфраструктурой, более строгие правила approval или необходимость в более глубоком audit и policy control. До этого момента GitLab делает процесс простым и менее подверженным ошибкам.

Ошибки, которые потом вызывают боль

Backend для Terraform обычно сначала ломается по скучному сценарию. Команда работает, никто не записывает правила, а через шесть месяцев никто не помнит, кто может читать state, кто может снимать блокировки и как восстановить его после неудачного запуска.

Одна из самых частых ошибок — дать доступ на чтение всем подряд. Файлы state могут раскрывать resource ID, приватные endpoints, а иногда и secrets, если что-то пошло не так выше по цепочке. Разработчику, которому нужен только plan output, не нужен доступ к сырому state, как и каждому CI job.

Команды ещё и пропускают versioning, потому что backend кажется достаточной защитой сам по себе. Обычно это не так. Если вы используете S3, включите versioning. Если вы используете state в GitLab или Terraform Cloud, заранее узнайте, какие у вас есть история и варианты восстановления, прежде чем они понадобятся. Потерянный или повреждённый state-файл может остановить изменения для всей команды.

Ещё одна проблема — негласные правила. Люди говорят что-то вроде "не делай force unlock, если не уверен" или "запускай apply только из этого pipeline", но никогда не записывают это в короткий документ. Потом одна неудачная apply превращается в длинную переписку в Slack, пока все гадают. Запишите, кто может снять state с блокировки, кто может его переносить и что делать после частичного apply.

Смешивание production и test state в одном месте тоже создаёт проблемы. В начале это кажется проще, особенно для небольшой команды, но один неправильный workspace, path или набор переменных может направить test-изменения в production state. Разделяйте среды с самого начала. Разные пути хранения помогают, а разные права — ещё больше.

Самая болезненная ошибка — ждать outage, чтобы проверить восстановление. Recovery — это не теория. Выберите непроизводственную среду и потренируйтесь: восстановите старую версию state, запустите plan и посмотрите, что изменилось, проверьте, что команда умеет аккуратно работать с блокировками, и запишите точные шаги, которые сработали.

Одна такая тренировка часто вскрывает настоящие пробелы. Возможно, backup существует, но к нему никто не может получить доступ. Возможно, процесс знает только один человек. Возможно, команда обнаружит, что восстановление Terraform state занимает больше времени, чем ожидалось. Лучше узнать это тихим днём, чем во время production-инцидента.

Быстрые проверки перед стандартизацией

Избегите переделки backend позже
Выберите setup, который подходит вашей команде сейчас и останется удобным через шесть месяцев.

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

Назначьте одного ответственного за настройку. Этот человек должен создать backend, написать заметку для команды и оставить первую версию простой. Ответственный важен, потому что маленькие пробелы быстро накапливаются: нет политики bucket, token с лишним доступом или отсутствует письменный процесс восстановления.

Потом уберите проблему героя-одиночки. По крайней мере два человека должны уметь безопасно снимать блокировку state, доставать backup и восстанавливать последнюю рабочую версию. Если это может сделать только один человек, у команды нет процесса. У неё есть слабое место.

Достаточно короткого чек-листа. Ограничьте доступ на запись несколькими людьми и CI jobs, которые действительно запускают apply. Используйте один и тот же pattern backend во всех репозиториях, если только нет веской причины делать иначе. Храните шаги восстановления там, где команда быстро их найдёт. Намеренно проверьте flow блокировок. Отработайте восстановление на низкорисковом проекте.

Одна небольшая тренировка может сэкономить часы позже. Возьмите некритичный workspace, создайте свежую резервную копию, сымитируйте плохое изменение и восстановите state вместе со вторым участником команды по письменной инструкции. Если заметки расплывчаты или права доступа мешают, исправьте это сейчас, а не во время outage.

Держите backend скучным, ограничьте круг тех, кто может его менять, и сделайте восстановление рутиной. Для небольшой команды это обычно важнее, чем охота за идеальным списком функций.

Что делать дальше

Небольшой команде лучше помогает одно понятное решение, чем бесконечный спор. Выберите backend, который соответствует текущему размеру, рискам и привычкам, а потом запишите простыми словами, почему вы его выбрали. Двух-трёх предложений достаточно, если они описывают блокировки, доступ, backup и то, кто будет это поддерживать.

Не начинайте с самого чувствительного проекта. Сначала проведите короткий пилот на низкорисковом стеке, например на dev-среде или внутреннем инструменте. Так у вас появится безопасное место, чтобы проверить блокировки state, права команды и точные шаги восстановления, если кто-то повредит state-файл или случайно удалит доступ.

Лучше всего работает простой rollout. Выберите один backend и зафиксируйте причину. Протестируйте его на одном небольшом проекте в течение недели или двух. Исправьте пробелы в правах, прежде чем переносить больше стеков. Опишите шаги восстановления вместе с остальной документацией команды. Проводите тренировку восстановления каждые несколько месяцев.

Доступ обычно создаёт больше проблем, чем сам backend. Прежде чем переносить больше проектов, проверьте, кто может читать state, кто может писать в него и кто может менять настройки backend. Если эти правила расплывчаты, сбавьте темп и сначала исправьте их. Плохая модель прав может превратить обычное изменение в длинный день.

Восстановление заслуживает настоящей тренировки, а не заметки в wiki, которую никто не проверял. Выберите спокойный день, восстановите недавнюю версию и убедитесь, что команда может вернуться к рабочему состоянию без догадок. Если тренировка занимает час путаницы, это полезный сигнал: процесс восстановления всё ещё нужно доработать.

Если перед стандартизацией вам нужен внешний взгляд, Oleg Sotnikov из oleg.is консультирует стартапы и небольшие команды по выбору backend, правилам доступа и планам восстановления. Такой обзор помогает, когда вы выбираете между GitLab state, S3 и Terraform Cloud и хотите не переделывать решение через несколько месяцев.