Vorbereitung
Einschränkungs-Framework
gcloud beta terraform vet
verwendet Constraint Framework-Richtlinien, die aus Einschränkungen und Einschränkungsvorlagen bestehen. So unterscheiden sich die beiden:
- Eine Einschränkungsvorlage kann man sich vorstellen wie eine Funktionsdeklaration. Sie definiert eine Regel und kann optional Variablen als Eingaben verwenden.
- Eine Einschränkung ist eine Datei, die auf eine Einschränkungsvorlage verweist und die Werte definiert, die damit verwendet werden sollen.
CAI-Assets und Terraform-Ressourcen
Cloud Asset Inventory-Assets sind ein standardmäßiges Google-Datenexportformat, das für viele GCP-Ressourcen verfügbar ist.
CAI-Daten sind normalerweise erst verfügbar, wenn eine Ressource erstellt oder aktualisiert wurde.
Durch die Konvertierung von Terraform-Ressourcenänderungen in CAI-Asset-Daten können Sie jedoch mit gcloud beta terraform vet
eine Richtlinie einmal schreiben und sowohl vor der Anwendung als auch als Audit-Prüfung mit kompatiblen Tools verwenden.
Kompatible Tools
Die folgenden Tools sind keine offiziellen Google-Produkte und werden nicht unterstützt.
Sie sind jedoch möglicherweise mit Richtlinien kompatibel, die für gcloud beta terraform vet
geschrieben wurden.
Einschränkungsvorlage erstellen
Prüfen Sie vor der Entwicklung der Einschränkungsvorlage, ob das Asset, für das Sie eine Richtlinie schreiben möchten, sowohl von Cloud Asset Inventory als auch von gcloud beta terraform vet
unterstützt wird.
1. Beispieldaten erfassen
Um eine Einschränkungsvorlage schreiben zu können, benötigen Sie Beispieldaten. CAI-basierte Einschränkungen gelten für CAI-Asset-Daten. Erfassen Sie Beispieldaten. Erstellen Sie dazu Ressourcen des entsprechenden Typs und exportieren Sie diese als JSON, wie in der CAI-Kurzanleitung beschrieben.
Hier ist ein Beispiel für einen JSON-Export für eine Compute-Adresse:
[
{
"name": "//compute.googleapis.com/projects/789/regions/us-central1/addresses/my-internal-address",
"asset_type": "compute.googleapis.com/Address",
"ancestors: [
"organization/123",
"folder/456",
"project/789"
],
"resource": {
"version": "v1",
"discovery_document_uri": "https://www.googleapis.com/discovery/v1/apis/compute/v1/rest",
"discovery_name": "Address",
"parent": "//cloudresourcemanager.googleapis.com/projects/789",
"data": {
"address": "10.0.42.42",
"addressType": "INTERNAL",
"name": "my-internal-address",
"region": "projects/789/global/regions/us-central1"
}
}
},
]
2. Rego schreiben
Nachdem Sie Beispieldaten haben, können Sie die Logik für Ihre Einschränkungsvorlage in Rego schreiben.
Ihr Rego muss eine violations
-Regel enthalten. Das überprüfte Asset ist als input.review
verfügbar. Einschränkungsparameter sind als input.parameters
verfügbar.
Wenn Sie beispielsweise anfordern möchten, dass compute.googleapis.com/Address
-Assets einen zulässigen addressType
haben, schreiben Sie:
# validator/gcp_compute_address_address_type_allowlist_constraint_v1.rego
package templates.gcp.GCPComputeAddressAddressTypeAllowlistConstraintV1
violation[{
"msg": message,
"details": metadata,
}] {
asset := input.review
asset.asset_type == "compute.googleapis.com/Address"
allowed_address_types := input.parameters.allowed_address_types
count({asset.resource.data.addressType} & allowed_address_types) >= 1
message := sprintf(
"Compute address %s has a disallowed address_type: %s",
[asset.name, asset.resource.data.addressType]
)
metadata := {"asset": asset.name}
}
Einschränkungsvorlage benennen
Im vorherigen Beispiel wird der Name GCPComputeAddressAddressTypeAllowlistConstraintV1
verwendet.
Dies ist eine eindeutige Kennung für jede Einschränkungsvorlage. Wir empfehlen, diese Richtlinien für Namen zu verwenden:
- Allgemeines Format:
GCP{resource}{feature}Constraint{version}
. CamelCase verwenden. Schreiben Sie also jedes neue Wort in Großbuchstaben. - Wenn Sie Einschränkungen für einzelne Ressourcen verwenden möchten, folgen Sie den gcloud-Gruppennamen für die Benennung von Ressourcen. Verwenden Sie beispielsweise "compute" anstelle von "gce", "sql" anstelle von "cloud-sql" und "container-cluster" anstelle von "gke".
- Wenn eine Vorlage für mehr als einen Ressourcentyp gilt, lassen Sie den Ressourcenteil weg und fügen Sie nur das Feature ein (Beispiel: "GCPAddressTypeAllowlistConstraintV1").
- Die Versionsnummer folgt nicht der semver-Form. nur eine einzige Zahl. Dadurch wird jede Version einer Vorlage zu einer eindeutigen Vorlage.
Wir empfehlen, für Ihre Rego-Datei einen Namen zu verwenden, der mit dem Namen der Einschränkungsvorlage übereinstimmt, aber "snake_case" verwendet. Mit anderen Worten, konvertieren Sie den Namen mit _
in Kleinbuchstaben. Im obigen Beispiel lautet der empfohlene Dateiname gcp_compute_address_address_type_allowlist_constraint_v1.rego
3. Rego testen
Sie können Ihr Rego manuell mit Rego Playground testen. Verwenden Sie nicht vertrauliche Daten.
Wir empfehlen, automatisierte Tests zu schreiben.
Fügen Sie Ihre gesammelten Beispieldaten in validator/test/fixtures/<constraint filename>/assets/data.json
ein und verweisen Sie in Ihrer Testdatei so darauf:
# validator/gcp_compute_address_address_type_allowlist_constraint_v1_test.rego
package templates.gcp.GCPComputeAddressAddressTypeAllowlistConstraintV1
import data.test.fixtures.gcp_compute_address_address_type_allowlist_constraint_v1_test.assets as assets
test_violation_with_disallowed_address_type {
parameters := {
"allowed_address_types": "EXTERNAL"
}
violations := violation with input.review as assets[_]
with input.parameters as parameters
count(violations) == 1
}
Platzieren Sie den Rego und den Test im Ordner validator
Ihrer Richtlinienbibliothek.
4. Basis-Einschränkungsvorlage einrichten
Nachdem Sie eine funktionierende und getestete Rego-Regel haben, müssen Sie diese als Einschränkungsvorlage verpacken. Constraint Framework verwendet benutzerdefinierte Kubernetes-Ressourcendefinitionen als Container für den Richtlinien-Rego.
Die Einschränkungsvorlage definiert mithilfe des Schemas OpenAPI V3 auch, welche Parameter als Eingaben von Einschränkungen zulässig sind.
Verwenden Sie für das Skelett denselben Namen wie für den Rego. Beispiele:
- Verwenden Sie denselben Dateinamen wie für Ihren Rego. Beispiel:
gcp_compute_address_address_type_allowlist_constraint_v1.yaml
spec.crd.spec.names.kind
muss den Vorlagennamen enthaltenmetadata.name
muss den Vorlagennamen enthalten, muss aber kleingeschrieben werden
Platzieren Sie das Basisschema der Einschränkungsvorlage in policies/templates
.
Für das obige Beispiel:
# policies/templates/gcp_compute_address_address_type_allowlist_constraint_v1.yaml
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: gcpcomputeaddressaddresstypeallowlistconstraintv1
spec:
crd:
spec:
names:
kind: GCPComputeAddressAddressTypeAllowlistConstraintV1
validation:
openAPIV3Schema:
properties:
allowed_address_types:
description: "A list of address_types allowed, for example: ['INTERNAL']"
type: array
items:
type: string
targets:
- target: validation.gcp.forsetisecurity.org
rego: |
#INLINE("validator/gcp_compute_address_address_type_allowlist_constraint_v1.rego")
#ENDINLINE
5 Ihr Rego einbinden
In Anlehnung an das vorherige Beispiel sieht Ihr Verzeichnislayout nun folgendermaßen aus:
| policy-library/
|- validator/
||- gcp_compute_address_address_type_allowlist_constraint_v1.rego
||- gcp_compute_address_address_type_allowlist_constraint_v1_test.rego
|- policies
||- templates
|||- gcp_compute_address_address_type_allowlist_constraint_v1.yaml
Wenn Sie das von Google bereitgestellte Repository für die Richtlinienbibliothek geklont haben, können Sie make build
ausführen, um Ihre Einschränkungsvorlagen in policies/templates
automatisch mit den in validator
definierten rego zu aktualisieren.
6. Eine Einschränkung einrichten
Einschränkungen enthalten drei Informationen, die gcloud beta terraform vet
ordnungsgemäß erzwingen und Verstöße melden muss:
severity
:low
,medium
oderhigh
match
: Parameter, um zu bestimmen, ob eine Einschränkung für eine bestimmte Ressource gilt. Die folgenden Übereinstimmungsparameter werden unterstützt:target
: eine Liste der Herkunftspfade, die mithilfe des Glob-Stil-Abgleichs einbezogen werden sollenexclude
: (Optional) Eine Liste mit Herkunftspfaden, die mithilfe des Glob-Stils ausgeschlossen werden sollen.
parameters
: Werte für die Eingabeparameter der Einschränkungsvorlage.
Achten Sie darauf, dass kind
den Namen der Einschränkungsvorlage enthält. Wir empfehlen, metadata.name
auf eine beschreibende Slug festzulegen.
Wenn Sie beispielsweise nur INTERNAL
-Adresstypen mit der vorherigen Beispieleinschränkungsvorlage zulassen möchten, schreiben Sie:
# policies/constraints/gcp_compute_address_internal_only.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: GCPComputeAddressAddressTypeAllowlistConstraintV1
metadata:
name: gcp_compute_address_internal_only
spec:
severity: high
match:
target:
- "**"
parameters:
allowed_address_types:
- "INTERNAL"
Beispiele für Übereinstimmungen:
Herkunftspfad-Matcher | Beschreibung |
---|---|
organizations/** | Alle Organisationen |
organizations/123/** | Alles in Organisation 123 |
organizations/123/folders/** | Alles in Organisation 123, das sich unter einem Ordner befindet |
organizations/123/folders/456 | Alles in Ordner 456 in Organisation 123 |
organizations/123/folders/456/projects/789 | Alles in Projekt 789 in Ordner 456 in Organisation 123 |
Wenn eine Ressourcenadresse mit den Werten in target
und exclude
übereinstimmt, wird sie ausgeschlossen.
Beschränkungen
Die Daten eines Terraform-Plans liefern nach dem Anwenden die beste verfügbare Darstellung des tatsächlichen Status. In vielen Fällen ist der Zustand nach dem Anwenden jedoch möglicherweise nicht bekannt, da er serverseitig berechnet wird. In diesen Fällen sind die Daten auch nicht in den konvertierten CAI-Assets verfügbar.
Unterstützte Ressourcen
Wenn Sie möchten, dass gcloud beta terraform vet
Support für eine Ressource hinzufügt, die nicht auf dieser Liste steht, öffnen Sie eine Verbesserungsanfrage und erwägen Sie, Code beizusteuern.
Die Liste der unterstützten Ressourcen hängt davon ab, welche Version von gcloud beta terraform vet
installiert ist. Aktuell werden folgende Ressourcen unterstützt:
Terraform-Ressource | Cloud Asset Inventory-Assets |
---|---|
google_access_context_manager_access_policy_iam_binding | accesscontextmanager.googleapis.com/AccessPolicy |
google_access_context_manager_access_policy_iam_member | accesscontextmanager.googleapis.com/AccessPolicy |
google_access_context_manager_access_policy_iam_policy | accesscontextmanager.googleapis.com/AccessPolicy |
google_access_context_manager_service_perimeter | accesscontextmanager.googleapis.com/ServicePerimeter |
google_apigee_environment_iam_binding | apigee.googleapis.com/Environment |
google_apigee_environment_iam_member | apigee.googleapis.com/Environment |
google_apigee_environment_iam_policy | apigee.googleapis.com/Environment |
google_bigquery_dataset | bigquery.googleapis.com/Dataset |
google_bigquery_dataset_iam_binding | bigquery.googleapis.com/Dataset |
google_bigquery_dataset_iam_member | bigquery.googleapis.com/Dataset |
google_bigquery_dataset_iam_policy | bigquery.googleapis.com/Dataset |
google_bigquery_table | bigquery.googleapis.com/Table |
google_bigquery_table_iam_binding | bigquery.googleapis.com/Table |
google_bigquery_table_iam_member | bigquery.googleapis.com/Table |
google_bigquery_table_iam_policy | bigquery.googleapis.com/Table |
google_bigtable_instance | bigtableadmin.googleapis.com/Cluster, bigtableadmin.googleapis.com/Instance |
google_binary_authorization_attestor_iam_binding | binaryauthorization.googleapis.com/Attestor |
google_binary_authorization_attestor_iam_member | binaryauthorization.googleapis.com/Attestor |
google_binary_authorization_attestor_iam_policy | binaryauthorization.googleapis.com/Attestor |
google_cloud_run_domain_mapping | run.googleapis.com/DomainMapping |
google_cloud_run_service | run.googleapis.com/Service |
google_cloud_run_service_iam_binding | run.googleapis.com/Service |
google_cloud_run_service_iam_member | run.googleapis.com/Service |
google_cloud_run_service_iam_policy | run.googleapis.com/Service |
google_cloudfunctions_function | cloudfunctions.googleapis.com/CloudFunction |
google_cloudfunctions_function_iam_binding | cloudfunctions.googleapis.com/CloudFunction |
google_cloudfunctions_function_iam_member | cloudfunctions.googleapis.com/CloudFunction |
google_cloudfunctions_function_iam_policy | cloudfunctions.googleapis.com/CloudFunction |
google_compute_address | compute.googleapis.com/Address |
google_compute_backend_service_iam_binding | compute.googleapis.com/BackendService |
google_compute_backend_service_iam_member | compute.googleapis.com/BackendService |
google_compute_backend_service_iam_policy | compute.googleapis.com/BackendService |
google_compute_disk | compute.googleapis.com/Disk |
google_compute_disk_iam_binding | compute.googleapis.com/Disk |
google_compute_disk_iam_member | compute.googleapis.com/Disk |
google_compute_disk_iam_policy | compute.googleapis.com/Disk |
google_compute_firewall | compute.googleapis.com/Firewall |
google_compute_forwarding_rule | compute.googleapis.com/ForwardingRule |
google_compute_global_address | compute.googleapis.com/GlobalAddress |
google_compute_global_forwarding_rule | compute.googleapis.com/GlobalForwardingRule |
google_compute_image_iam_binding | compute.googleapis.com/Image |
google_compute_image_iam_member | compute.googleapis.com/Image |
google_compute_image_iam_policy | compute.googleapis.com/Image |
google_compute_instance | compute.googleapis.com/Instance |
google_compute_instance_iam_binding | compute.googleapis.com/Instance |
google_compute_instance_iam_member | compute.googleapis.com/Instance |
google_compute_instance_iam_policy | compute.googleapis.com/Instance |
google_compute_network | compute.googleapis.com/Network |
google_compute_region_backend_service_iam_binding | compute.googleapis.com/RegionBackendService |
google_compute_region_backend_service_iam_member | compute.googleapis.com/RegionBackendService |
google_compute_region_backend_service_iam_policy | compute.googleapis.com/RegionBackendService |
google_compute_region_disk_iam_binding | compute.googleapis.com/RegionDisk |
google_compute_region_disk_iam_member | compute.googleapis.com/RegionDisk |
google_compute_region_disk_iam_policy | compute.googleapis.com/RegionDisk |
google_compute_security_policy | compute.googleapis.com/SecurityPolicy |
google_compute_snapshot | compute.googleapis.com/Snapshot |
google_compute_ssl_policy | compute.googleapis.com/SslPolicy |
google_compute_subnetwork | compute.googleapis.com/Subnetwork |
google_compute_subnetwork_iam_binding | compute.googleapis.com/Subnetwork |
google_compute_subnetwork_iam_member | compute.googleapis.com/Subnetwork |
google_compute_subnetwork_iam_policy | compute.googleapis.com/Subnetwork |
google_container_cluster | container.googleapis.com/Cluster |
google_container_node_pool | container.googleapis.com/NodePool |
google_data_catalog_entry_group_iam_binding | datacatalog.googleapis.com/EntryGroup |
google_data_catalog_entry_group_iam_member | datacatalog.googleapis.com/EntryGroup |
google_data_catalog_entry_group_iam_policy | datacatalog.googleapis.com/EntryGroup |
google_data_catalog_tag_template_iam_binding | datacatalog.googleapis.com/TagTemplate |
google_data_catalog_tag_template_iam_member | datacatalog.googleapis.com/TagTemplate |
google_data_catalog_tag_template_iam_policy | datacatalog.googleapis.com/TagTemplate |
google_dns_managed_zone | dns.googleapis.com/ManagedZone |
google_dns_policy | dns.googleapis.com/Policy |
google_endpoints_service_consumers_iam_binding | servicemanagement.googleapis.com/ServiceConsumers |
google_endpoints_service_consumers_iam_member | servicemanagement.googleapis.com/ServiceConsumers |
google_endpoints_service_consumers_iam_policy | servicemanagement.googleapis.com/ServiceConsumers |
google_endpoints_service_iam_binding | servicemanagement.googleapis.com/Service |
google_endpoints_service_iam_member | servicemanagement.googleapis.com/Service |
google_endpoints_service_iam_policy | servicemanagement.googleapis.com/Service |
google_filestore_instance | file.googleapis.com/Instance |
google_folder_iam_binding | cloudresourcemanager.googleapis.com/Folder |
google_folder_iam_member | cloudresourcemanager.googleapis.com/Folder |
google_folder_iam_policy | cloudresourcemanager.googleapis.com/Folder |
google_folder_organization_policy | cloudresourcemanager.googleapis.com/Folder |
google_healthcare_consent_store_iam_binding | healthcare.googleapis.com/ConsentStore |
google_healthcare_consent_store_iam_member | healthcare.googleapis.com/ConsentStore |
google_healthcare_consent_store_iam_policy | healthcare.googleapis.com/ConsentStore |
google_iap_tunnel_iam_binding | iap.googleapis.com/Tunnel |
google_iap_tunnel_iam_member | iap.googleapis.com/Tunnel |
google_iap_tunnel_iam_policy | iap.googleapis.com/Tunnel |
google_iap_tunnel_instance_iam_binding | iap.googleapis.com/TunnelInstance |
google_iap_tunnel_instance_iam_member | iap.googleapis.com/TunnelInstance |
google_iap_tunnel_instance_iam_policy | iap.googleapis.com/TunnelInstance |
google_iap_web_iam_binding | iap.googleapis.com/Web |
google_iap_web_iam_member | iap.googleapis.com/Web |
google_iap_web_iam_policy | iap.googleapis.com/Web |
google_kms_crypto_key | cloudkms.googleapis.com/CryptoKey |
google_kms_crypto_key_iam_binding | cloudkms.googleapis.com/CryptoKey |
google_kms_crypto_key_iam_member | cloudkms.googleapis.com/CryptoKey |
google_kms_crypto_key_iam_policy | cloudkms.googleapis.com/CryptoKey |
google_kms_key_ring | cloudkms.googleapis.com/KeyRing |
google_kms_key_ring_iam_binding | cloudkms.googleapis.com/KeyRing |
google_kms_key_ring_iam_member | cloudkms.googleapis.com/KeyRing |
google_kms_key_ring_iam_policy | cloudkms.googleapis.com/KeyRing |
google_monitoring_alert_policy | monitoring.googleapis.com/AlertPolicy |
google_monitoring_notification_channel | monitoring.googleapis.com/NotificationChannel |
google_notebooks_instance_iam_binding | notebooks.googleapis.com/Instance |
google_notebooks_instance_iam_member | notebooks.googleapis.com/Instance |
google_notebooks_instance_iam_policy | notebooks.googleapis.com/Instance |
google_notebooks_runtime_iam_binding | notebooks.googleapis.com/Runtime |
google_notebooks_runtime_iam_member | notebooks.googleapis.com/Runtime |
google_notebooks_runtime_iam_policy | notebooks.googleapis.com/Runtime |
google_organization_iam_binding | cloudresourcemanager.googleapis.com/Organization |
google_organization_iam_custom_role | iam.googleapis.com/Role |
google_organization_iam_member | cloudresourcemanager.googleapis.com/Organization |
google_organization_iam_policy | cloudresourcemanager.googleapis.com/Organization |
google_organization_policy | cloudresourcemanager.googleapis.com/Organization |
google_privateca_ca_pool_iam_binding | privateca.googleapis.com/CaPool |
google_privateca_ca_pool_iam_member | privateca.googleapis.com/CaPool |
google_privateca_ca_pool_iam_policy | privateca.googleapis.com/CaPool |
google_privateca_certificate_template_iam_binding | privateca.googleapis.com/CertificateTemplate |
google_privateca_certificate_template_iam_member | privateca.googleapis.com/CertificateTemplate |
google_privateca_certificate_template_iam_policy | privateca.googleapis.com/CertificateTemplate |
google_project | cloudbilling.googleapis.com/ProjectBillingInfo, cloudresourcemanager.googleapis.com/Project |
google_project_iam_binding | cloudresourcemanager.googleapis.com/Project |
google_project_iam_custom_role | iam.googleapis.com/Role |
google_project_iam_member | cloudresourcemanager.googleapis.com/Project |
google_project_iam_policy | cloudresourcemanager.googleapis.com/Project |
google_project_organization_policy | cloudresourcemanager.googleapis.com/Project |
google_project_service | serviceusage.googleapis.com/Service |
google_pubsub_lite_reservation | pubsublite.googleapis.com/Reservation |
google_pubsub_lite_subscription | pubsublite.googleapis.com/Subscription |
google_pubsub_lite_topic | pubsublite.googleapis.com/Topic |
google_pubsub_schema | pubsub.googleapis.com/Schema |
google_pubsub_subscription | pubsub.googleapis.com/Subscription |
google_pubsub_subscription_iam_binding | pubsub.googleapis.com/Subscription |
google_pubsub_subscription_iam_member | pubsub.googleapis.com/Subscription |
google_pubsub_subscription_iam_policy | pubsub.googleapis.com/Subscription |
google_pubsub_topic | pubsub.googleapis.com/Topic |
google_pubsub_topic_iam_binding | pubsub.googleapis.com/Topic |
google_pubsub_topic_iam_member | pubsub.googleapis.com/Topic |
google_pubsub_topic_iam_policy | pubsub.googleapis.com/Topic |
google_redis_instance | redis.googleapis.com/Instance |
google_secret_manager_secret_iam_binding | secretmanager.googleapis.com/Secret |
google_secret_manager_secret_iam_member | secretmanager.googleapis.com/Secret |
google_secret_manager_secret_iam_policy | secretmanager.googleapis.com/Secret |
google_spanner_database | spanner.googleapis.com/Database |
google_spanner_database_iam_binding | spanner.googleapis.com/Database |
google_spanner_database_iam_member | spanner.googleapis.com/Database |
google_spanner_database_iam_policy | spanner.googleapis.com/Database |
google_spanner_instance | spanner.googleapis.com/Instance |
google_spanner_instance_iam_binding | spanner.googleapis.com/Instance |
google_spanner_instance_iam_member | spanner.googleapis.com/Instance |
google_spanner_instance_iam_policy | spanner.googleapis.com/Instance |
google_sql_database | sqladmin.googleapis.com/Database |
google_sql_database_instance | sqladmin.googleapis.com/Instance |
google_storage_bucket | storage.googleapis.com/Bucket |
google_storage_bucket_iam_binding | storage.googleapis.com/Bucket |
google_storage_bucket_iam_member | storage.googleapis.com/Bucket |
google_storage_bucket_iam_policy | storage.googleapis.com/Bucket |
google_vpc_access_connector | vpcaccess.googleapis.com/Connector |