8.5

Смотреть на английском

8.5 Автоматизация тестов и процессов

Обзор и мотивация

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

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

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

Ключевые принципы

  • Автоматизируйте работу повторяющуюся, предсказуемую и основанную на правилах; оставляйте человеческое усилие для суждения.
  • Делайте автоматические тесты быстрыми, надёжными и детерминированными, иначе их проигнорируют.
  • Запускайте тесты параллельно и сдвигайте их раньше, чтобы обратная связь оставалась быстрой по мере роста набора.
  • Кодифицируйте операционные процедуры как ранбуки как код, чтобы они были версионируемыми, тестируемыми и исполняемыми.
  • Предпочитайте хорошо интегрированную автоматизацию хрупким скриптам, прицепляемым к системам снаружи.
  • Генерируйте свидетельства соответствия автоматически как побочный продукт обычных рабочих процессов.
  • Держите человека в контуре для высокорисковых действий; автоматизируйте сначала безопасное и рутинное.

Рекомендации

Стройте быструю, надёжную, параллельную инфраструктуру тестирования

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

Автоматизируйте выпуск, соответствие и сбор свидетельств

Распространите автоматизацию за пределы тестирования на рабочий процесс выпуска и соответствия. Пусть конвейер автоматически производит артефакты, нужные аудиторам: записи о том, кто утвердил изменение, какие тесты прошли и успешны, что нашли проверки безопасности и какой именно артефакт был развёрнут. Воспринимайте средства контроля как код, так что требуемые проверки принуждаются единообразно, а их результаты журналируются. Это «соответствие как код» превращает сбор свидетельств из ручной суеты перед аудитом в непрерывную, всегда актуальную запись. Оно также делает позицию соответствия системы наблюдаемой в любой момент.

Принимайте ChatOps и ранбуки как код

Кодифицируйте операционные процедуры как исполняемые ранбуки под контролем версий, а не как прозаические документы, которые устаревают. Где процедура безопасна и хорошо понятна, подключите её к автоматизации, способной запускать её по требованию. ChatOps приносит эти операции в общий чат-интерфейс, так что операторы запускают и наблюдают автоматизированные действия в прозрачном, совместном, журналируемом разговоре. Это делает операции видимыми всей команде и создаёт автоматическую запись того, что было сделано. Это также снижает барьер для менее опытных инженеров безопасно выполнять процедуры, потому что автоматизация кодирует правильные шаги.

Внедряйте автоматическое исправление осторожно

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

Правильно размещайте роботизированную автоматизацию процессов (RPA)

Роботизированная автоматизация процессов управляет существующими пользовательскими интерфейсами и приложениями, чтобы автоматизировать задачи, имитируя щелчки и нажатия клавиш, которые выполнял бы человек. У RPA есть законное место как моста для унаследованных или сторонних систем, не открывающих API и не интегрируемых иначе. Используйте её прагматично для таких случаев, но знайте её пределы. Автоматизация через интерфейс по природе хрупка: она ломается при любом изменении интерфейса и не решает лежащее в основе отсутствие интеграции. Где доступен настоящий API или интеграция, предпочитайте их. Воспринимайте RPA как тактическую заглушку, а не стратегический фундамент, и планируйте её замену по мере модернизации систем.

Автоматизируйте управление, безопасность и контроль цены

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

Компромиссы: плюсы и минусы

ВыборПлюсыМинусыЛучше всего подходит
Широкое автоматическое тестированиеБыстрая согласованная обратная связь; делает возможными измененияЦена построения и сопровождения; риск ненадёжностиВсе команды в масштабе
Соответствие как кодНепрерывные, готовые к аудиту свидетельстваИнженерия заранее для кодификации средств контроляРегулируемые организации
Ранбуки как код + ChatOpsПовторяемые, видимые, журналируемые операцииУсилия на кодификацию и сопровождениеКоманды с реальной операционной нагрузкой
Автоматическое исправлениеБыстрее восстановление; меньше рутиныРиск при неверном обнаруженииХорошо понятные повторяющиеся проблемы
RPA (автоматизация интерфейса)Соединяет системы без APIХрупко; маскирует пробелы интеграцииУнаследованные системы как заглушка
Автоматизированное управлениеЕдинообразные необходимые средства контроляУсилия по написанию и настройке политикБольшие управляемые хозяйства

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

