TL;DR

  • OPA — ваш выбор для мультиплатформенного enforcement политик (Kubernetes, Terraform, APIs); Sentinel превосходен в экосистеме HashiCorp
  • Тесты политик — это код. Пишите их до самой политики, используя встроенный тестовый фреймворк OPA
  • Ошибка #1: относиться к политикам как к документации, а не как к тестируемому, версионированному коду

Подходит для: Команд, управляющих инфраструктурой в нескольких облаках или платформах, которым нужно единое governance Пропустите, если: Вы на 100% в Terraform Cloud/Enterprise и никогда не работаете с Kubernetes Время чтения: 11 минут

Ваш Terraform план прошёл все тесты. CI зелёный. Вы делаете merge и deploy. Через три часа кто-то создаёт публично доступный S3 bucket без шифрования. Ваша команда безопасности в ярости.

Проблема не в тестах — вы тестируете не тот уровень. Инфраструктурные тесты проверяют что деплоится. Тесты политик проверяют что разрешено деплоить. В 2026, когда AI-инструменты генерируют Terraform конфиги быстрее, чем когда-либо, это различие критично.

Настоящая Проблема

Большинство команд подходят к policy as code задом наперёд. Они пишут политики после инцидентов, хранят их в wiki и надеются, что разработчики их прочитают. Это политика как документация, а не политика как код.

Настоящий policy as code означает:

  • Политики версионируются в Git вместе с инфраструктурой
  • У политик есть юнит-тесты, которые запускаются в CI
  • Политики блокируют деплойменты автоматически, а не через комментарии в code review
  • Нарушения политик выдают actionable сообщения об ошибках, а не криптические failures

Переход от “guidelines” к “guardrails” требует смены ментальной модели. Вы не пишете правила для людей — вы пишете исполняемые ограничения, которые enforce’ят машины.

OPA vs Sentinel: Реальность 2026

Open Policy Agent (OPA) v1.9.0 и HashiCorp Sentinel оба решают enforcement политик, но их scope кардинально различается.

АспектOPASentinel
ЭкосистемаПлатформонезависимый (K8s, Terraform, APIs, CI/CD)HashiCorp stack (Terraform, Vault, Nomad, Consul)
ЯзыкRego (декларативный, JSON-native)HSL (HashiCorp Sentinel Language)
ТестированиеВстроенная команда opa testCLI с sentinel test
Входные данныеЛюбой JSON (требует terraform show -json)Нативные импорты Terraform plan
GovernanceDIY enforcement через CI gatesВстроенные уровни advisory/soft/hard
СтоимостьOpen source, бесплатноТребует Terraform Cloud/Enterprise

Моя рекомендация: Начните с OPA, если работаете на нескольких платформах или цените портабельность. Выбирайте Sentinel, если глубоко инвестированы в HashiCorp Cloud Platform и хотите тесную интеграцию без шагов трансформации.

Написание Тестируемых OPA Политик

Ключевой инсайт: политики должны писаться test-first. Перед написанием политики определите, что должно пройти и что должно упасть.

package terraform.aws.s3

import rego.v1

# Запретить S3 buckets без шифрования
deny contains msg if {
    resource := input.planned_values.root_module.resources[_]
    resource.type == "aws_s3_bucket"
    not has_encryption(resource)
    msg := sprintf("S3 bucket '%s' must have server-side encryption enabled", [resource.name])
}

has_encryption(bucket) if {
    bucket.values.server_side_encryption_configuration[_].rule[_].apply_server_side_encryption_by_default[_].sse_algorithm
}

Обратите внимание на import rego.v1 — это современный синтаксис OPA v1.x. Ключевое слово contains и guards if — это конвенции Rego v1, которые заменяют старую неявную генерацию sets.

Тестирование Ваших Политик

Тестовый фреймворк OPA позволяет проверить поведение политик до деплоймента. Создайте тестовый файл рядом с вашей политикой:

package terraform.aws.s3_test

import data.terraform.aws.s3

# Тест: Зашифрованный bucket должен быть разрешён
test_encrypted_bucket_allowed if {
    count(s3.deny) == 0 with input as {
        "planned_values": {
            "root_module": {
                "resources": [{
                    "type": "aws_s3_bucket",
                    "name": "secure_bucket",
                    "values": {
                        "server_side_encryption_configuration": [{
                            "rule": [{
                                "apply_server_side_encryption_by_default": [{
                                    "sse_algorithm": "AES256"
                                }]
                            }]
                        }]
                    }
                }]
            }
        }
    }
}

# Тест: Незашифрованный bucket должен быть запрещён
test_unencrypted_bucket_denied if {
    count(s3.deny) > 0 with input as {
        "planned_values": {
            "root_module": {
                "resources": [{
                    "type": "aws_s3_bucket",
                    "name": "insecure_bucket",
                    "values": {}
                }]
            }
        }
    }
}

Запустите тесты с opa test . -v для подробного вывода. Флаг -v показывает какие тесты прошли и какие упали с причинами.

Интеграция CI/CD

Workflow для Terraform + OPA в вашем pipeline:

# 1. Сгенерировать план
terraform plan -out=tfplan.binary

# 2. Конвертировать в JSON для OPA
terraform show -json tfplan.binary > tfplan.json

