diff --git a/docs/resources/google_compute_zones.md b/docs/resources/google_compute_zones.md
index 688135e03..63253c532 100644
--- a/docs/resources/google_compute_zones.md
+++ b/docs/resources/google_compute_zones.md
@@ -59,7 +59,7 @@ The following examples show how to use this InSpec audit resource.
### Test that a subset of all zones matching "us*" are "UP"
- describe google_compute_zones(project: gcp_project_id).where(zone_name: /^us/).zone_names.each do |zone_name|
+ google_compute_zones(project: 'chef-inspec-gcp').where(zone_name: /^us/).zone_names.each do |zone_name|
describe google_compute_zone(project: 'chef-inspec-gcp', zone: zone_name) do
it { should exist }
its('kind') { should eq "compute#zone" }
diff --git a/docs/resources/google_sql_database_instance.md b/docs/resources/google_sql_database_instance.md
new file mode 100644
index 000000000..1463bca24
--- /dev/null
+++ b/docs/resources/google_sql_database_instance.md
@@ -0,0 +1,69 @@
+---
+title: About the google_sql_database_instance Resource
+platform: gcp
+---
+
+# google\_sql\_database\_instance
+
+Use the `google_sql_database_instance` InSpec audit resource to test properties of a single GCP Cloud SQL Database instance.
+
+
+
+## Syntax
+
+A `google_sql_database_instance` resource block declares the tests for a single CP Cloud SQL Database instance by project and name.
+
+ describe google_sql_database_instance(project: 'chef-inspec-gcp', database: 'my-database') do
+ it { should exist }
+ end
+
+
+
+## Examples
+
+The following examples show how to use this InSpec audit resource.
+
+
+### Test that a GCP Cloud SQL Database instance is in the expected state
+
+ describe google_sql_database_instance(project: 'chef-inspec-gcp', database: 'my-database') do
+ its('state') { should eq 'RUNNABLE' }
+ end
+
+### Test that a GCP Cloud SQL Database instance generation type
+
+ describe google_sql_database_instance(project: 'chef-inspec-gcp', database: 'my-database') do
+ its('backend_type') { should eq "SECOND_GEN" }
+ end
+
+### Test that a GCP Cloud SQL Database instance connection name is as expected
+
+ describe google_sql_database_instance(project: 'spaterson-project', database: 'gcp-inspec-db-instance') do
+ its('connection_name') { should eq "spaterson-project:europe-west2:gcp-inspec-db-instance" }
+ end
+
+### Confirm that a GCP Cloud SQL Database instance has the correct version
+
+ describe google_sql_database_instance(project: 'spaterson-project', database: 'gcp-inspec-db-instance') do
+ its('database_version') { should eq "MYSQL_5_7" }
+ end
+
+### Confirm that a GCP Cloud SQL Database instance is running in the desired region and zone
+
+ describe google_sql_database_instance(project: 'spaterson-project', database: 'gcp-inspec-db-instance') do
+ its('gce_zone') { should eq "europe-west2-a" }
+ its('region') { should eq "europe-west2" }
+ end
+
+
+
+## Properties
+
+* `backend_type`, `connection_name`, `database_version`, `etag`, `gce_zone`, `instance_type`, `ip_addresses`, `kind`, `name`, `project`, `region`, `server_ca_cert`, `service_account_email_address`, `settings`, `state`
+
+
+
+
+## GCP Permissions
+
+Ensure the [Cloud SQL API](https://console.cloud.google.com/projectselector/apis/api/sqladmin.googleapis.com/overview) is enabled for the project.
\ No newline at end of file
diff --git a/docs/resources/google_sql_database_instances.md b/docs/resources/google_sql_database_instances.md
new file mode 100644
index 000000000..cbde25c83
--- /dev/null
+++ b/docs/resources/google_sql_database_instances.md
@@ -0,0 +1,88 @@
+---
+title: About the google_sql_database_instances Resource
+platform: gcp
+---
+
+# google\_sql\_database\_instances
+
+Use the `google_sql_database_instances` InSpec audit resource to test properties of GCP Cloud SQL Database instances.
+
+
+
+## Syntax
+
+A `google_sql_database_instances` resource block collects GCP zones by project then tests that group.
+
+ describe google_sql_database_instances(project: 'chef-inspec-gcp') do
+ it { should exist }
+ end
+
+Use this InSpec resource to enumerate IDs then test in-depth using `google_sql_database_instance`.
+
+ google_sql_database_instances(project: 'chef-inspec-gcp').instance_names.each do |instance_name|
+ describe google_sql_database_instance(project: 'chef-inspec-gcp', database: instance_name) do
+ it { should exist }
+ its('backend_type') { should eq "SECOND_GEN" }
+ end
+ end
+
+
+
+## Examples
+
+The following examples show how to use this InSpec audit resource.
+
+### Test that there are no more than a specified number of zones available for the project
+
+ describe google_sql_database_instances(project: 'chef-inspec-gcp') do
+ its('count') { should be <= 100}
+ end
+
+
+### Test that a database instance exists in the expected zone
+
+ describe google_sql_database_instances(project: 'chef-inspec-gcp') do
+ its('instance_zones') { should include "us-east1-b" }
+ end
+
+### Test that a database instance exists in the expected region
+
+ describe google_sql_database_instances(project: 'chef-inspec-gcp') do
+ its('instance_regions') { should include "us-east1" }
+ end
+
+
+### Confirm that at least one database instance is in "RUNNABLE" state
+
+ describe google_sql_database_instances(project: 'chef-inspec-gcp') do
+ its('instance_states') { should include "RUNNABLE" }
+ end
+
+### Test that a subset of all database instances matching "*mysqldb*" are all version "MYSQL_5_7"
+
+ google_sql_database_instances(project: 'chef-inspec-gcp').where(instance_name: /mysqldb/).instance_names.each do |instance_name|
+ describe google_sql_database_instance(project: 'chef-inspec-gcp', database: instance_name) do
+ it { should exist }
+ its('database_version') { should eq "MYSQL_5_7" }
+ end
+ end
+
+
+
+## Filter Criteria
+
+This resource supports the following filter criteria: `instance_name`; `instance_region`; `instance_zone` and `instance_state`. Any of these may be used with `where`, as a block or as a method.
+
+## Properties
+
+* `instance_names` - an array of google_sql_database_instance name strings
+* `instance_regions`- an array of google_compute_region name strings
+* `instance_zones`- an array of google_sql_database_instance name strings
+* `instance_states`- an array of google_sql_database_instance state strings
+
+
+
+
+## GCP Permissions
+
+Ensure the [Compute Engine API](https://console.cloud.google.com/apis/library/compute.googleapis.com/) is enabled for the project where the resource is located.
\ No newline at end of file
diff --git a/libraries/google_sql_database_instance.rb b/libraries/google_sql_database_instance.rb
new file mode 100644
index 000000000..d64b4a114
--- /dev/null
+++ b/libraries/google_sql_database_instance.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'gcp_backend'
+require 'google/apis/sqladmin_v1beta4'
+
+module Inspec::Resources
+ class GoogleCloudSqlDatabaseInstance < GcpResourceBase
+ name 'google_sql_database_instance'
+ desc 'Verifies settings for a GCP Cloud SQL Database instance'
+
+ example "
+ describe google_sql_database_instance(project: 'chef-inspec-gcp', database: 'my-database') do
+ it { should exist }
+ end
+ "
+
+ def initialize(opts = {})
+ # Call the parent class constructor
+ super(opts)
+ @display_name = opts[:database]
+ catch_gcp_errors do
+ @database = @gcp.gcp_client(Google::Apis::SqladminV1beta4::SQLAdminService).get_instance(opts[:project], opts[:database])
+ create_resource_methods(@database)
+ end
+ end
+
+ def exists?
+ !@database.nil?
+ end
+
+ def to_s
+ "Database #{@display_name}"
+ end
+ end
+end
diff --git a/libraries/google_sql_database_instances.rb b/libraries/google_sql_database_instances.rb
new file mode 100644
index 000000000..e1e3ee8eb
--- /dev/null
+++ b/libraries/google_sql_database_instances.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'gcp_backend'
+
+module Inspec::Resources
+ class GoogleCloudSqlDatabaseInstances < GcpResourceBase
+ name 'google_sql_database_instances'
+ desc 'Verifies settings for GCP Cloud SQL Database instances in bulk'
+
+ example "
+ describe google_sql_database_instances(project: 'chef-inspec-gcp') do
+ it { should exist }
+ end
+ "
+
+ def initialize(opts = {})
+ # Call the parent class constructor
+ super(opts)
+ @project = opts[:project]
+ end
+
+ # FilterTable setup
+ filter_table_config = FilterTable.create
+ filter_table_config.add(:instance_names, field: :instance_name)
+ filter_table_config.add(:instance_regions, field: :instance_region)
+ filter_table_config.add(:instance_zones, field: :instance_zone)
+ filter_table_config.add(:instance_states, field: :instance_state)
+ filter_table_config.connect(self, :fetch_data)
+
+ def fetch_data
+ instance_rows = []
+ catch_gcp_errors do
+ @databases = @gcp.gcp_client(Google::Apis::SqladminV1beta4::SQLAdminService).list_instances(opts[:project])
+ end
+ return [] if !@databases || !@databases.items
+ @databases.items.map do |instance|
+ instance_rows+=[{ instance_name: instance.name,
+ instance_region: instance.region,
+ instance_zone: instance.gce_zone,
+ instance_state: instance.state }]
+ end
+ @databases = instance_rows
+ end
+ end
+end
diff --git a/test/integration/build/gcp.tf b/test/integration/build/gcp.tf
index f413e834e..5f92442a9 100644
--- a/test/integration/build/gcp.tf
+++ b/test/integration/build/gcp.tf
@@ -784,6 +784,7 @@ resource "google_sql_database" "cloud-sql-db-name" {
}
resource "google_sql_user" "cloud-sql-db-user" {
+ project = "${var.gcp_project_id}"
name = "${var.gcp_db_user_name}"
instance = "${google_sql_database_instance.cloud-sql-db-instance.name}"
password = "${var.gcp_db_user_password}"
diff --git a/test/integration/verify/controls/google_sql_database_instance.rb b/test/integration/verify/controls/google_sql_database_instance.rb
new file mode 100644
index 000000000..a75a86d5d
--- /dev/null
+++ b/test/integration/verify/controls/google_sql_database_instance.rb
@@ -0,0 +1,17 @@
+title 'Test single GCP Cloud SQL Database instance'
+
+gcp_project_id = attribute(:gcp_project_id, default: '', description: 'The GCP project identifier.')
+gcp_db_instance_name = attribute(:gcp_db_instance_name, default: '', description: 'The GCP DB instance name.')
+
+control 'gcp-db-instance-1.0' do
+
+ impact 1.0
+ title 'Ensure GCP Cloud SQL Database instance has the correct properties.'
+
+ describe google_sql_database_instance(project: gcp_project_id, database: gcp_db_instance_name) do
+ it { should exist }
+ its('state') { should eq 'RUNNABLE' }
+ its('backend_type') { should eq 'SECOND_GEN' }
+ its('database_version') { should eq 'MYSQL_5_7' }
+ end
+end
\ No newline at end of file
diff --git a/test/integration/verify/controls/google_sql_database_instances.rb b/test/integration/verify/controls/google_sql_database_instances.rb
new file mode 100644
index 000000000..a886b8e40
--- /dev/null
+++ b/test/integration/verify/controls/google_sql_database_instances.rb
@@ -0,0 +1,17 @@
+title 'GCP Cloud SQL Database Instances Properties'
+
+gcp_project_id = attribute(:gcp_project_id, default: '', description: 'The GCP project identifier.')
+gcp_db_instance_name = attribute(:gcp_db_instance_name, default: '', description: 'The GCP DB instance name.')
+
+control 'gcp-db-instances-1.0' do
+
+ impact 1.0
+ title 'Ensure GCP Cloud SQL Database instances have the correct properties in bulk'
+
+ describe google_sql_database_instances(project: gcp_project_id) do
+ its('count') { should be <= 100}
+ its('instance_states') { should include 'RUNNABLE' }
+ its('instance_names') { should include gcp_db_instance_name }
+ end
+
+end
\ No newline at end of file