Вопросы для обсуждения с командой

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

  2. Кодифицированы ли операционные процедуры как ранбуки как код и выводятся ли они через ChatOps или всё ещё живут как проза, которая устаревает? Кодифицированные ранбуки под контролем версий тестируемы и исполняемы, а их запуск через общий чат-интерфейс делает каждое действие видимым и автоматически журналируемым. Это снижает барьер для менее опытного дежурного инженера действовать безопасно, потому что автоматизация кодирует правильные шаги, а не полагается на племенную память. Решите, какие процедуры достаточно безопасны и хорошо понятны, чтобы подключить их первыми, и как вы сохраняете возможность человека вмешаться. Для большого хозяйства эта прозрачность служит также записью аудита о том, кто что и когда сделал. Принесите ваши нынешние ранбуки, отметьте устаревшие и определите две-три самые часто выполняемые процедуры для кодификации в первую очередь.

  3. Какие проверки безопасности и политики в вашем конвейере блокируют слияние, а какие лишь предупреждают? Автоматизированное управление стоит строить, только если средства контроля необходимы, потому что проверка, которая лишь предупреждает, игнорируется под давлением сроков точно как политика в вики. Решите, средство контроля за средством контроля, что блокирует и что предупреждает: критичная уязвимость или отсутствующий тег шифрования вероятно блокирует, а находка о стиле меньшей серьёзности может предупреждать. В масштабе именно так вы принуждаете ограждения безопасности и цены единообразно по объёму изменений, которого никакая ручная рецензия не покрыла бы. Принесите вашу нынешнюю опись проверок и отметьте каждую как блокирующую или рекомендательную, затем обсудите долю ложных срабатываний, потому что шумная блокирующая проверка приучает людей требовать исключений. Линия между блокировкой и предупреждением то, где ваше управление либо имеет зубы, либо нет.

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

  5. Как мы финансируем и назначаем владение сопровождением нашей автоматизации, чтобы она не разложилась в обязательство? Тесты, ранбуки, проверки политик и боты RPA все гниют по мере изменения окружающих систем, а заброшенная автоматизация хуже отсутствия: устаревший ранбук даёт ложную уверенность в кризисе, а сломанный бот RPA молча теряет работу. Напряжение в том, что сопровождение конкурирует с работой над функциями за тех же инженеров и невидимо, пока что-то не сломается, поэтому его первым урезают под давлением сроков. Принесите нынешнюю опись активов автоматизации, очередь ненадёжных тестов и сломанных ботов и честную оценку инженерных часов, уже идущих на поддержание, против заложенного в бюджет. В корпоративной или государственной среде назовите подотчётного владельца каждой критичной автоматизации и финансируйте её сопровождение отдельной статьёй, потому что аудиторы и разборы инцидентов спросят, кто отвечал, когда несопровождаемое средство контроля молча отказало.

  6. Для каждой унаследованной системы, которую мы автоматизируем RPA, каков конкретный план и триггер вывода этой RPA в пользу настоящей интеграции? RPA законный мост для систем без API, но мост без плана выхода тихо затвердевает в постоянную хрупкую инфраструктуру, ломающуюся при каждом изменении интерфейса и закрепляющую тот самый пробел интеграции, который она призвана была перекрыть. Компромисс реален: RPA быстро и дёшево даёт ценность сейчас, тогда как настоящая интеграция по API стоит больше заранее, но долговечна, поэтому дисциплина в том, чтобы воспринимать RPA как датированный заём, а не покупку. Принесите список ботов RPA в производстве, системы, от которых зависит каждый, как часто каждый ломается и финансируется ли и запланировано ли для лежащей в основе системы усилие по модернизации или интеграции. Для корпоративных и государственных хозяйств, несущих десятилетние основные приложения, привяжите каждого бота RPA к названной вехе модернизации, потому что RPA, тихо ставшая критичной без даты вывода, технический долг, накапливающийся каждый год, пока интерфейс, который она скребёт, продолжает меняться.

