使用 Rego 编写自定义规则

本文档介绍了如何使用 Rego 政策语言编写自定义规则。您可以在 Workload Manager 中使用这些规则,根据为贵组织定义的最佳实践评估工作负载。

如需了解详情,请参阅 Workload Manager 中的自定义规则简介

准备工作

使用 Rego 编写自定义规则

Google 提供了一个 GitHub 示例代码库,其中包含一组预定义规则,可供您评估工作负载。这些示例涵盖了多种用例。从代码库中选择规则,或创建用于描述评估要求的规则 (.rego) 文件。

自定义规则包含以下部分:

  • 元数据。以下字段用于定义规则元数据:

    • DETAILS:规则的简短说明。
    • SEVERITY:用户定义的值,用于定义违反规则的严重程度。例如,HIGHCRITICALMEDIUMLOW
    • ASSET_TYPE:受支持的素材资源之一。请参阅支持的数据源
    • TAGS:规则的一个或多个标记。这些标记有助于过滤规则。
  • 软件包声明。例如 templates.google.compute.instance.label

  • Import 语句。例如 data.validator.google.lib as lib

  • 规则定义。用于定义规则的一组说明。

示例规则

以下示例规则可在 GitHub 代码库 GoogleCloudPlatform/workload-manager 中找到。您可以将这些规则按原样上传到 Cloud Storage 存储分区,并使用这些规则运行评估。或者,根据贵组织的政策修改规则,然后将文件上传到 Cloud Storage 存储桶

  • 示例 1:确保您的虚拟机至少有一个标签。
  • 示例 2:确保您的工作负载不会使用 Compute Engine 默认服务账号。
  • 示例 3:确保工作负载中的虚拟机不使用外部 IP 地址。

如需查看可在 Workload Manager 中使用的示例规则的完整列表,请参阅 GoogleCloudPlatform/workload-manager GitHub 代码库。

示例 1

确保 Compute Engine 资源至少有一个标记。

# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

########################################################################
# DETAILS:  MUST have atleast one tag
# SEVERITY: Medium
# ASSET_TYPE: compute.googleapis.com/Instance
# TAGS: Tags, Cost, Management, Compute Engine
########################################################################

package google.compute.instance.tags

import data.validator.google.lib as lib
import data.validator.google.lib.parameters as gparam
import future.keywords

asset := input.asset

params:= lib.get_default(gparam.global_parameters,"compute",{})

deny [{"msg": message, "details": metadata}] {

	# Check if resource is in exempt list
	exempt_list := lib.get_default(params, "exemptions", [])
	exempt := {asset.name} & {ex | ex := exempt_list[_]}
	not count(exempt) != 0

	tags := lib.get_default(asset.resource.data, "tags", {"items": []})
	count(tags.items) == 0

	message:="Compute resource is missing tags. Ensure appropriate tags are applied."

	metadata:={"name": asset.name}
}

示例 2

确保您的工作负载不使用 Compute Engine 默认服务账号

# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

########################################################################
# DETAILS:  MUST NOT use default service account
# SEVERITY: Medium
# ASSET_TYPE: compute.googleapis.com/Instance
# TAGS: Defaults, Management, Compute Engine
########################################################################

package google.compute.defaultserviceAccount

import data.validator.google.lib as lib
import data.validator.google.lib.parameters as gparam
import future.keywords

asset := input.asset

input_enriched := object.union({"resource": {"data": {"serviceAccounts": []}}}, asset)

params := lib.get_default(gparam.global_parameters, "compute", {})

deny[{
	"msg": "Disallowed default service account",
	"details": {"name": asset.name},
}] {

	account = input_enriched.resource.data.serviceAccounts[_]
	endswith(account.email, params.default_sa)
}

示例 3

确保工作负载中的虚拟机不使用外部 IP 地址。

# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

########################################################################
# DETAILS:  Ensure VMs dont have External IP
# SEVERITY: High
# ASSET_TYPE: compute.googleapis.com/Instance
# TAGS: Security, Network, Compute Engine, External IP, VM, Virtual Machine
########################################################################

package google.compute.instance.approved.external.ip

import data.validator.google.lib as lib
import data.validator.google.lib.parameters as gparam
import future.keywords

asset := input.asset

params := lib.get_default(gparam.global_parameters, "compute", {})

deny [{"msg": message, "details": metadata}] {

	# Check if resource is in exempt list
	exempt_list := lib.get_default(params, "exemptions", [])
	exempt := {asset.name} & {ex | ex := exempt_list[_]}
	not count(exempt) != 0

	# Find network access config block w/ external IP
	instance := asset.resource.data
	access_config := instance.networkInterfaces[_].accessConfigs
	count(access_config) > 0

	message := sprintf("%v : VM Instance has external IP. current config: %v",[asset.name, access_config])
	metadata := {"name": asset.name}
}

将规则上传到 Cloud Storage 存储分区

创建 .rego 文件后,将其上传到 Cloud Storage 存储桶。Cloud Storage 存储桶的顶层必须包含 /lib/rules 文件夹:

  • lib
    • parameters.rego
    • utils.rego
  • /rules
    • rule_name1.rego
    • rule_name2.rego

后续步骤