ポリシーを遵守した Google Cloud リソースを作成する

このチュートリアルでは、プラットフォーム管理者が Anthos Config Management Policy Controller または Open Policy Agent Gatekeeper ポリシーを使用して、Config Connector で Google Cloud リソースを作成する方法について説明します。

Kubernetes または Google Kubernetes Engine(GKE)の基本的な知識があることを前提としています。このチュートリアルでは、Cloud Storage バケットに対して許可されるロケーションを制限するポリシーを定義します。

概要

Policy Controller は、セキュリティ、規制、ビジネスルールに関するポリシーを使用して Kubernetes クラスタ リソースのコンプライアンスを確認、監査、適用します。Policy Controller は、オープンソース プロジェクトの Gatekeeper から構築されています。

Config Connector は、Kubernetes カスタム リソースとして記述することによって、Cloud Storage バケットや Compute Engine 仮想マシン インスタンスなどの Google Cloud のリソースのライフサイクルを作成および管理します。Google Cloud リソースを作成するには、Config Connector が管理する名前空間に Kubernetes リソースを作成します。次の例は、Config Connector を使用して Cloud Storage バケットを記述する方法を示しています。

apiVersion: storage.cnrm.cloud.google.com/v1beta1
kind: StorageBucket
metadata:
  name: my-bucket
spec:
  location: us-east1

Config Connector を使用して Google Cloud リソースを管理することで、GKE クラスタでリソースを作成するときに、そのリソースに Policy Controller または Gatekeeper ポリシーを適用できます。これらのポリシーを使用すると、ポリシーに違反する方法でリソースを作成または変更するアクションを防止または報告できます。たとえば、Cloud Storage バケットのロケーションを制限するポリシーを適用できます。

この方法では、Kubernetes リソースモデル(KRM)に基づいて、一貫したツールとワークフローを使用して Kubernetes リソースと Google Cloud リソースの両方を管理できます。このチュートリアルでは、次の方法について説明します。

  • Google Cloud リソースを管理するポリシーを定義します。
  • デベロッパーと管理者がポリシーに違反する Google Cloud リソースの作成を防ぐコントロールを実装します。
  • Config Connector 以外でリソースを作成した場合でも、既存の Google Cloud リソースをポリシーに照らして監査する実装を実装します。
  • リソース定義を作成、更新する場合に、デベロッパーや管理者に迅速なフィードバックを提供します。
  • Kubernetes クラスタに定義を適用する前に、ポリシーに照らして Google Cloud リソース定義を検証します。

目標

  • Config Connector アドオンを含む GKE クラスタを作成します。
  • Policy Controller または Gatekeeper をインストールします。
  • ゲートキーパー ポリシーを作成して、許可された Cloud Storage バケットのロケーションを制限します。
  • ゲートキーパー ポリシーにより、許可されていないロケーションに Cloud Storage バケットが作成されないことを確認します。
  • 開発中に Cloud Storage バケット定義のポリシー コンプライアンスを評価します。
  • ポリシー コンプライアンス用の既存の Cloud Storage バケットを監査します。

料金

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。新しい Google Cloud ユーザーは無料トライアルをご利用いただけます。

始める前に

  1. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    [プロジェクトの選択] ページに移動

  2. Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  3. Cloud Console で、Cloud Shell をアクティブにします。

    Cloud Shell をアクティブにする

  4. Cloud Shell で、このチュートリアルで使用する Google Cloud プロジェクトを設定します。

    gcloud config set project PROJECT_ID
    

    PROJECT_ID を、プロジェクトの Cloud プロジェクト ID に置き換えます。このコマンドを実行すると、Cloud Shell は、プロジェクト ID を含む GOOGLE_CLOUD_PROJECT という名前のエクスポートされた環境変数を作成します。Cloud Shell を使用しない場合は、次のコマンドで環境変数を作成できます。

    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value core/project)
    
  5. Cloud API と GKE API を有効にします。

    gcloud services enable \
      cloudapis.googleapis.com \
      container.googleapis.com
    
  6. このチュートリアル用に作成したファイルを保存するディレクトリを作成します。

    mkdir -p ~/cnrm-gatekeeper-tutorial
    
  7. 作成したディレクトリに移動します。

    cd ~/cnrm-gatekeeper-tutorial
    

