Comprobaciones de directiva de artefactos
Azure DevOps Services
Las directivas de artefacto se aplican antes de su implementación en entornos críticos, como el entorno de producción. Estas directivas se evalúan en todos los artefactos que se pueden implementar en la ejecución de canalización determinada y bloquean la implementación si los artefactos no cumplen. Agregar una comprobación para evaluar un artefacto requiere que se configure la directiva personalizada. En esta guía, se describe cómo se pueden crear directivas personalizadas.
Nota:
Actualmente, los tipos de artefacto admitidos son para imágenes de contenedor y entornos de Kubernetes.
Requisitos previos
Use Rego para definir una directiva fácil de leer y escribir.
Familiarícese con el lenguaje de consulta Rego. Los conceptos básicos son suficientes.
Para admitir modelos de documentos estructurados como JSON, Rego amplía Datalog. Las consultas de Rego son aserciones en los datos almacenados en OPA. Estas consultas se pueden usar para definir directivas que enumeran instancias de datos que infringen el estado esperado del sistema.
Creación de directivas personalizadas
A continuación, se muestran las directivas de ejemplo compartidas. En función de sus requisitos, puede crear su propio conjunto de directivas.
Comprobación de proyectos o canalizaciones específicos
Esta directiva comprueba si las imágenes se crean con Azure Pipelines y Pipeline-foo. Para que esto funcione, la definición de canalización debe invalidar el campo de nombre en algo parecido a: AzureDevOps_$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r). Consulte más información sobre cómo asignar nombres a las ejecuciones de canalización aquí.
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], "/@")
}
Comprobación de los registros permitidos
Esta directiva comprueba si las imágenes solo proceden de registros permitidos.
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], "/@")
}
Comprobación de puertos prohibidos
Esta directiva comprueba si hay puertos prohibidos expuestos en la imagen de contenedor.
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], "/@")
}
Comprobación de las implementaciones anteriores
Esta directiva comprueba si la imagen se ha implementado previamente en uno o varios de los entornos antes de implementarse en un entorno o recursos específicos con Comprobación configurada.
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], "/@")
}