From be54fe31d7a2e393b44212e08410de1d08bdcfd9 Mon Sep 17 00:00:00 2001 From: Simone Ruffilli Date: Wed, 4 May 2022 09:48:31 +0200 Subject: [PATCH] Adds Spot VM support to compute-vm --- modules/compute-vm/README.md | 48 ++++++++++++++++++++++++++------- modules/compute-vm/main.tf | 2 ++ modules/compute-vm/variables.tf | 6 +++++ 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/modules/compute-vm/README.md b/modules/compute-vm/README.md index 81cbee2c..5f2c9fbf 100644 --- a/modules/compute-vm/README.md +++ b/modules/compute-vm/README.md @@ -31,6 +31,34 @@ module "simple-vm-example" { ``` +### Spot VM + +[Spot VMs](https://cloud.google.com/compute/docs/instances/spot) are ephemeral compute instances suitable for batch jobs and fault-tolerant workloads. Spot VMs provide new features that [preemptible instances](https://cloud.google.com/compute/docs/instances/preemptible) do not support, such as the absence of a maximum runtime. + +```hcl +module "spot-vm-example" { + source = "./modules/compute-vm" + project_id = var.project_id + zone = "europe-west1-b" + name = "test" + options = { + allow_stopping_for_update = true + deletion_protection = false + preemptible = true + spot = true + } + network_interfaces = [{ + network = var.vpc.self_link + subnetwork = var.subnet.self_link + nat = false + addresses = null + }] + service_account_create = true +} +# tftest modules=1 resources=2 + +``` + ### Disk sources Attached disks can be created and optionally initialized from a pre-existing source, or attached to VMs when pre-existing. The `source` and `source_type` attributes of the `attached_disks` variable allows several modes of operation: @@ -300,8 +328,8 @@ module "instance-group" { |---|---|:---:|:---:|:---:| | [name](variables.tf#L160) | Instance name. | string | ✓ | | | [network_interfaces](variables.tf#L174) | Network interfaces configuration. Use self links for Shared VPC, set addresses to null if not needed. | list(object({…})) | ✓ | | -| [project_id](variables.tf#L201) | Project id. | string | ✓ | | -| [zone](variables.tf#L260) | Compute zone. | string | ✓ | | +| [project_id](variables.tf#L207) | Project id. | string | ✓ | | +| [zone](variables.tf#L266) | Compute zone. | string | ✓ | | | [attached_disk_defaults](variables.tf#L17) | Defaults for attached disks options. | object({…}) | | {…} | | [attached_disks](variables.tf#L32) | Additional disks, if options is null defaults will be used in its place. Source type is one of 'image' (zonal disks in vms and template), 'snapshot' (vm), 'existing', and null. | list(object({…})) | | [] | | [boot_disk](variables.tf#L58) | Boot disk properties. | object({…}) | | {…} | @@ -320,14 +348,14 @@ module "instance-group" { | [metadata](variables.tf#L148) | Instance metadata. | map(string) | | {} | | [min_cpu_platform](variables.tf#L154) | Minimum CPU platform. | string | | null | | [network_interface_options](variables.tf#L165) | Network interfaces extended options. The key is the index of the inteface to configure. The value is an object with alias_ips and nic_type. Set alias_ips or nic_type to null if you need only one of them. | map(object({…})) | | {} | -| [options](variables.tf#L187) | Instance options. | object({…}) | | {…} | -| [scratch_disks](variables.tf#L206) | Scratch disks configuration. | object({…}) | | {…} | -| [service_account](variables.tf#L218) | Service account email. Unused if service account is auto-created. | string | | null | -| [service_account_create](variables.tf#L224) | Auto-create service account. | bool | | false | -| [service_account_scopes](variables.tf#L232) | Scopes applied to service account. | list(string) | | [] | -| [shielded_config](variables.tf#L238) | Shielded VM configuration of the instances. | object({…}) | | null | -| [tag_bindings](variables.tf#L248) | Tag bindings for this instance, in key => tag value id format. | map(string) | | null | -| [tags](variables.tf#L254) | Instance network tags for firewall rule targets. | list(string) | | [] | +| [options](variables.tf#L187) | Instance options. | object({…}) | | {…} | +| [scratch_disks](variables.tf#L212) | Scratch disks configuration. | object({…}) | | {…} | +| [service_account](variables.tf#L224) | Service account email. Unused if service account is auto-created. | string | | null | +| [service_account_create](variables.tf#L230) | Auto-create service account. | bool | | false | +| [service_account_scopes](variables.tf#L238) | Scopes applied to service account. | list(string) | | [] | +| [shielded_config](variables.tf#L244) | Shielded VM configuration of the instances. | object({…}) | | null | +| [tag_bindings](variables.tf#L254) | Tag bindings for this instance, in key => tag value id format. | map(string) | | null | +| [tags](variables.tf#L260) | Instance network tags for firewall rule targets. | list(string) | | [] | ## Outputs diff --git a/modules/compute-vm/main.tf b/modules/compute-vm/main.tf index 55581fee..0f98fd04 100644 --- a/modules/compute-vm/main.tf +++ b/modules/compute-vm/main.tf @@ -215,6 +215,7 @@ resource "google_compute_instance" "default" { automatic_restart = !var.options.preemptible on_host_maintenance = local.on_host_maintenance preemptible = var.options.preemptible + provisioning_model = var.options.spot ? "SPOT" : null } dynamic "scratch_disk" { @@ -341,6 +342,7 @@ resource "google_compute_instance_template" "default" { automatic_restart = !var.options.preemptible on_host_maintenance = local.on_host_maintenance preemptible = var.options.preemptible + provisioning_model = var.options.spot ? "SPOT" : null } service_account { diff --git a/modules/compute-vm/variables.tf b/modules/compute-vm/variables.tf index 653c66da..c13eaed9 100644 --- a/modules/compute-vm/variables.tf +++ b/modules/compute-vm/variables.tf @@ -190,11 +190,17 @@ variable "options" { allow_stopping_for_update = bool deletion_protection = bool preemptible = bool + spot = bool }) default = { allow_stopping_for_update = true deletion_protection = false preemptible = false + spot = false + } + validation { + condition = !var.options.spot || (var.options.spot && var.options.preemptible) + error_message = "Variable var.option.preemptible should be `true` when var.options.spot is set to `true`." } }