Инфраструктура как код. Фото любезно предоставлено: @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 ./dockerfilediswallowed_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»