Рубрики
Uncategorized

Как работает агент открытого политики (OPA)?

В этой статье я хочу дать обзор агента открытого политики, почему вы захотите его использовать, как … с меткой OPA, OpenPolicicagent, Terraform, Devops.

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

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

OPA может быть использован для ряда целей, в том числе:

  • Авторизация конечных точек API отдыха.
  • Позволяя или отрицать изменения террафора на основе правил соблюдения или безопасности.
  • Интеграция пользовательской логики авторизации в приложения.
  • Реализация контроллеров приема Kubernetes для проверки запросов API.

OPA был изначально создан Стира И теперь является частью фонда нативных вычислений облачного (CNCF), наряду с другими технологиями CNCF, такими как Kubernetes и Premetheus.

Мы можем визуализировать, как работает OPA, используя следующую диаграмму: как вы можете видеть, OPA принимает политику, ввод и запрос и генерирует ответ на основе этого. Входной вход может быть любой действительный документ JSON, позволяющий OPA интегрироваться с любым инструментом, который производит вывод JSON.

В следующих разделах я пойду в более конкретные примеры использования OPA, которые должны помочь сделать все более четкими, но прежде чем я сделаю, вот краткий список причин, которые я заинтересован в использовании OPA:

  • Политики, поскольку код позволяют вам следить за своим стандартным жизненным циклом разработки с PRS, CI и т. Д., И предоставить вам историю изменений в вашей политике.
  • OPA предназначен для работы с любым видом ввода JSON, что означает, что он может легко интегрироваться с любым инструментом, который производит вывод JSON.
  • Поскольку OPA интегрируется с рядом различных инструментов, он позволяет использовать стандартный язык политики во многих частях вашей системы, а не полагаться на несколько технологий, специфичных для поставщиков.
  • OPA поддерживает тестирование подразделения, что облегчает и быстрее, чтобы с уверенностью соблюдать вашу политику, что они не будут ломаться.

Давайте попробуем сделать это немного менее теоретическим, используя конкретный пример: Террафом Отказ Террафом может производить план в формате JSON через команду Terraform Show. Это означает, что мы можем определить политики для нашей инфраструктуры, а также использовать OPA для принятия решения о том, безопасен ли план для применения или нет:

Например, скажем, у нас есть следующее определение террафора для создания экземпляра EC2:

provider "aws" {
 region = "eu-central-1"
}

resource "aws_instance" "web" {
 ami           = "ami-00003c1d"
 instance_type = "t3.micro"
}

Теперь скажем, мы хотим убедиться, что каждый ресурс Terraform имеет тег имени, мы могли бы принять это, создавая файл под названием Plan.rego Со следующим контентом:

package spacelift

allow {
   resource_change := input.resource_changes[_]

   resource_change.change.after.tags["Name"]
}

Чтобы использовать OPA для оценки нашей политики, нам нужно сделать следующие шаги:

  1. Создайте план террафора как JSON.
  2. RUN OPA EVAL, чтобы проверить, проходит ли этот план нашей политики или нет.

Чтобы получить представление JSON нашего плана, нам нужно выводить наш план в файл, а затем использовать команду Terraform Show для вывода этого плана как JSON:

terraform plan -out spacelift.plan
terraform show -json spacelift.plan > spacelift.json

Затем мы можем использовать OPA Eval для оценки нашего плана против нашей политики:

$ opa eval --data plan.rego --input spacelift.json "data.spacelift.allow"
{}

Как вы можете видеть, мы используем данные запроса. SpaceLift.allift.allow, потому что наша политика загружается в виде файла данных, и мы определили наше правило разрешения в пространстве пространства Sepacelift. Вы также можете увидеть, что OPA Eval производится пустой выход ({}). Это означает, что наше правило разрешения не оценивало значение TARE, так и не производим вывода.

Давайте настроим нашу определение террафора, чтобы включить тег имени:

resource "aws_instance" "web" {
 ami           = "ami-00003c1d"
 instance_type = "t3.micro"

 tags = {
   Name = "my-instance"
 }
}

Теперь, если мы создам наш план и снова оцените политику, мы должны получить немного другой вывод:

$ terraform plan -out spacelift.plan && \
 terraform show -json spacelift.plan > spacelift.json
... lots of Terraform output

$ opa eval --data plan.rego --input spacelift.json "data.spacelift.allow"
{
 "result": [
   {
     "expressions": [
       {
         "value": true,
         "text": "data.spacelift.allow",
         "location": {
           "row": 1,
           "col": 1
         }
       }
     ]
   }
 ]
}

