linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
Intro
Lessons
Footer
linuxlab-УчебникиЦеныО платформеКонфиденциальность и куки
Copyright © 2026 LinuxLab. Все права защищены.
linuxlab.io
Учебники▾
  • Линукс и сети
    Файловая система, процессы, TCP/IP, BGP и OSPF
    →
  • Terraform и IaC
    HCL, state, plan/apply на sandbox LocalStack
    →
  • Git и GitHub
    Объектная модель, plumbing, ветвление, GitHub Actions
    →
Все учебники →
ЦеныО платформеВойтиСоздать аккаунт
/
  • Введение
  • Уроки
  • How it works
  • База знаний
  • Шпаргалка
  • Capstone
  • Собеседование
Cluster

← все кластеры

Workflow и CI/CD

Что происходит между plan и apply. Зачем fmt и validate в pipeline. Как ходить в AWS из GitHub Actions без долгоживущих ключей. Drift detection, require-approval, разделение state по env. Вопросы DevOps/SRE-ролей.

6 вопросов · ~23 мин чтения

Questions

На этой странице

  1. 01Что делает `terraform plan` против `apply`? Что апплай делает с plan'ом?
  2. 02Что делает `fmt`, что делает `validate`, и зачем оба в CI?
  3. 03Как ходить в AWS из GitHub Actions без долгоживущих ключей?
  4. 04Как настроить drift detection в CI? Что мониторить?
  5. 05Как разделять state по env: dev / stage / prod?
  6. 06Как устроен типовой CI для Terraform: PR, plan, approval, apply?

#plan-vs-apply-semantics

juniorчасто

Что делает `terraform plan` против `apply`? Что апплай делает с plan'ом?

Что отвечать

Plan читает state + HCL, опрашивает провайдер (refresh), считает diff, печатает что собирается сделать и почему. Ничего не меняет в провайдере. Apply берёт уже посчитанный план (из файла `-out=plan.tfplan` или на лету через interactive prompt) и выполняет change set. Если apply запускается без `-out`, он сам делает plan под капотом, потом применяет - это удобно локально, но в CI правильно: plan→artifact→apply из artifact'а. Так ревью видит ровно то, что катится.

Что хотят услышать

Senior должен: - назвать ключевую разницу: plan side-effect free (кроме refresh), apply мутирует и обновляет state - объяснить `-out=plan.tfplan`: бинарный артефакт, в нём зафиксирован снимок state + change set; apply применяет ровно этот change set - сказать что между plan и apply state может измениться (кто-то зашёл в Console и поменял) - apply на stale план может упасть с «expected state did not match» - упомянуть `terraform show -json plan.tfplan` для парсинга и post-processing в CI (cost estimation, OPA policy)

Подводные камни

  • ✗ Бегать `apply -auto-approve` в CI без сохранённого plan'а - что ревьюер видел и что покатилось может расходиться
  • ✗ Не учитывать что refresh между plan и apply может найти новый drift, apply на stale-plan'е упадёт
  • ✗ Сохранять plan-файл как artifact публично - он содержит state secrets в plain

Follow-up

  • ? Зачем `-out` если можно `terraform apply` напрямую?
  • ? Что произойдёт если apply пытается применить устаревший plan?
  • ? Как защитить tfplan-артефакт в CI? Что в нём чувствительно?

Глубина в базе знаний

  • terraform plan: посмотреть, что Terraform собирается сделать
  • terraform apply: применить план в реальном облаке
  • Plan-as-artifact и automation mode в CI
tags: workflow, plan, apply

#fmt-validate-in-pipeline

juniorчасто

Что делает `fmt`, что делает `validate`, и зачем оба в CI?

Что отвечать

`fmt` форматирует HCL: отступы, выравнивание, кавычки. Не проверяет смысл. `validate` парсит HCL и проверяет внутреннюю консистентность: типы, references к несуществующим переменным/ресурсам, обязательные аргументы. Не подключается к провайдеру и не делает refresh - быстро. В CI оба нужны: `fmt -check` блокирует PR с неотформатированным кодом, `validate` ловит typos до того как кто-то ждал 10 минут на plan, чтобы увидеть «unknown variable foo».

Что хотят услышать

Кандидат должен: - различить роли: fmt = стиль, validate = синтаксис + базовая семантика - сказать что `fmt -check -recursive` для CI, `fmt` без флага для локального fix-on-save - назвать что validate не находит ошибок типа «такой instance type не существует в AWS» - это узнается только в plan через провайдер - упомянуть `tflint` как более глубокий статический анализ: знает про специфику провайдеров (правильные instance type, deprecated arguments)

