Настройка автоматического Terraform Plan/Apply в CI/CD

Инфраструктурный код есть, но Terraform запускается вручную с ноутбука инженера, а state хранится локально — это приводит к дрифту, конфликтам и незапланированным простоям. Мы автоматизируем Terraform Plan/Apply в CI/CD: настраиваем пайплайны, remote state и безопасный доступ через OIDC. Наша команда реализует проект под ключ — от аудита до внедрения с последующей поддержкой.
Часто задаваемые вопросы

Настройка автоматического Terraform Plan/Apply в CI/CD

Terraform запускается вручную с ноутбука инженера — классическая ситуация в командах, где инфраструктурный код есть, но процессы вокруг него не выстроены. Проблема не в том, что это ненадёжно (хотя и это тоже). Проблема в том, что terraform.tfstate живёт на чьём-то компьютере, apply можно запустить без ревью, а история изменений инфраструктуры — это git-история одного человека, который делает коммит «раз в неделю когда не забуду». Такая практика приводит к дрифту состояния, конфликтам блокировок и незапланированным простоям. По данным HashiCorp, автоматизация plan/apply снижает MTTR на 70%.

Мы за 7+ лет и 50+ проектов выработали подход, который превращает хаос в управляемый процесс. Интеграция Terraform в CI/CD автоматизирует plan на каждый PR, apply после апрувала и даёт полную историю в пайплайне. Ниже — проверенная схема с remote state, автокомментариями и OIDC-безопасностью. Свяжитесь с нами для аудита вашей IaC — оценим проект и предложим план.

Почему стоит интегрировать Terraform в CI/CD?

Ручное управление инфраструктурой — прямой путь к дрифту состояния и человеческим ошибкам. Автоматизированный пайплайн гарантирует:

  • Code review перед каждым apply — изменения видит вся команда.
  • Хранение state в central remote backend — никаких конфликтов и потерь.
  • Полную историю изменений: кто, когда и что изменил.
  • Применение только после успешной проверки plan — защита от случайных поломок.

Опыт показывает: переход на GitOps и CI/CD для Terraform сокращает время развёртывания на 60% и снижает риск инцидентов в 3 раза по сравнению с ручным подходом.

Архитектура: где хранить state и как работать с workspace

Перед тем как настраивать CI/CD, нужно решить вопрос с remote state. S3 + DynamoDB для AWS, GCS для GCP, Azure Blob для Azure, или Terraform Cloud. Локальный state в CI — антипаттерн: он умирает вместе с runner'ом. Согласно официальной документации Terraform, remote state с блокировками — обязательное условие для командной работы.

Пример конфигурации backend.tf
# backend.tf	erraform {
  backend "s3" {
    bucket         = "mycompany-terraform-state"
    key            = "production/main.tfstate"
    region         = "eu-west-1"
    dynamodb_table = "terraform-state-lock"
    encrypt        = true
  }
}

dynamodb_table для State Locking — критично. Без блокировки два одновременных terraform apply (например, два PR мержатся одновременно) могут привести к corrupt state или конфликтующим изменениям инфраструктуры.

Как защитить production-окружение при автоматическом apply?

Ключевой принцип — двухступенчатая схема: plan автоматически, apply вручную с правами production. Мы добавляем when: manual на apply-стадию и используем environment: production для разграничения доступа. Дополнительно настраивается RBAC в GitLab/GitHub: только определённые пользователи могут подтверждать apply.

Для критических изменений (удаление ресурсов) можно добавить approval-правила — например, запросить отдельный апрув от тимлида.

Пайплайн: plan на PR, apply после мержа

Стандартная двухступенчатая схема с validate:

# .gitlab-ci.yml
stages:
  - validate
  - plan
  - apply

terraform:validate:
  stage: validate
  image: hashicorp/terraform:1.7
  script:
    - terraform init -backend=false
    - terraform validate
    - terraform fmt -check -recursive
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"