Взгляд по секторам

Стартап. С двумя-тремя инженерами и без времени на построение инфраструктуры держите малую быструю пирамиду тестов, проходящую за пару минут на каждое изменение, и воспринимайте любой ненадёжный тест как настоящую ошибку, которую нужно исправить или удалить на этой неделе. Пропустите тяжёлые инструменты соответствия и политику как код, которые вам пока не нужны, и кодифицируйте только два-три самых часто выполняемых операционных исправления как простые скрипты, запускаемые из чата. Автоматизируйте то, что убирает ежедневную рутину, и сопротивляйтесь построению механизмов управления, пока у вас нет проблемы управления.

Малый бизнес. Без выделенного специалиста по тестам или платформе опирайтесь на автоматизацию, встроенную в уже оплачиваемые инструменты: встроенные исполнители тестов сервиса CI, его дополнения для сканирования и управляемые среды, а не заказное построение тестовой инфраструктуры. Формулируйте выбор «покупать или строить» вокруг сопровождения, которое вы можете реалистично выдержать, потому что хитроумный заказной конвейер, который никто не может сопровождать, худший исход, чем более простой размещённый. Используйте RPA скупо и только там, где инструмент поставщика соединяет систему, которую нельзя интегрировать иначе.

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

Государственный сектор. Правила закупок, обязанности прозрачности и мандаты непрерывного мониторинга делают соответствие как код почти необходимым: каждый запуск конвейера должен записывать проверенные средства контроля, выполненные проверки и данные утверждения как защищённые от подделки, готовые к аудиту свидетельства. Предпочитайте открытую переносимую автоматизацию проприетарной привязке, чтобы будущий контракт мог перейти к другому поставщику, и держите человека подотчётным за любое исправление, касающееся сервисов, обращённых к гражданам. Где десятилетняя система вынуждает использовать RPA, документируйте её как намеренный временный мост с публичным планом модернизации и держите проверки управления на предписанной базе безопасности при каждом изменении.

Примеры

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

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

Государственный сектор. Государственное ведомство, подчинённое строгим требованиям непрерывного мониторинга, внедряет соответствие как код. Каждый запуск конвейера записывает проверенные средства контроля, выполненные проверки и данные утверждения, производя защищённые от подделки свидетельства, удовлетворяющие аудиторов по требованию. Поскольку одна из его основных систем десятилетнее приложение без API, ведомство использует RPA как намеренный мост для автоматизации ввода данных в неё, пока идёт усилие по модернизации, с явным планом вывода RPA, как только появится настоящая интеграция. Автоматизированные проверки управления принуждают предписанную базу безопасности при каждом изменении инфраструктуры.

Бизнес-обоснование: мотивы, ROI и TCO

ROI автоматизации тестов и процессов проявляется как возвращённое инженерное время, более быстрая и безопасная поставка, более быстрое восстановление после инцидентов и резко сниженная цена соответствия. Автоматизированное тестирование делает возможными быстрые уверенные изменения, на которых держится эффективность поставки. Автоматизированные операции и исправление сокращают рутину и простои, истощающие команды и бюджеты. Соответствие как код может превратить аудит из недель ручной подготовки в рутинный запрос, экономия и финансовая, и репутационная.

Сравнение TCO сопоставляет реальную постоянную цену построения и сопровождения автоматизации с ценой неавтоматизации. Ручное тестирование и операции стоят не только потраченных часов. Они стоят также ускользнувших дефектов, затянувшихся инцидентов, аудитов, поглощающих специалистов, и выгорания инженеров, делающих повторяющуюся рутину. Для руководства довод прост: автоматизация превращает повторяющиеся операционные расходы и риск в вложение «разовое плюс сопровождение», которое масштабируется, и делает качество и соответствие непрерывными, а не эпизодическими. Одну оговорку стоит назвать прямо. Автоматизацию нужно сопровождать и ей нужно доверять; нефинансируемая заброшенная автоматизация разлагается в обязательство.

