לפני שמתחילים
Constraint Framework
בשדה gcloud beta terraform vet פועלת מדיניות של Constraint Framework, שמכילה אילוצים וגם תבניות אילוצים. ההבדל בין שניהם:
- תבנית אילוצים דומה להצהרת פונקציה. היא מגדירה כלל ב-Rego ומאפשרת להשתמש בפרמטרים של הקלט.
- אילוץ הוא קובץ שמפנה לתבנית אילוצים, ובו מוגדרים הפרמטרים של הקלט שצריך להעביר לתבנית ואת המשאבים שהמדיניות חלה עליהם.
כך אפשר להימנע מחזרה על הגדרות. תוכלו לכתוב מדיניות כללית בתבנית אילוצים, ולאחר מכן לכתוב כמה אילוצים שתצטרכו – עם פרמטרים שונים של קלט או עם כללים שונים להתאמת המשאבים.
נכסי CAI לעומת משאבי Terraform
נכסים של מאגר משאבי הענן (CAI) הם פורמט סטנדרטי לייצוא נתונים מ-Google שזמין למשאבים רבים Google Cloud .
בדרך כלל נתוני CAI זמינים רק אחרי שיוצרים או מעדכנים משאבים.
עם זאת, כשממירים שינויים במשאבי Terraform לנתונים של נכסי CAI, אפשר להשתמש ב-gcloud beta terraform vet כדי לכתוב מדיניות אחת ולהשתמש בה גם כבדיקה מקדימה וגם כביקורת באמצעות הכלים התואמים.
הכלים התואמים
הכלים הבאים הם לא מוצרים רשמיים של Google ואנחנו לא תומכים בהם.
עם זאת, יכול להיות שהם יתאימו לכללי מדיניות שייכתבו עבור gcloud beta terraform vet.
יצירה של תבנית אילוצים
לפני שאתם מפתחים את תבנית האילוצים, ודאו שהנכס שאתם רוצים לכתוב עבורו מדיניות נתמך גם על ידי מאגר משאבי הענן וגם על ידי gcloud beta terraform vet.
אלה השלבים ליצירת תבנית אילוצים:
- איסוף של נתונים לדוגמה.
- כתיבה בשפת Rego
- בדיקת ה-Rego
- הגדרת שלד של תבנית אילוצים
- הצבת ה-Rego בתוך שורה
- הגדרת אילוץ
איסוף נתונים לדוגמה
כדי לכתוב תבנית אילוצים יש צורך בנתונים לדוגמה שאפשר להסתמך עליהם. אילוצים המבוססים על CAI מסתמכים על נתונים של נכסי CAI. כדי לאסוף נתונים לדוגמה תצטרכו ליצור משאבים מהסוג המתאים ולייצא אותם כקובץ JSON. תוכלו להיעזר בהסבר שמופיע במדריך למתחילים ל-CAI.
דוגמה לייצוא קובץ JSON לכתובת ב-Compute:
[
{
"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"
}
}
},
]
כתיבה בשפת Rego
אחרי שהנתונים לדוגמה מתקבלים, אפשר לכתוב את הלוגיקה של תבנית האילוצים ב-Rego.
חייב להיות כלל violations ב-Rego. הנכס שנמצא בבדיקה זמין בתור input.review. הפרמטרים של האילוצים זמינים בתור input.parameters.
לדוגמה, כדי לדרוש שלנכסים של compute.googleapis.com/Address יהיה addressType מורשה, צריך לכתוב:
# 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}
}
בחירת שם לתבנית האילוצים
בדוגמה הקודמת השתמשנו בשם GCPComputeAddressAddressTypeAllowlistConstraintV1. זהו מזהה ייחודי של כל תבנית אילוצים. מומלץ לבחור שמות לפי ההנחיות הבאות:
- פורמט כללי:
GCP{resource}{feature}Constraint{version}. צריך להשתמש ב-CamelCase (כלומר, כל מילה חדשה תתחיל באות רישית). - באילוצים של משאב יחיד, צריך להשתמש בשמות הקבוצות של gcloudעבור שמות המשאבים. לדוגמה, צריך לכתוב "compute" במקום "gce", "sql" במקום "cloud-sql" ו-"container-cluster" במקום "gke".
- אם תבנית חלה על כמה סוגי משאבים, צריך להשמיט את החלק של המשאב ולכלול רק את המאפיין (לדוגמה: "GCPAddressTypeAllowlistConstraintV1").
- מספר הגרסה מורכב ממספר אחד בלבד, ולא לפי תבנית semver. כך למעשה כל גרסה של תבנית הופכת לתבנית ייחודית.
מומלץ לבחור שם לקובץ ה-Rego שמתאים לשם של תבנית האילוצים, אבל עם שימוש ב-snake_case. במילים אחרות, צריך להמיר את השם למילים נפרדות באותיות קטנות באמצעות _. בדוגמה הקודמת, שם הקובץ המומלץ הוא gcp_compute_address_address_type_allowlist_constraint_v1.rego.
בדיקת ה-Rego
תוכלו לבדוק את קוד ה-Rego באופן ידני בעזרת Rego Playground. הקפידו להשתמש בנתונים שלא מכילים מידע אישי רגיש.
אנחנו ממליצים לנסח בדיקות אוטומטיות.
עליכם להכניס את נתוני הדגימה שאספתם אל validator/test/fixtures/<constraint
filename>/assets/data.json ולציין אותם בקובץ הבדיקה, באופן הבא:
# 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
}
העבירו את ה-Rego ואת הבדיקה לתיקייה validator שבספריית המדיניות שלכם.
הגדרת שלד של תבנית אילוצים
אחרי שיצרתם כלל Rego שנבדק ופועל, עליכם לארוז אותו כתבנית אילוצים. המדיניות Constraint Framework משתמשת ב-Kubernetes Custom Resource Definitions בתור הקונטיינר של ה-Rego במדיניות.
תבנית האילוצים גם מגדירה באמצעות הסכימה OpenAPI V3 באילו פרמטרים אפשר להשתמש כמקורות קלט מאילוצים.
שם השלד צריך להיות זהה לשם שהשתמשתם ב-Rego. הקפידו במיוחד על הדברים הבאים:
- השתמשו באותו שם קובץ שבחרתם ל-Rego. לדוגמה:
gcp_compute_address_address_type_allowlist_constraint_v1.yaml - השדה
spec.crd.spec.names.kindחייב להכיל את שם התבנית. - השדה
metadata.nameחייב להכיל את שם התבנית, אבל צריך להשתמש באותיות קטנות.
עליכם להציב את השלד של תבנית האילוצים ב-policies/templates.
בדוגמה הקודמת, זה יופיע כך:
# 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
הצבת ה-Rego בתוך שורה
עכשיו, לאחר הדוגמה הקודמת, הפריסה של הספריות נראית כך:
| 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
אם שכפלתם את מאגר ספריית המדיניות של Google, תוכלו להריץ את make build כדי לעדכן אוטומטית את תבניות האילוצים ב-policies/templates לפי ה-Rego שהוגדר ב-validator.
הגדרת אילוץ
האילוצים מכילים שלושה פרטים שנדרשים ל-gcloud beta terraform vet כדי לאכוף הפרות ולדווח עליהן כמו שצריך:
severity:low,mediumאוhighmatch: פרמטרים שנועדו לקבוע אם האילוץ חל על משאב מסוים. אפשר להשתמש בפרמטרים הבאים להתאמה:ancestries: רשימת נתיבים לישויות אב שצריך לכלול באמצעות התאמה של glob-style.excludedAncestries: (אופציונלי) רשימה של נתיבים לישויות אב שצריך להחריג באמצעות התאמה של glob-style.
parameters: ערכים לפרמטרים של הקלט של תבנית האילוצים.
הקפידו שהשדה kind יכלול את השם של תבנית האילוצים. מומלץ להגדיר שהשדה metadata.name יהיה שורה עם תיאור.
לדוגמה, כדי לאפשר רק כתובות מסוג INTERNAL באמצעות תבנית האילוצים מהדוגמה הקודמת, עליכם לכתוב:
# 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:
ancestries:
- "**"
parameters:
allowed_address_types:
- "INTERNAL"
דוגמאות להתאמות:
| כלי להתאמת נתיבים לישויות אב | תיאור |
|---|---|
| organizations/** | כל הארגונים |
| organizations/123/** | כל מה שבארגון 123 |
| organizations/123/folders/** | כל מה שבתיקייה של ארגון 123 |
| organizations/123/folders/456 | כל מה שבתיקייה 456 של ארגון 123 |
| organizations/123/folders/456/projects/789 | כל מה שבפרויקט 789 בתיקייה 456 של ארגון 123 |
אם כתובת של משאב תואמת לערכים ב-ancestries וב-excludedAncestries, היא תוחרג.
מגבלות
הנתונים של תוכנית Terraform מציגים הכי טוב את הייצוג הזמין של המצב בפועל אחרי ההחלה. עם זאת, במקרים רבים ייתכן שהמצב לאחר ההחלה לא יהיה ידוע כי הוא מחושב בצד של השרת. במקרים כאלה, הנתונים לא יהיו זמינים גם בפורמט המומר של נכסי CAI.
בניית נתיבים לישויות אב של CAI היא חלק מתהליך אימות המדיניות. לצורך כך משתמשים בפרויקט ברירת המחדל שסופק, כדי לעקוף מזהי פרויקטים לא ידועים. אם לא סופק פרויקט ברירת מחדל, ברירת המחדל של הנתיב לישויות האב היא organizations/unknown.
אפשר למנוע שימוש בישויות אב עם מזהים לא ידועים על ידי הוספת האילוץ הבא:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: GCPAlwaysViolatesConstraintV1
metadata:
name: disallow_unknown_ancestry
annotations:
description: |
Unknown ancestry is not allowed; use --project=<project> to set a
default ancestry
spec:
severity: high
match:
ancestries:
- "organizations/unknown"
parameters: {}
משאבים נתמכים
אם אתם רוצים להוסיף תמיכה ב-gcloud beta terraform vet למשאב שלא מופיע ברשימה, תוכלו ליצור בקשה לשיפור ולשקול לתרום קוד.
רשימת המשאבים הנתמכים תלויה בגרסה של gcloud beta terraform vet שמותקנת. רשימת המשאבים הנתמכים:
| משאב Terraform | נכסים במאגר משאבי הענן |
|---|---|
| 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 |