Udostępnij przez


Kontrola zasad dotyczących artefaktów

Azure DevOps Services

Zasady artefaktów są wymuszane zanim nastąpi wdrożenie w kluczowych środowiskach, takich jak produkcyjne. "Wszystkie artefakty możliwe do wdrożenia w danym procesie pipeline są oceniane względem tych zasad, które blokują wdrożenie, jeśli artefakty nie są zgodne." Dodanie testu w celu oceny artefaktu wymaga skonfigurowania niestandardowej polityki. W tym przewodniku opisano sposób tworzenia zasad niestandardowych.

Uwaga / Notatka

Obecnie obsługiwane typy artefaktów są przeznaczone dla obrazów kontenerów i środowisk Kubernetes

Wymagania wstępne

Użyj programu Rego do definiowania zasad, które są łatwe do odczytania i zapisu.

Zapoznaj się z językiem zapytań Rego . Podstawy wystarczą.

Aby obsługiwać modele dokumentów strukturalnych, takie jak JSON, rego rozszerza dziennik danych. Zapytania Rego to asercje na temat danych przechowywanych w OPA. Te zapytania mogą służyć do definiowania zasad, które wyliczają wystąpienia danych, które naruszają oczekiwany stan systemu.

Tworzenie zasad niestandardowych

Poniżej przedstawiono udostępnione przykładowe zasady. Na podstawie wymagań możesz utworzyć własny zestaw zasad.

Sprawdzanie określonego projektu/potoku

Te zasady sprawdzają, czy obrazy są tworzone przez usługi Azure Pipelines i Pipeline-foo. W tym celu definicja potoku powinna zastąpić pole nazwy na przykład: AzureDevOps_$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r). Zobacz więcej na temat nazewnictwa przebiegów potoku tutaj.

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], "/@")
}

Sprawdź dozwolone rejestry

Te zasady sprawdzają, czy obrazy pochodzą tylko z dozwolonych rejestrów.

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], "/@")
}

Sprawdzanie portów zabronionych

Te zasady sprawdzają wszystkie niedozwolone porty uwidocznione w obrazie kontenera.

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], "/@")
}

Sprawdzanie wcześniejszych wdrożeń

Ta zasada sprawdza, czy obraz został wstępnie wdrożony w jednym lub więcej środowiskach przed wdrożeniem w określonym środowisku/zasobach ze skonfigurowaną opcją Sprawdź.

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], "/@")
}