Vérifications de la stratégie d’artefacts
Azure DevOps Services
Les stratégies d’artefact sont appliquées avant le déploiement dans des environnements critiques tels que la production. Ces stratégies sont évaluées par rapport à tous les artefacts déployables dans l’exécution du pipeline donné et bloquent le déploiement si les artefacts ne sont pas conformes. L’ajout d’une vérification pour évaluer Artifact nécessite que la politique personnalisée soit configurée. Ce guide décrit comment les stratégies personnalisées peuvent être créées.
Notes
Actuellement, les types d’artefacts pris en charge sont destinés aux images conteneur et aux environnements Kubernetes
Prérequis
Utilisez Rego pour définir une stratégie facile à lire et à écrire.
Familiarisez-vous avec le langage de requête Rego. Les bases suffisent.
Pour prendre en charge des modèles de documents structurés comme JSON, Rego étend Datalog. Les requêtes Rego sont des assertions sur les données stockées dans OPA. Ces requêtes peuvent être utilisées pour définir des stratégies qui énumèrent des instances de données qui ne sont pas conformes à l’état attendu du système.
Utilisation de stratégies personnalisées
Vous trouverez ci-dessous les exemples de stratégies partagées. En fonction de vos besoins, vous pouvez créer votre propre ensemble de stratégies.
Vérifier un projet/un pipeline spécifique
Cette stratégie vérifie si les images sont générées par Azure Pipelines et Pipeline-foo. Pour que cela fonctionne, la définition du pipeline doit remplacer le champ de nom par quelque chose comme : AzureDevOps_$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r). Vous trouverez plus d’informations sur la dénomination des exécutions de pipelines ici.
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], "/@")
}
Vérifier les registres autorisés
Cette stratégie vérifie si les images proviennent uniquement des registres autorisés.
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], "/@")
}
Vérifier les ports interdits
Cette stratégie vérifie les ports interdits exposés dans l’image conteneur.
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], "/@")
}
Vérifier les déploiements antérieurs
Cette stratégie vérifie si l’image a été prédéployée sur un ou plusieurs environnements avant d’être déployée sur un environnement ou des ressources spécifiques avec Check configuré.
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], "/@")
}