gcloud beta terraform vet quickstart

本快速入門導覽課程說明如何套用限制網域的限制條件。您將測試該限制條件,並故意擲回錯誤。接著,您將修改限制條件,讓網域通過驗證。

事前準備

  • 您需要一個 Google Cloud 專案
  • 您需要具備該專案的以下身分與存取權管理 (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。這會指定只有來自 gserviceaccount.com 網域的成員才能出現在 IAM 政策中。

  4. 如要驗證政策是否正常運作,請在目前目錄中建立下列 Terraform main.tf 檔案。您可以使用 nano、vim 或 Cloud Shell 編輯器建立 policy-library/main.tf

    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:電子郵件地址範例。可以是任何有效的電子郵件地址。例如:[email protected]
  5. 初始化 Terraform,並使用下列項目產生 Terraform 計畫:

    terraform init
    
  6. 匯出 Terraform 企劃書,如果出現提示訊息,請點選「授權」

    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:[email protected]",
      "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:[email protected]",
          "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.tf 中的 PROJECT_ID 替換為專案名稱,或是您沒有指定專案的必要權限。

編輯專案名稱和/或權限 (resourcemanager.projects.getIamPolicyresourcemanager.projects.get) 後,請返回並再次匯出 Terraform 計畫,然後將 Terraform 計畫轉換為 JSON。