Skip to content

Commit

Permalink
Sql database add deletion policy (#6821) (#13107)
Browse files Browse the repository at this point in the history
* feat: adding deletion_policy=abandon to google_sql_database resource

* feat: honing in on correct behavior of google_sql_database

* feat: got tests to pass

* fix: simplified adding deletion_policy to google_sql_database

* chore: switch deletion_policy to virtual field

Signed-off-by: Modular Magician <magic-modules@google.com>

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician committed Nov 22, 2022
1 parent 7e9bd55 commit 36b2aa4
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/6821.txt
@@ -0,0 +1,3 @@
```release-note:enhancement
sql: added field `deletion_policy` to resource `google_sql_database`
```
25 changes: 25 additions & 0 deletions google/resource_sql_database.go
Expand Up @@ -75,6 +75,15 @@ a value of 'UTF8' at creation time.`,
and Postgres' [Collation Support](https://www.postgresql.org/docs/9.6/static/collation.html)
for more details and supported values. Postgres databases only support
a value of 'en_US.UTF8' at creation time.`,
},
"deletion_policy": {
Type: schema.TypeString,
Optional: true,
Default: "ABANDON",
Description: `The deletion policy for the database. Setting ABANDON allows the resource
to be abandoned rather than deleted. This is useful for Postgres, where databases cannot be
deleted from the API if there are users other than cloudsqlsuperuser with access. Possible
values are: "ABANDON".`,
},
"project": {
Type: schema.TypeString,
Expand Down Expand Up @@ -207,6 +216,12 @@ func resourceSQLDatabaseRead(d *schema.ResourceData, meta interface{}) error {
return handleNotFoundError(transformSQLDatabaseReadError(err), d, fmt.Sprintf("SQLDatabase %q", d.Id()))
}

// Explicitly set virtual fields to default values if unset
if _, ok := d.GetOkExists("deletion_policy"); !ok {
if err := d.Set("deletion_policy", "ABANDON"); err != nil {
return fmt.Errorf("Error setting deletion_policy: %s", err)
}
}
if err := d.Set("project", project); err != nil {
return fmt.Errorf("Error reading Database: %s", err)
}
Expand Down Expand Up @@ -337,6 +352,11 @@ func resourceSQLDatabaseDelete(d *schema.ResourceData, meta interface{}) error {
}

var obj map[string]interface{}
if deletionPolicy := d.Get("deletion_policy"); deletionPolicy == "ABANDON" {
// Allows for database to be abandoned without deletion to avoid deletion failing
// for Postgres databases in some circumstances due to existing SQL users
return nil
}
log.Printf("[DEBUG] Deleting Database %q", d.Id())

// err == nil indicates that the billing_project value was found
Expand Down Expand Up @@ -380,6 +400,11 @@ func resourceSQLDatabaseImport(d *schema.ResourceData, meta interface{}) ([]*sch
}
d.SetId(id)

// Explicitly set virtual fields to default values on import
if err := d.Set("deletion_policy", "ABANDON"); err != nil {
return nil, fmt.Errorf("Error setting deletion_policy: %s", err)
}

return []*schema.ResourceData{d}, nil
}

Expand Down
47 changes: 47 additions & 0 deletions google/resource_sql_database_generated_test.go
Expand Up @@ -69,6 +69,53 @@ resource "google_sql_database_instance" "instance" {
`, context)
}

func TestAccSQLDatabase_sqlDatabaseDeletionPolicyExample(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"deletion_protection": false,
"random_suffix": randString(t, 10),
}

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckSQLDatabaseDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccSQLDatabase_sqlDatabaseDeletionPolicyExample(context),
},
{
ResourceName: "google_sql_database.database_deletion_policy",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccSQLDatabase_sqlDatabaseDeletionPolicyExample(context map[string]interface{}) string {
return Nprintf(`
resource "google_sql_database" "database_deletion_policy" {
name = "tf-test-my-database%{random_suffix}"
instance = google_sql_database_instance.instance.name
deletion_policy = "ABANDON"
}
# See versions at https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance#database_version
resource "google_sql_database_instance" "instance" {
name = "tf-test-my-database-instance%{random_suffix}"
region = "us-central1"
database_version = "POSTGRES_14"
settings {
tier = "db-g1-small"
}
deletion_protection = "%{deletion_protection}"
}
`, context)
}

func testAccCheckSQLDatabaseDestroyProducer(t *testing.T) func(s *terraform.State) error {
return func(s *terraform.State) error {
for name, rs := range s.RootModule().Resources {
Expand Down
32 changes: 32 additions & 0 deletions website/docs/r/sql_database.html.markdown
Expand Up @@ -52,6 +52,33 @@ resource "google_sql_database_instance" "instance" {
deletion_protection = "true"
}
```
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
<a href="https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fdocs-examples.git&cloudshell_working_dir=sql_database_deletion_policy&cloudshell_image=gcr.io%2Fgraphite-cloud-shell-images%2Fterraform%3Alatest&open_in_editor=main.tf&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md" target="_blank">
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
</a>
</div>
## Example Usage - Sql Database Deletion Policy


```hcl
resource "google_sql_database" "database_deletion_policy" {
name = "my-database"
instance = google_sql_database_instance.instance.name
deletion_policy = "ABANDON"
}
# See versions at https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance#database_version
resource "google_sql_database_instance" "instance" {
name = "my-database-instance"
region = "us-central1"
database_version = "POSTGRES_14"
settings {
tier = "db-g1-small"
}
deletion_protection = "true"
}
```

## Argument Reference

Expand Down Expand Up @@ -91,6 +118,11 @@ The following arguments are supported:
* `project` - (Optional) The ID of the project in which the resource belongs.
If it is not provided, the provider project is used.

* `deletion_policy` - (Optional) The deletion policy for the database. Setting ABANDON allows the resource
to be abandoned rather than deleted. This is useful for Postgres, where databases cannot be
deleted from the API if there are users other than cloudsqlsuperuser with access. Possible
values are: "ABANDON".


## Attributes Reference

Expand Down

0 comments on commit 36b2aa4

Please sign in to comment.