diff --git a/modules/compute-vm/README.md b/modules/compute-vm/README.md index 8ad96af4..48b06979 100644 --- a/modules/compute-vm/README.md +++ b/modules/compute-vm/README.md @@ -9,7 +9,7 @@ In both modes, an optional service account can be created and assigned to either ## Examples -### Instance leveraging defaults +### Instance using defaults The simplest example leverages defaults for the boot disk image and size, and uses a service account created by the module. Multiple instances can be managed via the `instance_count` variable. @@ -189,6 +189,7 @@ module "instance-group" { | *attached_disks* | Additional disks, if options is null defaults will be used in its place. | list(object({...})) | | [] | | *boot_disk* | Boot disk properties. | object({...}) | | ... | | *can_ip_forward* | Enable IP forwarding. | bool | | false | +| *confidential_compute* | Enable Confidential Compute for these instances. | bool | | false | | *enable_display* | Enable virtual display on the instances | bool | | false | | *encryption* | Encryption options. Only one of kms_key_self_link and disk_encryption_key_raw may be set. If needed, you can specify to encrypt or not the boot disk. | object({...}) | | null | | *group* | Define this variable to create an instance group for instances. Disabled for template use. | object({...}) | | null | diff --git a/modules/compute-vm/main.tf b/modules/compute-vm/main.tf index 782c4425..f4423691 100644 --- a/modules/compute-vm/main.tf +++ b/modules/compute-vm/main.tf @@ -25,6 +25,11 @@ locals { for pair in setproduct(keys(local.names), keys(local.attached_disks)) : "${pair[0]}-${pair[1]}" => { disk_name = pair[1], name = pair[0] } } + on_host_maintenance = ( + var.options.preemptible || var.confidential_compute + ? "TERMINATE" + : "MIGRATE" + ) iam_members = var.use_instance_template ? {} : { for pair in setproduct(keys(var.iam), keys(local.names)) : "${pair.0}/${pair.1}" => { role = pair.0, name = pair.1, members = var.iam[pair.0] } @@ -89,6 +94,7 @@ resource "google_compute_disk" "disks" { } resource "google_compute_instance" "default" { + provider = google-beta for_each = var.use_instance_template ? {} : local.names project = var.project_id zone = local.zones[each.key] @@ -130,6 +136,13 @@ resource "google_compute_instance" "default" { kms_key_self_link = var.encryption != null ? var.encryption.kms_key_self_link : null } + dynamic confidential_instance_config { + for_each = var.confidential_compute ? [""] : [] + content { + enable_confidential_compute = true + } + } + dynamic network_interface { for_each = var.network_interfaces iterator = config @@ -163,7 +176,7 @@ resource "google_compute_instance" "default" { scheduling { automatic_restart = ! var.options.preemptible - on_host_maintenance = var.options.preemptible ? "TERMINATE" : "MIGRATE" + on_host_maintenance = local.on_host_maintenance preemptible = var.options.preemptible } @@ -206,6 +219,7 @@ resource "google_compute_instance_iam_binding" "default" { } resource "google_compute_instance_template" "default" { + provider = google-beta count = var.use_instance_template ? 1 : 0 project = var.project_id region = var.region @@ -225,6 +239,13 @@ resource "google_compute_instance_template" "default" { boot = true } + dynamic confidential_instance_config { + for_each = var.confidential_compute ? [""] : [] + content { + enable_confidential_compute = true + } + } + dynamic disk { for_each = local.attached_disks iterator = config @@ -255,7 +276,7 @@ resource "google_compute_instance_template" "default" { scheduling { automatic_restart = ! var.options.preemptible - on_host_maintenance = var.options.preemptible ? "TERMINATE" : "MIGRATE" + on_host_maintenance = local.on_host_maintenance preemptible = var.options.preemptible } diff --git a/modules/compute-vm/variables.tf b/modules/compute-vm/variables.tf index a3aa80a2..3f83a9e1 100644 --- a/modules/compute-vm/variables.tf +++ b/modules/compute-vm/variables.tf @@ -66,6 +66,12 @@ variable "can_ip_forward" { default = false } +variable "confidential_compute" { + description = "Enable Confidential Compute for these instances." + type = bool + default = false +} + variable "encryption" { description = "Encryption options. Only one of kms_key_self_link and disk_encryption_key_raw may be set. If needed, you can specify to encrypt or not the boot disk." type = object({ diff --git a/modules/compute-vm/versions.tf b/modules/compute-vm/versions.tf new file mode 100644 index 00000000..21c535aa --- /dev/null +++ b/modules/compute-vm/versions.tf @@ -0,0 +1,22 @@ +/** + * Copyright 2020 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.0" + required_providers { + google-beta = ">= 3.36.0" + } +} diff --git a/tests/modules/compute_vm/fixture/main.tf b/tests/modules/compute_vm/fixture/main.tf index 749742d8..ade9835f 100644 --- a/tests/modules/compute_vm/fixture/main.tf +++ b/tests/modules/compute_vm/fixture/main.tf @@ -24,6 +24,7 @@ module "test" { service_account_create = var.service_account_create instance_count = var.instance_count use_instance_template = var.use_instance_template + confidential_compute = var.confidential_compute group = var.group iam = var.iam metadata = var.metadata diff --git a/tests/modules/compute_vm/fixture/variables.tf b/tests/modules/compute_vm/fixture/variables.tf index b1fd91fe..341c97bd 100644 --- a/tests/modules/compute_vm/fixture/variables.tf +++ b/tests/modules/compute_vm/fixture/variables.tf @@ -14,6 +14,11 @@ * limitations under the License. */ +variable "confidential_compute" { + type = bool + default = false +} + variable "group" { type = any default = null diff --git a/tests/modules/compute_vm/test_plan.py b/tests/modules/compute_vm/test_plan.py index 698bf33a..ef46beb8 100644 --- a/tests/modules/compute_vm/test_plan.py +++ b/tests/modules/compute_vm/test_plan.py @@ -75,3 +75,22 @@ def test_iam(plan_runner): 'roles/iam.serviceAccountUser/test-1': ['user:a@a.com'], 'roles/iam.serviceAccountUser/test-2': ['user:a@a.com'], } + + +def test_confidential_compute(plan_runner): + _, resources = plan_runner(FIXTURES_DIR, instance_count=1, + confidential_compute='true') + assert len(resources) == 1 + assert resources[0]['values']['confidential_instance_config'] == [ + {'enable_confidential_compute': True}] + assert resources[0]['values']['scheduling'][0]['on_host_maintenance'] == 'TERMINATE' + + +def test_confidential_compute_template(plan_runner): + _, resources = plan_runner(FIXTURES_DIR, instance_count=1, + confidential_compute='true', + use_instance_template='true') + assert len(resources) == 1 + assert resources[0]['values']['confidential_instance_config'] == [ + {'enable_confidential_compute': True}] + assert resources[0]['values']['scheduling'][0]['on_host_maintenance'] == 'TERMINATE'