diff --git a/mmv1/third_party/terraform/resources/resource_bigtable_instance.go b/mmv1/third_party/terraform/resources/resource_bigtable_instance.go index fea6d9ad3794..1d2437efbee0 100644 --- a/mmv1/third_party/terraform/resources/resource_bigtable_instance.go +++ b/mmv1/third_party/terraform/resources/resource_bigtable_instance.go @@ -36,10 +36,6 @@ func resourceBigtableInstance() *schema.Resource { }, }, - // ---------------------------------------------------------------------- - // IMPORTANT: Do not add any additional ForceNew fields to this resource. - // Destroying/recreating instances can lead to data loss for users. - // ---------------------------------------------------------------------- Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -82,6 +78,13 @@ func resourceBigtableInstance() *schema.Resource { ValidateFunc: validation.StringInSlice([]string{"SSD", "HDD"}, false), Description: `The storage type to use. One of "SSD" or "HDD". Defaults to "SSD".`, }, + "kms_key_name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Description: `Describes the Cloud KMS encryption key that will be used to protect the destination Bigtable cluster. The requirements for this key are: 1) The Cloud Bigtable service account associated with the project that contains this cluster must be granted the cloudkms.cryptoKeyEncrypterDecrypter role on the CMEK key. 2) Only regional keys can be used and the region of the CMEK key must match the region of the cluster. 3) All clusters within an instance must use the same CMEK key. Values are of the form projects/{project}/locations/{location}/keyRings/{keyring}/cryptoKeys/{key}`, + }, }, }, }, @@ -354,6 +357,7 @@ func flattenBigtableCluster(c *bigtable.ClusterInfo) map[string]interface{} { "num_nodes": c.ServeNodes, "cluster_id": c.Name, "storage_type": storageType, + "kms_key_name": c.KMSKeyName, } } @@ -378,6 +382,7 @@ func expandBigtableClusters(clusters []interface{}, instanceID string, config *C ClusterID: cluster["cluster_id"].(string), NumNodes: int32(cluster["num_nodes"].(int)), StorageType: storageType, + KMSKeyName: cluster["kms_key_name"].(string), }) } return results, nil diff --git a/mmv1/third_party/terraform/tests/resource_bigtable_instance_test.go b/mmv1/third_party/terraform/tests/resource_bigtable_instance_test.go index 8a03841842b1..a39985068a89 100644 --- a/mmv1/third_party/terraform/tests/resource_bigtable_instance_test.go +++ b/mmv1/third_party/terraform/tests/resource_bigtable_instance_test.go @@ -158,6 +158,33 @@ func TestAccBigtableInstance_allowDestroy(t *testing.T) { }) } +func TestAccBigtableInstance_kms(t *testing.T) { + // bigtable instance does not use the shared HTTP client, this test creates an instance + skipIfVcr(t) + t.Parallel() + + kms := BootstrapKMSKeyInLocation(t, "us-central1") + pid := getTestProjectFromEnv() + instanceName := fmt.Sprintf("tf-test-%s", randString(t, 10)) + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckBigtableInstanceDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccBigtableInstance_kms(pid, instanceName, kms.CryptoKey.Name, 3), + }, + { + ResourceName: "google_bigtable_instance.instance", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"deletion_protection", "instance_type"}, // we don't read instance type back + }, + }, + }) +} + func testAccCheckBigtableInstanceDestroyProducer(t *testing.T) func(s *terraform.State) error { return func(s *terraform.State) error { var ctx = context.Background() @@ -339,3 +366,32 @@ resource "google_bigtable_instance" "instance" { } `, instanceName, instanceName, numNodes) } + +func testAccBigtableInstance_kms(pid, instanceName, kmsKey string, numNodes int) string { + return fmt.Sprintf(` +data "google_project" "project" { + project_id = "%s" +} + + +resource "google_project_iam_member" "kms_project_binding" { + project = data.google_project.project.project_id + role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" + member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-bigtable.iam.gserviceaccount.com" +} + +resource "google_bigtable_instance" "instance" { + name = "%s" + cluster { + cluster_id = "%s" + zone = "us-central1-b" + num_nodes = %d + storage_type = "HDD" + kms_key_name = "%s" + } + depends_on = [google_project_iam_member.kms_project_binding] + deletion_protection = false + +} +`, pid, instanceName, instanceName, numNodes, kmsKey) +} diff --git a/mmv1/third_party/terraform/website/docs/r/bigtable_instance.html.markdown b/mmv1/third_party/terraform/website/docs/r/bigtable_instance.html.markdown index b170bfa87839..33169fe1fe4d 100644 --- a/mmv1/third_party/terraform/website/docs/r/bigtable_instance.html.markdown +++ b/mmv1/third_party/terraform/website/docs/r/bigtable_instance.html.markdown @@ -90,6 +90,12 @@ for a `DEVELOPMENT` instance. * `storage_type` - (Optional) The storage type to use. One of `"SSD"` or `"HDD"`. Defaults to `"SSD"`. +* `kms_key_name` - (Optional) Describes the Cloud KMS encryption key that will be used to protect the destination Bigtable cluster. The requirements for this key are: 1) The Cloud Bigtable service account associated with the project that contains this cluster must be granted the `cloudkms.cryptoKeyEncrypterDecrypter` role on the CMEK key. 2) Only regional keys can be used and the region of the CMEK key must match the region of the cluster. 3) All clusters within an instance must use the same CMEK key. Values are of the form `projects/{project}/locations/{location}/keyRings/{keyring}/cryptoKeys/{key}` + +!> **Warning**: Modifying this field will cause Terraform to delete/recreate the entire resource. + +-> **Note**: To remove this field once it is set, set the value to an empty string. Removing the field entirely from the config will cause the provider to default to the backend value. + !> **Warning:** Modifying the `storage_type` or `zone` of an existing cluster (by `cluster_id`) will cause Terraform to delete/recreate the entire `google_bigtable_instance` resource. If these values are changing, use a new