Подводные камни

  • ✗ Поставить только `validate` в CI без `fmt -check` - в репо попадает код разных стилей, diff'ы шумные
  • ✗ Думать что validate ловит ВСЕ ошибки - не ловит логические: бесконечный count, неверный регион в provider
  • ✗ Бегать `validate` в каждой подпапке отдельно - на большом repo тяжело; `terraform validate` после `init` корректнее

Follow-up

  • ? Чем `tflint` глубже чем `terraform validate`?
  • ? Зачем `fmt -recursive` и почему по умолчанию не recursive?
  • ? Что нужно сделать перед `validate` чтобы он не ругался на провайдеры?

Глубина в базе знаний

  • terraform fmt: каноничное форматирование HCL
  • terraform validate: проверка HCL без облака
  • [[tf-fmt-validate-ci]]
tags: workflow, ci, fmt, validate

#oidc-aws-no-static-keys

seniorчасто

Как ходить в AWS из GitHub Actions без долгоживущих ключей?

Что отвечать

OIDC. GitHub выдаёт runner'у короткоживущий JWT с claims про репозиторий и ветку. В AWS настраиваешь Identity Provider (token.actions.github.com) и IAM role с trust policy, которая принимает JWT с конкретными claims (`sub = repo:owner/repo:ref:refs/heads/main`). Runner вызывает `aws-actions/configure-aws-credentials@v4`, экшен обменивает JWT на `AssumeRoleWithWebIdentity`, получает temporary credentials. Срок жизни - сессия job'а. AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY в Secrets больше не нужны.

Что хотят услышать

Senior должен: - объяснить trust policy с конкретным `sub`-claim: только PR из конкретной ветки или org/repo - принимается, остальное - 403 - назвать `permissions: id-token: write` в job-level - без этого GitHub не выдаст JWT - сказать что временные credentials живут только пока run - утечка из логов не даёт долгосрочного доступа - упомянуть пагубный паттерн `sub = repo:owner/repo:*` - принимает JWT из любой ветки и любого PR, включая forks; правильно ограничивать веткой или environment

Подводные камни

  • ✗ Дать trust policy с wildcard `sub = repo:owner/repo:*` - любой PR из fork'а может ассимить роль (если CI запускается на PR)
  • ✗ Забыть `permissions: id-token: write` и получить пустой JWT, AWS-call падает с UnauthorizedOperation
  • ✗ Использовать default audience: `sts.amazonaws.com` ожидает конкретный audience-claim, иначе AssumeRoleWithWebIdentity отклоняет

Follow-up

  • ? Что должен содержать `sub`-claim чтобы trust policy его приняла?
  • ? Чем `id-token: write` отличается от других permissions?
  • ? Как ограничить роль только конкретным environment в GitHub?

Глубина в базе знаний

  • OIDC между GitHub Actions и AWS, без access keys
  • Plan-as-artifact и automation mode в CI
tags: cicd, security, aws, oidcbook: Packt.Terraform.Cookbook.pdf:ch11

#drift-detection-cron

intermediateиногда

Как настроить drift detection в CI? Что мониторить?

Что отвечать

Cron-job в GitHub Actions раз в час: `terraform init && terraform plan -detailed-exitcode -lock-timeout=5m`. Exit 0 = нет изменений, exit 2 = есть, exit 1 = ошибка. На exit 2 - шлёшь алерт в Slack/PagerDuty с ссылкой на run-логи. Алерт даёт владельцу понять что что-то поменялось в инфре без PR. Реагировать можно: либо apply'ить через обычный PR, возвращая state в HCL, либо ассимилировать drift через update HCL.

Что хотят услышать

Senior должен: - назвать `-detailed-exitcode` как кирпич, без него парсить stdout - хрупко - различить shum (cloud-managed attrs: ASG capacity, lambda function ARN после blue/green) и реальный drift (security group открыл порт, тег убрали) - упомянуть `ignore_changes` для атрибутов которые штатно меняются не-Terraform'ом - сказать про Terraform Cloud / TFE drift detection как штатное решение из коробки с UI и nofification - назвать что drift на shared modules - сигнал что несколько root'ов трогают один ресурс, надо разрулить владение

Подводные камни

  • ✗ Поднять drift detection без exclusion list - алерты сыпятся каждый час, инженеры начинают игнорировать (alert fatigue)
  • ✗ Использовать `plan` с `-lock=false` - конкурируешь с настоящим apply, можешь увидеть transient state
  • ✗ Делать drift detection на staging чаще чем на prod - редкая комбинация, обычно наоборот