GKE クラスタの作成

  1. Cloud Shell で、Config Connector アドオンWorkload Identity を使用して GKE クラスタを作成します。

    gcloud container clusters create CLUSTER_NAME \
      --addons ConfigConnector \
      --enable-ip-alias \
      --enable-stackdriver-kubernetes \
      --release-channel regular \
      --workload-pool $GOOGLE_CLOUD_PROJECT.svc.id.goog \
      --zone ZONE
    

    以下を置き換えます。

    • CLUSTER_NAME: このプロジェクトに使用するクラスタの名前(例: cnrm-gatekeeper-tutorial)。
    • ZONE: ロケーションに近い Compute Engine ゾーン(例: asia-southeast1-b)。

    Config Connector アドオンは、GKE クラスタの Google Cloud リソースカスタム リソース定義(CRD)をインストールします。

  2. (省略可)環境で限定公開クラスタを使用する場合は、GKE クラスタ コントロール プレーンが Policy Controller または Gatekeeper Webhook に接続できるようにファイアウォール ルールを追加します。

    gcloud compute firewall-rules create allow-cluster-control-plane-tcp-8443 \
      --allow tcp:8443 \
      --network default \
      --source-ranges CONTROL_PLANE_CIDR \
      --target-tags NODE_TAG
    

    以下を置き換えます。

    • CONTROL_PLANE_CIDR: GKE クラスタ コントロール プレーンの IP 範囲(例: 172.16.0.16/28)。
    • NODE_TAG: GKE クラスタ内のすべてのノードに適用されるタグ。

    このオプション ファイアウォール ルールは、クラスタでプライベート ノードを使用している場合に Policy Controller または ゲートキーパー Webhook が機能するために必要です。

Config Connector の設定

Config Connector をインストールする Google Cloud プロジェクトは、ホスト プロジェクトと呼ばれます。Config Connector を使用してリソースを管理するプロジェクトは、マネージド プロジェクトと呼ばれます。このチュートリアルでは、Config Connector を使用して GKE クラスタと同じプロジェクトに Google Cloud リソースを作成します。これにより、ホスト プロジェクトとマネージド プロジェクトが同じプロジェクトになります。

  1. Cloud Shell で、Config Connector の Google サービス アカウントを作成します。

    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name "Config Connector Gatekeeper tutorial"
    

    SERVICE_ACCOUNT_NAME を、このサービス アカウントに使用する名前に置き換えます(例: cnrm-gatekeeper-tutorial) Config Connector は、この Google サービス アカウントを使用してマネージド プロジェクトでリソースを作成します。

  2. Google サービス アカウントにストレージ管理者の役割を付与します。

    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
      --member "serviceAccount:SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
      --role roles/storage.admin
    

    このチュートリアルでは、Storage Connector を使用して Cloud Storage バケットを作成しているため、ストレージ管理者の役割を使用します。実際の環境で、Config Connector 用に作成する Google Cloud リソースの管理に必要な役割を付与します。定義済みの役割の詳細については、IAM ドキュメントの役割についてをご覧ください。

  3. このチュートリアルで作成する Config Connector リソースの Kubernetes 名前空間を作成します。

    kubectl create namespace NAMESPACE
    

    NAMESPACE は、チュートリアルで使用する Kubernetes 名前空間(tutorial など)に置き換えます。

  4. 名前空間にアノテーションを付けて、Google Cloud リソース(マネージド プロジェクト)の作成に使用するプロジェクト設定を指定します。

    kubectl annotate namespace NAMESPACE \
        cnrm.cloud.google.com/project-id=$GOOGLE_CLOUD_PROJECT
    
  5. ConfigConnectorContext リソースを作成し、Kubernetes 名前空間の Config Connector を有効にして、作成した Google サービス アカウントに関連付けます。

    cat << EOF | kubectl apply -f -
    apiVersion: core.cnrm.cloud.google.com/v1beta1
    kind: ConfigConnectorContext
    metadata:
      name: configconnectorcontext.core.cnrm.cloud.google.com
      namespace: NAMESPACE
    spec:
      googleServiceAccount: SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    EOF
    

    ConfigConnectorContext リソースを作成すると、Config Connector は Namespace 内の Config Connector リソースを管理する cnrm-system 名前空間に Kubernetes サービス アカウントStatefulSet を作成します。

  6. 名前空間の Config Connector コントローラ ポッドを待ちます。

    kubectl wait --namespace cnrm-system --for=condition=Ready pod \
      -l cnrm.cloud.google.com/component=cnrm-controller-manager,cnrm.cloud.google.com/scoped-namespace=NAMESPACE
    

    ポッドの準備ができると、Cloud Shell プロンプトが表示されます。

  7. IAM ポリシー バインディングを作成して、Config Connector Kubernetes サービス アカウントを Google サービス アカウントにバインドします。

    gcloud iam service-accounts add-iam-policy-binding \
      SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
      --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.svc.id.goog[cnrm-system/cnrm-controller-manager-NAMESPACE]" \
      --role roles/iam.workloadIdentityUser
    

    このバインドにより、cnrm-system 名前空間内の cnrm-controller-manager-NAMESPACE Kubernetes サービス アカウントが、作成した Google サービス アカウントとして機能します。