Антипаттерны и ловушки

  • Терпимость к ненадёжным тестам. Перемежающиеся отказы разрушают доверие и приучают инженеров игнорировать красные результаты.
  • Автоматизация сломанного процесса. Автоматизация плохого рабочего процесса лишь заставляет беспорядок происходить быстрее; сначала исправьте процесс.
  • RPA как стратегия. Опора на хрупкую автоматизацию интерфейса как на постоянное решение маскирует и закрепляет пробелы интеграции.
  • Исправление без надёжного обнаружения. Автоматические исправления, запущенные плохими сигналами, могут усилить инцидент.
  • Ранбуки как устаревшая проза. Процедуры, живущие в устаревших документах, дают ложную уверенность в кризисе.
  • Свидетельства соответствия собираются вручную. Периодическая ручная охота за свидетельствами дорога и оставляет пробелы между аудитами.
  • Нет человека в контуре для высокорисковых действий. Полная автоматизация опасных операций убирает суждение, предотвращающее катастрофы.

Модель зрелости

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

Уровень 2, Развитие. Автоматические тесты существуют, но медленные, ненадёжные или запускаются непоследовательно, а практики сильно различаются между командами. Некоторые операционные скрипты и ранбуки существуют в карманах, но исправление остаётся ручным, а управление принуждается периодической рецензией, а не непрерывными проверками.

Уровень 3, Стандартизация. Быстрая, параллельная, надёжная инфраструктура тестирования документированный стандарт по организации. Ранбуки как код и ChatOps в общем использовании, свидетельства соответствия генерируются автоматически из запусков конвейера, а средства контроля управления работают как принуждаемые автоматические проверки, применяемые последовательно по командам.

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

Уровень 5, Оркестрация. Автоматизация непрерывно улучшается и интегрирована по организации. Автоматическое исправление обрабатывает рутинные инциденты с проверенными защитными мерами, соответствие непрерывно и всегда готово к аудиту, а инструменты тестирования, эксплуатации и управления адаптируются по мере изменения систем, с активным выводом мостов RPA по мере зрелости интеграций. Люди сосредоточены на суждении, пока машины занимаются повторяемым, и вся система перебалансируется по свидетельствам.

Идеи для обсуждения

  • Какие операционные процедуры безопасно автоматизировать полностью, а какие должны сохранять человека в контуре?
  • Как держать большой набор тестов быстрым и без ненадёжности по мере его роста?
  • Где RPA оправданный мост для ваших унаследованных систем и каков план её вывода?
  • Какие средства контроля можно перевести от ручного аудита к непрерывному соответствию как коду в первую очередь?
  • Как строить доверие к автоматическому исправлению, не рискуя усиленными инцидентами?
  • Как финансировать постоянное сопровождение, которого требует автоматизация, чтобы она не разложилась в обязательство?

Главные выводы

  • Автоматизируйте повторяющееся, предсказуемое и основанное на правилах; оставляйте человеческое усилие для суждения и решений с высоким риском.
  • Делайте автоматические тесты быстрыми, параллельными и надёжными и беспощадно устраняйте ненадёжность.
  • Кодифицируйте операции как ранбуки как код и выводите их через ChatOps для видимости и записи.
  • Генерируйте свидетельства соответствия автоматически, чтобы аудиты опирались на непрерывную актуальную запись.
  • Используйте RPA только как намеренный временный мост для систем без API и планируйте её вывод.
  • Принуждайте управление, безопасность и контроль цены как непрерывные автоматические проверки, а за рискованными действиями пусть надзирают люди.

Источники и дополнительное чтение

  • Lisa Crispin and Janet Gregory, Agile Testing: A Practical Guide for Testers and Agile Teams.
  • Jez Humble and David Farley, Continuous Delivery.
  • Betsy Beyer, Chris Jones, Jennifer Petoff, and Niall Richard Murphy (eds.), Site Reliability Engineering (see the chapter on eliminating toil).
  • Gene Kim, Jez Humble, Patrick Debois, and John Willis, The DevOps Handbook.
  • Nicole Forsgren, Jez Humble, and Gene Kim, Accelerate.
  • NIST Special Publication 800-53 and 800-137 (continuous monitoring).
  • Open Policy Agent documentation (policy as code).