Prima di iniziare
Framework di vincolo
gcloud beta terraform vet
utilizza i criteri di Vincolo di vincoli, che sono costituiti da vincoli e modelli di vincolo. La
differenza tra i due elementi è la seguente:
- Un modello di vincolo è come una dichiarazione di funzioni: definisce una regola e, se vuoi, accetta le variabili come input.
- Un vincolo è un file che fa riferimento a un modello di vincolo e definisce i valori da utilizzare.
Asset CAI e risorse Terraform
Gli asset dell'inventario Cloud Asset sono un formato di esportazione dei dati di Google standard
disponibile per molte risorse GCP.
I dati CAI sono generalmente disponibili solo dopo aver creato o aggiornato una risorsa.
Tuttavia, convertendo le modifiche apportate alle risorse Terraform in dati degli asset CAI, gcloud beta terraform vet
ti consente di scrivere un criterio una volta e di utilizzarlo sia prima dell'applicazione sia come controllo di controllo con strumenti compatibili.
Strumenti compatibili
I seguenti strumenti non sono prodotti Google ufficiali e non sono supportati.
Tuttavia, potrebbero essere compatibili con le norme scritte per gcloud beta terraform vet
.
Crea un modello di vincolo
Prima di sviluppare il modello di vincolo, verifica che l'asset per cui vuoi scrivere un criterio sia supportato sia da Cloud Asset Inventory sia da gcloud beta terraform vet
.
1. Raccogli dati di esempio
Per scrivere un modello di vincolo, devi disporre di dati di esempio su cui operare. I vincoli basati sul CAI funzionano sui dati degli asset CAI. Raccogli dati di esempio creando risorse del tipo appropriato ed esportandole in formato JSON, come descritto nella guida rapida di CAI.
Di seguito è riportato un esempio di esportazione JSON per un indirizzo 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"
}
}
},
]
2. Scrivi riepilogo
Dopo aver ricevuto i dati di esempio, puoi scrivere la logica per il modello di vincolo in Rego.
La regola Rego deve avere una regola violations
. La risorsa che viene recensita è disponibile come input.review
. I parametri di vincolo sono disponibili come input.parameters
.
Ad esempio, per richiedere che gli asset compute.googleapis.com/Address
abbiano un elemento
addressType
consentito, scrivi:
# 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}
}
Assegna un nome al modello di vincolo
L'esempio precedente utilizza il nome GCPComputeAddressAddressTypeAllowlistConstraintV1
.
Si tratta di un identificatore univoco per ogni modello di vincolo. Ti consigliamo di seguire queste linee guida per l'assegnazione dei nomi:
- Formato generale:
GCP{resource}{feature}Constraint{version}
. Utilizza CamelCase. (in altre parole, tutte le parole in maiuscolo.) - Per i vincoli risorsa singola, segui i nomi dei gruppi gcloud per la denominazione delle risorse. Ad esempio, usa "compute" invece di "gce", "sql".
- Se un modello si applica a più tipi di risorse, ometti la parte in questione e includi solo la funzionalità (ad esempio: "GCPAddressTypeAllowlistConstraintV1").
- Il numero di versione non segue il formato semver; è un solo numero. In questo modo, ogni versione di un modello è un modello univoco.
Ti consigliamo di utilizzare per il file rego un nome che corrisponda al nome del modello di vincolo, ma utilizza snake_case. In altre parole, converti il nome
in parole separate da lettere minuscole con _
. Per l'esempio precedente, il nome
file consigliato è gcp_compute_address_address_type_allowlist_constraint_v1.rego
3. Testa la tua replica
Puoi testare manualmente la tua Rego con Rego Playground. Assicurati di utilizzare dati non sensibili.
Ti consigliamo di scrivere test automatici.
Inserisci i dati di esempio raccolti in validator/test/fixtures/<constraint filename>/assets/data.json
e fai riferimento al file di test in questo modo:
# 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
}
Inserisci il test e il test nella cartella validator
della libreria dei criteri.
4. Imposta uno scheletro di modello di vincolo
Dopo aver creato e testato una regola Rego, devi pacchettizzarla come modello di vincolo. Vincolo Framework utilizza le definizioni di risorsa personalizzate Kubernetes come contenitore del criterio Rego.
Il modello di vincolo definisce anche quali parametri sono consentiti come input dai vincoli, utilizzando lo schema OpenAPI V3.
Usa lo stesso nome per lo scheletro utilizzato per le riprese. In particolare:
- Utilizza lo stesso nome del file utilizzato per la ripetizione. Esempio:
gcp_compute_address_address_type_allowlist_constraint_v1.yaml
spec.crd.spec.names.kind
deve contenere il nome del modellometadata.name
deve contenere il nome del modello, ma in minuscolo
Inserisci lo scheletro del modello di vincolo in policies/templates
.
Per l'esempio precedente:
# 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. Incorpora il tuo reso
A questo punto, seguendo l'esempio precedente, il layout della directory ha il seguente aspetto:
| 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
Se hai clonato il repository della libreria dei criteri fornito da Google,
puoi eseguire make build
per aggiornare automaticamente i modelli di vincolo in
policies/templates
con la definizione definita in validator
.
6. Configura un vincolo
I vincoli contengono tre informazioni di cui gcloud beta terraform vet
ha bisogno per applicare correttamente e segnalare le violazioni:
severity
:low
,medium
ohigh
match
: parametri per determinare se un vincolo si applica a una determinata risorsa. Sono supportati i seguenti parametri di corrispondenza:target
: un elenco di percorsi di predecessore da includere utilizzando la corrispondenza in stile Mappamondoexclude
: (facoltativo) un elenco di percorsi di predecessori da escludere utilizzando la corrispondenza in stile Mappamondo.
parameters
: valori per i parametri di input del modello di vincolo.
Assicurati che kind
contenga il nome del modello di vincolo. Ti consigliamo di impostare
metadata.name
su uno slug descrittivo.
Ad esempio, per consentire solo i tipi di indirizzi INTERNAL
utilizzando il modello di vincolo precedente, scrivi:
# 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"
Esempi corrispondenti:
Corrispondenza percorso precedente | Descrizione |
---|---|
organizzazioni/** | Tutte le organizzazioni |
organizzazioni/123/** | Informazioni sull'organizzazione 123 |
organizzazioni/123/cartelle/** | Tutti gli elementi dell'organizzazione 123 che si trovano in una cartella |
organizzazioni/123/cartelle/456 | Tutto nell'organizzazione 123 |
organizzazioni/123/cartelle/456/progetti/789 | Tutto nel progetto 789 della cartella 456 dell'organizzazione 123 |
Se un indirizzo della risorsa corrisponde ai valori in target
e exclude
, viene escluso.
Limitazioni
I dati del piano Terraform offrono la migliore rappresentazione disponibile dello stato effettivo dopo l'applicazione; tuttavia, in molti casi lo stato dopo l'applicazione potrebbe non essere noto perché viene calcolato sul lato server. In questi casi, i dati non sono disponibili neppure negli asset CAI convertiti.
Risorse supportate
Se vuoi che gcloud beta terraform vet
aggiunga assistenza per una risorsa non presente in questo elenco, apri una richiesta di miglioramento e valuta la possibilità di aggiungere codice.
L'elenco delle risorse supportate dipende dalla versione di gcloud beta terraform vet
installata. Di seguito è riportato l'elenco delle risorse supportate:
Risorsa Terraform | Asset inventario Cloud Asset |
---|---|
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 |
tabella_google_bigquery | bigquery.googleapis.com/Table |
google_bigquery_table_iam_binding | bigquery.googleapis.com/Table |
google_bigquery_table_iam_member | bigquery.googleapis.com/Table |
criterio_tabella_iam_bigquery_google_bigquery | 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_cloudfunzioni_funzione | 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 |
indirizzo_google_compute. | compute.googleapis.com/Address |
google_compute_backend_service_iam_binding | compute.googleapis.com/BackendService |
google_compute_backend_service_iam_member | compute.googleapis.com/BackendService |
criterio_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 |
membro_Google_compute_disk_iam_member | compute.googleapis.com/Disk |
norme_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 |
norme_google_compute_image_iam_policy | compute.googleapis.com/Image |
istanza_google_compute | compute.googleapis.com/Instance |
google_compute_instance_iam_binding | compute.googleapis.com/Instance |
google_compute_instance_iam_member | compute.googleapis.com/Instance |
criterio_google_compute_instance_iam_policy | compute.googleapis.com/Instance |
rete_google_compute | compute.googleapis.com/Network |
google_compute_region_backend_service_iam_binding | compute.googleapis.com/RegionBackendService |
google_compute_region_region_backend_service_iam_member | compute.googleapis.com/RegionBackendService |
google_compute_region_region_backend_service_iam_policy | compute.googleapis.com/RegionBackendService |
google_compute_region_disk_iam_binding | compute.googleapis.com/RegionDisk |
area_google_compute_region_disk_iam_member | compute.googleapis.com/RegionDisk |
norme_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 |
criterio_google_compute.ssl | compute.googleapis.com/SslPolicy |
google_compute_subnetwork | compute.googleapis.com/Subnetwork |
google_compute_subnetwork_iam_binding | compute.googleapis.com/Subnetwork |
membro_Google_compute_subnetwork_iam_member | compute.googleapis.com/Subnetwork |
criterio_google_compute_subnetwork_iam_policy | compute.googleapis.com/Subnetwork |
google_container_cluster | container.googleapis.com/Cluster |
pool_nodo_google_container | container.googleapis.com/NodePool |
google_data_catalog_entry_group_iam_binding | datacatalog.googleapis.com/EntryGroup |
google_data_catalog_entry_group_iam_member [Membro_gruppo_di_google_dati] | 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 |
catalogo_dati_google_tag_template_iam_policy | datacatalog.googleapis.com/TagTemplate |
zona_gestita_google_dns | dns.googleapis.com/ManagedZone |
norme_google_dns | 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 |
istanza_file_google_store | 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_care_consent_store_iam_binding | healthcare.googleapis.com/ConsentStore |
google_health_consent_store_iam_member | healthcare.googleapis.com/ConsentStore |
norme_google_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 |
norme_web_google_iam | iap.googleapis.com/Web |
chiave_cripta_google_km | cloudkms.googleapis.com/CryptoKey |
google_kms_crypto_key_iam_binding | cloudkms.googleapis.com/CryptoKey |
membro_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 |
membro_google_km_chi_ring_iam | cloudkms.googleapis.com/KeyRing |
norme_google_km_ring_iam_km | cloudkms.googleapis.com/KeyRing |
criterio_avviso_google_monitoring | 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 |
ruolo_google_organizzazione_iam_custom_role | iam.googleapis.com/Role |
google_organization_iam_member | cloudresourcemanager.googleapis.com/Organization |
criterio_organizzazione_google_iam | cloudresourcemanager.googleapis.com/Organization |
norme_google_organization | cloudresourcemanager.googleapis.com/Organization |
google_privateca_ca_pool_iam_binding | privateca.googleapis.com/CaPool |
google_privateca_ca_pool_iam_member | privateca.googleapis.com/CaPool |
criterio_google_private_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 |
progetto_google | 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 |
criterio_organizzazione_google_progetto | cloudresourcemanager.googleapis.com/Project |
servizio_progetto_google | serviceusage.googleapis.com/Service |
google_pubsub_lite_reservation | pubsublite.googleapis.com/Reservation |
abbonamento_google_pub_lite_subscription | pubsublite.googleapis.com/Subscription |
google_pubsub_lite_topic | pubsublite.googleapis.com/Topic |
schema_google_pub_google | pubsub.googleapis.com/Schema |
abbonamento_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 |
criterio_google_pub_subscription_iam_policy | pubsub.googleapis.com/Subscription |
google_pubsub_argomento | pubsub.googleapis.com/Topic |
google_pubsub_topic_iam_binding | pubsub.googleapis.com/Topic |
google_pubsub_topic_iam_member | pubsub.googleapis.com/Topic |
criterio_google_pub_argomento_iam_policy | pubsub.googleapis.com/Topic |
istanza_google_redis | 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 |
istanza_google_spanner | 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 |
bucket_google_storage | storage.googleapis.com/Bucket |
google_storage_bucket_iam_binding | storage.googleapis.com/Bucket |
google_storage_bucket_iam_member | storage.googleapis.com/Bucket |
criterio_archiviazione_google_bucket | storage.googleapis.com/Bucket |
google_vpc_access_connector | vpcaccess.googleapis.com/Connector |