Skip to content

Commit 3329923

Browse files
Add deletion_protection field to Memcache Instance (#15025) (#24613)
[upstream:bc77deae2dcf14fa3162402847cd058f24424975] Signed-off-by: Modular Magician <[email protected]>
1 parent 19a587a commit 3329923

File tree

6 files changed

+95
-224
lines changed

6 files changed

+95
-224
lines changed

.changelog/15025.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
memcache: added `deletion_protection` field to `memcache_instance` to make deleting them require an explicit intent. `memcache_instance` resources now cannot be destroyed unless `deletion_protection = false` is set for the resource.
3+
```

google/services/memcache/resource_memcache_instance.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,16 @@ resolution and up to nine fractional digits.`,
369369
and default labels configured on the provider.`,
370370
Elem: &schema.Schema{Type: schema.TypeString},
371371
},
372+
"deletion_protection": {
373+
Type: schema.TypeBool,
374+
Optional: true,
375+
Description: `Whether Terraform will be prevented from destroying the instance.
376+
When a 'terraform destroy' or 'terraform apply' would delete the instance,
377+
the command will fail if this field is not set to false in Terraform state.
378+
When the field is set to true or unset in Terraform state, a 'terraform apply'
379+
or 'terraform destroy' that would delete the instance will fail.
380+
When the field is set to false, deleting the instance is allowed.`,
381+
},
372382
"project": {
373383
Type: schema.TypeString,
374384
Optional: true,
@@ -543,6 +553,7 @@ func resourceMemcacheInstanceRead(d *schema.ResourceData, meta interface{}) erro
543553
return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("MemcacheInstance %q", d.Id()))
544554
}
545555

556+
// Explicitly set virtual fields to default values if unset
546557
if err := d.Set("project", project); err != nil {
547558
return fmt.Errorf("Error reading Instance: %s", err)
548559
}
@@ -784,6 +795,9 @@ func resourceMemcacheInstanceDelete(d *schema.ResourceData, meta interface{}) er
784795
}
785796

786797
headers := make(http.Header)
798+
if d.Get("deletion_protection").(bool) {
799+
return fmt.Errorf("cannot destroy memcache instance without setting deletion_protection=false and running `terraform apply`")
800+
}
787801

788802
log.Printf("[DEBUG] Deleting Instance %q", d.Id())
789803
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
@@ -830,6 +844,8 @@ func resourceMemcacheInstanceImport(d *schema.ResourceData, meta interface{}) ([
830844
}
831845
d.SetId(id)
832846

847+
// Explicitly set virtual fields to default values on import
848+
833849
return []*schema.ResourceData{d}, nil
834850
}
835851

google/services/memcache/resource_memcache_instance_generated_meta.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ api_resource_type_kind: 'Instance'
77
fields:
88
- field: 'authorized_network'
99
- field: 'create_time'
10+
- field: 'deletion_protection'
11+
provider_only: true
1012
- field: 'discovery_endpoint'
1113
- field: 'display_name'
1214
- field: 'effective_labels'

google/services/memcache/resource_memcache_instance_sweeper.go

Lines changed: 0 additions & 223 deletions
This file was deleted.

google/services/memcache/resource_memcache_instance_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package memcache_test
1818

1919
import (
2020
"fmt"
21+
"regexp"
2122
"testing"
2223

2324
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
@@ -113,3 +114,67 @@ data "google_compute_network" "memcache_network" {
113114
}
114115
`, name, network)
115116
}
117+
118+
func TestAccMemcacheInstance_deletionprotection(t *testing.T) {
119+
t.Parallel()
120+
121+
prefix := fmt.Sprintf("%d", acctest.RandInt(t))
122+
name := fmt.Sprintf("tf-test-%s", prefix)
123+
network := acctest.BootstrapSharedServiceNetworkingConnection(t, "memcache-instance-update-1")
124+
125+
acctest.VcrTest(t, resource.TestCase{
126+
PreCheck: func() { acctest.AccTestPreCheck(t) },
127+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
128+
CheckDestroy: testAccCheckMemcacheInstanceDestroyProducer(t),
129+
Steps: []resource.TestStep{
130+
{
131+
Config: testAccMemcacheInstanceConfig(prefix, name, network, "us-central1", true), // deletion_protection = true
132+
},
133+
{
134+
ResourceName: "google_memcache_instance.test",
135+
ImportState: true,
136+
ImportStateVerify: true,
137+
ImportStateVerifyIgnore: []string{"reserved_ip_range_id", "deletion_protection"},
138+
},
139+
{
140+
Config: testAccMemcacheInstanceConfig(prefix, name, network, "us-west2", true), // deletion_protection = true
141+
ExpectError: regexp.MustCompile("deletion_protection"),
142+
},
143+
{
144+
Config: testAccMemcacheInstanceConfig(prefix, name, network, "us-central1", false), // deletion_protection = false
145+
},
146+
{
147+
ResourceName: "google_memcache_instance.test",
148+
ImportState: true,
149+
ImportStateVerify: true,
150+
ImportStateVerifyIgnore: []string{"reserved_ip_range_id", "deletion_protection"},
151+
},
152+
},
153+
})
154+
}
155+
156+
func testAccMemcacheInstanceConfig(prefix, name, network, region string, deletionProtection bool) string {
157+
return fmt.Sprintf(`
158+
resource "google_memcache_instance" "test" {
159+
name = "%s"
160+
region = "%s"
161+
authorized_network = data.google_compute_network.memcache_network.id
162+
deletion_protection = %t
163+
node_config {
164+
cpu_count = 1
165+
memory_size_mb = 1024
166+
}
167+
node_count = 1
168+
memcache_parameters {
169+
params = {
170+
"listen-backlog" = "2048"
171+
"max-item-size" = "8388608"
172+
}
173+
}
174+
reserved_ip_range_id = ["tf-bootstrap-addr-memcache-instance-update-1"]
175+
}
176+
data "google_compute_network" "memcache_network" {
177+
name = "%s"
178+
}
179+
`, name, region, deletionProtection, network)
180+
}

website/docs/r/memcache_instance.html.markdown

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ resource "google_service_networking_connection" "private_service_connection" {
6363
resource "google_memcache_instance" "instance" {
6464
name = "test-instance"
6565
authorized_network = google_service_networking_connection.private_service_connection.network
66-
66+
deletion_protection = false
67+
6768
labels = {
6869
env = "test"
6970
}
@@ -161,6 +162,13 @@ The following arguments are supported:
161162
* `project` - (Optional) The ID of the project in which the resource belongs.
162163
If it is not provided, the provider project is used.
163164

165+
* `deletion_protection` - (Optional) Whether Terraform will be prevented from destroying the instance.
166+
When a `terraform destroy` or `terraform apply` would delete the instance,
167+
the command will fail if this field is not set to false in Terraform state.
168+
When the field is set to true or unset in Terraform state, a `terraform apply`
169+
or `terraform destroy` that would delete the instance will fail.
170+
When the field is set to false, deleting the instance is allowed.
171+
164172

165173

166174
<a name="nested_node_config"></a>The `node_config` block supports:

0 commit comments

Comments
 (0)