Policy Controller のインストール

マネージド Anthos クラスタがある場合は、このセクションの手順に従って Policy Controller をインストールします。インストールされていない場合は、次のセクションに進み、オープンソースのゲートキーパーのディストリビューションをインストールしてください。

  1. Cloud Shell で、Config Management 演算子のカスタム リソース定義(CRD)マニフェストをダウンロードして適用します。

    gsutil cp gs://config-management-release/released/latest/config-management-operator.yaml .
    
    kubectl apply -f config-management-operator.yaml
    
  2. オペレータ CRD に基づいて ConfigManagement マニフェストを作成し、適用します。

    cat << EOF > config-management.yaml
    apiVersion: configmanagement.gke.io/v1
    kind: ConfigManagement
    metadata:
      name: config-management
    spec:
      policyController:
        enabled: true
    EOF
    
    kubectl apply -f config-management.yaml
    

    このマニフェストでは、Config Management オペレータが Policy Controller をインストールするように指示しています。

  3. 1 分ほど待ってから、オペレータが Policy Controller がインストールされていることを確認します。

    kubectl rollout status deploy gatekeeper-controller-manager \
      --namespace gatekeeper-system
    

    インストールが完了してから数分経つと、deployment "gatekeeper-controller-manager" successfully rolled out が表示されます。Error from server (NotFound): namespaces "gatekeeper-system" not found メッセージが表示されたら、しばらく待ってからコマンドのステップを再度実行します。

Gatekeeper のインストール

マネージド Anthos クラスタがない場合は、Policy Controller の代わりにオープンソースの ゲートキーパー ディストリビューションをインストールできます。前のセクションで Policy Controller をインストールした場合は、次のセクションに進みます。

  1. Cloud Shell で、cluster-admin クラスタ役割を Google アカウントに付与します。

    kubectl create clusterrolebinding cluster-admin-binding \
      --clusterrole cluster-admin \
      --user $(gcloud config get-value core/account)
    

    Gatekeeper をインストールするには、このクラスタのロールが必要です。

  2. インストールするゲートキーパーを定義します。

    GATEKEEPER_VERSION=v3.1.3
    
  3. Gatekeeper をインストールするには:

    kubectl apply \
      -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/$GATEKEEPER_VERSION/deploy/gatekeeper.yaml
    
  4. Gatekeeper がインストールされていることを確認します。

    kubectl rollout status deploy gatekeeper-controller-manager \
      --namespace gatekeeper-system
    

    インストールが完了すると、deployment "gatekeeper-controller-manager" successfully rolled out が表示されます。

Config Connector を使用した Google Cloud リソースの作成

  1. Cloud Shell で、us-central1 リージョンの Cloud Storage バケットを表す Config Connector マニフェストを作成します。

    cat << EOF > tutorial-storagebucket-us-central1.yaml
    apiVersion: storage.cnrm.cloud.google.com/v1beta1
    kind: StorageBucket
    metadata:
      name: tutorial-us-central1-$GOOGLE_CLOUD_PROJECT
      namespace: NAMESPACE
    spec:
      location: us-central1
    EOF
    
  2. マニフェストを適用して、Cloud Storage バケットを作成します。

    kubectl apply -f tutorial-storagebucket-us-central1.yaml
    
  3. Config Connector が Cloud Storage バケットを作成したことを確認します。

    gsutil ls | grep tutorial
    

    Config Connector が Cloud Storage バケットを作成すると、出力は次のようになります。

    gs://tutorial-us-central1-GOOGLE_CLOUD_PROJECT/
    

    ここで、GOOGLE_CLOUD_PROJECT は Cloud プロジェクト ID です。

    この出力が表示されない場合は、少し待ってからもう一度手順を繰り返します。

