Home

Awesome

InSpec GCP (Google Cloud Platform) Resource Pack

For more information on project states and SLAs, see this documentation.

This InSpec resource pack uses the native Google Cloud Platform (GCP) support in InSpec and provides the required resources to write tests for GCP.

This implementation was inspired on the ideas by Martez Reed.

Prerequisites

Install and configure the Google cloud SDK*

Download the SDK and run the installation:

./google-cloud-sdk/install.sh

Create credentials file via:

gcloud auth application-default login

If successful, this should be similar to:

$ cat ~/.config/gcloud/application_default_credentials.json

{
  "client_id": "764086051850-6qr4p6gpi6hn50asdr.apps.googleusercontent.com",
  "client_secret": "d-fasdfasdfasdfaweroi23jknrmfs;f8sh",
  "refresh_token": "1/asdfjlklwna;ldkna'dfmk-lCkju3-yQmjr20xVZonrfkE48L",
  "type": "authorized_user"
}

While InSpec can use user accounts for authentication, Google Cloud documentation recommends using service accounts.

Create Service Accounts

  1. Go to Console in the Google Cloud.
  2. Click on Service Accounts.
  3. Click on Create Service Accounts and give the required details.
  4. Click on Done.
  5. Now Click on Keys Tab.
  6. Click on Add Key.
  7. Click on Create New Key.
  8. Select the Key type as JSON.
  9. Click on Create.
  10. The Service Account Key will be downloaded. For example: myproject-1-feb7993e8660.jsonmyproject-1-feb7993e8660.json
  11. Move the key to the ~/.config/gcloud folder. If the file gets downloaded in the Downloads folder, use the below command.
mv ~/Downloads/myproject-1-feb7993e8660.json ~/.config/gcloud/
  1. The json credential file for a service account looks like this:
$ cat ~/.config/gcloud/myproject-1-feb7993e8660.json
{
  "type": "service_account",
  "project_id": "myproject-1",
  "private_key_id": "eb45b2fc0c33ea9b6fa212aaa08b1ed814bf8660",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADAN3662...fke9n6LAf268E/4EWhIzg==\n-----END PRIVATE KEY-----\n",
  "client_email": "auto-testing@myproject-1.iam.gserviceaccount.com",
  "client_id": "112144174133171863632",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/auto-testing%40myproject-1.iam.gserviceaccount.com"
}
  1. Now Setup the environmental variable for the 'GOOGLE_APPLICATION_CREDENTIALS'. And InSpec can be instructed to use it by setting this ENV variable prior to running inspec exec:
$ export GOOGLE_APPLICATION_CREDENTIALS='~/.config/gcloud/myproject-1-feb7993e8660.json'

NOTE:

If still error comes, please check your IAM roles and permissions.

Enable the appropriate APIs that you want to use:

Use the resources

Since this is an InSpec resource pack, it only defines InSpec resources. It includes example tests only. To easily use the GCP resources in your tests do the following:

Create a new profile for GCP

$ inspec init profile --platform gcp my-gcp-profile

Create new profile at /Users/spaterson/my-gcp-profile
 * Create directory libraries
 * Create file README.md
 * Create directory controls
 * Create file controls/example.rb
 * Create file inspec.yml
 * Create file attributes.yml
 * Create file libraries/.gitkeep

Update inputs.yml to point to your project

gcp_project_id: 'my-gcp-project'

The generated inspec.yml file automatically points to the InSpec GCP resource pack:

name: my-gcp-profile
title: My GCP InSpec Profile
version: 0.1.0
inspec_version: '>= 4'
inputs:
  - name: gcp_project_id
    required: true
    description: 'The GCP project identifier.'
depends:
  - name: inspec-gcp
    url: https://github.com/inspec/inspec-gcp/archive/x.tar.gz
supports:
  - platform: gcp

(For available inspec-gcp versions, see this list of inspec-gcp versions.)

Run the tests

$ cd my-gcp-profile/
$ inspec exec . -t gcp:// --input-file inputs.yml

