Skip to content

Commit

Permalink
Support deleting Firestore databases (GoogleCloudPlatform#9450)
Browse files Browse the repository at this point in the history
Due to backwards compatibility concerns, the default behavior remains to
abandon the database upon destroy rather than to actually delete it.

To actually delete the database, you must set deletion_policy to DELETE,
and apply if necessary, before running `terraform destroy`.

This also cleans up some related deletion-related docs and bugs:

* Updates the delete protection docs
* delete_protection_state being enabled with deletion_policy = DELETE fails the destroy

Fixes hashicorp/terraform-provider-google#16488
Fixes hashicorp/terraform-provider-google#16404
Fixes hashicorp/terraform-provider-google#16325
  • Loading branch information
rwhogg authored and trodge committed Dec 8, 2023
1 parent 010071a commit 311e11d
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 78 deletions.
55 changes: 39 additions & 16 deletions mmv1/products/firestore/Database.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ async: !ruby/object:Api::OpAsync
error: !ruby/object:Api::OpAsync::Error
path: 'error'
message: 'message'
skip_delete: true
autogen_async: true
id_format: 'projects/{{project}}/databases/{{name}}'
import_format:
Expand All @@ -59,52 +58,73 @@ examples:
name: 'firestore_default_database'
primary_resource_id: 'database'
pull_external: true
vars:
delete_protection_state: "DELETE_PROTECTION_ENABLED"
test_env_vars:
org_id: :ORG_ID
project_id: :PROJECT_NAME
test_vars_overrides:
delete_protection_state: '"DELETE_PROTECTION_DISABLED"'
ignore_read_extra:
- project
- etag
vars:
project_id: 'my-project'
- deletion_policy
- !ruby/object:Provider::Terraform::Examples
name: 'firestore_database'
primary_resource_id: 'database'
vars:
name: "example-database-id"
delete_protection_state: "DELETE_PROTECTION_ENABLED"
test_env_vars:
project_id: :PROJECT_NAME
test_vars_overrides:
delete_protection_state: '"DELETE_PROTECTION_DISABLED"'
ignore_read_extra:
- project
- etag
- deletion_policy
- !ruby/object:Provider::Terraform::Examples
name: 'firestore_default_database_in_datastore_mode'
primary_resource_id: 'datastore_mode_database'
pull_external: true
vars:
delete_protection_state: "DELETE_PROTECTION_ENABLED"
test_env_vars:
org_id: :ORG_ID
project_id: :PROJECT_NAME
test_vars_overrides:
delete_protection_state: '"DELETE_PROTECTION_DISABLED"'
ignore_read_extra:
- project
- etag
vars:
project_id: 'my-project'
- deletion_policy
skip_test: true
- !ruby/object:Provider::Terraform::Examples
name: 'firestore_database_in_datastore_mode'
primary_resource_id: 'datastore_mode_database'
vars:
name: "example-database-id"
delete_protection_state: "DELETE_PROTECTION_ENABLED"
test_env_vars:
project_id: :PROJECT_NAME
test_vars_overrides:
delete_protection_state: '"DELETE_PROTECTION_DISABLED"'
ignore_read_extra:
- project
- etag
- !ruby/object:Provider::Terraform::Examples
name: 'firestore_database_with_delete_protection'
primary_resource_id: 'database'
vars:
name: "example-database-id"
test_env_vars:
project_id: :PROJECT_NAME
skip_test: true
- deletion_policy
virtual_fields:
- !ruby/object:Api::Type::Enum
name: 'deletion_policy'
description: |
Deletion behavior for this database.
If the deletion policy is `ABANDON`, the database will be removed from Terraform state but not deleted from Google Cloud upon destruction.
If the deletion policy is `DELETE`, the database will both be removed from Terraform state and deleted from Google Cloud upon destruction.
The default value is `ABANDON`.
See also `delete_protection`.
values:
- :ABANDON
- :DELETE
default_value: :ABANDON
custom_code: !ruby/object:Provider::Terraform::CustomCode
pre_delete: templates/terraform/pre_delete/firestore_database.go.erb
properties:
- !ruby/object:Api::Type::String
name: name
Expand Down Expand Up @@ -177,6 +197,9 @@ properties:
name: deleteProtectionState
description: |
State of delete protection for the database.
When delete protection is enabled, this database cannot be deleted.
The default value is `DELETE_PROTECTION_STATE_UNSPECIFIED`, which is currently equivalent to `DELETE_PROTECTION_DISABLED`.
**Note:** Additionally, to delete this database using `terraform destroy`, `deletion_policy` must be set to `DELETE`.
values:
- :DELETE_PROTECTION_STATE_UNSPECIFIED
- :DELETE_PROTECTION_ENABLED
Expand Down
2 changes: 2 additions & 0 deletions mmv1/templates/terraform/examples/firestore_database.tf.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ resource "google_firestore_database" "<%= ctx[:primary_resource_id] %>" {
concurrency_mode = "OPTIMISTIC"
app_engine_integration_mode = "DISABLED"
point_in_time_recovery_enablement = "POINT_IN_TIME_RECOVERY_ENABLED"
delete_protection_state = "<%= ctx[:vars]['delete_protection_state'] %>"
deletion_policy = "DELETE"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ resource "google_firestore_database" "<%= ctx[:primary_resource_id] %>" {
concurrency_mode = "OPTIMISTIC"
app_engine_integration_mode = "DISABLED"
point_in_time_recovery_enablement = "POINT_IN_TIME_RECOVERY_ENABLED"
delete_protection_state = "<%= ctx[:vars]['delete_protection_state'] %>"
deletion_policy = "DELETE"
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,27 +1,8 @@
resource "google_project" "project" {
project_id = "<%= ctx[:vars]['project_id'] %>"
name = "<%= ctx[:vars]['project_id'] %>"
org_id = "<%= ctx[:test_env_vars]['org_id'] %>"
}

resource "time_sleep" "wait_60_seconds" {
depends_on = [google_project.project]

create_duration = "60s"
}

resource "google_project_service" "firestore" {
project = google_project.project.project_id
service = "firestore.googleapis.com"
# Needed for CI tests for permissions to propagate, should not be needed for actual usage
depends_on = [time_sleep.wait_60_seconds]
}

resource "google_firestore_database" "<%= ctx[:primary_resource_id] %>" {
project = google_project.project.project_id
name = "(default)"
location_id = "nam5"
type = "FIRESTORE_NATIVE"

depends_on = [google_project_service.firestore]
project = "<%= ctx[:test_env_vars]['project_id'] %>"
name = "(default)"
location_id = "nam5"
type = "FIRESTORE_NATIVE"
delete_protection_state = "<%= ctx[:vars]['delete_protection_state'] %>"
deletion_policy = "DELETE"
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,8 @@
resource "google_project" "project" {
project_id = "tf-test%{random_suffix}"
name = "tf-test%{random_suffix}"
org_id = "<%= ctx[:test_env_vars]['org_id'] %>"
}

resource "time_sleep" "wait_60_seconds" {
depends_on = [google_project.project]
create_duration = "60s"
}

resource "google_project_service" "firestore" {
project = google_project.project.project_id
service = "firestore.googleapis.com"
# Needed for CI tests for permissions to propagate, should not be needed for actual usage
depends_on = [time_sleep.wait_60_seconds]
}

resource "google_firestore_database" "<%= ctx[:primary_resource_id] %>" {
project = google_project.project.project_id

name = "(default)"

location_id = "nam5"
type = "DATASTORE_MODE"

depends_on = [google_project_service.firestore]
project = "<%= ctx[:test_env_vars]['project_id'] %>"
name = "(default)"
location_id = "nam5"
type = "DATASTORE_MODE"
delete_protection_state = "<%= ctx[:vars]['delete_protection_state'] %>"
deletion_policy = "DELETE"
}
7 changes: 7 additions & 0 deletions mmv1/templates/terraform/pre_delete/firestore_database.go.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
if deletionPolicy := d.Get("deletion_policy"); deletionPolicy != "DELETE" {
log.Printf("[WARN] Firestore database %q deletion_policy is not set to 'DELETE', skipping deletion", d.Get("name").(string))
return nil
}
if deleteProtection := d.Get("delete_protection_state"); deleteProtection == "DELETE_PROTECTION_ENABLED" {
return fmt.Errorf("Cannot delete Firestore database %s: Delete Protection is enabled. Set delete_protection_state to DELETE_PROTECTION_DISABLED for this resource and run \"terraform apply\" before attempting to delete it.", d.Get("name").(string))
}

0 comments on commit 311e11d

Please sign in to comment.