Crea vincoli CAI

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

Prima di iniziare

Framework del vincolo

gcloud beta terraform vet utilizza i criteri vincolo di vincolo, che sono costituiti dai modelli di vincolo e dai modelli di vincolo. La differenza tra i due elementi è la seguente:

  • Un modello di vincolo è come una dichiarazione di funzione; definisce una regola in Rego e, facoltativamente, accetta parametri di input.
  • Un vincolo è un file che fa riferimento a un modello di vincolo e definisce i parametri di input da trasmettere e le risorse coperte dal criterio.

In questo modo eviterai le ripetizioni. Puoi scrivere un modello di vincolo con un criterio generico, quindi scrivere un numero qualsiasi di vincoli che forniscono parametri di input o regole di corrispondenza delle risorse diverse.

Confronto tra asset CAI e risorse Terraform

Gli asset dell'inventario Cloud Asset sono un formato di esportazione dati standard di Google disponibile per molte risorse Google Cloud. I dati CAI sono generalmente disponibili solo dopo che una risorsa è stata creata o aggiornata. Tuttavia, la conversione delle modifiche delle risorse di Terraform in dati di asset CAI gcloud beta terraform vet consente di scrivere un criterio una volta e di utilizzarlo prima dell'applicazione e 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 i criteri scritti 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.

Per creare un modello di vincolo:

  1. Raccogli dati di esempio.
  2. Scrivi Rego.
  3. Testa il tuo Rego.
  4. Imposta uno scheletro del modello di vincolo.
  5. Incorpora il tuo Rego.
  6. Configura un vincolo.

Raccogli dati di esempio

Per scrivere un modello di vincolo, devi disporre di dati di esempio su cui operare. I vincoli basati sulla CAI operano sui dati degli asset CAI. Raccogli i dati di esempio creando risorse del tipo appropriato ed esportandole come JSON, come descritto nella guida rapida di CAI.

Di seguito è riportato un esempio di esportazione JSON per un indirizzo di computing:

[
  {
    "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"
      }
    }
  },
]

Scrittura Rego

Dopo aver ottenuto i dati di esempio, puoi scrivere la logica del modello di vincolo in Rego. Il tuo Rego deve avere una regola violations. L'asset che stai esaminando è disponibile come input.review. I parametri del vincolo sono disponibili come input.parameters. Ad esempio, per richiedere che gli asset compute.googleapis.com/Address abbiano un 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 ciascun modello di vincolo. Ti consigliamo di seguire queste linee guida di denominazione:

  • Formato generale: GCP{resource}{feature}Constraint{version}. Utilizzare CamelCase. (in altre parole, tutte le parole vanno in maiuscolo).
  • Per i vincoli di risorsa singola, segui i nomi dei gruppi gcloud per la denominazione delle risorse. Ad esempio, utilizza "compute" invece di "gce", "sql" invece di "cloud-sql" e "container-cluster" invece di "gke".
  • Se un modello si applica a più tipi di risorse, ometti la parte della risorsa e includi soltanto la funzionalità (ad esempio: "GCPAddressTypeAllowlistConstraintV1").
  • Il numero di versione non segue il formato ememperante; è solo un numero singolo. Ciò rende efficace ogni versione di un modello come modello univoco.

Ti consigliamo di utilizzare un nome per il file Rego che corrisponda al nome del modello di vincolo, ma di utilizzare snake_case. In altre parole, converti il nome in minuscolo per separare le parole con _. Nell'esempio precedente, il nome file consigliato è gcp_compute_address_address_type_allowlist_constraint_v1.rego

Testa il tuo Rego

Puoi testare Rego manualmente con Rego Playground. Assicurati di utilizzare dati non sensibili.

Ti consigliamo di scrivere test automatizzati. 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 tuo Rego e il test nella cartella validator della raccolta dei criteri.

Imposta uno scheletro del modello di vincolo

Dopo aver creato e testato una regola Rego, devi pacchettizzarla come modello di vincolo. Il vincolo di vincolo utilizza le definizioni di risorse personalizzate di Kubernetes come container per il 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 che hai usato per il Rego. In particolare:

  • Utilizza lo stesso nome del file per Rego. Esempio: gcp_compute_address_address_type_allowlist_constraint_v1.yaml
  • spec.crd.spec.names.kind deve contenere il nome del modello
  • metadata.name deve contenere il nome del modello, ma minuscolo

Inserisci lo scheletro del modello di vincolo in policies/templates.

Nell'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

Incorpora il tuo Rego

A questo punto, seguendo l'esempio precedente, il layout della directory avrà 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 delle raccolte di criteri fornite da Google, puoi eseguire make build per aggiornare automaticamente i modelli di vincoli in policies/templates con Rego definito in validator.

Configurare un vincolo