Profile: GCP InSpec Profile (my-profile)
Version: 0.1.0
Target:  gcp://local-service-account@my-gcp-project.iam.gserviceaccount.com
Target ID: 8123456-12a3-1234-123a-a12s5c5abcx1

  ✔  gcp-single-region-1.0: Ensure single region has the correct properties.
     ✔  Region europe-west2 zone_names should include "europe-west2-a"
  ✔  gcp-regions-loop-1.0: Ensure regions have the correct properties in bulk.
     ✔  Region asia-east1 is expected to be up
     ✔  Region asia-east2 is expected to be up
     ✔  Region asia-northeast1 is expected to be up
     ✔  Region asia-northeast2 is expected to be up
     ✔  Region asia-northeast3 is expected to be up
     ✔  Region asia-south1 is expected to be up
     ✔  Region asia-south2 is expected to be up
     ✔  Region asia-southeast1 is expected to be up
     ✔  Region asia-southeast2 is expected to be up
     ✔  Region australia-southeast1 is expected to be up
     ✔  Region australia-southeast2 is expected to be up
     ✔  Region europe-central2 is expected to be up
     ✔  Region europe-north1 is expected to be up
     ✔  Region europe-southwest1 is expected to be up
     ✔  Region europe-west1 is expected to be up
     ✔  Region europe-west2 is expected to be up
     ✔  Region europe-west3 is expected to be up
     ✔  Region europe-west4 is expected to be up
     ✔  Region europe-west6 is expected to be up
     ✔  Region europe-west8 is expected to be up
     ✔  Region europe-west9 is expected to be up
     ✔  Region me-west1 is expected to be up
     ✔  Region northamerica-northeast1 is expected to be up
     ✔  Region northamerica-northeast2 is expected to be up
     ✔  Region southamerica-east1 is expected to be up
     ✔  Region southamerica-west1 is expected to be up
     ✔  Region us-central1 is expected to be up
     ✔  Region us-east1 is expected to be up
     ✔  Region us-east4 is expected to be up
     ✔  Region us-east5 is expected to be up
     ✔  Region us-south1 is expected to be up
     ✔  Region us-west1 is expected to be up
     ✔  Region us-west2 is expected to be up
     ✔  Region us-west3 is expected to be up
     ✔  Region us-west4 is expected to be up


Profile:   Google Cloud Platform Resource Pack (inspec-gcp)
Version:   1.10.37
Target:    gcp://local-service-account@my-gcp-project.iam.gserviceaccount.com
Target ID: 8123456-12a3-1234-123a-a12s5c5abcx1

     No tests executed.

Profile Summary: 2 successful controls, 0 control failures, 0 controls skipped
Test Summary:  36 successful, 0 failures, 0 skipped

Resource documentation

The following resources are available in the InSpec GCP Profile

InSpec GCP Supported Resourceshttps://www.inspec.io/docs/reference/resources/#gcp-resources
Singular ResourcePlural Resource
google_access_context_manager_access_levelgoogle_access_context_manager_access_levels
google_access_context_manager_access_policygoogle_access_context_manager_access_policies
google_access_context_manager_service_perimetergoogle_access_context_manager_service_perimeters
google_apigee_endpoint_attachmentgoogle_apigee_endpoint_attachments
google_apigee_organization_envgroupgoogle_apigee_organization_envgroups
google_apigee_organization_instance_attachmentgoogle_apigee_organization_instance_attachments
google_apigee_organization_envgroup_attachmentgoogle_apigee_organization_envgroup_attachments
google_appengine_standard_app_versiongoogle_appengine_standard_app_versions
google_bigquery_datasetgoogle_bigquery_datasets
google_bigquery_tablegoogle_bigquery_tables
google_bigtableadmin_clustergoogle_bigtableadmin_clusters
google_bigtableadmin_instance_app_profilegoogle_bigtableadmin_instance_app_profiles
google_billing_project_billing_infoNo Plural Resource
google_cloud_scheduler_jobgoogle_cloud_scheduler_jobs
google_cloudbuild_triggergoogle_cloudbuild_triggers
google_cloudfunctions_cloud_functiongoogle_cloudfunctions_cloud_functions
google_composer_project_location_environmentgoogle_composer_project_location_environments
google_compute_addressgoogle_compute_addresses
google_compute_autoscalergoogle_compute_autoscalers
google_compute_backend_bucketNo Plural Resource
google_compute_backend_servicegoogle_compute_backend_services
google_compute_diskgoogle_compute_disks
google_compute_disk_typegoogle_compute_disk_types
google_data_loss_prevention_inspect_templategoogle_data_loss_prevention_inspect_templates
google_compute_external_vpn_gatewaygoogle_compute_external_vpn_gateways
google_compute_firewallgoogle_compute_firewalls
google_compute_forwarding_rulegoogle_compute_forwarding_rules
google_compute_global_addressgoogle_compute_global_addresses
google_compute_global_forwarding_rulegoogle_compute_global_forwarding_rules
google_compute_global_network_endpoint_groupgoogle_compute_global_network_endpoint_groups
google_compute_global_operationgoogle_compute_global_operations
google_compute_health_checkgoogle_compute_health_checks
google_compute_health_check_servicegoogle_compute_health_check_services
google_compute_http_health_checkgoogle_compute_http_health_checks
google_compute_https_health_checkgoogle_compute_https_health_checks
google_compute_image_family_viewNo Plural Resource
google_compute_imageNo Plural Resource
google_compute_instancegoogle_compute_instances
google_compute_instancegoogle_compute_instances
google_compute_instance_groupgoogle_compute_instance_groups
google_compute_instance_group_managergoogle_compute_instance_group_managers
google_compute_instance_templategoogle_compute_instance_templates
google_compute_interconnectgoogle_compute_interconnects
google_compute_interconnect_locationgoogle_compute_interconnect_locations
google_compute_license_codeNo Plural Resource
google_compute_licensegoogle_compute_licenses
google_compute_machine_imagegoogle_compute_machine_images
google_compute_machine_typegoogle_compute_machine_types
google_compute_network_attachmentgoogle_compute_network_attachments
google_compute_network_edge_security_serviceNo Plural Resource
google_compute_networkgoogle_compute_networks
google_compute_network_endpoint_groupgoogle_compute_network_endpoint_groups
google_compute_network_firewall_policygoogle_compute_network_firewall_policies
google_compute_node_groupgoogle_compute_node_groups
google_compute_node_templategoogle_compute_node_templates
google_compute_node_typegoogle_compute_node_types
google_compute_packet_mirroringgoogle_compute_packet_mirrorings
google_compute_project_infoNo Plural Resource
google_compute_public_delegated_prefixgoogle_compute_public_delegated_prefixes
google_compute_regiongoogle_compute_regions
google_compute_region_backend_servicegoogle_compute_region_backend_services
google_compute_region_commitmentgoogle_compute_region_commitments
google_compute_region_disk_typegoogle_compute_region_disk_types
google_compute_region_health_checkgoogle_compute_region_health_checks
google_compute_region_instance_groupgoogle_compute_region_instance_groups
google_compute_region_instance_group_managergoogle_compute_region_instance_group_managers
google_compute_region_operationgoogle_compute_region_operations
google_compute_region_operationgoogle_compute_region_operations
google_compute_regional_diskgoogle_compute_regional_disks
google_compute_reservationgoogle_compute_reservations
google_compute_resource_policygoogle_compute_resource_policies
google_compute_routegoogle_compute_routes
google_compute_routergoogle_compute_routers
google_compute_router_natgoogle_compute_router_nats
google_compute_security_policygoogle_compute_security_policies
google_compute_snapshotgoogle_compute_snapshots
google_compute_ssl_certificategoogle_compute_ssl_certificates
google_compute_ssl_policygoogle_compute_ssl_policies
google_compute_service_attachmentgoogle_compute_service_attachments
google_compute_subnetworkgoogle_compute_subnetworks
google_compute_target_grpc_proxygoogle_compute_target_grpc_proxies
google_compute_subnetwork_iam_bindingNo Plural Resource
google_compute_subnetwork_iam_policyNo Plural Resource
google_compute_target_http_proxygoogle_compute_target_http_proxies
google_compute_target_https_proxygoogle_compute_target_https_proxies
google_compute_target_https_proxygoogle_compute_target_https_proxies
google_compute_target_poolgoogle_compute_target_pools
google_compute_target_ssl_proxygoogle_compute_target_ssl_proxies
google_compute_target_tcp_proxygoogle_compute_target_tcp_proxies
google_compute_url_mapgoogle_compute_url_maps
google_compute_vpn_tunnelgoogle_compute_vpn_tunnels
No Singular Resourcegoogle_compute_xpn_resources
google_compute_zonegoogle_compute_zones
google_compute_zone_operationgoogle_compute_zone_operations
google_compute_region_target_http_proxygoogle_compute_region_target_http_proxies
google_container_clustergoogle_container_clusters
google_container_node_poolgoogle_container_node_pools
google_container_server_configNo Plural Resource
google_data_fusion_instancegoogle_data_fusion_instances
google_dataflow_project_location_jobgoogle_dataflow_project_location_jobs
google_dataproc_autoscaling_policygoogle_dataproc_autoscaling_policies
google_dataproc_batchgoogle_dataproc_batches
google_dataproc_clustergoogle_dataproc_clusters
google_dataproc_jobgoogle_dataproc_jobs
google_dataproc_metastore_federationgoogle_dataproc_metastore_federations
google_dataproc_metastore_service_backupgoogle_dataproc_metastore_service_backups
google_dataproc_metastore_servicegoogle_dataproc_metastore_services
google_dataproc_sessiongoogle_dataproc_sessions
google_dataproc_workflow_templategoogle_dataproc_workflow_templates
google_dns_managed_zonegoogle_dns_managed_zones
google_dns_resource_record_setgoogle_dns_resource_record_sets
google_dlp_dtgoogle_dlp_dts
google_dlp_inspect_templategoogle_dlp_inspect_templates
google_dlp_job_triggergoogle_dlp_job_triggers
google_dlp_jobgoogle_dlp_jobs
google_dlp_stored_info_typegoogle_dlp_stored_info_types
google_filestore_instancegoogle_filestore_instances
google_iam_organization_custom_rolegoogle_iam_organization_custom_roles
google_kms_crypto_keygoogle_kms_crypto_keys
google_kms_crypto_key_iam_bindinggoogle_kms_crypto_key_iam_bindings
google_kms_crypto_key_iam_policyNo Plural Resource
google_kms_crypto_key_versiongoogle_kms_crypto_key_versions
google_kms_ekm_connectiongoogle_kms_ekm_connections
google_kms_key_ringgoogle_kms_key_rings
google_kms_key_ring_iam_bindinggoogle_kms_key_ring_iam_bindings
google_kms_key_ring_iam_policyNo Plural Resource
google_kms_key_ring_import_jobgoogle_kms_key_ring_import_jobs
google_kms_locationgoogle_kms_locations
google_logging_folder_exclusiongoogle_logging_folder_exclusions
google_logging_folder_log_sinkgoogle_logging_folder_log_sinks
google_logging_organization_log_sinkgoogle_logging_organization_log_sinks
google_logging_project_exclusiongoogle_logging_project_exclusions
google_logging_project_sinkgoogle_logging_project_sinks
google_memcache_instancegoogle_memcache_instances
google_ml_engine_modelgoogle_ml_engine_models
google_monitoring_groupgoogle_monitoring_groups
google_organizationgoogle_organizations
No Singular Resourcegoogle_orgpolicy_folder_constraints
No Singular Resourcegoogle_orgpolicy_organization_constraints
No Singular Resourcegoogle_orgpolicy_project_constraints
google_orgpolicy_folder_policygoogle_orgpolicy_folder_policies
google_orgpolicy_organization_policygoogle_orgpolicy_organization_policies
google_orgpolicy_project_policygoogle_orgpolicy_project_policies
google_organization_iam_bindingNo Plural Resource
google_organization_iam_policyNo Plural Resource
google_organization_policyNo Plural Resource
google_projectgoogle_projects
google_project_alert_policygoogle_project_alert_policies
google_project_alert_policy_conditionNo Plural Resource
google_project_iam_bindinggoogle_project_iam_bindings
google_project_iam_custom_rolegoogle_project_iam_custom_roles
google_project_iam_policyNo Plural Resource
google_project_logging_audit_configNo Plural Resource
google_project_metricgoogle_project_metrics
google_project_servicegoogle_project_services
google_pubsub_subscriptiongoogle_pubsub_subscriptions
google_pubsub_subscription_iam_bindingNo Plural Resource
google_pubsub_subscription_iam_policyNo Plural Resource
google_pubsub_topicgoogle_pubsub_topics
google_pubsub_topic_iam_bindingNo Plural Resource
google_pubsub_topic_iam_policyNo Plural Resource
google_redis_instancegoogle_redis_instances
google_compute_region_security_policygoogle_compute_region_security_policies
google_resourcemanager_foldergoogle_resourcemanager_folders
google_resourcemanager_folder_iam_bindingNo Plural Resource
google_resourcemanager_folder_iam_policyNo Plural Resource
google_run_jobgoogle_run_jobs
google_run_servicegoogle_run_services
google_runtime_config_configgoogle_runtime_config_configs
google_runtime_config_config_iam_bindingNo Plural Resource
google_runtime_config_config_iam_policyNo Plural Resource
google_runtime_config_variablegoogle_runtime_config_variables
google_secret_manager_secretgoogle_secret_manager_secrets
google_service_accountgoogle_service_accounts
No Singular Resourcegoogle_service_networking_service_connections
google_service_account_keygoogle_service_account_keys
google_sourcerepo_repositorygoogle_sourcerepo_repositories
google_spanner_databasegoogle_spanner_databases
google_spanner_instancegoogle_spanner_instances
google_spanner_instance_iam_bindingNo Plural Resource
google_spanner_instance_iam_policyNo Plural Resource
google_sql_connectNo Plural Resource
google_sql_databasegoogle_sql_databases
google_sql_database_instancegoogle_sql_database_instances
No Singular Resourcegoogle_sql_flags
google_sql_operationgoogle_sql_operations
google_sql_ssl_certgoogle_sql_ssl_certs
google_sql_usergoogle_sql_users
google_storage_bucketgoogle_storage_buckets
google_storage_bucket_aclNo Plural Resource
google_storage_bucket_iam_bindinggoogle_storage_bucket_iam_bindings
google_storage_bucket_iam_policyNo Plural Resource
google_storage_bucket_objectgoogle_storage_bucket_objects
google_storage_default_object_aclNo Plural Resource
google_storage_object_aclNo Plural Resource
google_usergoogle_users
google_vertex_ai_batch_prediction_jobgoogle_vertex_ai_batch_prediction_jobs
google_vertex_ai_custom_jobgoogle_vertex_ai_custom_jobs
google_vertex_ai_datasetgoogle_vertex_ai_datasets
google_vertex_ai_datasets_annotation_specNo Plural Resource
No Singular Resourcegoogle_vertex_ai_datasets_data_items
No Singular Resourcegoogle_vertex_ai_datasets_saved_queries
google_vertex_ai_endpointgoogle_vertex_ai_endpoints
google_vertex_ai_featurestoregoogle_vertex_ai_featurestores
google_vertex_ai_featurestores_entity_typegoogle_vertex_ai_featurestores_entity_types
google_vertex_ai_featurestore_entity_type_featuregoogle_vertex_ai_featurestore_entity_type_features
google_vertex_ai_hyperparameter_tuning_jobgoogle_vertex_ai_hyperparameter_tuning_jobs
google_vertex_ai_index_endpointgoogle_vertex_ai_index_endpoints
google_vertex_ai_indexgoogle_vertex_ai_indices
google_vertex_ai_metadata_storegoogle_vertex_ai_metadata_stores
google_vertex_ai_metadata_stores_artifactgoogle_vertex_ai_metadata_stores_artifacts
google_vertex_ai_metadata_stores_contextgoogle_vertex_ai_metadata_stores_contexts
google_vertex_ai_metadata_stores_executiongoogle_vertex_ai_metadata_stores_executions
google_vertex_ai_metadata_stores_metadata_schemagoogle_vertex_ai_metadata_stores_metadata_schemas
google_vertex_ai_model_deployment_monitoring_jobgoogle_vertex_ai_model_deployment_monitoring_jobs
google_vertex_ai_modelgoogle_vertex_ai_models
google_vertex_ai_models_evaluationgoogle_vertex_ai_models_evaluations
google_vertex_ai_models_evaluation_slicegoogle_vertex_ai_models_evaluation_slices
google_vertex_ai_nas_jobgoogle_vertex_ai_nas_jobs
google_vertex_ai_nas_jobs_nas_trial_detailgoogle_vertex_ai_nas_jobs_nas_trial_details
google_vertex_ai_pipeline_jobgoogle_vertex_ai_pipeline_jobs
google_vertex_ai_schedulegoogle_vertex_ai_schedules
google_vertex_ai_studygoogle_vertex_ai_studies
google_vertex_ai_studies_trialgoogle_vertex_ai_studies_trials
google_vertex_ai_tensorboardgoogle_vertex_ai_tensorboards
google_vertex_ai_tensorboards_experimentgoogle_vertex_ai_tensorboards_experiments
google_vertex_ai_tensorboard_experiment_rungoogle_vertex_ai_tensorboard_experiment_runs
google_vertex_ai_tensorboard_experiment_run_time_series_resourcegoogle_vertex_ai_tensorboard_experiment_run_time_series_resources
google_vertex_ai_training_pipelinegoogle_vertex_ai_training_pipelines

Examples

Check SSH is Disabled for INGRESS across all GCP Projects

We use several plural resources for this example that loops across all projects and firewall rules. Making use of a plural resource property, we filter firewall rules for direction 'INGRESS' :

title 'Loop over all GCP projects and look at firewalls in INGRESS direction'

control 'gcp-projects-firewalls-loop-1.0' do

  impact 1.0
  title 'Ensure INGRESS firewalls in all projects have the correct properties using google_compute_firewall for detail.'

  google_projects.project_names.each do |project_name|
    google_compute_firewalls(project: project_name).where(firewall_direction: 'INGRESS').firewall_names.each do |firewall_name|
      describe google_compute_firewall(project: project_name, name: firewall_name) do
        its('allowed_ssh?')  { should be false }
      end
    end
  end
end

This example assumes there are sufficient privileges to list all GCP projects.

Check that a particular label exists on all VMs across all projects and zones

This check ensures that VMs have label must_be_there for each project:

title 'Loop over all GCP projects and ensure all VMs have a particular label'

control 'gcp-projects-zones-vm-label-loop-1.0' do

  impact 1.0
  title 'Ensure all VMs have must_be_there label key set'

  google_projects.project_names.each do |project_name|
    google_compute_zones(project: project_name).zone_names.each do |zone_name|
      google_compute_instances(project: project_name, zone: zone_name).instance_names.each do |instance_name|
        describe google_compute_instance(project: project_name, zone: zone_name, name: instance_name) do
          its('labels_keys') { should include 'must_be_there' }
        end
      end
    end
  end