# 3. Оценить политики
opa exec --decision terraform/aws/s3/deny --bundle policies/ tfplan.json

# 4. Упасть если есть нарушения
if [ $(opa eval -d policies/ -i tfplan.json 'data.terraform.aws.s3.deny' | jq '.result[0].expressions[0].value | length') -gt 0 ]; then
    echo "Policy violations detected!"
    exit 1
fi

Для Conftest (специализированный инструмент OPA для тестирования конфиг-файлов) синтаксис проще:

conftest test tfplan.json --policy policies/

Conftest автоматически ищет правила deny и выходит с ненулевым кодом, если какое-то сработало.

Sentinel для Terraform Cloud

Если вы используете Terraform Cloud или Enterprise, Sentinel предлагает более тесную интеграцию. Эквивалентная политика шифрования S3:

import "tfplan/v2" as tfplan

s3_buckets = filter tfplan.resource_changes as _, rc {
    rc.type is "aws_s3_bucket" and
    rc.mode is "managed" and
    (rc.change.actions contains "create" or rc.change.actions contains "update")
}

encryption_required = rule {
    all s3_buckets as _, bucket {
        bucket.change.after.server_side_encryption_configuration is not null
    }
}

main = rule {
    encryption_required
}

Импорт tfplan/v2 в Sentinel даёт вам нативный доступ к структуре Terraform plan без JSON-конвертации. Уровни enforcement (advisory, soft-mandatory, hard-mandatory) позволяют раскатывать политики постепенно.

AI-Ассистированные Подходы

Написание политик на Rego или Sentinel требует изучения нового языка. В 2026 году AI-инструменты значительно ускоряют этот процесс.

Что AI делает хорошо:

  • Генерация начальных черновиков политик из требований на естественном языке
  • Конвертация между синтаксисом OPA и Sentinel
  • Создание комплексных тест-кейсов для edge conditions
  • Объяснение сложных Rego comprehensions

Что всё ещё требует людей:

  • Решения о том, какие ресурсы требуют каких ограничений
  • Установка appropriate уровней severity для нарушений
  • Ревью AI-сгенерированных политик на логическую корректность
  • Понимание бизнес-контекста за compliance требованиями

Полезный промпт:

Напиши OPA Rego политику, которая:
1. Запрещает AWS EC2 инстансы без тега "Environment"
2. Разрешает исключения для инстансов с "temporary: true" в metadata
3. Включает комплексные юнит-тесты для обоих случаев
4. Использует синтаксис Rego v1 с явными импортами

Когда Это Не Работает

Policy as code имеет ограничения:

Взрыв сложности: По мере роста политик взаимозависимости становятся трудноотслеживаемыми. Политика, разрешающая t3.micro инстансы, конфликтует с политикой, требующей зашифрованные EBS volumes на определённых типах инстансов.

Ложные срабатывания: Слишком строгие политики блокируют легитимные use cases. Команды начинают просить исключения, и вы оказываетесь с политикой, полной исключений.

Производительность на масштабе: Оценка тысяч политик против больших Terraform планов может значительно замедлить CI. OPA справляется с этим хорошо через partial evaluation, но нужно оптимизировать.

Drift между политикой и реальностью: Политики enforce’ят то, что запланировано, а не то, что работает. Вручную созданный ресурс обходит все policy checks.

Рассмотрите дополнительные инструменты:

Фреймворк Принятия Решений

Выбирайте OPA когда:

  • Вы управляете Kubernetes вместе с Terraform
  • Вам нужны политики для авторизации API или CI/CD gates
  • Ваша инфраструктура охватывает несколько облаков
  • Бюджетные ограничения исключают Terraform Enterprise

Выбирайте Sentinel когда:

  • Вы all-in на HashiCorp Cloud Platform
  • Вы хотите уровни enforcement без построения кастомной CI логики
  • Ваша команда уже знает Sentinel из Vault или Nomad
  • Вам нужен first-class support и SLA

Используйте оба когда:

  • OPA для Kubernetes admission control (Gatekeeper)
  • Sentinel для Terraform-специфичного governance в TFC

Измерение Успеха

МетрикаДоПослеКак отслеживать
Нарушения политик в продеНеизвестно0Cloud audit logs
Среднее время обнаружения нарушенияДни/недели<5 минутTimestamps CI pipeline
Покрытие политиками0%80%+ ресурсовopa test –coverage
Частота ложных срабатыванийN/A<5%Количество запросов на исключения

Тревожные признаки что не работает:

  • Команды обходят CI чтобы избежать policy checks
  • Растущий список постоянных исключений
  • Политики которые никогда не срабатывают (слишком permissive)
  • Политики блокирующие каждый PR (слишком strict)

Что Дальше

Начните с малого. Выберите одну high-impact политику — может быть шифрование S3 или tagging инстансов — и внедрите её end-to-end:

  1. Напишите политику с тестами
  2. Добавьте в CI как warning (advisory mode)
  3. Мониторьте ложные срабатывания в течение спринта
  4. Повысьте до blocking (mandatory mode)
  5. Расширьте на следующую политику

Цель не 100% покрытие политиками в первый день. Цель — выработать muscle memory для отношения к политикам как к продакшн-коду.


Связанные статьи:

Внешние ресурсы: