Compute VM module refactor (#3805)

* add ad for compute-vm refactor

* Exclue nic_type from validated fields, add split of main.tf and template.tf

* boot disk

* fix examples and fixtures

* attached disks

* fix further examples and module-level tests

* remove extra file

* fix mig examples

* finish refactoring variables

* align fast and other modules

* refactor(compute-vm): align examples and ADR with the newly implemented interface

This commit addresses the remaining references of the `instance_type` and `confidential_compute` parameters in the testing environment and updates the ADR.

* feat(compute-vm): add network_performance_config to instance and templates

This change implements the usage of the `network_performance_tier` variable we added earlier into the actual Terraform resources.

---------

Co-authored-by: Wiktor Niesiobędzki <wiktorn@google.com>
This commit is contained in:
Ludovico Magnocavallo
2026-03-26 12:31:40 +01:00
committed by GitHub
parent 2c39df6453
commit a4eb4d24fd
64 changed files with 1971 additions and 1119 deletions

View File

@@ -15,22 +15,10 @@
*/
locals {
_region = join("-", slice(split("-", local.zone), 0, 2))
advanced_mf = var.options.advanced_machine_features
attached_disks = {
for i, disk in var.attached_disks :
coalesce(disk.name, disk.device_name, "disk-${i}") => merge(disk, {
options = disk.options == null ? var.attached_disk_defaults : disk.options
})
}
attached_disks_regional = {
for k, v in local.attached_disks :
k => v if try(v.options.replica_zone, null) != null
}
attached_disks_zonal = {
for k, v in local.attached_disks :
k => v if try(v.options.replica_zone, null) == null
}
_region = join("-", slice(split("-", local.zone), 0, 2))
advanced_mf = anytrue([
for k, v in var.machine_features_config : v != null
])
ctx = {
for k, v in var.context : k => {
for kk, vv in v : "${local.ctx_p}${k}:${kk}" => vv
@@ -42,10 +30,13 @@ locals {
})
ctx_p = "$"
gpu = var.gpu != null
on_host_maintenance = (
var.options.spot || var.confidential_compute || local.gpu
? "TERMINATE"
: "MIGRATE"
on_host_maintenance = coalesce(
var.scheduling_config.on_host_maintenance,
(
var.scheduling_config.provisioning_model == "SPOT" ||
var.confidential_compute != null ||
local.gpu
) ? "TERMINATE" : "MIGRATE"
)
project_id = lookup(local.ctx.project_ids, var.project_id, var.project_id)
region = lookup(local.ctx.locations, local._region, local._region)
@@ -75,7 +66,9 @@ locals {
)
}
termination_action = (
var.options.spot || var.options.max_run_duration != null ? coalesce(var.options.termination_action, "STOP") : null
var.scheduling_config.provisioning_model == "SPOT" || var.scheduling_config.max_run_duration != null
? coalesce(var.scheduling_config.termination_action, "STOP")
: null
)
zone = lookup(local.ctx.locations, var.zone, var.zone)
}
@@ -92,366 +85,6 @@ resource "google_kms_key_handle" "default" {
resource_type_selector = each.value.resource_type_selector
}
resource "google_compute_disk" "boot" {
count = !local.template_create && var.boot_disk.use_independent_disk ? 1 : 0
project = local.project_id
zone = local.zone
# by default, GCP creates boot disks with the same name as instance, the deviation here is kept for backwards
# compatibility
name = coalesce(var.boot_disk.name, "${var.name}-boot")
type = var.boot_disk.initialize_params.type
size = var.boot_disk.initialize_params.size
architecture = var.boot_disk.initialize_params.architecture
image = var.boot_disk.initialize_params.image
provisioned_iops = var.boot_disk.initialize_params.provisioned_iops
provisioned_throughput = var.boot_disk.initialize_params.provisioned_throughput
storage_pool = var.boot_disk.initialize_params.storage_pool
labels = merge(var.labels, {
disk_name = "boot"
disk_type = var.boot_disk.initialize_params.type
})
dynamic "disk_encryption_key" {
for_each = var.encryption != null ? [""] : []
content {
raw_key = var.encryption.disk_encryption_key_raw
kms_key_self_link = lookup(
local.ctx_kms_keys,
var.encryption.kms_key_self_link,
var.encryption.kms_key_self_link
)
}
}
}
resource "google_compute_disk" "disks" {
for_each = local.template_create ? {} : {
for k, v in local.attached_disks_zonal :
k => v if v.source_type != "attach"
}
project = local.project_id
zone = local.zone
name = "${var.name}-${each.key}"
type = each.value.options.type
size = each.value.size
architecture = each.value.options.architecture
image = each.value.source_type == "image" ? each.value.source : null
provisioned_iops = each.value.options.provisioned_iops
provisioned_throughput = each.value.options.provisioned_throughput
snapshot = each.value.source_type == "snapshot" ? each.value.source : null
storage_pool = each.value.options.storage_pool
labels = merge(var.labels, {
disk_name = each.value.name
disk_type = each.value.options.type
})
dynamic "disk_encryption_key" {
for_each = var.encryption != null ? [""] : []
content {
raw_key = var.encryption.disk_encryption_key_raw
kms_key_self_link = lookup(
local.ctx_kms_keys,
var.encryption.kms_key_self_link,
var.encryption.kms_key_self_link
)
}
}
}
resource "google_compute_region_disk" "disks" {
provider = google-beta
for_each = local.template_create ? {} : {
for k, v in local.attached_disks_regional :
k => v if v.source_type != "attach"
}
project = local.project_id
region = local.region
replica_zones = [local.zone, each.value.options.replica_zone]
name = "${var.name}-${each.key}"
type = each.value.options.type
size = each.value.size
# image = each.value.source_type == "image" ? each.value.source : null
snapshot = each.value.source_type == "snapshot" ? each.value.source : null
labels = merge(var.labels, {
disk_name = each.value.name
disk_type = each.value.options.type
})
dynamic "disk_encryption_key" {
for_each = var.encryption != null ? [""] : []
content {
raw_key = var.encryption.disk_encryption_key_raw
# TODO: check if self link works here
kms_key_name = lookup(
local.ctx_kms_keys,
var.encryption.kms_key_self_link,
var.encryption.kms_key_self_link
)
}
}
}
resource "google_compute_instance" "default" {
provider = google-beta
count = local.template_create ? 0 : 1
project = local.project_id
zone = local.zone
name = var.name
hostname = var.hostname
description = var.description
tags = var.tags
machine_type = var.instance_type
min_cpu_platform = var.min_cpu_platform
can_ip_forward = var.can_ip_forward
allow_stopping_for_update = var.options.allow_stopping_for_update
deletion_protection = var.options.deletion_protection
key_revocation_action_type = var.options.key_revocation_action_type
enable_display = var.enable_display
labels = var.labels
metadata = var.metadata
metadata_startup_script = var.metadata_startup_script
resource_policies = (
var.resource_policies == null && var.instance_schedule == null
? null
: concat(
coalesce(var.resource_policies, []),
coalesce(local.ischedule, [])
)
)
dynamic "advanced_machine_features" {
for_each = local.advanced_mf != null ? [""] : []
content {
enable_nested_virtualization = local.advanced_mf.enable_nested_virtualization
enable_uefi_networking = local.advanced_mf.enable_uefi_networking
performance_monitoring_unit = local.advanced_mf.performance_monitoring_unit
threads_per_core = local.advanced_mf.threads_per_core
turbo_mode = (
local.advanced_mf.enable_turbo_mode ? "ALL_CORE_MAX" : null
)
visible_core_count = local.advanced_mf.visible_core_count
}
}
dynamic "attached_disk" {
for_each = local.attached_disks_zonal
iterator = config
content {
device_name = (
config.value.device_name != null
? config.value.device_name
: config.value.name
)
mode = config.value.options.mode
source = (
config.value.source_type == "attach"
? config.value.source
: google_compute_disk.disks[config.key].name
)
}
}
dynamic "attached_disk" {
for_each = local.attached_disks_regional
iterator = config
content {
device_name = coalesce(
config.value.device_name, config.value.name, config.key
)
mode = config.value.options.mode
source = (
config.value.source_type == "attach"
? config.value.source
: google_compute_region_disk.disks[config.key].id
)
}
}
boot_disk {
auto_delete = (
var.boot_disk.use_independent_disk
? false
: var.boot_disk.auto_delete
)
source = (
var.boot_disk.use_independent_disk
? google_compute_disk.boot[0].id
: var.boot_disk.source
)
disk_encryption_key_raw = (
var.encryption != null ?
try(
local.ctx_kms_keys[var.encryption.disk_encryption_key_raw],
var.encryption.disk_encryption_key_raw
)
: null
)
kms_key_self_link = (
var.encryption != null
? try(
local.ctx_kms_keys[var.encryption.kms_key_self_link],
var.encryption.kms_key_self_link
)
: null
)
dynamic "initialize_params" {
for_each = (
var.boot_disk.initialize_params == null
||
var.boot_disk.use_independent_disk
||
var.boot_disk.source != null
? []
: [""]
)
content {
architecture = var.boot_disk.initialize_params.architecture
image = var.boot_disk.initialize_params.image
size = var.boot_disk.initialize_params.size
type = var.boot_disk.initialize_params.type
resource_manager_tags = var.tag_bindings_immutable
provisioned_iops = var.boot_disk.initialize_params.provisioned_iops
provisioned_throughput = var.boot_disk.initialize_params.provisioned_throughput
storage_pool = var.boot_disk.initialize_params.storage_pool
}
}
}
dynamic "confidential_instance_config" {
for_each = var.confidential_compute ? [""] : []
content {
enable_confidential_compute = true
}
}
dynamic "network_interface" {
for_each = var.network_interfaces
iterator = config
content {
network = lookup(
local.ctx.networks, config.value.network, config.value.network
)
subnetwork = lookup(
local.ctx.subnets, config.value.subnetwork, config.value.subnetwork
)
network_ip = try(
local.ctx.addresses[config.value.addresses.internal],
config.value.addresses.internal,
null
)
nic_type = config.value.nic_type
stack_type = config.value.stack_type
dynamic "access_config" {
for_each = config.value.nat || config.value.network_tier != null ? [""] : []
content {
nat_ip = try(
local.ctx.addresses[config.value.addresses.external],
config.value.addresses.external,
null
)
network_tier = try(config.value.network_tier, null)
}
}
dynamic "alias_ip_range" {
for_each = config.value.alias_ips
iterator = config_alias
content {
subnetwork_range_name = config_alias.key
ip_cidr_range = config_alias.value
}
}
}
}
dynamic "network_interface" {
for_each = var.network_attached_interfaces
content {
network_attachment = network_interface.value
}
}
scheduling {
automatic_restart = !var.options.spot
instance_termination_action = local.termination_action
on_host_maintenance = local.on_host_maintenance
preemptible = var.options.spot
provisioning_model = var.options.spot ? "SPOT" : "STANDARD"
dynamic "max_run_duration" {
for_each = var.options.max_run_duration == null ? [] : [""]
content {
nanos = var.options.max_run_duration.nanos
seconds = var.options.max_run_duration.seconds
}
}
dynamic "node_affinities" {
for_each = var.options.node_affinities
iterator = affinity
content {
key = affinity.key
operator = affinity.value.in ? "IN" : "NOT_IN"
values = affinity.value.values
}
}
dynamic "graceful_shutdown" {
for_each = var.options.graceful_shutdown != null ? [""] : []
content {
enabled = var.options.graceful_shutdown.enabled
dynamic "max_duration" {
for_each = var.options.graceful_shutdown.enabled == true && var.options.graceful_shutdown.max_duration_secs != null ? [""] : []
content {
seconds = var.options.graceful_shutdown.max_duration_secs
nanos = 0
}
}
}
}
}
dynamic "scratch_disk" {
for_each = [
for i in range(0, var.scratch_disks.count) : var.scratch_disks.interface
]
iterator = config
content {
interface = config.value
}
}
dynamic "service_account" {
for_each = var.service_account == null ? [] : [""]
content {
email = local.service_account.email
scopes = local.service_account.scopes
}
}
dynamic "shielded_instance_config" {
for_each = var.shielded_config != null ? [var.shielded_config] : []
iterator = config
content {
enable_secure_boot = config.value.enable_secure_boot
enable_vtpm = config.value.enable_vtpm
enable_integrity_monitoring = config.value.enable_integrity_monitoring
}
}
dynamic "params" {
for_each = var.tag_bindings_immutable == null ? [] : [""]
content {
resource_manager_tags = var.tag_bindings_immutable
}
}
dynamic "guest_accelerator" {
for_each = local.gpu ? [var.gpu] : []
content {
type = guest_accelerator.value.type
count = guest_accelerator.value.count
}
}
}
resource "google_compute_instance_iam_binding" "default" {
project = local.project_id
for_each = var.iam
@@ -465,7 +98,7 @@ resource "google_compute_instance_iam_binding" "default" {
}
resource "google_compute_instance_group" "unmanaged" {
count = var.group != null && !local.template_create ? 1 : 0
count = var.group != null && !local.is_template ? 1 : 0
project = local.project_id
network = (
length(var.network_interfaces) > 0