end

This example verifies there are sufficient privileges to list all regions.

next unless google_compute_regions(project: gcp_project_id).resource_failed?
google_compute_regions(project: gcp_project_id).region_names.each do |region_name|
  describe google_compute_region(project: gcp_project_id,  region: region_name) do
    it { should be_up }
  end
end

if google_compute_regions(project: gcp_project_id).resource_failed?
  puts google_compute_regions(project: gcp_project_id).resource_exception_message
  puts google_compute_regions(project: gcp_project_id,name: region_name).pretty_inspect
end

This example assumes there are sufficient privileges to list all GCP projects.

Test inspec-gcp resources

  1. Create a new GCP project
  2. Ensure this is currently set following: https://cloud.google.com/shell/docs/examples
$ gcloud config set project <project-name>
$ gcloud config list project
  1. Enable billing for your new project
  2. Enable various services necessary to run the tests:
$ gcloud services enable compute.googleapis.com \
    sourcerepo.googleapis.com \
    dns.googleapis.com \
    container.googleapis.com \
    cloudkms.googleapis.com \
    cloudbuild.googleapis.com
  1. Environment variables can be used to specify project details e.g.
export GCP_PROJECT_NAME=<project-name>
export GCP_PROJECT_NUMBER=<project-number>
export GCP_PROJECT_ID=<project-id>

