gcloud beta terraform vet クイックスタート

このクイックスタートでは、ドメイン制限を適用する制約の適用方法について説明します。この制約をテストして、意図的にエラーを発生させます。次に、ドメインが合格にするように制約を変更します。

始める前に

  • Google Cloud プロジェクトが必要です。
  • プロジェクトに次の Identity and Access Management(IAM)権限が必要です。

    • resourcemanager.projects.getIamPolicy - この権限は、組織のセキュリティ審査担当者のロールによって付与されます。
    • resourcemanager.projects.get - この権限は、組織のプロジェクト閲覧者のロールによって付与されます。

すぐに開始できるように、この手順では、Terraform がプリインストールされた Cloud Shell とポリシー ライブラリ リポジトリのクローンを使用します。この手順では、すでに Google Cloud アカウントがあることを前提としています。

クイックスタート

  1. Cloud Shell に移動して、ポリシー ライブラリのクローンを作成します。

    ポリシー ライブラリのクローンを作成

  2. サンプルの IAM ドメイン制限の制約を policies/constraints ディレクトリにコピーします。

    cp samples/iam_service_accounts_only.yaml policies/constraints
    
  3. コピーした制約をターミナルに出力して確認します。

    cat policies/constraints/iam_service_accounts_only.yaml
    

    出力は次のようになります。

    # This constraint checks that all IAM policy members are in the
    # "gserviceaccount.com" domain.
    apiVersion: constraints.gatekeeper.sh/v1alpha1
    kind: GCPIAMAllowedPolicyMemberDomainsConstraintV2
    metadata:
      name: service_accounts_only
      annotations:
        description: Checks that members that have been granted IAM roles belong to allowlisted
          domains.
    spec:
      severity: high
      match:
        target: # {"$ref":"#/definitions/io.k8s.cli.setters.target"}
        - "organizations/**"
      parameters:
        domains:
        - gserviceaccount.com
    

    一番下にある gserviceaccount.com に注意してください。これにより、IAM ポリシーに gserviceaccount.com ドメインのメンバーのみが存在できることが指定されます。

  4. ポリシーが想定どおりに機能することを確認するため、現在のディレクトリに次の Terraform main.tf ファイルを作成します。policy-library/main.tf を作成するには、nano、vim、または Cloud Shell エディタを使用します。

    terraform {
      required_providers {
        google = {
          source = "hashicorp/google"
          version = "~> 3.84"
        }
      }
    }
    
    resource "google_project_iam_binding" "sample_iam_binding" {
      project = "PROJECT_ID"
      role    = "roles/viewer"
    
      members = [
        "user:EMAIL_ADDRESS"
      ]
    }
    

    次のように置き換えます。

    • PROJECT_ID: プロジェクト ID。
    • EMAIL_ADDRESS: サンプルのメールアドレス。ここには、有効な任意のメールアドレスを指定できます。例: user@example.com
  5. Terraform を初期化し、以下を使用して Terraform プランを生成します。

    terraform init
    
  6. Terraform プランをエクスポートします。プロンプトが表示されたら、[Authorize] をクリックします。

    terraform plan -out=test.tfplan
    
  7. Terraform プランを JSON に変換します。

    terraform show -json ./test.tfplan > ./tfplan.json
    
  8. terraform-tools コンポーネントをインストールします。

    sudo apt-get install google-cloud-sdk-terraform-tools
    
  9. 次のコマンドを入力して、Terraform プランがポリシーを遵守していることを確認します。

    gcloud beta terraform vet tfplan.json --policy-library=. --format=json
    

    IAM ポリシー バインディングで指定したメールアドレスはサービス アカウントに属していないため、プランは設定した制約に違反しています。

    [
    {
      "constraint": "GCPIAMAllowedPolicyMemberDomainsConstraintV2.service_accounts_only",
      "constraint_config": {
        "api_version": "constraints.gatekeeper.sh/v1alpha1",
        "kind": "GCPIAMAllowedPolicyMemberDomainsConstraintV2",
        "metadata": {
          "annotations": {
            "description": "Checks that members that have been granted IAM roles belong to allowlisted domains.",
            "validation.gcp.forsetisecurity.org/originalName": "service_accounts_only",
            "validation.gcp.forsetisecurity.org/yamlpath": "policies/constraints/iam_service_accounts_only.yaml"
          },
          "name": "service-accounts-only"
        },
        "spec": {
          "match": {
            "target": [
              "organizations/**"
            ]
          },
          "parameters": {
            "domains": [
              "gserviceaccount.com"
            ]
          },
          "severity": "high"
        }
      },
      "message": "IAM policy for //cloudresourcemanager.googleapis.com/projects/PROJECT_ID contains member from unexpected domain: user:user@example.com",
      "metadata": {
        "ancestry_path": "organizations/ORG_ID/projects/PROJECT_ID",
        "constraint": {
          "annotations": {
            "description": "Checks that members that have been granted IAM roles belong to allowlisted domains.",
            "validation.gcp.forsetisecurity.org/originalName": "service_accounts_only",
            "validation.gcp.forsetisecurity.org/yamlpath": "policies/constraints/iam_service_accounts_only.yaml"
          },
          "labels": {},
          "parameters": {
            "domains": [
              "gserviceaccount.com"
            ]
          }
        },
        "details": {
          "member": "user:user@example.com",
          "resource": "//cloudresourcemanager.googleapis.com/projects/PROJECT_ID"
        }
      },
      "resource": "//cloudresourcemanager.googleapis.com/projects/PROJECT_ID",
      "severity": "high"
    }
    ]
  10. 別のドメイン(メール)を許可するには、policy-library/policies/constraints/iam_service_accounts_only.yaml を編集して、ドメインの許可リストにメールドメインを追加します。次の例では、example.com を追加していますが、自分のメールアドレスのドメインを入力します。

    apiVersion: constraints.gatekeeper.sh/v1alpha1
    kind: GCPIAMAllowedPolicyMemberDomainsConstraintV1
    metadata:
      name: service_accounts_only
    spec:
      severity: high
      match:
        target: ["organizations/**"]
      parameters:
        domains:
          - gserviceaccount.com
          - example.com
    
  11. Terraform プランを再度検証すると、違反は見つからないはずです。

    gcloud beta terraform vet tfplan.json --policy-library=. --format=json
    

    予想される出力:

    []

トラブルシューティング

"Error 403: The caller does not have permission, forbidden"」というエラーが表示された場合は、policy-library/main.tfPROJECT_ID がプロジェクト名に置き換えられていないか、指定したプロジェクトに対する必要な権限がありません。

プロジェクト名や権限(resourcemanager.projects.getIamPolicyresourcemanager.projects.get)を編集してから、再度 Terraform プランをエクスポートし、Terraform プランを JSON に変換します。