Инфраструктура как код. Фото любезно предоставлено: @Bass Emmen
Первоначально опубликовано в https://pbnj.dev
Оглавление
- Обзор
- Начиная
- Dockerfile
- Kubernetes
- Следующие шаги
Обзор
Эра инфраструктуры как кода (IAC) разблокировала огромную производительность разработчика и функции ловкости. Теперь, как инженер, мы можем объявить нашу инфраструктуру и среды как структурированные данные в файлах конфигурации, таких как шаблоны Terraform, Dockerfiles и Kubernetes.
Тем не менее, эта ловкость и скорость обеспечения и настройки инфраструктуры поставляются с высоким риском ошибок в форме неправильных сборов.
К счастью, мы можем решить эту проблему так же, как мы можем решить для других ошибок в наши продукты, написав модульные тесты Анкет
Одним из таких инструментов, который может помочь нам проверить на наших файлах конфигурации Conftest
Анкет Что уникально в Conftest
это то, что он использует Открытый политика-агент (OPA) и политика Язык, называемый Рего к выполнить это.
Сначала это может показаться трудным, но это начнет иметь смысл.
Давайте рассмотрим 2 использования, где мы можем проверить наши конфигурации!
Начиная
Во -первых, некоторые предпосылки:
Conftest
:- macOS:
Brew Install Intustraa/Instrumenta/Conftest
- macOS:
(Необязательно)
опе
:- macOS:
Бросить установка OPA
- macOS:
Dockerfile
Допустим, мы хотим предотвратить некоторые изображения и/или теги (например, Последние
).
Нам нужно создать простой Dockerfile:
FROM kalilinux/kali-linux-docker:latest ENTRYPOINT ["echo"]
Теперь нам нужно создать наш первый тестовый файл модуля, давайте назовем его test.rego
и Поместите это в каталог, назовем это политика
(это настраивается).
package main disallowed_tags := ["latest"] disallowed_images := ["kalilinux/kali-linux-docker"] deny[msg] { input[i].Cmd == "from" val := input[i].Value tag := split(val[i], ":")[1] contains(tag, disallowed_tags[_]) msg = sprintf("[%s] tag is not allowed", [tag]) } deny[msg] { input[i].Cmd == "from" val := input[i].Value image := split(val[i], ":")[0] contains(image, disallowed_images[_]) msg = sprintf("[%s] image is not allowed", [image]) }
Предполагая, что мы находимся в правильном каталоге, мы можем проверить наш Dockerfile:
$ ls Dockerfile policy/ $ conftest test -i Dockerfile ./Dockerfile FAIL - ./Dockerfile - [latest] tag is not allowed FAIL - ./Dockerfile - [kalilinux/kali-linux-docker] image is not allowed
Просто чтобы быть уверенным, давайте изменим этот Dockerfile, чтобы пройти тест:
# FROM kalilinux/kali-linux-docker:latest FROM debian:buster ENTRYPOINT ["echo"]
$ ls Dockerfile policy/ $ conftest test -i Dockerfile ./Dockerfile PASS - ./Dockerfile - data.main.deny
«Оно работает! Но я не понимаю, как, — слышу, что вы думаете про себя.
Давайте разберем синтаксис Рего вниз:
Пакет Main
это способ для нас разместить некоторые правила, которые принадлежат вместе в пространстве имен. В этом случае мы назвали этоГлавный
Потому чтоConftest
по умолчанию, но мы можем легко сделать что -то вродеПакет Docker
а затем бегиConftest Test -i Dockerfile -Namespace Docker ./dockerfile
diswallowed_tags
&diswallowed_images
просто простые переменные, которые содержат массив струнdeny [msg] {...}
является началом правила отказа, и это означает, что DockerFile должен быть отклонен, и пользователю должно быть предоставлено сообщение об ошибкеMSG
Если условия в теле (то есть{...}
) верны- Выражения в теле правила отрицания рассматриваются как логичные и. Например:
1 == 1 # IF 1 is equal to 1 contains("foobar", "foo") # AND "foobar" contains "foo" # This would trigger the deny rule
Вход [i] .cmd
Проверяет, является ли команда DockerОт
АнкетВход [i]
означает, что у нас может быть тестирование нескольких DockerFiles одновременно. Это будет повторять их- Следующие 2 строки — это назначения только для того, чтобы разделить строку и сохранить некоторые данные в переменных
Содержит (TAG, DINALDED_TAGS [_])
Вернут True, еслитег
Мы получили из DockerFile содержит один изdiswallowed_tags
.массив [_]
Синтаксис означает итерацию над значениямиMSG (...)
Создает сообщение, которое мы хотим сообщить нашему пользователю, если это правило отказано- Второй
отрицание [msg]
Правило проверяет, что само изображение не в блоке.
Kubernetes
Допустим, мы хотим убедиться, что все стручки работают в качестве пользователя, не являющегося корнями.
Нам нужно создать наше развертывание
$ mkdir -p kubernetes $ cat <./kubernetes/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 EOF
Теперь нам нужно создать наш модульный тест:
$ mkdir -p ./kubernetes/policy $ cat <./kubernetes/policy/test.rego package main name := input.metadata.name deny[msg] { input.kind == "Deployment" not input.spec.template.spec.securityContext.runAsNonRoot msg = sprintf("Containers must run as non root in Deployment %s. See: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", [name]) } EOF
И давайте запустим это:
conftest test -i yaml ./kubernetes/deployment.yaml FAIL - ./kubernetes/deployment.yaml - Containers must run as non root in Deployment nginx-deployment. See: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
Это немного проще:
- Получите
Metadata.name
изВход
(Который является развертыванием kubernetes yaml file) - Создайте правило отказа, которое запускается, если:
input.kind
этоРазвертывание
иSecurityContext.RunasnonRoot
не установлен
- Верните сообщение об ошибке пользователю о том, что контейнеры должны работать как без корня и указывать им на документы.
Следующие шаги
Итак, куда идти отсюда?
Язык Rego огромный, и это может потребоваться немного, чтобы обернуть голову вокруг, как он работает. Вы даже можете отправить и получать HTTP -запросы внутри Рего.
Я рекомендую прочитать документы, чтобы узнать больше о возможностях Рего:
Я также едва поцарапал поверхность Conftest
В этом блоге. Репозиторий имеет хороший список Примеры что ты должен просмотрите на досуге. Conftest
Даже поддерживает политики обмена через загрузку ОПА связки для OCI-совместимых реестров, например, conftest push ...
, Conftest Pull ...
Анкет
Наконец, если у вас есть какие -либо вопросы, сообщество OPA дружелюбно и гостеприимно. Не стесняйтесь присоединиться к #conftest
канал в Opa Slack Анкет
Счастливого кодирования!
Оригинал: «https://dev.to/pbnj/unit-test-your-configuration-files-3mnf»