Это говорит нам, что правило разрешения оценивается верным. Мы можем получить это немного более лаконичным способом, используя Красивая Формат опция:

$ opa eval --data plan.rego --input spacelift.json --format pretty "data.spacelift.allow"
true

На этом этапе вы можете представить, как вы можете интегрировать это в ваш CI/CD-трубопровод для обеспечения применения схем именования, правила безопасности и различных других организационных политик.

Следующие примеры иллюстрируют некоторые возможные случаи использования для OPA с террафором. Все примеры были взяты из окрестностей План политики Документация Но были изменены на работу с простой ванильным террафом.

Пример 1. Требуется человеческий обзор, когда ресурсы будут удалены или обновлены

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

package spacelift

warn[sprintf(message, [action, resource.address])] {
  message  := "action '%s' requires human review (%s)"
  review   := {"update", "delete"}
  resource := input.resource_changes[_]
  action   := resource.change.actions[_]
  review[action]
}

Пример 2. Требует коммитов быть разумно размером

Как только PR пойдет на определенный размер, становится трудно рассмотреть без пропущенных вещей. То же самое верно для планов террафора. Следующая политика может быть использована для предупреждения, когда количество изменений идет на определенный порог:

package spacelift

warn[msg] {
   msg := too_many_changes[_]
}

too_many_changes[msg] {
   threshold := 50
   res := input.resource_changes
   ret := count([r | r := res[_]; r.change.actions != ["no-op"]])
   msg := sprintf("more than %d changes (%d)", [threshold, ret])
   ret > threshold
}

Пример 3. Радиус взрыва

Следующие попытки политики для определения риска определенного плана, присваивая различные взвешивания к типу изменений (создайте, обновление, удаление), наряду с пораженным типом ресурса (Cluster ECS, экземпляр EC2, ETC). Требуется подход, что обновление или удаление более рискованно, чем создание, потому что это влияет на существующий ресурс:

package spacelift

warn[msg] { msg := blast_radius_too_high[_] }

blast_radius_too_high[sprintf("change blast radius too high (%d/100)", [blast_radius])] {
   blast_radius := sum([blast |
                        resource := input.resource_changes[_];
                        blast := blast_radius_for_resource(resource)])

   blast_radius > 100   
}

blast_radius_for_resource(resource) = ret {
   blasts_radii_by_action := { "delete": 10, "update": 5, "create": 1, "no-op": 0 }

   ret := sum([value | action := resource.change.actions[_]
                   action_impact := blasts_radii_by_action[action]
                   type_impact := blast_radius_for_type(resource.type)
                   value := action_impact * type_impact])
}

# Let's give some types of resources special blast multipliers.
blasts_radii_by_type := { "aws_ecs_cluster": 20, "aws_ecs_user": 10, "aws_ecs_role": 5 }

# By default, blast radius has a value of 1.
blast_radius_for_type(type) = 1 {
   not blasts_radii_by_type[type]
}

blast_radius_for_type(type) = ret {
   blasts_radii_by_type[type] = ret
}

Как мы можем убедиться, что наши политики работают, как мы ожидаем, и что они не разбиваются со временем, так как мы вносим их изменения? Вы догадались: тестирование подразделения! К счастью для нас, OPA имеет первоклассную поддержку для тестирования через OPA Тест команда.

Чтобы создать тесты на нашу политику, все, что нам нужно сделать, это создать еще один файл REGO с серией правил, префиксированных с контрольная работа_ . Каждое правило, начинающееся с этого префикса, определяет отдельный тест.

Давайте пойдем вперед и создадим файл под названием Plan_test.rego. С следующим содержанием:

package spacelift

test_allow_missing_name_tag {
 not allow with input as {
     "resource_changes": [
       {
         "change": {
           "after": {
             "tags": null,
           },
         }
       }
     ]
   }
}

Как видите, OPA делает его очень простым указывать ввод политики, используя <Переменная> как <значение> синтаксис. Это позволяет нам создавать очень лаконичные тесты, включая значения, которые мы заботимся о введении политики, а не должны использовать весь вывод плана.

Давайте идти вперед и запустим Опа-тест :

$ opa test .
data.spacelift.test_allow_missing_name_tag: PASS (188.503µs)
--------------------------------------------------------------------------------
PASS: 1/1




   resource_change.change.after.tags["Name"]

   resource_change.change.after.tags["Environment"]

}

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

