Skip to content

Commit 10cc891

Browse files
Sql database add deletion policy (#6821) (#4916)
* 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 <[email protected]> Signed-off-by: Modular Magician <[email protected]>
1 parent 17befac commit 10cc891

File tree

4 files changed

+107
-0
lines changed

4 files changed

+107
-0
lines changed

.changelog/6821.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
sql: added field `deletion_policy` to resource `google_sql_database`
3+
```

google-beta/resource_sql_database.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ a value of 'UTF8' at creation time.`,
7575
and Postgres' [Collation Support](https://www.postgresql.org/docs/9.6/static/collation.html)
7676
for more details and supported values. Postgres databases only support
7777
a value of 'en_US.UTF8' at creation time.`,
78+
},
79+
"deletion_policy": {
80+
Type: schema.TypeString,
81+
Optional: true,
82+
Default: "ABANDON",
83+
Description: `The deletion policy for the database. Setting ABANDON allows the resource
84+
to be abandoned rather than deleted. This is useful for Postgres, where databases cannot be
85+
deleted from the API if there are users other than cloudsqlsuperuser with access. Possible
86+
values are: "ABANDON".`,
7887
},
7988
"project": {
8089
Type: schema.TypeString,
@@ -207,6 +216,12 @@ func resourceSQLDatabaseRead(d *schema.ResourceData, meta interface{}) error {
207216
return handleNotFoundError(transformSQLDatabaseReadError(err), d, fmt.Sprintf("SQLDatabase %q", d.Id()))
208217
}
209218

219+
// Explicitly set virtual fields to default values if unset
220+
if _, ok := d.GetOkExists("deletion_policy"); !ok {
221+
if err := d.Set("deletion_policy", "ABANDON"); err != nil {
222+
return fmt.Errorf("Error setting deletion_policy: %s", err)
223+
}
224+
}
210225
if err := d.Set("project", project); err != nil {
211226
return fmt.Errorf("Error reading Database: %s", err)
212227
}
@@ -337,6 +352,11 @@ func resourceSQLDatabaseDelete(d *schema.ResourceData, meta interface{}) error {
337352
}
338353

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

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

403+
// Explicitly set virtual fields to default values on import
404+
if err := d.Set("deletion_policy", "ABANDON"); err != nil {
405+
return nil, fmt.Errorf("Error setting deletion_policy: %s", err)
406+
}
407+
383408
return []*schema.ResourceData{d}, nil
384409
}
385410

google-beta/resource_sql_database_generated_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,53 @@ resource "google_sql_database_instance" "instance" {
6969
`, context)
7070
}
7171

72+
func TestAccSQLDatabase_sqlDatabaseDeletionPolicyExample(t *testing.T) {
73+
t.Parallel()
74+
75+
context := map[string]interface{}{
76+
"deletion_protection": false,
77+
"random_suffix": randString(t, 10),
78+
}
79+
80+
vcrTest(t, resource.TestCase{
81+
PreCheck: func() { testAccPreCheck(t) },
82+
Providers: testAccProviders,
83+
CheckDestroy: testAccCheckSQLDatabaseDestroyProducer(t),
84+
Steps: []resource.TestStep{
85+
{
86+
Config: testAccSQLDatabase_sqlDatabaseDeletionPolicyExample(context),
87+
},
88+
{
89+
ResourceName: "google_sql_database.database_deletion_policy",
90+
ImportState: true,
91+
ImportStateVerify: true,
92+
},
93+
},
94+
})
95+
}
96+
97+
func testAccSQLDatabase_sqlDatabaseDeletionPolicyExample(context map[string]interface{}) string {
98+
return Nprintf(`
99+
resource "google_sql_database" "database_deletion_policy" {
100+
name = "tf-test-my-database%{random_suffix}"
101+
instance = google_sql_database_instance.instance.name
102+
deletion_policy = "ABANDON"
103+
}
104+
105+
# See versions at https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance#database_version
106+
resource "google_sql_database_instance" "instance" {
107+
name = "tf-test-my-database-instance%{random_suffix}"
108+
region = "us-central1"
109+
database_version = "POSTGRES_14"
110+
settings {
111+
tier = "db-g1-small"
112+
}
113+
114+
deletion_protection = "%{deletion_protection}"
115+
}
116+
`, context)
117+
}
118+
72119
func testAccCheckSQLDatabaseDestroyProducer(t *testing.T) func(s *terraform.State) error {
73120
return func(s *terraform.State) error {
74121
for name, rs := range s.RootModule().Resources {

website/docs/r/sql_database.html.markdown

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,33 @@ resource "google_sql_database_instance" "instance" {
5252
deletion_protection = "true"
5353
}
5454
```
55+
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
56+
<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">
57+
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
58+
</a>
59+
</div>
60+
## Example Usage - Sql Database Deletion Policy
61+
62+
63+
```hcl
64+
resource "google_sql_database" "database_deletion_policy" {
65+
name = "my-database"
66+
instance = google_sql_database_instance.instance.name
67+
deletion_policy = "ABANDON"
68+
}
69+
70+
# See versions at https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance#database_version
71+
resource "google_sql_database_instance" "instance" {
72+
name = "my-database-instance"
73+
region = "us-central1"
74+
database_version = "POSTGRES_14"
75+
settings {
76+
tier = "db-g1-small"
77+
}
78+
79+
deletion_protection = "true"
80+
}
81+
```
5582

5683
## Argument Reference
5784

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

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

95127
## Attributes Reference
96128

0 commit comments

Comments
 (0)