From ffa003332ec59aacb56918fe7a33f9991915c51a Mon Sep 17 00:00:00 2001 From: Arthur de Lapertosa Lisboa Date: Mon, 12 Aug 2024 15:27:38 -0300 Subject: [PATCH 1/4] feat: add confidential computing example --- examples/confidential_computing/main.tf | 90 +++++++++++++++++++ examples/confidential_computing/outputs.tf | 36 ++++++++ examples/confidential_computing/variables.tf | 53 +++++++++++ metadata.yaml | 2 + modules/compute_disk_snapshot/metadata.yaml | 2 + modules/compute_instance/metadata.yaml | 2 + modules/instance_template/metadata.yaml | 2 + modules/mig/metadata.yaml | 2 + modules/mig_with_percent/metadata.yaml | 2 + .../metadata.yaml | 2 + modules/umig/metadata.yaml | 2 + .../confidential_compute_instance/main.tf | 24 +++++ .../confidential_compute_instance/network.tf | 1 + .../confidential_compute_instance/outputs.tf | 40 +++++++++ .../variables.tf | 20 +++++ .../confidential_compute_instance/versions.tf | 19 ++++ .../confidential_compute_instance_test.go | 51 +++++++++++ 17 files changed, 350 insertions(+) create mode 100644 examples/confidential_computing/main.tf create mode 100644 examples/confidential_computing/outputs.tf create mode 100644 examples/confidential_computing/variables.tf create mode 100644 test/fixtures/confidential_compute_instance/main.tf create mode 120000 test/fixtures/confidential_compute_instance/network.tf create mode 100644 test/fixtures/confidential_compute_instance/outputs.tf create mode 100644 test/fixtures/confidential_compute_instance/variables.tf create mode 100644 test/fixtures/confidential_compute_instance/versions.tf create mode 100644 test/integration/confidential_compute_instance/confidential_compute_instance_test.go diff --git a/examples/confidential_computing/main.tf b/examples/confidential_computing/main.tf new file mode 100644 index 00000000..934a85b9 --- /dev/null +++ b/examples/confidential_computing/main.tf @@ -0,0 +1,90 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_suffix = var.suffix == "" ? random_string.suffix.result : var.suffix + key_name = "${var.key}-${local.default_suffix}" +} + +resource "random_string" "suffix" { + length = 4 + special = false + upper = false +} + +module "kms" { + source = "terraform-google-modules/kms/google" + version = "2.3.0" + + keyring = "${var.keyring}-${local.default_suffix}" + location = var.location + project_id = var.project_id + keys = [local.key_name] + purpose = "ENCRYPT_DECRYPT" + key_protection_level = "HSM" + prevent_destroy = false +} + +resource "google_service_account" "default" { + project = var.project_id + account_id = "confidential-compute-sa-${local.default_suffix}" + display_name = "Custom SA for confidential VM Instance" +} + +data "google_project" "project" { + project_id = var.project_id +} + +resource "google_kms_crypto_key_iam_binding" "crypto_key" { + crypto_key_id = module.kms.keys[local.key_name] + role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" + members = [ + "serviceAccount:service-${data.google_project.project.number}@compute-system.iam.gserviceaccount.com", + ] +} + +module "instance_template" { + source = "../../modules/instance_template" + + region = var.region + project_id = var.project_id + subnetwork = var.subnetwork + + name_prefix = "confidential-encrypted-template" + source_image_project = "ubuntu-os-cloud" + source_image = "ubuntu-2004-lts" + machine_type = "n2d-standard-2" + min_cpu_platform = "AMD Milan" + enable_confidential_vm = true + confidential_instance_type = "SEV" + + service_account = { + email = google_service_account.default.email + scopes = ["cloud-platform"] + } + disk_encryption_key = module.kms.keys[local.key_name] +} + +module "compute_instance" { + source = "terraform-google-modules/vm/google//modules/compute_instance" + version = "~> 11.0" + + region = var.region + subnetwork = var.subnetwork + hostname = "confidential-encrypted-instance" + instance_template = module.instance_template.self_link + deletion_protection = false +} diff --git a/examples/confidential_computing/outputs.tf b/examples/confidential_computing/outputs.tf new file mode 100644 index 00000000..407b9e1d --- /dev/null +++ b/examples/confidential_computing/outputs.tf @@ -0,0 +1,36 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +output "self_link" { + description = "Self-link to the instance template." + value = module.instance_template.self_link +} + +output "name" { + description = "Name of the instance templates." + value = module.instance_template.name +} + +output "instance_self_link" { + description = "Self-link for compute instance" + value = module.compute_instance.instances_self_links[0] +} + +output "suffix" { + description = "Suffix used as an identifier for resources." + value = local.default_suffix +} diff --git a/examples/confidential_computing/variables.tf b/examples/confidential_computing/variables.tf new file mode 100644 index 00000000..a4e00f6b --- /dev/null +++ b/examples/confidential_computing/variables.tf @@ -0,0 +1,53 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +variable "project_id" { + description = "The Google Cloud project ID." + type = string +} + +variable "region" { + description = "The GCP region to create and test resources in." + type = string + default = "us-central1" +} + +variable "subnetwork" { + description = "The subnetwork selflink to host the compute instances in." + type = string +} + +variable "location" { + description = "Location for the resources (keyring, key, network, etc.)." + type = string + default = "global" +} + +variable "suffix" { + description = "A suffix to be used as an identifier for resources. (e.g., suffix for KMS Key, Keyring, SAs, etc.)." + type = string + default = "" +} + +variable "keyring" { + description = "Keyring name." + type = string +} + +variable "key" { + description = "Key name." + type = string +} diff --git a/metadata.yaml b/metadata.yaml index 23332753..b7ccf310 100644 --- a/metadata.yaml +++ b/metadata.yaml @@ -48,6 +48,8 @@ spec: location: examples/instance_template/alias_ip_range - name: autoscaler location: examples/mig/autoscaler + - name: confidential_computing + location: examples/confidential_computing - name: confidential_computing location: examples/instance_template/confidential_computing - name: disk_snapshot diff --git a/modules/compute_disk_snapshot/metadata.yaml b/modules/compute_disk_snapshot/metadata.yaml index b536f0eb..39c67281 100644 --- a/modules/compute_disk_snapshot/metadata.yaml +++ b/modules/compute_disk_snapshot/metadata.yaml @@ -38,6 +38,8 @@ spec: location: examples/instance_template/alias_ip_range - name: autoscaler location: examples/mig/autoscaler + - name: confidential_computing + location: examples/confidential_computing - name: confidential_computing location: examples/instance_template/confidential_computing - name: disk_snapshot diff --git a/modules/compute_instance/metadata.yaml b/modules/compute_instance/metadata.yaml index f8002ab7..3b13695c 100644 --- a/modules/compute_instance/metadata.yaml +++ b/modules/compute_instance/metadata.yaml @@ -38,6 +38,8 @@ spec: location: examples/instance_template/alias_ip_range - name: autoscaler location: examples/mig/autoscaler + - name: confidential_computing + location: examples/confidential_computing - name: confidential_computing location: examples/instance_template/confidential_computing - name: disk_snapshot diff --git a/modules/instance_template/metadata.yaml b/modules/instance_template/metadata.yaml index 4dd52c84..75630159 100644 --- a/modules/instance_template/metadata.yaml +++ b/modules/instance_template/metadata.yaml @@ -38,6 +38,8 @@ spec: location: examples/instance_template/alias_ip_range - name: autoscaler location: examples/mig/autoscaler + - name: confidential_computing + location: examples/confidential_computing - name: confidential_computing location: examples/instance_template/confidential_computing - name: disk_snapshot diff --git a/modules/mig/metadata.yaml b/modules/mig/metadata.yaml index fbecdc82..78173971 100644 --- a/modules/mig/metadata.yaml +++ b/modules/mig/metadata.yaml @@ -38,6 +38,8 @@ spec: location: examples/instance_template/alias_ip_range - name: autoscaler location: examples/mig/autoscaler + - name: confidential_computing + location: examples/confidential_computing - name: confidential_computing location: examples/instance_template/confidential_computing - name: disk_snapshot diff --git a/modules/mig_with_percent/metadata.yaml b/modules/mig_with_percent/metadata.yaml index 9baa487d..90c0102f 100644 --- a/modules/mig_with_percent/metadata.yaml +++ b/modules/mig_with_percent/metadata.yaml @@ -38,6 +38,8 @@ spec: location: examples/instance_template/alias_ip_range - name: autoscaler location: examples/mig/autoscaler + - name: confidential_computing + location: examples/confidential_computing - name: confidential_computing location: examples/instance_template/confidential_computing - name: disk_snapshot diff --git a/modules/preemptible_and_regular_instance_templates/metadata.yaml b/modules/preemptible_and_regular_instance_templates/metadata.yaml index ede089cd..d334879c 100644 --- a/modules/preemptible_and_regular_instance_templates/metadata.yaml +++ b/modules/preemptible_and_regular_instance_templates/metadata.yaml @@ -38,6 +38,8 @@ spec: location: examples/instance_template/alias_ip_range - name: autoscaler location: examples/mig/autoscaler + - name: confidential_computing + location: examples/confidential_computing - name: confidential_computing location: examples/instance_template/confidential_computing - name: disk_snapshot diff --git a/modules/umig/metadata.yaml b/modules/umig/metadata.yaml index 588ac192..ced71e18 100644 --- a/modules/umig/metadata.yaml +++ b/modules/umig/metadata.yaml @@ -38,6 +38,8 @@ spec: location: examples/instance_template/alias_ip_range - name: autoscaler location: examples/mig/autoscaler + - name: confidential_computing + location: examples/confidential_computing - name: confidential_computing location: examples/instance_template/confidential_computing - name: disk_snapshot diff --git a/test/fixtures/confidential_compute_instance/main.tf b/test/fixtures/confidential_compute_instance/main.tf new file mode 100644 index 00000000..bf52f2ea --- /dev/null +++ b/test/fixtures/confidential_compute_instance/main.tf @@ -0,0 +1,24 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module "confidential_computing" { + source = "../../../examples/confidential_computing" + project_id = var.project_id + region = "us-central1" + subnetwork = google_compute_subnetwork.main.self_link + keyring = "key-ring-test" + key = "key-test" +} diff --git a/test/fixtures/confidential_compute_instance/network.tf b/test/fixtures/confidential_compute_instance/network.tf new file mode 120000 index 00000000..98e7464a --- /dev/null +++ b/test/fixtures/confidential_compute_instance/network.tf @@ -0,0 +1 @@ +../shared/network.tf \ No newline at end of file diff --git a/test/fixtures/confidential_compute_instance/outputs.tf b/test/fixtures/confidential_compute_instance/outputs.tf new file mode 100644 index 00000000..bc49de48 --- /dev/null +++ b/test/fixtures/confidential_compute_instance/outputs.tf @@ -0,0 +1,40 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +output "self_link" { + description = "Self-link to the instance template." + value = module.confidential_computing.self_link +} + +output "name" { + description = "Name of the instance templates." + value = module.confidential_computing.name +} + +output "instance_self_link" { + description = "Self-link for compute instance" + value = module.confidential_computing.instance_self_link +} + +output "project_id" { + description = "The GCP project to use for integration tests." + value = var.project_id +} + +output "suffix" { + description = "Suffix used as an identifier for resources." + value = module.confidential_computing.suffix +} diff --git a/test/fixtures/confidential_compute_instance/variables.tf b/test/fixtures/confidential_compute_instance/variables.tf new file mode 100644 index 00000000..e232b248 --- /dev/null +++ b/test/fixtures/confidential_compute_instance/variables.tf @@ -0,0 +1,20 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +variable "project_id" { + description = "The GCP project to use for integration tests." + type = string +} diff --git a/test/fixtures/confidential_compute_instance/versions.tf b/test/fixtures/confidential_compute_instance/versions.tf new file mode 100644 index 00000000..940b48d4 --- /dev/null +++ b/test/fixtures/confidential_compute_instance/versions.tf @@ -0,0 +1,19 @@ +/** + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +terraform { + required_version = ">=0.13" +} diff --git a/test/integration/confidential_compute_instance/confidential_compute_instance_test.go b/test/integration/confidential_compute_instance/confidential_compute_instance_test.go new file mode 100644 index 00000000..b116b280 --- /dev/null +++ b/test/integration/confidential_compute_instance/confidential_compute_instance_test.go @@ -0,0 +1,51 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package confidential_instance_template + +import ( + "fmt" + "testing" + + "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/gcloud" + "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" + "github.com/stretchr/testify/assert" +) + +func TestConfidentialInstanceTemplate(t *testing.T) { + const instanceNamePrefix = "confidential-encrypted-instance" + + confCompInst := tft.NewTFBlueprintTest(t) + confCompInst.DefineVerify(func(assert *assert.Assertions) { + confCompInst.DefaultVerify(assert) + projectId := confCompInst.GetStringOutput("project_id") + + computeInstanceList := gcloud.Run(t, fmt.Sprintf("compute instances list --format=json --project %s --filter name~%s", projectId, instanceNamePrefix)) + + assert.Len(computeInstanceList.Array(), 1) + computeInstance := computeInstanceList.Array()[0] + confidentialInstanceConfig := computeInstance.Get("confidentialInstanceConfig") + assert.True(confidentialInstanceConfig.Get("enableConfidentialCompute").Bool()) + assert.Equal("SEV", confidentialInstanceConfig.Get("confidentialInstanceType").String()) + assert.Equal("MIGRATE", computeInstance.Get("scheduling").Get("onHostMaintenance").String()) + serviceAccounts := computeInstance.Get("serviceAccounts").Array() + assert.Len(serviceAccounts, 1) + defaultSuffix := confCompInst.GetStringOutput("suffix") + assert.Equal(fmt.Sprintf("confidential-compute-sa-%s@%s.iam.gserviceaccount.com", defaultSuffix, projectId), serviceAccounts[0].Get("email").String()) + disks := computeInstance.Get("disks").Array() + assert.Len(disks, 1) + assert.Equal(fmt.Sprintf("projects/%s/locations/global/keyRings/key-ring-test-%s/cryptoKeys/key-test-%s/cryptoKeyVersions/1", projectId, defaultSuffix, defaultSuffix), disks[0].Get("diskEncryptionKey").Get("kmsKeyName").String()) + }) + confCompInst.Test() +} From 103fb77f96acf7d63d74c20d97881752803541ed Mon Sep 17 00:00:00 2001 From: Arthur de Lapertosa Lisboa Date: Wed, 28 Aug 2024 17:17:52 -0300 Subject: [PATCH 2/4] code review fixes --- examples/confidential_computing/README.md | 28 +++++++++++++++++++ examples/confidential_computing/main.tf | 4 +-- examples/confidential_computing/outputs.tf | 2 +- examples/confidential_computing/variables.tf | 4 +-- .../confidential_compute_instance_test.go | 6 ++-- 5 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 examples/confidential_computing/README.md diff --git a/examples/confidential_computing/README.md b/examples/confidential_computing/README.md new file mode 100644 index 00000000..7f4d2a62 --- /dev/null +++ b/examples/confidential_computing/README.md @@ -0,0 +1,28 @@ +# confidential computing vm + +This is an example of a vm creation with confidential computing, encrypted disk +using a Cloud HSM key and a custom service account with cloud-platform scope. + + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| key | Key name. | `string` | n/a | yes | +| keyring | Keyring name. | `string` | n/a | yes | +| location | Location for the resources (keyring, key, network, etc.). | `string` | `"us"` | no | +| project\_id | The Google Cloud project ID. | `string` | n/a | yes | +| region | The GCP region to create and test resources in. | `string` | `"us-central1"` | no | +| subnetwork | The subnetwork selflink to host the compute instances in. | `string` | n/a | yes | +| suffix | A suffix to be used as an identifier for resources. (e.g., suffix for KMS Key, Keyring). | `string` | `""` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| instance\_self\_link | Self-link for compute instance. | +| name | Name of the instance templates. | +| self\_link | Self-link to the instance template. | +| suffix | Suffix used as an identifier for resources. | + + \ No newline at end of file diff --git a/examples/confidential_computing/main.tf b/examples/confidential_computing/main.tf index 934a85b9..6c545be3 100644 --- a/examples/confidential_computing/main.tf +++ b/examples/confidential_computing/main.tf @@ -15,7 +15,7 @@ */ locals { - default_suffix = var.suffix == "" ? random_string.suffix.result : var.suffix + default_suffix = var.suffix == "" ? random_string.suffix.result : "${random_string.suffix.result}-${var.suffix}" key_name = "${var.key}-${local.default_suffix}" } @@ -40,7 +40,7 @@ module "kms" { resource "google_service_account" "default" { project = var.project_id - account_id = "confidential-compute-sa-${local.default_suffix}" + account_id = "confidential-compute-sa" display_name = "Custom SA for confidential VM Instance" } diff --git a/examples/confidential_computing/outputs.tf b/examples/confidential_computing/outputs.tf index 407b9e1d..6bcf2e82 100644 --- a/examples/confidential_computing/outputs.tf +++ b/examples/confidential_computing/outputs.tf @@ -26,7 +26,7 @@ output "name" { } output "instance_self_link" { - description = "Self-link for compute instance" + description = "Self-link for compute instance." value = module.compute_instance.instances_self_links[0] } diff --git a/examples/confidential_computing/variables.tf b/examples/confidential_computing/variables.tf index a4e00f6b..49d54bdd 100644 --- a/examples/confidential_computing/variables.tf +++ b/examples/confidential_computing/variables.tf @@ -33,11 +33,11 @@ variable "subnetwork" { variable "location" { description = "Location for the resources (keyring, key, network, etc.)." type = string - default = "global" + default = "us" } variable "suffix" { - description = "A suffix to be used as an identifier for resources. (e.g., suffix for KMS Key, Keyring, SAs, etc.)." + description = "A suffix to be used as an identifier for resources. (e.g., suffix for KMS Key, Keyring)." type = string default = "" } diff --git a/test/integration/confidential_compute_instance/confidential_compute_instance_test.go b/test/integration/confidential_compute_instance/confidential_compute_instance_test.go index b116b280..48e24ee4 100644 --- a/test/integration/confidential_compute_instance/confidential_compute_instance_test.go +++ b/test/integration/confidential_compute_instance/confidential_compute_instance_test.go @@ -41,11 +41,11 @@ func TestConfidentialInstanceTemplate(t *testing.T) { assert.Equal("MIGRATE", computeInstance.Get("scheduling").Get("onHostMaintenance").String()) serviceAccounts := computeInstance.Get("serviceAccounts").Array() assert.Len(serviceAccounts, 1) - defaultSuffix := confCompInst.GetStringOutput("suffix") - assert.Equal(fmt.Sprintf("confidential-compute-sa-%s@%s.iam.gserviceaccount.com", defaultSuffix, projectId), serviceAccounts[0].Get("email").String()) + assert.Equal(fmt.Sprintf("confidential-compute-sa@%s.iam.gserviceaccount.com", projectId), serviceAccounts[0].Get("email").String()) disks := computeInstance.Get("disks").Array() assert.Len(disks, 1) - assert.Equal(fmt.Sprintf("projects/%s/locations/global/keyRings/key-ring-test-%s/cryptoKeys/key-test-%s/cryptoKeyVersions/1", projectId, defaultSuffix, defaultSuffix), disks[0].Get("diskEncryptionKey").Get("kmsKeyName").String()) + defaultSuffix := confCompInst.GetStringOutput("suffix") + assert.Equal(fmt.Sprintf("projects/%s/locations/us/keyRings/key-ring-test-%s/cryptoKeys/key-test-%s/cryptoKeyVersions/1", projectId, defaultSuffix, defaultSuffix), disks[0].Get("diskEncryptionKey").Get("kmsKeyName").String()) }) confCompInst.Test() } From 6af2ab38c6f32d92f0182ffdaa71fe42e6810399 Mon Sep 17 00:00:00 2001 From: Arthur de Lapertosa Lisboa Date: Thu, 29 Aug 2024 15:34:05 -0300 Subject: [PATCH 3/4] fix lint Co-authored-by: Andrew Peabody --- examples/confidential_computing/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/confidential_computing/README.md b/examples/confidential_computing/README.md index 7f4d2a62..422242ce 100644 --- a/examples/confidential_computing/README.md +++ b/examples/confidential_computing/README.md @@ -25,4 +25,4 @@ using a Cloud HSM key and a custom service account with cloud-platform scope. | self\_link | Self-link to the instance template. | | suffix | Suffix used as an identifier for resources. | - \ No newline at end of file + From 8db92a903d4c91370d1cb873d7685e5093c2fd12 Mon Sep 17 00:00:00 2001 From: Arthur de Lapertosa Lisboa Date: Fri, 6 Sep 2024 15:21:56 -0300 Subject: [PATCH 4/4] code review changes --- examples/confidential_computing/README.md | 6 ++++-- examples/confidential_computing/main.tf | 8 ++++++++ examples/confidential_computing/variables.tf | 6 ++++++ modules/compute_disk_snapshot/README.md | 4 ++-- modules/compute_disk_snapshot/metadata.yaml | 4 ++-- modules/compute_disk_snapshot/outputs.tf | 4 ++-- test/fixtures/confidential_compute_instance/main.tf | 13 +++++++------ .../confidential_compute_instance_test.go | 3 +++ 8 files changed, 34 insertions(+), 14 deletions(-) diff --git a/examples/confidential_computing/README.md b/examples/confidential_computing/README.md index 422242ce..ca5b2a77 100644 --- a/examples/confidential_computing/README.md +++ b/examples/confidential_computing/README.md @@ -1,7 +1,8 @@ # confidential computing vm -This is an example of a vm creation with confidential computing, encrypted disk -using a Cloud HSM key and a custom service account with cloud-platform scope. +This is an example of a vm creation with confidential computing, +encrypted disk using a multiregion (US by default) Cloud HSM key +and a custom service account with cloud-platform scope. ## Inputs @@ -13,6 +14,7 @@ using a Cloud HSM key and a custom service account with cloud-platform scope. | location | Location for the resources (keyring, key, network, etc.). | `string` | `"us"` | no | | project\_id | The Google Cloud project ID. | `string` | n/a | yes | | region | The GCP region to create and test resources in. | `string` | `"us-central1"` | no | +| service\_account\_roles | Predefined roles for the Service account that will be created for the VM. Remember to follow principles of least privileges with Cloud IAM. | `list(string)` | `[]` | no | | subnetwork | The subnetwork selflink to host the compute instances in. | `string` | n/a | yes | | suffix | A suffix to be used as an identifier for resources. (e.g., suffix for KMS Key, Keyring). | `string` | `""` | no | diff --git a/examples/confidential_computing/main.tf b/examples/confidential_computing/main.tf index 6c545be3..e1309736 100644 --- a/examples/confidential_computing/main.tf +++ b/examples/confidential_computing/main.tf @@ -44,6 +44,14 @@ resource "google_service_account" "default" { display_name = "Custom SA for confidential VM Instance" } +resource "google_project_iam_member" "service_account_roles" { + for_each = toset(var.service_account_roles) + + project = var.project_id + role = each.key + member = "serviceAccount:${google_service_account.default.email}" +} + data "google_project" "project" { project_id = var.project_id } diff --git a/examples/confidential_computing/variables.tf b/examples/confidential_computing/variables.tf index 49d54bdd..6fe70f28 100644 --- a/examples/confidential_computing/variables.tf +++ b/examples/confidential_computing/variables.tf @@ -51,3 +51,9 @@ variable "key" { description = "Key name." type = string } + +variable "service_account_roles" { + description = "Predefined roles for the Service account that will be created for the VM. Remember to follow principles of least privileges with Cloud IAM." + type = list(string) + default = [] +} diff --git a/modules/compute_disk_snapshot/README.md b/modules/compute_disk_snapshot/README.md index 07658c0a..4b9fcda5 100644 --- a/modules/compute_disk_snapshot/README.md +++ b/modules/compute_disk_snapshot/README.md @@ -26,7 +26,7 @@ See the [disk snapshot](https://github.com/terraform-google-modules/terraform-go | Name | Description | |------|-------------| -| attachments | Disk attachments to the resource policy | -| policy | Resource snapshot policy details | +| attachments | Disk attachments to the resource policy. | +| policy | Resource snapshot policy details. | diff --git a/modules/compute_disk_snapshot/metadata.yaml b/modules/compute_disk_snapshot/metadata.yaml index 39c67281..1d796b72 100644 --- a/modules/compute_disk_snapshot/metadata.yaml +++ b/modules/compute_disk_snapshot/metadata.yaml @@ -150,9 +150,9 @@ spec: required: true outputs: - name: attachments - description: Disk attachments to the resource policy + description: Disk attachments to the resource policy. - name: policy - description: Resource snapshot policy details + description: Resource snapshot policy details. requirements: roles: - level: Project diff --git a/modules/compute_disk_snapshot/outputs.tf b/modules/compute_disk_snapshot/outputs.tf index b40e408c..c1489441 100644 --- a/modules/compute_disk_snapshot/outputs.tf +++ b/modules/compute_disk_snapshot/outputs.tf @@ -15,11 +15,11 @@ */ output "policy" { - description = "Resource snapshot policy details" + description = "Resource snapshot policy details." value = google_compute_resource_policy.policy } output "attachments" { - description = "Disk attachments to the resource policy" + description = "Disk attachments to the resource policy." value = google_compute_disk_resource_policy_attachment.attachment[*] } diff --git a/test/fixtures/confidential_compute_instance/main.tf b/test/fixtures/confidential_compute_instance/main.tf index bf52f2ea..d42751bd 100644 --- a/test/fixtures/confidential_compute_instance/main.tf +++ b/test/fixtures/confidential_compute_instance/main.tf @@ -15,10 +15,11 @@ */ module "confidential_computing" { - source = "../../../examples/confidential_computing" - project_id = var.project_id - region = "us-central1" - subnetwork = google_compute_subnetwork.main.self_link - keyring = "key-ring-test" - key = "key-test" + source = "../../../examples/confidential_computing" + project_id = var.project_id + region = "us-central1" + subnetwork = google_compute_subnetwork.main.self_link + keyring = "key-ring-test" + key = "key-test" + service_account_roles = ["roles/compute.imageUser", "roles/compute.networkUser"] } diff --git a/test/integration/confidential_compute_instance/confidential_compute_instance_test.go b/test/integration/confidential_compute_instance/confidential_compute_instance_test.go index 48e24ee4..d36d255c 100644 --- a/test/integration/confidential_compute_instance/confidential_compute_instance_test.go +++ b/test/integration/confidential_compute_instance/confidential_compute_instance_test.go @@ -42,6 +42,9 @@ func TestConfidentialInstanceTemplate(t *testing.T) { serviceAccounts := computeInstance.Get("serviceAccounts").Array() assert.Len(serviceAccounts, 1) assert.Equal(fmt.Sprintf("confidential-compute-sa@%s.iam.gserviceaccount.com", projectId), serviceAccounts[0].Get("email").String()) + serviceAccountBindings := gcloud.Runf(t, "projects get-iam-policy %s --flatten bindings --filter bindings.members:'serviceAccount:%s' --format json", projectId, serviceAccounts[0].Get("email").String()).Array() + assert.Equal(2, len(serviceAccountBindings), "expect two bindings") + assert.ElementsMatch([]string{"roles/compute.imageUser", "roles/compute.networkUser"}, []string{serviceAccountBindings[0].Get("bindings.role").String(), serviceAccountBindings[1].Get("bindings.role").String()}) disks := computeInstance.Get("disks").Array() assert.Len(disks, 1) defaultSuffix := confCompInst.GetStringOutput("suffix")