Some resources require elevated privileges to create in GCP. These are disabled by default but can be activated via:

export GCP_ENABLE_PRIVILEGED_RESOURCES=1

This takes effect during the "plan" task as described in the next section. Affected terraform resources are included/excluded and associated inspec tests enabled/disabled accordingly.

The resource pack defaults to region europe-west2. If a different region is desired e.g. us-central1, the following variables should be set:

export GCP_LOCATION="us-central1"
export GCP_ZONE="us-central1-a"
export GCP_LB_REGION="us-central1"
export GCP_LB_ZONE="us-central1-a"
export GCP_LB_ZONE_MIG2="us-central1-b"
export GCP_LB_ZONE_MIG3="us-central1-c"
export GCP_KUBE_CLUSTER_ZONE="us-central1-a"
export GCP_KUBE_CLUSTER_ZONE_EXTRA1="us-central1-b"
export GCP_KUBE_CLUSTER_ZONE_EXTRA2="us-central1-c"
export GCP_CLOUD_FUNCTION_REGION="us-central1"

Other regions can be targeted by updating the above. For example, see https://cloud.google.com/compute/docs/regions-zones/ for suitable values.

  1. Ensure the In-use IP addresses quota is set to 20 or above for chosen region

  2. Run the integration tests via:

bundle install && bundle exec rake test:integration