Follow-up

  • ? Что такое cloud-managed drift и как его отличить от реального?
  • ? Чем drift detection в Terraform Cloud отличается от cron в GitHub Actions?
  • ? Как настроить alert routing чтобы избежать fatigue?

Глубина в базе знаний

  • [[tf-drift-detection]]
  • terraform plan: посмотреть, что Terraform собирается сделать
  • Plan-as-artifact и automation mode в CI
tags: cicd, drift, monitoring

#state-per-env-and-isolation

intermediateчасто

Как разделять state по env: dev / stage / prod?

Что отвечать

Три подхода. Один - workspaces: один root, разные state-файлы под именами env. Прост, но один HCL покрывает все env'ы - сложно делать разные топологии. Два - отдельные root-директории (`envs/dev/`, `envs/prod/`), общий код через child-модули. Контроль явный, версии модулей разные, но дублирование backend-конфига. Три - terragrunt или аналог: генератор который разворачивает env-конфиг в root на лету. Большинство prod-команд выбирает (2) или (3); workspaces оставляют для feature-веток внутри dev.

Что хотят услышать

Senior должен: - различить три подхода и для каждого назвать сильную сторону - сказать что prod'у нужны разные настройки от dev (multi-az, RDS size, backup-policy) - workspaces плохо подходят, потому что условные ветвления по `terraform.workspace` плодят `if-else` в HCL - упомянуть что каждый env = свой backend (свой bucket для state), чтобы blast radius был ограничен - назвать что переменные между env'ами лучше через .tfvars-файлы или remote secrets, не через `terraform.workspace`-switching

Подводные камни

  • ✗ Использовать workspaces для prod/staging - условная логика расползается, ревьювать diff трудно
  • ✗ Положить state всех env'ов в один bucket с разными ключами - случайно дашь stage-доступ к prod-state через IAM
  • ✗ Дублировать HCL вместо child-модулей - первая ошибка в одном env, потом разъехались

Follow-up

  • ? Когда workspaces всё-таки уместны?
  • ? Чем terragrunt помогает в multi-env layout?
  • ? Как избежать дублирования backend-конфига между env-директориями?

Глубина в базе знаний

  • terraform workspace: несколько state в одной директории
  • Remote state в S3: бакет, DynamoDB lock, encryption
  • Terragrunt, DRY-обёртка над Terraform
  • Композиция модулей: module of modules, передача провайдеров
tags: cicd, environments, workspaces

#pipeline-approval-and-secrets

seniorиногда

Как устроен типовой CI для Terraform: PR, plan, approval, apply?

Что отвечать

Поток: PR открывается → CI бежит `init`, `fmt -check`, `validate`, `tflint`/`checkov`, `terraform plan -out=tfplan` в read-only роль → результат plan'а постится в PR-комментарий или sticky thread → ревьюер видит change set, аппрувит → merge запускает apply из того же tfplan-артефакта в write-роль с manual approval gate. Secrets не лежат в репо; CI получает OIDC-роль с least privilege; tfplan хранится как artifact с retention 7-14 дней.

Что хотят услышать

Senior должен: - назвать роль разделения plan-роль (read-only) и apply-роль (write). Если PR что-то странное - read-only роль не даст ничего сломать - сказать что apply-gate должен быть manual approval с конкретными approvers, не «automerge при passing tests» - различить prod и не-prod: stage может авто-апплаиться при merge в main, prod - всегда manual - упомянуть что plan-комментарий в PR ускоряет ревью в разы; Atlantis, Spacelift, Terraform Cloud делают это из коробки - назвать что tfplan-артефакт должен жить до apply, дольше - утечка snapshot'а state'а

Подводные камни

  • ✗ Использовать одну роль для plan и apply - PR от внешнего контрибьютера получает доступ к write-операциям
  • ✗ Не публиковать plan в PR - ревьюер апрувит вслепую
  • ✗ Хранить tfplan долго как public artifact - это readable snapshot state'а с secrets

Follow-up

  • ? Чем плох Terraform Cloud, если нужна полная изоляция?
  • ? Как делать plan-комментарий в PR на чистом GitHub Actions?
  • ? Какие минимальные права у plan-роли в AWS?

Глубина в базе знаний

  • Plan-as-artifact и automation mode в CI
  • OIDC между GitHub Actions и AWS, без access keys
  • OPA + Rego, policy as code для Terraform plan
tags: cicd, workflow, approvalsbook: Packt.Terraform.Cookbook.pdf:ch11
Footer
linuxlab-
Copyright © 2026 LinuxLab. Все права защищены.
Учебники
Цены
О платформе
Конфиденциальность и куки