test_allow_missing_environment_tag {
 not allow with input as {
     "resource_changes": [
       {
         "change": {
           "after": {
             "tags": { "Name": "my-instance" },
           },
         }
       }
     ]
   }
}

Выполнение теста OPA снова показывает нам сбой:

$ opa test .
data.spacelift.test_allow_missing_environment_tag: FAIL (118.078µs)
--------------------------------------------------------------------------------
PASS: 1/2
FAIL: 1/2

Что мы можем исправить, обновляя нашу политику:

allow {
   resource_change := input.resource_changes[_]
   resource_change.change.after.tags["Name"]
   resource_change.change.after.tags["Environment"]
}

На этом этапе, если вы снова запустите команду теста, он должен показать 2 пропуска:

$ opa test .
PASS: 2/2

Если вы хотите узнать больше о тестировании OPA, Официальные документы полны отличных примеров и информации о том, что вы можете сделать.

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

К счастью для вас, в SuceLift все тяжелые подъема сделаны для вас, позволяя вам получить преимущества использования OPA для политики-кода без необходимости реализовать все с нуля для себя. В этом разделе я хочу продемонстрировать некоторые функции, которые Spacelift предоставляет, что относится к OPA.

1) Типы политики

Spacelift позволяет использовать политики OPA для управления различными аспектами вашей учетной записи Supacelift, а не только во время планирования. Например, вы можете использовать политики для контроля, которые могут войти в свою учетную запись, а также то, к чему у них есть доступ. Для получения дополнительной информации см. https://docssspacelift.io/concepts/policy Отказ

2) PR чеки

Sucelift может автоматически запускать планирование, когда вы нажимаете изменения в свой поставщик VCS. Например, вот что вы можете увидеть в Github после создания PR:

Если все идет хорошо, ваш чек добится успеха, но если политика нарушена, сообщается, что будет сообщена неудачная проверка:

Затем вы можете просмотреть детали сбоя в Sucalift:

3) Ручные одобрения

Sucalift План политики Используйте немного другой формат, чем мы использовали в наших примерах политиках ранее в этом посте. Они не только позволяют вам указать сообщение, которое будет отображаться, но они также имеют концепцию отказываться от и предупреждать :

package spacelift

deny["you shall not pass"] {
 true
}

warn["hey, you look suspicious"] {
 true
}

отрицать Правило не работает полностью, пока предупреждать Правило просто отображает предупреждение в журналах.

предупреждать Правила принимают еще одну роль, когда пробег будет развернуть изменения (VS, просто показывая запланированные изменения против PR). Если во время развертывания сообщается какие-либо предупреждения, прогон будет ждать одобрения вручную до применения любых изменений.

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

suggested_tags := { "Name", "Environment" }

warn[sprintf("resource %q does not have all suggested tags (%s)", [resource.address, concat(", ", missing_tags)])] {
 resource := input.terraform.resource_changes[_]
 tags := resource.change.after.tags

 missing_tags := { tag | suggested_tags[tag]; not tags[tag] }
 count(missing_tags) > 0
}

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

Это позволяет создавать сложные рабочие процессы, где определенные изменения полностью заблокированы, но другие допускаются до тех пор, пока изменения пересматриваются первыми.

Проверьте План политики поваренной книги Для получения дополнительных идей о том, что вы можете сделать.

Spacelift предоставляет Поставщик террафора Для управления учетной записью вашего SPALIFT. Это означает, что вы можете управлять политиками, доступными в вашей учетной записи, а также стеки, которые они относятся к коду.

Например, чтобы добавить политику, которую мы определены ранее для SuceLift, мы можем использовать Spacelift_policy Ресурс такой:

resource "spacelift_policy" "plan" {
 type = "PLAN"

 name = "Plan Policy"
 body = file("${path.module}/plan.rego")
}

Затем мы можем прикрепить эту политику в стек для укрупания с использованием ресурса SPACELIFT_POLICY_ATTACHMENT:

resource "spacelift_policy_attachment" "mystack-plan" {
 policy_id = spacelift_policy.plan.id
 stack_id  = spacelift_stack.mystack.id
}

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

Я надеюсь, что вам понравился этот пост и вижу значение, которое OPA приносит в таблицу. Если вы заинтересованы в попытках пробовать в укуме, чтобы увидеть, что он должен предложить, почему бы не подписаться на Бесплатная пробная версия ? Вы можете настроить учетную запись Supacelift за считанные минуты, и начните в путешествии агента открытого политики!

Оригинал: «https://dev.to/spacelift/how-does-open-policy-agent-work-27kc»