ポリシーの作成

Policy Controller と Gatekeeper のポリシーは、制約テンプレート制約で構成されます。制約テンプレートにポリシーのロジックが含まれています。制約では、ポリシーが適用される場所と、ポリシー ロジックに入力パラメータを指定します。

  1. Cloud Shell で、Cloud Storage バケットのロケーションを制限する制約テンプレートを作成します。

    cat << EOF > tutorial-storagebucket-location-template.yaml
    apiVersion: templates.gatekeeper.sh/v1beta1
    kind: ConstraintTemplate
    metadata:
      name: gcpstoragelocationconstraintv1
    spec:
      crd:
        spec:
          names:
            kind: GCPStorageLocationConstraintV1
          validation:
            openAPIV3Schema:
              properties:
                locations:
                  type: array
                  items:
                    type: string
                exemptions:
                  type: array
                  items:
                    type: string
      targets:
      - target: admission.k8s.gatekeeper.sh
        rego: |
          package gcpstoragelocationconstraintv1
    
          allowedLocation(reviewLocation) {
              locations := input.parameters.locations
              satisfied := [ good | location = locations[_]
                                    good = lower(location) == lower(reviewLocation)]
              any(satisfied)
          }
    
          exempt(reviewName) {
              input.parameters.exemptions[_] == reviewName
          }
    
          violation[{"msg": msg}] {
              bucketName := input.review.object.metadata.name
              bucketLocation := input.review.object.spec.location
              not allowedLocation(bucketLocation)
              not exempt(bucketName)
              msg := sprintf("Cloud Storage bucket <%v> uses a disallowed location <%v>, allowed locations are %v", [bucketName, bucketLocation, input.parameters.locations])
          }
    
          violation[{"msg": msg}] {
              not input.parameters.locations
              bucketName := input.review.object.metadata.name
              msg := sprintf("No permitted locations provided in constraint for Cloud Storage bucket <%v>", [bucketName])
          }
    EOF
    
  2. テンプレートを適用して Cloud Storage バケットを作成します。

    kubectl apply -f tutorial-storagebucket-location-template.yaml
    
  3. シンガポールとジャカルタのリージョン(asia-southeast1asia-southeast2)のバケットのみを許可する制約を作成します。この制約は、前に作成した名前空間に適用されます。Cloud Build のデフォルトの Cloud Storage バケットが除外されます。

    cat << EOF > tutorial-storagebucket-location-constraint.yaml
    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: GCPStorageLocationConstraintV1
    metadata:
      name: singapore-and-jakarta-only
    spec:
      enforcementAction: deny
      match:
        kinds:
        - apiGroups:
          - storage.cnrm.cloud.google.com
          kinds:
          - StorageBucket
        namespaces:
        - NAMESPACE
      parameters:
        locations:
        - asia-southeast1
        - asia-southeast2
        exemptions:
        - ${GOOGLE_CLOUD_PROJECT}_cloudbuild
    EOF
    
  4. 制約を適用して、バケットが存在するゾーンを制限します。

    kubectl apply -f tutorial-storagebucket-location-constraint.yaml
    

