Sdílet prostřednictvím


Kontroly zásad artefaktů

Azure DevOps Services

Zásady artefaktů se vynucují před nasazením do důležitých prostředí, jako je produkční prostředí. Tyto zásady se vyhodnocují se všemi nasaditelnými artefakty v daném spuštění kanálu a blokují nasazení, pokud artefakty nevyhovují. Přidání kontroly k vyhodnocení artefaktu vyžaduje konfiguraci vlastních zásad. Tato příručka popisuje, jak je možné vytvářet vlastní zásady.

Poznámka

V současné době jsou podporované typy artefaktů pro image kontejnerů a prostředí Kubernetes.

Požadavky

Pomocí rego můžete definovat zásady, které se snadno čtou a zapisuje.

Seznamte se s dotazovacím jazykem Rego . Základní informace budou dělat.

Pro podporu modelů strukturovaných dokumentů, jako je JSON, rozšiřuje Rego datalog. Dotazy Rego jsou kontrolní výrazy pro data uložená v OPA. Tyto dotazy lze použít k definování zásad, které vyčíslují instance dat, které porušují očekávaný stav systému.

Vytváření vlastních zásad

Níže jsou uvedené ukázkové sdílené zásady. Na základě vašich požadavků můžete vytvořit vlastní sadu zásad.

Kontrola konkrétního projektu nebo kanálu

Tato zásada kontroluje, jestli image vytváří Azure Pipelines a Pipeline-foo. Aby to fungovalo, definice kanálu by měla pole názvu přepsat takto: AzureDevOps_$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r). Další informace o pojmenování spuštění kanálů najdete tady.

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

Kontrola povolených registrů

Tato zásada kontroluje, jestli image pocházejí pouze z povolených registrů.

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

Kontrola zakázaných portů

Tato zásada kontroluje všechny zakázané porty vystavené v imagi kontejneru.

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

Kontrola předchozích nasazení

Tato zásada zkontroluje, jestli je image před nasazením do jednoho nebo více prostředí před nasazením do konkrétního prostředí nebo prostředků s nakonfigurovanou funkcí Check.

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