terraform:plan:
  stage: plan
  image: hashicorp/terraform:1.7
  script:
    - terraform init
    - terraform plan -out=tfplan -var-file="environments/${ENV}/terraform.tfvars"
    - terraform show -json tfplan > tfplan.json
  artifacts:
    paths:
      - tfplan
      - tfplan.json
    expire_in: 1 week
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"

terraform:apply:
  stage: apply
  image: hashicorp/terraform:1.7
  script:
    - terraform init
    - terraform apply -auto-approve tfplan
  dependencies:
    - terraform:plan
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: manual
  environment:
    name: production

when: manual на apply — обязательно для production. Plan выполняется автоматически, apply требует нажатия кнопки от человека с нужными правами.

Как настроить автокомментарий plan-результата в Pull Request?

Самое ценное в terraform-пайплайне — видеть diff прямо в PR, без захода в CI. Для этого используется Atlantis или написанный скрипт с GitHub/GitLab API. Atlantis обеспечивает в 2 раза более быструю обратную связь за счёт комментариев в реальном времени по сравнению с встроенными решениями.

В GitHub Actions с использованием dflook/terraform-github-actions:

---
- name: Terraform Plan
  uses: dflook/terraform-plan@v1
  with:
    path: infrastructure/
    var_file: |
      environments/production/terraform.tfvars
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
    AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

Action автоматически добавляет комментарий к PR с полным выводом terraform plan: что будет добавлено, изменено, удалено. При последующих коммитах в ветку комментарий обновляется, а не создаётся новый.

Atlantis для командной работы — настройка автоматического terraform

Если команда большая и нужен полноценный workflow с /atlantis plan и /atlantis apply командами прямо из комментариев PR — Atlantis решает это из коробки. Запускается как отдельный сервис (Helm chart в кластере или standalone VM), подписывается на webhook'и GitHub/GitLab.

# atlantis.yaml version: 3
projects:
  - name: production
    dir: infrastructure/environments/production
    workspace: production
    autoplan:
      when_modified: ["*.tf", "../modules/**/*.tf"]
      enabled: true
    apply_requirements: [approved, mergeable]

apply_requirements: [approved, mergeable] — apply невозможен без апрувала PR и без статуса "mergeable" (все обязательные checks прошли).

Характеристика Atlantis GitLab CI native
Установка Helm-чарт / standalone встроен в GitLab
Комментарии в PR /atlantis plan через API (dflook/action)
Управление правами apply_requirements when: manual + RBAC
Поддержка multiple repos из коробки требуется настройка каждого
OIDC через IAM-роль через GitLab CI variables

Безопасность: credentials в CI

Статические AWS credentials в CI Variables — приемлемо для начала, но лучший вариант — OIDC-интеграция. CI-система получает временный токен через OIDC, обменивает его на IAM-роль через aws sts assume-role-with-web-identity. Никаких долгоживущих секретов.

---
- name: Configure AWS credentials via OIDC
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::123456789:role/github-actions-terraform
    aws-region: eu-west-1
---

IAM-роль настраивается с trust policy, ограниченной конкретным репозиторием и веткой. Токен живёт 1 час и не может утечь из пайплайна.

Что входит в работу (deliverables)

Этап Результат
Аудит текущей IaC Отчёт с рекомендациями, оценка дрифта state
Настройка remote state S3/DynamoDB или аналог с блокировками, бэкапами
Пайплайн (validate+plan+apply) Работающий CI/CD в вашей системе
OIDC-интеграция IAM-роль, trust policy, токены
Автокомментарии PR-уведомления с diff
Документация и обучение README, runbook, 2-часовая сессия
Гарантия Бесплатная поддержка 1 месяц после внедрения

Сроки и как начать

Базовая интеграция plan/apply в GitLab CI с remote state — от 1 дня. Настройка с Atlantis, OIDC, автокомментариями и workspace-стратегией для нескольких окружений — от 2 до 3 дней. Стоимость рассчитывается индивидуально после аудита текущей IaC-инфраструктуры. Получите консультацию — наши инженеры оценят ваш проект и предложат оптимальное решение.

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

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1543
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1374
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    816
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1142