ポリシーの確認

  1. 許可されていない場所で Cloud Storage バケットを表すマニフェスト(us-west1)を作成します。

    cat << EOF > tutorial-storagebucket-us-west1.yaml
    apiVersion: storage.cnrm.cloud.google.com/v1beta1
    kind: StorageBucket
    metadata:
      name: tutorial-us-west1-$GOOGLE_CLOUD_PROJECT
      namespace: NAMESPACE
    spec:
      location: us-west1
    EOF
    
  2. マニフェストを適用して、Cloud Storage バケットを作成します。

    kubectl apply -f tutorial-storagebucket-us-west1.yaml
    

    出力は次のとおりです。

    Error from server (denied by singapore-and-jakarta-only Cloud Storage bucket
    <tutorial-us-west1-GOOGLE_CLOUD_PROJECT> uses a disallowed
    location <us-west1>, allowed locations are
    "asia-southeast1", "asia-southeast2"): error when creating
    "tutorial-storagebucket-us-west1.yaml": admission webhook
    "validation.gatekeeper.sh" denied the request: (denied by
    singapore-and-jakarta-only) Cloud Storage bucket
    <tutorial-us-west1-GOOGLE_CLOUD_PROJECT> uses a
    disallowed location <us-west1>, allowed locations are
    "asia-southeast1", "asia-southeast2"
    
  3. 許可されているロケーション(asia-southeast1)にある Cloud Storage バケットを表すマニフェストを作成します。

    cat << EOF > tutorial-storagebucket-asia-southeast1.yaml
    apiVersion: storage.cnrm.cloud.google.com/v1beta1
    kind: StorageBucket
    metadata:
      name: tutorial-asia-southeast1-$GOOGLE_CLOUD_PROJECT
      namespace: NAMESPACE
    spec:
      location: asia-southeast1
    EOF
    
  4. マニフェストを適用して、Cloud Storage バケットを作成します。

    kubectl apply -f tutorial-storagebucket-asia-southeast1.yaml
    

    出力は次のとおりです。

    storagebucket.storage.cnrm.cloud.google.com/tutorial-asia-southeast1-GOOGLE_CLOUD_PROJECT created
    

    ここで、GOOGLE_CLOUD_PROJECT は Cloud プロジェクト ID です。

  5. Config Connector が Cloud Storage バケットを作成したことを確認します。

    gsutil ls | grep tutorial
    

    Config Connector が Cloud Storage バケットを作成すると、次のように出力されます。

    gs://tutorial-asia-southeast1-GOOGLE_CLOUD_PROJECT/
    gs://tutorial-us-central1-GOOGLE_CLOUD_PROJECT/
    

    この出力が表示されない場合は、少し待ってからこの手順を繰り返します。

制約の監査

Policy Controller と Gatekeeper の監査コントローラは、制約に照らしてリソースを定期的に評価します。コントローラは、制約より前に作成されたリソースと、Config Connector の外部で作成されたリソースに対するポリシー違反を検出します。

  1. Cloud Shell で、GCPStorageLocationConstraintV1 制約テンプレートを使用するすべての制約の違反を表示します。

    kubectl get gcpstoragelocationconstraintv1 -o json \
      | jq '.items[].status.violations'
    

    出力は次のとおりです。

    [
      {
        "enforcementAction": "deny",
        "kind": "StorageBucket",
        "message": "Cloud Storage bucket <tutorial-us-central1-GOOGLE_CLOUD_PROJECT>
        uses a disallowed location <us-central1>, allowed locations are
        \"asia-southeast1\", \"asia-southeast2\"",
        "name": "tutorial-us-central1-GOOGLE_CLOUD_PROJECT",
        "namespace": "NAMESPACE"
      }
    ]
    

    制約を作成する前に、us-central1 で作成した Cloud Storage バケットが表示されます。

開発中のリソースの検証

開発および継続的インテグレーション ビルドの際に、リソースを GKE クラスタに適用する前に、制約に照らしてリソースを検証しておくと便利です。検証によって迅速なフィードバックが得られ、リソースと制約の問題を早期に見つけることができます。ここでは、kpt を使用してリソースを検証する方法について説明します。kpt コマンドライン ツールを使用すると、Kubernetes リソース マニフェストを管理、適用できます。

Cloud Shell 以外の環境を使用する場合は、kinstall のウェブサイトにあるインストール手順をご覧ください。

  1. Cloud Shell で、kpt をインストールします。

    sudo apt-get install -y google-cloud-sdk-kpt
    
  2. kpt パイプラインを作成して実行します。

    kpt fn source tutorial-*.yaml \
      | kpt fn run --image gcr.io/kpt-functions/gatekeeper-validate
    

    このパイプラインは、kpt ソース関数を使用して、制約テンプレート、制約、Config Connector Cloud Storage バケット リソースを含む Kubernetes リソースリストを作成します。パイプラインは、gatekeeper-validate kpt 構成関数を使用して、Config Connector Cloud Storage バケット リソースを制約に照らして検証します。この関数は、Container Registry で使用可能なコンテナ イメージとしてパッケージ化されます。

    この関数により、us-central1 リージョンと us-west1 リージョンにある Cloud Storage バケットのマニフェスト ファイルが制約に違反していることがレポートされます。

    出力は次のとおりです。

    Error: Found 2 violations:
    
    [1] Cloud Storage bucket <tutorial-us-central1-GOOGLE_CLOUD_PROJECT>
    uses a disallowed location <us-central1>, allowed locations are
    "asia-southeast1", "asia-southeast2"
    
    name: "tutorial-us-central1-GOOGLE_CLOUD_PROJECT"
    path: tutorial-storagebucket-us-central1.yaml
    
    [2] Cloud Storage bucket <tutorial-us-west1-GOOGLE_CLOUD_PROJECT>
    uses a disallowed location <us-west1>, allowed locations are
    "asia-southeast1", "asia-southeast2"
    
    name: "tutorial-us-west1-GOOGLE_CLOUD_PROJECT"
    path: tutorial-storagebucket-us-west1.yaml
    
    error: exit status 1
    

