验证政策

准备工作

安装 Google Cloud CLI

要使用 gcloud beta terraform vet,您必须先安装 Google Cloud CLI:

  1. 安装 Google Cloud CLI,但跳过 gcloud init 命令。

  2. 运行以下命令以安装 terraform-tools 组件:

    gcloud components update
    gcloud components install terraform-tools
    
  3. 通过运行以下命令来验证 gcloud CLI 已安装:

    gcloud beta terraform vet --help
    

获取所需权限

您用于验证的 Google Cloud 账号必须具有以下权限:

  • getIamPolicygcloud beta terraform vet 需要获取完整的 Identity and Access Management (IAM) 政策并将其与成员和绑定合并,以获取准确的结束状态进行验证。
  • resourcemanager.projects.getgcloud beta terraform vet 需要从 API 获取项目祖先实体,才能准确构建与验证资源相关的所有项目的完整 CAI 资源名称。
  • resourcemanager.folders.get:如果经过验证的资源包含任何与文件夹相关的资源,则 gcloud beta terraform vet 需要从 API 获取文件夹祖先实体才能准确构建完整的 CAI 资源名称。

设置政策库

您需要创建政策库以使用此工具。

验证政策

1. 生成 Terraform 方案

gcloud beta terraform vet 与 Terraform 0.12+ 兼容。gcloud beta terraform vetterraform plan JSON 作为输入。您可以通过在 Terraform 目录中运行以下命令来生成 JSON 文件:

terraform plan -out=tfplan.tfplan
terraform show -json ./tfplan.tfplan > ./tfplan.json

2. 运行 gcloud beta terraform vet

gcloud beta terraform vet 可让您根据组织的 POLICY_LIBRARY_REPO 验证 terraform plan JSON。例如:

git clone POLICY_LIBRARY_REPO POLICY_LIBRARY_DIR
gcloud beta terraform vet tfplan.json --policy-library=POLICY_LIBRARY_DIR

执行此命令时,gcloud beta terraform vet 会使用准确验证方案所需的 Google Cloud API 来检索项目数据。

标志

  • --policy-library=POLICY_LIBRARY_DIR - 包含政策库的目录。
  • --project=PROJECT_ID - gcloud beta terraform vet 接受可选的 --project 标志。此标志用于在为未设置显式项目的任何资源构建祖先实体(在 Google Cloud 资源层次结构中)时指定默认项目
  • --format=FORMAT - 默认值为 yaml。支持的格式为:defaultjsonnonetextyaml。如需了解详情,请运行 $ gcloud topic formats

退出代码和输出

  • 如果所有限制条件都经过验证,该命令会返回退出代码 0,并且不会显示违规行为。
  • 如果发现违规行为,gcloud beta terraform vet 会返回退出代码 2,并显示违规行为列表。例如,JSON 输出可能如下所示:
[
  {
    "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:me@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:me@example.com",
        "resource": "//cloudresourcemanager.googleapis.com/projects/PROJECT_ID"
      }
    },
    "resource": "//cloudresourcemanager.googleapis.com/projects/PROJECT_ID",
    "severity": "high"
  }
]

CI/CD 示例

在 CI/CD 流水线中使用 gcloud beta terraform vet 的 bash 脚本可能如下所示:

terraform plan -out=tfplan.tfplan
terraform show -json ./tfplan.tfplan > ./tfplan.json
git clone POLICY_LIBRARY_REPO POLICY_LIBRARY_DIR
VIOLATIONS=$(gcloud beta terraform vet tfplan.json --policy-library=POLICY_LIBRARY_DIR --format=json)
retVal=$?
if [ $retVal -eq 2 ]; then
  # Optional: parse the VIOLATIONS variable as json and check the severity level
  echo "$VIOLATIONS"
  echo "Violations found; not proceeding with terraform apply"
  exit 1
fi
if [ $retVal -ne 0]; then
  echo "Error during gcloud beta terraform vet; not proceeding with terraform apply"
  exit 1
fi

echo "No policy violations detected; proceeding with terraform apply"

terraform apply

在运行 CI/CD 流水线之前,开发者还可以在本地使用 gcloud beta terraform vet 测试 Terraform 更改。