diff --git a/mmv1/products/spanner/api.yaml b/mmv1/products/spanner/api.yaml index 118b3ede4301..70177a93fabd 100644 --- a/mmv1/products/spanner/api.yaml +++ b/mmv1/products/spanner/api.yaml @@ -209,3 +209,14 @@ objects: description: | Fully qualified name of the KMS key to use to encrypt this database. This key must exist in the same location as the Spanner Database. + - !ruby/object:Api::Type::Enum + name: 'databaseDialect' + description: | + The dialect of the Cloud Spanner Database. + If it is not provided, "GOOGLE_STANDARD_SQL" will be used. + Note: Databases that are created with POSTGRESQL dialect do not support + extra DDL statements in the `CreateDatabase` call. You must therefore re-apply + terraform with ddl on the same database after creation. + values: + - :GOOGLE_STANDARD_SQL + - :POSTGRESQL \ No newline at end of file diff --git a/mmv1/products/spanner/terraform.yaml b/mmv1/products/spanner/terraform.yaml index 533b633494b7..670c3807d7b0 100644 --- a/mmv1/products/spanner/terraform.yaml +++ b/mmv1/products/spanner/terraform.yaml @@ -31,6 +31,11 @@ overrides: !ruby/object:Overrides::ResourceOverrides On older versions, it is strongly recommended to set `lifecycle { prevent_destroy = true }` on databases in order to prevent accidental data loss. See [Terraform docs](https://www.terraform.io/docs/configuration/resources.html#prevent_destroy) for more information on lifecycle parameters. + + Note: Databases that are created with POSTGRESQL dialect do not support + extra DDL statements in the `CreateDatabase` call. You must therefore re-apply + terraform with ddl on the same database after creation. + examples: - !ruby/object:Provider::Terraform::Examples name: "spanner_database_basic" @@ -58,6 +63,8 @@ overrides: !ruby/object:Overrides::ResourceOverrides ignore_read: true state: !ruby/object:Overrides::Terraform::PropertyOverride exclude: false + databaseDialect: !ruby/object:Overrides::Terraform::PropertyOverride + default_from_api: true custom_code: !ruby/object:Provider::Terraform::CustomCode constants: 'templates/terraform/constants/spanner_database.go.erb' encoder: templates/terraform/encoders/spanner_database.go.erb diff --git a/mmv1/templates/terraform/encoders/spanner_database.go.erb b/mmv1/templates/terraform/encoders/spanner_database.go.erb index 6651f0d9e475..c88fb37463f9 100644 --- a/mmv1/templates/terraform/encoders/spanner_database.go.erb +++ b/mmv1/templates/terraform/encoders/spanner_database.go.erb @@ -1,4 +1,7 @@ obj["createStatement"] = fmt.Sprintf("CREATE DATABASE `%s`", obj["name"]) +if dialect, ok := obj["databaseDialect"]; ok && dialect == "POSTGRESQL" { + obj["createStatement"] = fmt.Sprintf("CREATE DATABASE %s", obj["name"]) +} delete(obj, "name") delete(obj, "instance") return obj, nil diff --git a/mmv1/third_party/terraform/tests/resource_spanner_database_test.go.erb b/mmv1/third_party/terraform/tests/resource_spanner_database_test.go.erb index ba176341d3ca..87f4bf0abf58 100644 --- a/mmv1/third_party/terraform/tests/resource_spanner_database_test.go.erb +++ b/mmv1/third_party/terraform/tests/resource_spanner_database_test.go.erb @@ -117,6 +117,90 @@ resource "google_spanner_database" "basic" { `, instanceName, instanceName, databaseName) } +func TestAccSpannerDatabase_postgres(t *testing.T) { + t.Parallel() + + rnd := randString(t, 10) + instanceName := fmt.Sprintf("tf-test-%s", rnd) + databaseName := fmt.Sprintf("tfgen_%s", rnd) + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckSpannerDatabaseDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccSpannerDatabase_postgres(instanceName, databaseName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("google_spanner_database.basic_spangres", "state"), + ), + }, + { + // Test import with default Terraform ID + ResourceName: "google_spanner_database.basic_spangres", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"ddl", "deletion_protection"}, + }, + { + Config: testAccSpannerDatabase_postgresUpdate(instanceName, databaseName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("google_spanner_database.basic_spangres", "state"), + ), + }, + { + // Test import with default Terraform ID + ResourceName: "google_spanner_database.basic_spangres", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"ddl", "deletion_protection"}, + }, + }, + }) +} + +func testAccSpannerDatabase_postgres(instanceName, databaseName string) string { + return fmt.Sprintf(` +resource "google_spanner_instance" "basic" { + name = "%s" + config = "regional-us-central1" + display_name = "%s-display" + num_nodes = 1 +} + +resource "google_spanner_database" "basic_spangres" { + instance = google_spanner_instance.basic.name + name = "%s_spangres" + database_dialect = "POSTGRESQL" + deletion_protection = false +} +`, instanceName, instanceName, databaseName) +} + +func testAccSpannerDatabase_postgresUpdate(instanceName, databaseName string) string { + return fmt.Sprintf(` +resource "google_spanner_instance" "basic" { + name = "%s" + config = "regional-us-central1" + display_name = "%s-display" + num_nodes = 1 +} + +resource "google_spanner_database" "basic_spangres" { + instance = google_spanner_instance.basic.name + name = "%s_spangres" + database_dialect = "POSTGRESQL" + ddl = [ + "CREATE TABLE t1 (t1 bigint NOT NULL PRIMARY KEY)", + "CREATE TABLE t2 (t2 bigint NOT NULL PRIMARY KEY)", + "CREATE TABLE t3 (t3 bigint NOT NULL PRIMARY KEY)", + "CREATE TABLE t4 (t4 bigint NOT NULL PRIMARY KEY)", + ] + deletion_protection = false +} +`, instanceName, instanceName, databaseName) +} + // Unit Tests for type spannerDatabaseId func TestDatabaseNameForApi(t *testing.T) { id := spannerDatabaseId{ @@ -350,4 +434,4 @@ resource "google_project_service_identity" "ck_sa" { `, context) } -<% end -%> +<% end -%> \ No newline at end of file