次の方法で共有


成果物ポリシー チェック

Azure DevOps Services

成果物ポリシーは、運用環境などの重要な環境にデプロイする前に適用されます。 これらのポリシーは、指定されたパイプライン実行内のすべてのデプロイ可能な成果物に対して評価され、成果物が準拠していない場合はデプロイをブロックします。 アーティファクトを評価するためのチェックを追加するには、カスタム ポリシーを構成する必要があります。 このガイドでは、カスタム ポリシーを作成する方法について説明します。

現在、サポートされている成果物の種類はコンテナー イメージと Kubernetes 環境用です

[前提条件]

読みやすく書き込みやすいポリシーを定義するには、Rego を使用します。

Rego クエリ言語について理解を深めてください。 基本で十分です。

JSON などの構造化ドキュメント モデルをサポートするために、Rego は Datalog を拡張します。 Rego クエリは、OPA に格納されているデータに対するアサーションです。 これらのクエリを使用して、システムの予期される状態に違反するデータのインスタンスを列挙するポリシーを定義できます。

カスタム ポリシーの作成

共有されるサンプル ポリシーを次に示します。 要件に基づいて、独自のポリシー セットを構築できます。

特定のプロジェクト/パイプラインを確認する

このポリシーでは、イメージが Azure Pipelines と Pipeline-foo によってビルドされているかどうかを確認します。 これを機能させるには、パイプライン定義で名前フィールドを次のようにオーバーライドする必要があります : AzureDevOps_$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r)。 パイプラインの実行に名前を付ける方法の詳細については 、こちらを参照してください。

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

許可されているレジストリを確認する

このポリシーでは、イメージが許可されたレジストリからのみかどうかを確認します。

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

禁止されているポートを確認する

このポリシーは、コンテナー イメージで公開されている禁止ポートをチェックします。

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

以前のデプロイを確認する

このポリシーでは、Check が構成された特定の環境/リソースにデプロイされる前に、イメージが 1 つ以上の環境に事前にデプロイされているかどうかを確認します。

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