Controlli dei criteri degli artefatti
Azure DevOps Services
I criteri degli artefatti vengono applicati prima della distribuzione in ambienti critici, ad esempio la produzione. Questi criteri vengono valutati in base a tutti gli artefatti distribuibili nell'esecuzione della pipeline specificata e bloccano la distribuzione se gli artefatti non sono conformi. L'aggiunta di un controllo per valutare Artifact richiede la configurazione dei criteri personalizzati. Questa guida descrive come creare criteri personalizzati.
Nota
Attualmente, i tipi di artefatti supportati sono per le immagini del contenitore e gli ambienti Kubernetes
Prerequisiti
Usare Rego per definire criteri facili da leggere e scrivere.
Acquisire familiarità con il linguaggio di query Rego . Le nozioni di base verranno eseguite.
Per supportare modelli di documenti strutturati come JSON, Rego estende Datalog. Le query Rego sono asserzioni sui dati archiviati in OPA. Queste query possono essere usate per definire criteri che enumerare istanze di dati che violano lo stato previsto del sistema.
Creazione di criteri personalizzati
Di seguito sono riportati i criteri di esempio condivisi. In base ai requisiti, è possibile creare un set personalizzato di criteri.
Controllare un progetto o una pipeline specifici
Questo criterio controlla se le immagini vengono compilate da Azure Pipelines e Pipeline-foo. Per il corretto funzionamento, la definizione della pipeline deve eseguire l'override del campo del nome in un modo simile a: AzureDevOps_$(BuildDefinitionName)_$(Date:yyyYMMdd)$(Rev:.r). Per altre informazioni sulle esecuzioni della pipeline di denominazione, vedere qui.
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], "/@")
}
Controllare i registri consentiti
Questo criterio controlla se le immagini provengono solo da registri consentiti.
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], "/@")
}
Controllare le porte non consentite
Questo criterio verifica la presenza di porte non consentite esposte nell'immagine del contenitore.
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], "/@")
}
Controllare le distribuzioni precedenti
Questo criterio controlla se l'immagine è stata pre-distribuita in uno/più ambienti prima di essere distribuita in un ambiente o in risorse specifiche con Check configurato.
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], "/@")
}