Config Connector の外部で作成されたリソースの検証

Config Connector の外部で作成された Google Cloud リソースは、リソースをエクスポートすることで検証できます。リソースをエクスポートしたら、次のいずれかのオプションを使用して、エクスポートされたリソースに対して Policy Controller ポリシーを評価します。

  • kpt パイプライン内のリソースを検証する。

  • Config Connector にリソースをインポートします。

リソースをエクスポートするには、Cloud Asset Inventory を使用します

  1. Cloud Shell で、Cloud Asset API を有効にします。

    gcloud services enable cloudasset.googleapis.com
    
  2. 現在のプロジェクト内のすべての Cloud Storage リソースをエクスポートして、出力をバケット tutorial-asia-southeast1-GOOGLE_CLOUD_PROJECT に保存します。

    gcloud asset export \
      --asset-types "storage.googleapis.com/Bucket" \
      --content-type resource \
      --project $GOOGLE_CLOUD_PROJECT \
      --output-path gs://tutorial-asia-southeast1-$GOOGLE_CLOUD_PROJECT/export.ndjson
    

    このコマンドは、リソースをエクスポートするためのバックグラウンド プロセスを開始します。出力は次のようになります。

    Export in progress for root asset projects/GOOGLE_CLOUD_PROJECT.
    Use gcloud asset operations describe projects/GOOGLE_CLOUD_PROJECT/operations/ExportAssets/RESOURCE/UNIQUE_ID to check the status of the operation.
    
  3. 前のステップのターミナル出力に表示されたコマンドを使用して、エクスポートが完了したかどうかを確認します。

    gcloud asset operations describe --format 'value(done)' \
      projects/PROJECT_NUMBER/operations/ExportAssets/RESOURCE/UNIQUE_ID
    

    以下を置き換えます。

    done ステータスのみを表示するには、--format フラグを追加します。エクスポートが完了すると、コマンドの出力は次のようになります。

    True
    

    次のコマンドを実行して、3 つの間隔でブロックし、次のオペレーションが完了しているかどうかを調べます。

    until gcloud asset operations describe --format 'value(done)' \
      projects/PROJECT_NUMBER/operations/ExportAssets/RESOURCE/UNIQUE_ID \
      | grep True ; do sleep 3 ; done
    
  4. エクスポートされたリソースを含むファイルを現在のディレクトリにコピーする:

    gsutil cp gs://tutorial-asia-southeast1-$GOOGLE_CLOUD_PROJECT/export.ndjson .
    

    このファイルは、改行で区切られた JSON ファイル(NDJSON)であり、1 行に 1 つのリソースが格納されます。

  5. config-connector コマンドライン ツールを現在のディレクトリにダウンロードします。

    gsutil cp gs://cnrm/latest/cli.tar.gz - \
      | tar xz --strip-components 3 ./linux/amd64/config-connector
    

    ダウンロードが完了するまでに 1 分ほどかかることがあります。

  6. config-connector ツールを使用して、NDJSON ファイルを Config Connector リソース マニフェストを含む YAML ファイルに変換します。

    ./config-connector -iam-format=none < export.ndjson > export.yaml
    

    -iam-format=none フラグは、出力ファイルで IAM ポリシーをスキップします。自身の環境で IAM ポリシーに対するゲートキーパーの制約を検証するには、このフラグを削除します。

  7. kpt パイプラインを使用して、Cloud Storage バケットのロケーション ポリシーに照らしてリソースを検証します。

    kpt fn source tutorial-storagebucket-location-*.yaml export.yaml \
      | kpt fn run --image gcr.io/kpt-functions/set-namespace -- namespace=NAMESPACE \
      | kpt fn run --image gcr.io/kpt-functions/gatekeeper-validate
    

    このパイプラインは、set-namespace という kpt 構成関数を使用して、すべてのリソースの namespace メタデータ属性値を設定します。Config Connector によって管理されている名前空間内のリソースにのみ制約が適用されるため、名前空間を設定する必要があります。エクスポートされたリソースには、namespace 属性の値はありません。

    出力に、エクスポートしたリソースに関する違反が表示されます。

    Error: Found 1 violation:
    
    [1] Cloud Storage bucket <tutorial-us-central1-GOOGLE_CLOUD_PROJECT> uses a disallowed location <us-central1>, allowed locations are ["asia-southeast1", "asia-southeast2"]
    
    name: "tutorial-us-central1-GOOGLE_CLOUD_PROJECT"
    path: export.yaml
    
    error: exit status 1
    

    このチュートリアルで使用する Cloud Storage バケットに Cloud Storage バケットが含まれていて、そのロケーションが制約に違反している場合、以前に作成したバケットが出力に表示されます。