I vincoli contengono tre informazioni che gcloud beta terraform vet deve applicare in modo corretto e segnalare le violazioni:

  • severity: low, medium o high
  • match: parametri per determinare se un vincolo si applica a una particolare risorsa. Sono supportati i seguenti parametri di corrispondenza:
    • ancestries: un elenco di percorsi di origine da includere nella corrispondenza in stile glob
    • excludedAncestries: (facoltativo) un elenco di percorsi di discendenza da escludere utilizzando la corrispondenza in stile glob.
  • 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 tipi di indirizzo 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:
    ancestries:
    - "**"
  parameters:
    allowed_address_types:
    - "INTERNAL"

Esempi corrispondenti:

Corrispondenza del percorso di discendenza Descrizione
organizzazioni/** Tutte le organizzazioni
organizzazioni/123/** Tutto nell'organizzazione 123
organizzazioni/123/cartelle/** Tutto ciò che si trova in un'organizzazione 123 è all'interno di una cartella
organizzazioni/123/cartelle/456 Tutto nella cartella 456 dell'organizzazione 123
organizzazioni/123/cartelle/456/progetti/789 Tutto nel progetto 789 nella cartella 456 nell'organizzazione 123

Se un indirizzo di risorsa corrisponde ai valori in ancestries e excludedAncestries, viene escluso.

Limitazioni

I dati del piano Terraform offrono la migliore rappresentazione disponibile dopo l'applicazione dello stato effettivo. Tuttavia, in molti casi, lo stato successivo all'applicazione potrebbe non essere noto perché viene calcolato sul lato server. In questi casi, i dati non sono disponibili nemmeno negli asset CAI convertiti.

La creazione di percorsi di origine CAI è parte del processo di convalida dei criteri. che utilizza il progetto predefinito fornito per aggirare gli ID progetto sconosciuti. Nel caso in cui non venga fornito un progetto predefinito, il percorso originale è organizations/unknown.

Per impedire la discendenza sconosciuta, aggiungi il seguente vincolo:

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: {}

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 fornire 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
norme_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
norme_google_bigquery_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_membro bigquery.googleapis.com/Table
norme_google_bigquery_iam_policy bigquery.googleapis.com/Table
istanza_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
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
google_compute_backend_service_iam_policy compute.googleapis.com/BackendService
disco_google_compute compute.googleapis.com/Disk
google_compute_disk_iam_binding compute.googleapis.com/Disk
membro_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
regola_inoltro_google_compute 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
membro_immagine_google_compute_iam 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
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_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
pool_di_nodi_contenitore_google 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
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_cartella_iam_binding cloudresourcemanager.googleapis.com/Folder
google_folder_iam_member cloudresourcemanager.googleapis.com/Folder
norme_google_cartella cloudresourcemanager.googleapis.com/Folder
criterio_organizzazione_google_cartella cloudresourcemanager.googleapis.com/Folder
google_san_consent_store_iam_binding healthcare.googleapis.com/ConsentStore
google_health_consent_store_iam_member healthcare.googleapis.com/ConsentStore
norme_google_sanit_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
norme_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_google_iap_web_iam iap.googleapis.com/Web
google_kms_cripto_chiave cloudkms.googleapis.com/CryptoKey
google_kms_cripto_chiave_iam_binding cloudkms.googleapis.com/CryptoKey
google_kms_cripto_chiave_iam_membro cloudkms.googleapis.com/CryptoKey
google_kms_cripto_chiave_iam_policy cloudkms.googleapis.com/CryptoKey
google_kms_chiave_anello cloudkms.googleapis.com/KeyRing
google_kms_chiave_ring_iam_binding cloudkms.googleapis.com/KeyRing
google_kms_chiave_anello_iam_membro cloudkms.googleapis.com/KeyRing
google_kms_chiave_ring_iam_policy cloudkms.googleapis.com/KeyRing
criterio_avviso_google_monitoring monitoring.googleapis.com/AlertPolicy
google_monitoring_channel_notification monitoring.googleapis.com/NotificationChannel
google_notebooks_instance_iam_binding notebooks.googleapis.com/Instance
google_notebooks_instance_iam_member notebooks.googleapis.com/Instance
norme_google_notebooks_istanza_iam_policy notebooks.googleapis.com/Instance
google_notebooks_runtime_iam_binding notebooks.googleapis.com/Runtime
google_notebooks_runtime_iam_member notebooks.googleapis.com/Runtime
norme_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 [id_organizzazione_google] cloudresourcemanager.googleapis.com/Organization
norme_google_organization_iam_policy cloudresourcemanager.googleapis.com/Organization
norme_google_organization cloudresourcemanager.googleapis.com/Organization
google_privateca_ca_pool_iam_binding privateca.googleapis.com/CaPool
google_private_ca_pool_iam_member privateca.googleapis.com/CaPool
norme_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/ProjectFatturazioneInfo, cloudresourcemanager.googleapis.com/Progetto
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
norme_google_progetto cloudresourcemanager.googleapis.com/Project
google_project_organization_policy cloudresourcemanager.googleapis.com/Project
servizio_progetto_google 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
schema_google_pub 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
norme_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
google_pubsub_topic_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
norme_google_spanner_database_iam 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
database_google_sql 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
google_storage_bucket_iam_policy storage.googleapis.com/Bucket
google_vpc_access_connector vpcaccess.googleapis.com/Connector