Поделиться через


Проверки политики артефактов

Azure DevOps Services

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

Замечание

В настоящее время поддерживаемые типы артефактов предназначены для образов контейнеров и сред Kubernetes.

Предпосылки

Используйте Rego для определения политики, которую легко читать и записывать.

Ознакомьтесь с языком запросов Rego . Основы подойдут.

Для поддержки структурированных моделей документов, таких как JSON, Rego расширяет журнал данных. Запросы rego — это утверждения о данных, хранящихся в OPA. Эти запросы можно использовать для определения политик, перечисляющих экземпляры данных, которые нарушают ожидаемое состояние системы.

Создание настраиваемых политик

Ниже приведены общие примеры политик. На основе ваших требований можно создать собственный набор политик.

Проверка конкретного проекта или конвейера

Эта политика проверяет, создаются ли образы с помощью Azure Pipelines и Pipeline-foo. Для этого определение конвейера должно переопределить поле имени следующим образом: AzureDevOps_$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r). Дополнительные сведения об именовании запусков конвейера см. здесь.

allowedBuilder := "AzureDevOps_pipeline-foo"

checkBuilder[errors] {
    trace("Check if images are built by Azure Pipelines")
    resourceUri := values[index].build.resourceUri    
    image := fetchImage(resourceUri)
    builder := values[index].build.build.provenance.builderVersion
    trace(sprintf("%s: builder", [builder]))
    not startswith(builder, "allowedBuilder")
    errors := sprintf("%s: image not built by Azure Pipeline [%s]", [image,builder])
}

fetchRegistry(uri) = reg {
    out := regex.find_n("//.*/", uri, 1)
    reg = trim(out[0], "/")
}

fetchImage(uri) = img {
    out := regex.find_n("/.*@", uri, 1)
    img := trim(out[0], "/@")
}

Проверка разрешенных реестров

Эта политика проверяет, являются ли образы только из разрешенных реестров.

allowlist = {
 "gcr.io/myrepo",
 "raireg1.azurecr.io"
}

checkregistries[errors] {
    trace(sprintf("Allowed registries: %s", [concat(", ", allowlist)]))
    resourceUri := values[index].image.resourceUri
    registry := fetchRegistry(resourceUri)
    image := fetchImage(resourceUri)
    not allowlist[registry]
    errors := sprintf("%s: source registry not permitted", [image]) 
}

fetchRegistry(uri) = reg {
    out := regex.find_n("//.*/", uri, 1)
    reg = trim(out[0], "/")
}

fetchImage(uri) = img {
    out := regex.find_n("/.*@", uri, 1)
    img := trim(out[0], "/@")
}

Проверка запрещенных портов

Эта политика проверяет наличие запрещенных портов, предоставляемых на образе контейнера.

forbiddenPorts = {
    "80",
    "22"
}

checkExposedPorts[errors] {
    trace(sprintf("Checking for forbidden exposed ports: %s", [concat(", ", forbiddenPorts)]))
    layerInfos := values[index].image.image.layerInfo
    layerInfos[x].directive == "EXPOSE"
    resourceUri := values[index].image.resourceUri
    image := fetchImage(resourceUri)
    ports := layerInfos[x].arguments
    trace(sprintf("exposed ports: %s", [ports]))
    forbiddenPorts[ports]
    errors := sprintf("%s: image exposes forbidden port %s", [image,ports])
}

fetchRegistry(uri) = reg {
    out := regex.find_n("//.*/", uri, 1)
    reg = trim(out[0], "/")
}

fetchImage(uri) = img {
    out := regex.find_n("/.*@", uri, 1)
    img := trim(out[0], "/@")
}

Проверка предыдущих развертываний

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

predeployedEnvironments = {
    "env/resource1",
    "env2/resource3"
}

checkDeployedEnvironments[errors] {
    trace(sprintf("Checking if the image has been pre-deployed to one of: [%s]", [concat(", ", predeployedEnvironments)]))
    deployments := values[index].deployment
    deployedAddress := deployments[i].deployment.address
    trace(sprintf("deployed to : %s",[deployedAddress]))
    resourceUri := deployments[i].resourceUri
    image := fetchImage(resourceUri)
    not predeployedEnvironments[deployedAddress]
    trace(sprintf("%s: fails pre-deployed environment condition. found %s", [image,deployedAddress]))
    errors := sprintf("image %s fails pre-deployed environment condition. found %s", [image,deployedAddress])
}

fetchRegistry(uri) = reg {
    out := regex.find_n("//.*/", uri, 1)
    reg = trim(out[0], "/")
}

fetchImage(uri) = img {
    out := regex.find_n("/.*@", uri, 1)
    img := trim(out[0], "/@")
}