これで、Cloud Storage バケットに許容されるロケーションを管理するポリシーが正常に設定されました。チュートリアルはこれで終了です。引き続き、他の Google Cloud リソースに独自のポリシーを追加できます。

トラブルシューティング

Config Connector によって必要な Google Cloud リソースが作成されない場合は、Cloud Shell で次のコマンドを使用して、Config Connector コントローラ マネージャーのログを表示します。

kubectl logs --namespace cnrm-system --container manager \
  --selector cnrm.cloud.google.com/component=cnrm-controller-manager,cnrm.cloud.google.com/scoped-namespace=NAMESPACE

Policy Controller または Gatekeeper によってポリシーが正しく適用されない場合は、次のコマンドを使用してコントローラ マネージャーのログを表示します。

kubectl logs deployment/gatekeeper-controller-manager \
  --namespace gatekeeper-system

Policy Controller または Gatekeeper が制約オブジェクトの status フィールドで違反を報告しない場合は、次のコマンドを使用して監査コントローラのログを表示します。

kubectl logs deployment/gatekeeper-audit --namespace gatekeeper-system

このチュートリアルで問題が発生した場合は、次のドキュメントを確認することをおすすめします。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

プロジェクトの削除

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. 削除するプロジェクトが組織に関連付けられている場合、ページ上部の [組織] リストから組織を選択します。
  3. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  4. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

リソースの削除

このチュートリアルで使用した Cloud プロジェクトを残しておく場合は、個々のリソースを削除します。

  1. Cloud Shell で、Cloud Storage バケットのロケーションの制約を削除します。

    kubectl delete -f tutorial-storagebucket-location-constraint.yaml
    
  2. Config Connector によって管理されている名前空間内のすべての storagebucket リソースに、文字列値 truecnrm.cloud.google.com/force-destroy アノテーションを追加します。

    kubectl annotate storagebucket --all --namespace NAMESPACE \
      cnrm.cloud.google.com/force-destroy=true
    

    このアノテーションは、バケットにオブジェクトが含まれている場合でも、GKE クラスタで対応する storagebucket リソースを削除する際に Config Connector が Cloud Storage バケットを削除できるようにするディレクティブです。

  3. Cloud Storage バケットを表す Config Connector リソースを削除します。

    kubectl delete --namespace NAMESPACE storagebucket --all
    
  4. GKE クラスタを削除します。

    gcloud container clusters delete CLUSTER_NAME \
      --zone ZONE --async --quiet
    
  5. IAM で Workload Identity ポリシー バインディングを削除します。

    gcloud iam service-accounts remove-iam-policy-binding \
      SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
      --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.svc.id.goog[cnrm-system/cnrm-controller-manager-NAMESPACE]" \
      --role roles/iam.workloadIdentityUser
    
  6. Google サービス アカウントの Cloud Storage Admin 役割バインディングを削除します。

    gcloud projects remove-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
      --member "serviceAccount:SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
      --role roles/storage.admin
    
  7. Config Connector 用に作成した Google サービス アカウントを削除します。

    gcloud iam service-accounts delete --quiet \
      SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    

次のステップ