Sebelum memulai
Framework Batasan
gcloud beta terraform vet
menggunakan
kebijakan Framework Batasan,
yang terdiri dari batasan dan template batasan. Perbedaan
antara keduanya adalah sebagai berikut:
- Template batasan itu seperti deklarasi fungsi; yaitu menetapkan aturan di Rego dan secara opsional mengambil parameter input.
- Batasan adalah file yang mereferensikan template batasan dan menentukan parameter input yang akan diteruskan ke template tersebut serta resource yang dicakup oleh kebijakan.
Ini memungkinkan Anda untuk menghindari pengulangan. Anda dapat menulis template batasan dengan kebijakan umum, lalu menulis sejumlah batasan yang memberikan parameter input berbeda atau aturan pencocokan resource yang berbeda.
Aset CAI vs resource Terraform
Aset Inventaris Aset Cloud adalah format ekspor data Google standar yang
tersedia
untuk banyak resource Google Cloud.
Data CAI biasanya hanya tersedia setelah resource dibuat atau diperbarui.
Namun, dengan mengonversi perubahan resource Terraform menjadi data Aset CAI,
gcloud beta terraform vet
memungkinkan Anda menulis kebijakan satu kali dan menggunakannya
sebelum menerapkan serta sebagai pemeriksaan audit dengan alat yang kompatibel.
Alat yang kompatibel
Alat berikut bukan merupakan produk resmi Google dan tidak didukung.
Namun, alat ini mungkin kompatibel dengan kebijakan yang ditulis untuk gcloud beta terraform vet
:
Membuat template batasan
Sebelum mengembangkan template batasan, pastikan bahwa Aset yang ingin Anda
tulis kebijakannya didukung oleh
Inventaris Aset Cloud
dan gcloud beta terraform vet
.
Langkah-langkah untuk membuat template batasan adalah sebagai berikut:
- Kumpulkan data sampel.
- Tulis Rego.
- Uji Rego Anda.
- Siapkan kerangka template batasan.
- Sejajarkan Rego Anda.
- Siapkan batasan.
Mengumpulkan data sampel
Untuk menulis template batasan, Anda harus memiliki contoh data untuk beroperasi. Batasan berbasis CAI beroperasi pada Data Aset CAI. Kumpulkan data sampel dengan membuat resource dari jenis yang sesuai dan mengekspor resource tersebut sebagai JSON, seperti yang dijelaskan di panduan memulai CAI.
Berikut adalah contoh ekspor JSON untuk Alamat 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"
}
}
},
]
Tulis Rego
Setelah memiliki data contoh, Anda dapat menulis logika untuk template batasan
di
Rego.
Rego Anda harus memiliki aturan violations
. Aset yang sedang diulas tersedia
sebagai input.review
. Parameter batasan tersedia sebagai input.parameters
.
Misalnya, untuk mewajibkan aset compute.googleapis.com/Address
memiliki
addressType
yang diizinkan, tulis:
# 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}
}
Beri nama template batasan Anda
Contoh sebelumnya menggunakan nama
GCPComputeAddressAddressTypeAllowlistConstraintV1
. Ini adalah ID unik
untuk setiap template batasan. Sebaiknya ikuti panduan penamaan berikut:
- Format umum:
GCP{resource}{feature}Constraint{version}
. Gunakan CamelCase. (Dengan kata lain, gunakan huruf besar untuk setiap kata baru.) - Untuk batasan resource tunggal, ikuti nama grup gcloud untuk penamaan resource. Misalnya, gunakan "compute" bukan "gce", "sql", bukan "cloud-sql", dan "container-cluster" bukan "gke".
- Jika template berlaku untuk lebih dari satu jenis resource, hapus bagian resource dan hanya sertakan fiturnya (contoh: "GCPAddressTypeAllowlistConstraintV1").
- Nomor versi tidak mengikuti format semver; itu hanya satu angka. Cara ini secara efektif membuat setiap versi template menjadi template yang unik.
Sebaiknya gunakan nama untuk file Rego yang cocok dengan nama template
batasan, tetapi gunakan snake_case. Dengan kata lain, konversi nama menjadi
kata-kata yang menggunakan huruf kecil dan terpisah dengan _
. Untuk contoh sebelumnya, nama file
yang direkomendasikan adalah gcp_compute_address_address_type_allowlist_constraint_v1.rego
Uji Rego Anda
Anda dapat menguji Rego secara manual dengan Rego Playground. Pastikan untuk menggunakan data yang tidak sensitif.
Sebaiknya tulis
pengujian otomatis.
Masukkan data sampel yang Anda kumpulkan di validator/test/fixtures/<constraint
filename>/assets/data.json
dan referensikan data tersebut di file pengujian seperti ini:
# 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
}
Tempatkan Rego dan pengujian Anda dalam folder validator
di library kebijakan Anda.
Menyiapkan kerangka template batasan
Setelah memiliki aturan Rego yang berfungsi dan diuji, Anda harus mengemasnya sebagai template batasan. Framework Batasan menggunakan Definisi Resource Kustom Kubernetes sebagai container untuk kebijakan Rego.
Template batasan juga menentukan parameter yang diizinkan sebagai input dari batasan, menggunakan skema OpenAPI V3.
Gunakan nama yang sama untuk kerangka seperti yang Anda gunakan untuk Rego. Pada khususnya:
- Gunakan nama file yang sama seperti untuk Rego Anda. Contoh:
gcp_compute_address_address_type_allowlist_constraint_v1.yaml
spec.crd.spec.names.kind
harus berisi nama templatemetadata.name
harus berisi nama template, tetapi ditulis dengan huruf kecil
Tempatkan kerangka template batasan di policies/templates
.
Untuk contoh di atas:
# 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
Sejajarkan Rego Anda
Pada tahap ini, mengikuti contoh sebelumnya, tata letak direktori Anda akan terlihat seperti ini:
| 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
Jika meng-clone
repositori library kebijakan yang disediakan Google,
Anda dapat menjalankan make build
untuk mengupdate template batasan secara otomatis di
policies/templates
dengan Rego yang ditentukan di validator
.
Menyiapkan batasan
Batasan berisi tiga informasi yang diperlukan gcloud beta terraform vet
untuk menerapkan dan melaporkan pelanggaran dengan benar:
severity
:low
,medium
, atauhigh
match
: Parameter untuk menentukan apakah batasan berlaku untuk resource tertentu. Parameter pencocokan berikut didukung:ancestries
: Daftar jalur ancestry yang akan disertakan menggunakan pencocokan gaya globexcludedAncestries
: (Opsional) Daftar jalur ancestry yang akan dikecualikan menggunakan pencocokan gaya glob.
parameters
: Nilai untuk parameter input template batasan.
Pastikan kind
berisi nama template batasan. Sebaiknya
setel metadata.name
ke slug deskriptif.
Contohnya, untuk hanya mengizinkan jenis alamat INTERNAL
menggunakan contoh template
batasan sebelumnya, tulis:
# 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"
Contoh yang cocok:
Pencocok jalur ancestry | Deskripsi |
---|---|
organizations/** | Semua organisasi |
organizations/123/** | Segala sesuatu di organisasi 123 |
organizations/123/folders/** | Segala sesuatu di organisasi 123 yang berada di bawah folder |
organizations/123/folders/456 | Semua yang ada di folder 456 dalam organisasi 123 |
organizations/123/folders/456/projects/789 | Semuanya di project 789 di folder 456 dalam organisasi 123 |
Jika alamat resource cocok dengan nilai di ancestries
dan excludedAncestries
,
alamat tersebut akan dikecualikan.
Batasan
Data paket Terraform memberikan representasi terbaik dari status sebenarnya setelah penerapan. Namun, dalam banyak kasus, status setelah penerapan mungkin tidak diketahui karena dihitung di sisi server. Dalam kasus ini, data juga tidak tersedia dalam Aset CAI yang dikonversi.
Membuat jalur ancestry CAI adalah bagian dari proses saat memvalidasi kebijakan. Gunakan
project default yang disediakan untuk menyiasati project ID yang tidak dikenal. Jika
project default tidak disediakan, jalur ancestry akan ditetapkan secara default ke
organizations/unknown
.
Anda dapat melarang ancestry yang tidak diketahui dengan menambahkan batasan berikut:
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: {}
Resource yang didukung
Jika Anda ingin gcloud beta terraform vet
menambahkan dukungan untuk resource yang tidak ada dalam
daftar ini, buka
permintaan peningkatan
dan pertimbangkan untuk
menyumbangkan kode.
Daftar resource yang didukung bergantung pada versi gcloud beta terraform vet
yang diinstal. Daftar resource yang didukung saat ini adalah sebagai berikut:
Resource Terraform | Aset Inventaris Aset Cloud |
---|---|
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 |