Alternatively, finer grained rake tasks are also available. Executing these in order is the same as the above command:

bundle exec rake test:init_workspace
bundle exec rake test:plan_integration_tests
bundle exec rake test:setup_integration_tests
bundle exec rake test:run_integration_tests
bundle exec rake test:cleanup_integration_tests

Further Reading

FAQ

Failure running "inspec exec" on my GCP profile

If an error such as the below occurs when running "inspec exec" on a newly created GCP profile:

libraries/google_compute_instance.rb:26:in `block in initialize': undefined method `gcp_compute_client' for #<Train::Transports::Local::Connection:0x00007fcasdf1a532d0> (NoMethodError)

Check that the GCP transport is being specified as below:

$ inspec exec . -t gcp://

This tells the underlying transport layer (train) to use GCP.

access not configured error

InSpec relies on the GCP API's to verify the settings. Therefore, it requires access to the API. If you try to access an API via an InSpec resource that is not enabled in your account, then you see an error like:

googleapi: Error 403: Access Not Configured. Compute Engine API has not been used in project 41111111111 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/compute.googleapis.com/overview then retry.

Quota increase

The terraform templates generate sufficient resources to require an increase to default in_use IP addresses. Normally new projects have 10, increasing this to 20 or higher should be sufficient.

To find this setting, log in to the GCP web interface and go to IAM and admin->Quotas and look for "Compute Engine API In-use IP addresses". From here you can "Edit quotas" to request more.

Changed Quota:
+----------------------+------------------+
| Region: europe-west2 | IN_USE_ADDRESSES |
+----------------------+------------------+
|       Changes        |     8 -> 64      |
+----------------------+------------------+

Errors on terraform destroy

Sometimes there can be occasional errors when performing the cleanup rake task. This happens when resources are already deleted and can be ignored.

Upgrading to version 1.0

A guide on upgrading to version 1.0 can be found here

Support

The InSpec GCP resources are community supported. For bugs and features, please open a github issue and label it appropriately.

Kudos

This implementation is inspired by inspec-azure and inspec-gcp