Skip to content

Commit

Permalink
feat: Add CMEK support for Firestore database in Beta provider (#10044)
Browse files Browse the repository at this point in the history
* Modify database.yaml to add cmek related fields

* Add two examples for firestore CMEK databases for testing

* Resolve trailing space

* Update documentation for kmsKeyName field

* Resolve trailing space

* Make field immutable

* Update field documentation

* Update field description
  • Loading branch information
jinyangtang authored Mar 6, 2024
1 parent ffd2cf3 commit 787da35
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 0 deletions.
72 changes: 72 additions & 0 deletions mmv1/products/firestore/Database.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,23 @@ examples:
- project
- etag
- deletion_policy
- !ruby/object:Provider::Terraform::Examples
name: 'firestore_cmek_database'
min_version: beta
primary_resource_id: 'database'
vars:
database_id: "cmek-database-id"
delete_protection_state: "DELETE_PROTECTION_ENABLED"
kms_key_ring_name: "kms-key-ring"
kms_key_name: "kms-key"
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'
Expand All @@ -102,6 +119,23 @@ examples:
- project
- etag
- deletion_policy
- !ruby/object:Provider::Terraform::Examples
name: 'firestore_cmek_database_in_datastore_mode'
min_version: beta
primary_resource_id: 'database'
vars:
database_id: "cmek-database-id"
delete_protection_state: "DELETE_PROTECTION_ENABLED"
kms_key_ring_name: "kms-key-ring"
kms_key_name: "kms-key"
test_env_vars:
project_id: :PROJECT_NAME
test_vars_overrides:
delete_protection_state: '"DELETE_PROTECTION_DISABLED"'
ignore_read_extra:
- project
- etag
- deletion_policy
virtual_fields:
- !ruby/object:Api::Type::Enum
name: 'deletion_policy'
Expand Down Expand Up @@ -234,3 +268,41 @@ properties:
This value is continuously updated, and becomes stale the moment it is queried. If you are using this value to recover data, make sure to account for the time from the moment when the value is queried to the moment when you initiate the recovery.
A timestamp in RFC3339 UTC "Zulu" format, with nanosecond resolution and up to nine fractional digits. Examples: "2014-10-02T15:01:23Z" and "2014-10-02T15:01:23.045123456Z".
output: true
- !ruby/object:Api::Type::NestedObject
name: cmekConfig
min_version: beta
immutable: true
description: |
The CMEK (Customer Managed Encryption Key) configuration for a Firestore
database. If not present, the database is secured by the default Google
encryption key.
properties:
- !ruby/object:Api::Type::String
name: kmsKeyName
required: true
immutable: true
description: |
The resource ID of a Cloud KMS key. If set, the database created will
be a Customer-managed Encryption Key (CMEK) database encrypted with
this key. This feature is allowlist only in initial launch.
Only keys in the same location as this database are allowed to be used
for encryption. For Firestore's nam5 multi-region, this corresponds to Cloud KMS
multi-region us. For Firestore's eur3 multi-region, this corresponds to
Cloud KMS multi-region europe. See https://cloud.google.com/kms/docs/locations.
This value should be the KMS key resource ID in the format of
`projects/{project_id}/locations/{kms_location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}`.
How to retrive this resource ID is listed at
https://cloud.google.com/kms/docs/getting-resource-ids#getting_the_id_for_a_key_and_version.
- !ruby/object:Api::Type::Array
name: activeKeyVersion
output: true
description: |
Currently in-use KMS key versions (https://cloud.google.com/kms/docs/resource-hierarchy#key_versions).
During key rotation (https://cloud.google.com/kms/docs/key-rotation), there can be
multiple in-use key versions.
The expected format is
`projects/{project_id}/locations/{kms_location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}/cryptoKeyVersions/{key_version}`.
item_type: Api::Type::String
50 changes: 50 additions & 0 deletions mmv1/templates/terraform/examples/firestore_cmek_database.tf.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
data "google_project" "project" {
provider = google-beta
}

resource "google_firestore_database" "<%= ctx[:primary_resource_id] %>" {
provider = google-beta

project = "<%= ctx[:test_env_vars]['project_id'] %>"
name = "<%= ctx[:vars]['database_id']%>"
location_id = "nam5"
type = "FIRESTORE_NATIVE"
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"
cmek_config {
kms_key_name = google_kms_crypto_key.crypto_key.id
}

depends_on = [
google_kms_crypto_key_iam_binding.firestore_cmek_keyuser
]
}

resource "google_kms_crypto_key" "crypto_key" {
provider = google-beta

name = "<%= ctx[:vars]['kms_key_name'] %>"
key_ring = google_kms_key_ring.key_ring.id
purpose = "ENCRYPT_DECRYPT"
}

resource "google_kms_key_ring" "key_ring" {
provider = google-beta

name = "<%= ctx[:vars]['kms_key_ring_name'] %>"
location = "us"
}

resource "google_kms_crypto_key_iam_binding" "firestore_cmek_keyuser" {
provider = google-beta

crypto_key_id = google_kms_crypto_key.crypto_key.id
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"

members = [
"serviceAccount:service-${data.google_project.project.number}@gcp-sa-firestore.iam.gserviceaccount.com",
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
data "google_project" "project" {
provider = google-beta
}

resource "google_firestore_database" "<%= ctx[:primary_resource_id] %>" {
provider = google-beta

project = "<%= ctx[:test_env_vars]['project_id'] %>"
name = "<%= ctx[:vars]['database_id']%>"
location_id = "nam5"
type = "DATASTORE_MODE"
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"
cmek_config {
kms_key_name = google_kms_crypto_key.crypto_key.id
}

depends_on = [
google_kms_crypto_key_iam_binding.firestore_cmek_keyuser
]
}

resource "google_kms_crypto_key" "crypto_key" {
provider = google-beta

name = "<%= ctx[:vars]['kms_key_name'] %>"
key_ring = google_kms_key_ring.key_ring.id
purpose = "ENCRYPT_DECRYPT"
}

resource "google_kms_key_ring" "key_ring" {
provider = google-beta

name = "<%= ctx[:vars]['kms_key_ring_name'] %>"
location = "us"
}

resource "google_kms_crypto_key_iam_binding" "firestore_cmek_keyuser" {
provider = google-beta

crypto_key_id = google_kms_crypto_key.crypto_key.id
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"

members = [
"serviceAccount:service-${data.google_project.project.number}@gcp-sa-firestore.iam.gserviceaccount.com",
]
}

0 comments on commit 787da35

Please sign in to comment.