Безопасность, зрелость и куда расти

Terraform даёт огромную власть над инфраструктурой — а значит, требует дисциплины. Финальный урок: как защитить секреты и state, проверять конфиги политиками и куда расти дальше.

IaC ускоряет всё — включая ошибки. Одна опечатка в CIDR открывает базу всему интернету, а terraform destroy в проде сносит компанию за минуту. Зрелость — это процессы, которые ловят такое до применения.

С властью приходит ответственность. Главные оси безопасности Terraform: секреты (не в коде, не в state открыто), state (зашифрован, с блокировкой, без публичного доступа), проверки (статический анализ и политики до apply) и права (минимальные привилегии у пайплайна).

Слои защиты

# статический анализ безопасности конфигов
tfsec .            # ищет открытые порты, незашифрованные бакеты
checkov -d .       # сотни проверок compliance

# policy-as-code: правила, которые должен пройти plan
# OPA/Sentinel: "запретить публичные S3", "только разрешённые регионы"
terraform plan -out=tfplan && conftest test tfplan.json

Сканеры (tfsec, checkov) ловят типовые дыры: незашифрованные диски, открытые в мир security group, публичные бакеты. Policy-as-code (OPA/Sentinel) идёт дальше — это ваши правила: «никаких публичных S3», «только теги с владельцем», «инстансы не больше X». Они встают в пайплайн между plan и apply.

Как работает под капотом

Policy-as-code — это набор правил, прогоняемых по плану: если хоть одно нарушено, apply блокируется. Смоделируем policy-движок:

plan = [
    {"type": "aws_s3_bucket", "name": "logs", "public": False, "encrypted": True},
    {"type": "aws_s3_bucket", "name": "leak", "public": True,  "encrypted": False},
    {"type": "aws_instance",  "name": "web",  "size": "t2.micro"},
]

policies = [
    ("S3 не должен быть публичным",
     lambda r: not (r["type"] == "aws_s3_bucket" and r.get("public"))),
    ("S3 должен быть зашифрован",
     lambda r: not (r["type"] == "aws_s3_bucket" and not r.get("encrypted"))),
]

violations = []
for r in plan:
    for desc, rule in policies:
        if not rule(r):
            violations.append(f"{r['name']}: {desc}")

print("Нарушения:", violations or "нет")
print("apply разрешён:" , not violations)

«Попробуй сам ▶» — бакет leak валит две политики, и apply блокируется. Так policy-as-code не пускает дыры в прод автоматически.

Частые ошибки

  • Секреты в state без защиты доступа. Публичный или незашифрованный state-бакет — утечка всех паролей разом.
  • Широкие права у пайплайна. CI с админ-доступом ко всему облаку — огромная поверхность атаки.
  • Нет проверок до apply. Без сканеров и политик одна опечатка в CIDR открывает прод миру.

Best practices

  • Секреты — только в менеджере секретов; state зашифрован, доступ строго ограничен.
  • В пайплайне: fmtvalidatetfsec/checkov → policy-as-code → plan → approve → apply.
  • Пайплайну — минимальные права (least privilege); prevent_destroy на критичные ресурсы.
  • Дальше изучайте: тестирование (Terratest, terraform test), Terragrunt для DRY, и модели зрелости IaC.

Разбор глубже

Полезно держать в голове модель зрелости IaC как лестницу. На нижней ступени — локальный state и ручной apply с ноутбука: работает, но хрупко и небезопасно. Выше — удалённый state с блокировкой и базовое ревью. Ещё выше — полный CI/CD с plan в PR, статическим анализом и policy-as-code. На вершине — автоматическое обнаружение дрифта, тестирование инфраструктуры и least-privilege во всех средах. Команды не обязаны сразу прыгать наверх, но важно понимать, где они сейчас и какой следующий шаг даёт наибольший прирост безопасности за наименьшие усилия — обычно это перенос state в защищённый удалённый бэкенд и вынос apply в CI.

Тестирование инфраструктуры — отдельное направление, в которое стоит расти. Раньше для этого использовали внешние фреймворки вроде Terratest (на Go): он реально разворачивает инфраструктуру во временном окружении, проверяет её и сносит. В современных версиях появился встроенный terraform test с собственным форматом тестов, позволяющий проверять модули без внешних языков. Плюс статические инструменты — tfsec, checkov, trivy — ловят проблемы безопасности ещё до запуска, по самому коду. Вместе с policy-as-code (OPA/Conftest, Sentinel) это образует несколько эшелонов защиты: код проверяется на корректность, на безопасность и на соответствие политикам организации — и только пройдя все, доходит до прода.

Итог: зрелость Terraform — это защита секретов и state, статические сканеры и policy-as-code до apply, минимальные права. Теперь у вас есть полная картина: от первого plan до безопасного прод-процесса. Поздравляем — вы прошли путь IaC целиком!

Проверьте себя
1. Что делает policy-as-code (OPA/Sentinel) в пайплайне?
AУскоряет apply
BПроверяет план по заданным правилам и блокирует apply при нарушении
CШифрует state
DСкачивает провайдеры
2. Почему пайплайну стоит давать минимальные права (least privilege)?
AДля скорости
BЧтобы ограничить поверхность атаки: компрометация CI с админ-доступом опасна для всего облака
CЭто требование лицензии
DЧтобы уменьшить state