Google Cloud VM Autoscaling in Terraform - Updating Images

Viewed 27

I can create a fully-functioning autoscaling group in GCP Compute via Terraform, but it's not clear to me how to update the ASG to use a new image.

Here's an example of a working ASG:

resource "google_compute_region_autoscaler" "default" {
  name    = "example-autoscaler"
  region  = "us-west1"
  project = "my-project
  target  = google_compute_region_instance_group_manager.default.id

  autoscaling_policy {
    max_replicas    = 10
    min_replicas    = 3
    cooldown_period = 60
    cpu_utilization {
      target = 0.5
    }
  }
}

resource "google_compute_region_instance_group_manager" "default" {
  name   = "example-igm"
  region = "us-west1"

  version {
    instance_template  = google_compute_instance_template.default.id
    name               = "primary"
  }

  target_pools       = [google_compute_target_pool.default.id]
  base_instance_name = "example"
}

resource "google_compute_target_pool" "default" {
  name = "example-pool"
}

resource "google_compute_instance_template" "default" {
  name           = "example-template"
  machine_type   = "e2-medium"
  can_ip_forward = false
  tags           = ["my-tag"]
  disk {
     source_image = data.google_compute_image.default.id
  }
  network_interface {
    subnetwork = "my-subnet"
  }
}

data "google_compute_image" "default" {
  name = "my-image"
}

My goal is to be able to create a new Image (out of band) and then update my infrastructure to utilize it. It doesn't appear possible to change a google_compute_instance_template while it's in use.

One option I can think of is to create two separate templates, and then adjust the google_compute_region_instance_group_manager to refer to a different google_compute_instance_template which references the new image.

Another possible option is to use the version block inside the instance group manager. You can use this similarly to above to essentially toggle between two versions. You start with one "version" at 100%, and the other at 0%. When you create a new image, you update the version that is at 0% to point to the new image and change its skew to 100% and the other to 0%. I'm not actually sure this works, because you'd still have to update the template of the version that's at 0% and it might actually be in use.

Regardless, both of those methods are incredibly bulky for a large-scale production environment where we have multiple autoscaling groups in multiple regions and update them frequently.

Ideally I'd be able to change a variable that represents the image, terraform apply and that's it. Is there any way to do what I'm describing?

1 Answers

You need to use the lifecycle block with the create_before_destroy but also the attribute name of the google_compute_instance_template resource must be omitted or replaced by name_prefix attribute.

With this setup Terraform generates a unique name for your Instance Template and can then update the Instance Group manager without conflict before destroying the previous Instance Template.

References: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance_template#using-with-instance-group-manager

Related