Cómo escribir reglas personalizadas con Rego

En este documento, se describe cómo escribir reglas personalizadas con el lenguaje de políticas de Rego. Puedes usar estas reglas en Workload Manager para evaluar tus cargas de trabajo en función de las prácticas recomendadas definidas para tu organización.

Para obtener más información, consulta Acerca de las reglas personalizadas en Workload Manager.

Antes de comenzar

Cómo escribir reglas personalizadas con Rego

Google proporciona un repositorio de GitHub de muestra con un conjunto de reglas predefinidas que puedes usar para evaluar tus cargas de trabajo. Estos ejemplos abarcan varios casos de uso. Selecciona reglas del repositorio o crea un archivo de reglas (.rego) que describa tus requisitos de evaluación.

Una regla personalizada tiene las siguientes secciones:

  • Metadatos. Los siguientes campos definen los metadatos de la regla:

    • DETAILS: Es una descripción breve de la regla.
    • SEVERITY: Es un valor definido por el usuario que define la gravedad del incumplimiento de la regla. Por ejemplo: HIGH, CRITICAL, MEDIUM o LOW.
    • ASSET_TYPE: Es uno de los recursos admitidos. Consulta Fuentes de datos compatibles.
    • TAGS: Una o más etiquetas para la regla. Estas etiquetas ayudan a filtrar las reglas.
  • Declaración del paquete: Por ejemplo, templates.google.compute.instance.label

  • Declaraciones de importación. Por ejemplo, data.validator.google.lib as lib

  • Definiciones de reglas: Es un conjunto de instrucciones que define la regla.

Ejemplos de reglas

Las siguientes reglas de muestra están disponibles en el repositorio de GitHub GoogleCloudPlatform/workload-manager. Puedes subir estas reglas tal como están a tu bucket de Cloud Storage y usarlas para ejecutar tus evaluaciones. Como alternativa, modifica las reglas según las políticas de tu organización y, luego, sube los archivos a un bucket de Cloud Storage.

  • Ejemplo 1: Garantiza que haya al menos una etiqueta para tus VMs.
  • Ejemplo 2: Garantiza que tu carga de trabajo no use la cuenta de servicio predeterminada de Compute Engine.
  • Ejemplo 3: Garantiza que las VMs de tu carga de trabajo no usen una dirección IP externa.

Para obtener una lista completa de las reglas de muestra que puedes usar en Workload Manager, consulta el repositorio de GitHub GoogleCloudPlatform/workload-manager.

Ejemplo 1

Garantiza que haya al menos una etiqueta para los recursos de 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}
}

Ejemplo 2

Garantiza que tu carga de trabajo no use la cuenta de servicio predeterminada de 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)
}

Ejemplo 3

Garantiza que las VMs de tu carga de trabajo no usen una dirección IP externa.

# 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}
}

Sube la regla a un bucket de Cloud Storage

Después de crear el archivo .rego, súbelo a un bucket de Cloud Storage. El nivel superior de tu bucket de Cloud Storage debe incluir las carpetas /lib y /rules:

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

¿Qué sigue?