google_compute_instance_template

Manages a VM instance template resource within GCE. For more information see the official documentation and API.

Example Usage

resource "google_service_account" "default" {
  account_id   = "service-account-id"
  display_name = "Service Account"
}

resource "google_compute_instance_template" "default" {
  name        = "appserver-template"
  description = "This template is used to create app server instances."

  tags = ["foo", "bar"]

  labels = {
    environment = "dev"
  }

  instance_description = "description assigned to instances"
  machine_type         = "e2-medium"
  can_ip_forward       = false

  scheduling {
    automatic_restart   = true
    on_host_maintenance = "MIGRATE"
  }

  // Create a new boot disk from an image
  disk {
    source_image      = "debian-cloud/debian-11"
    auto_delete       = true
    boot              = true
    // backup the disk every day
    resource_policies = [google_compute_resource_policy.daily_backup.id]
  }

  // Use an existing disk resource
  disk {
    // Instance Templates reference disks by name, not self link
    source      = google_compute_disk.foobar.name
    auto_delete = false
    boot        = false
  }

  network_interface {
    network = "default"
  }

  metadata = {
    foo = "bar"
  }

  service_account {
    # Google recommends custom service accounts that have cloud-platform scope and permissions granted via IAM Roles.
    email  = google_service_account.default.email
    scopes = ["cloud-platform"]
  }
}

data "google_compute_image" "my_image" {
  family  = "debian-11"
  project = "debian-cloud"
}

resource "google_compute_disk" "foobar" {
  name  = "existing-disk"
  image = data.google_compute_image.my_image.self_link
  size  = 10
  type  = "pd-ssd"
  zone  = "us-central1-a"
}

resource "google_compute_resource_policy" "daily_backup" {
  name   = "every-day-4am"
  region = "us-central1"
  snapshot_schedule_policy {
    schedule {
      daily_schedule {
        days_in_cycle = 1
        start_time    = "04:00"
      }
    }
  }
}

Example Usage - Automatic Envoy deployment

data "google_compute_default_service_account" "default" {
}

data "google_compute_image" "my_image" {
  family  = "debian-11"
  project = "debian-cloud"
}

resource "google_compute_instance_template" "foobar" {
  name           = "appserver-template"
  machine_type   = "e2-medium"
  can_ip_forward = false
  tags           = ["foo", "bar"]

  disk {
    source_image = data.google_compute_image.my_image.self_link
    auto_delete  = true
    boot         = true
  }

  network_interface {
    network = "default"
  }

  scheduling {
    preemptible       = false
    automatic_restart = true
  }

  metadata = {
    gce-software-declaration = <<-EOF
    {
      "softwareRecipes": [{
        "name": "install-gce-service-proxy-agent",
        "desired_state": "INSTALLED",
        "installSteps": [{
          "scriptRun": {
            "script": "#! /bin/bash\nZONE=$(curl --silent http://metadata.google.internal/computeMetadata/v1/instance/zone -H Metadata-Flavor:Google | cut -d/ -f4 )\nexport SERVICE_PROXY_AGENT_DIRECTORY=$(mktemp -d)\nsudo gsutil cp   gs://gce-service-proxy-"$ZONE"/service-proxy-agent/releases/service-proxy-agent-0.2.tgz   "$SERVICE_PROXY_AGENT_DIRECTORY"   || sudo gsutil cp     gs://gce-service-proxy/service-proxy-agent/releases/service-proxy-agent-0.2.tgz     "$SERVICE_PROXY_AGENT_DIRECTORY"\nsudo tar -xzf "$SERVICE_PROXY_AGENT_DIRECTORY"/service-proxy-agent-0.2.tgz -C "$SERVICE_PROXY_AGENT_DIRECTORY"\n"$SERVICE_PROXY_AGENT_DIRECTORY"/service-proxy-agent/service-proxy-agent-bootstrap.sh"
          }
        }]
      }]
    }
    EOF
    gce-service-proxy        = <<-EOF
    {
      "api-version": "0.2",
      "proxy-spec": {
        "proxy-port": 15001,
        "network": "my-network",
        "tracing": "ON",
        "access-log": "/var/log/envoy/access.log"
      }
      "service": {
        "serving-ports": [80, 81]
      },
     "labels": {
       "app_name": "bookserver_app",
       "app_version": "STABLE"
      }
    }
    EOF
    enable-guest-attributes = "true"
    enable-osconfig         = "true"

  }

  service_account {
    email  = data.google_compute_default_service_account.default.email
    scopes = ["cloud-platform"]
  }

  labels = {
    gce-service-proxy = "on"
  }
}

Using with Instance Group Manager

Instance Templates cannot be updated after creation with the Google Cloud Platform API. In order to update an Instance Template, Terraform will destroy the existing resource and create a replacement. In order to effectively use an Instance Template resource with an Instance Group Manager resource, it's recommended to specify create_before_destroy in a lifecycle block. Either omit the Instance Template name attribute, or specify a partial name with name_prefix. Example:

resource "google_compute_instance_template" "instance_template" {
  name_prefix  = "instance-template-"
  machine_type = "e2-medium"
  region       = "us-central1"

  // boot disk
  disk {
    # ...
  }

  // networking
  network_interface {
    # ...
  }

  lifecycle {
    create_before_destroy = true
  }
}

resource "google_compute_instance_group_manager" "instance_group_manager" {
  name               = "instance-group-manager"
  instance_template  = google_compute_instance_template.instance_template.id
  base_instance_name = "instance-group-manager"
  zone               = "us-central1-f"
  target_size        = "1"
}

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.

Deploying the Latest Image

A common way to use instance templates and managed instance groups is to deploy the latest image in a family, usually the latest build of your application. There are two ways to do this in Terraform, and they have their pros and cons. The difference ends up being in how "latest" is interpreted. You can either deploy the latest image available when Terraform runs, or you can have each instance check what the latest image is when it's being created, either as part of a scaling event or being rebuilt by the instance group manager.

If you're not sure, we recommend deploying the latest image available when Terraform runs, because this means all the instances in your group will be based on the same image, always, and means that no upgrades or changes to your instances happen outside of a terraform apply. You can achieve this by using the google_compute_image data source, which will retrieve the latest image on every terraform apply, and will update the template to use that specific image:

data "google_compute_image" "my_image" {
  family  = "debian-11"
  project = "debian-cloud"
}

resource "google_compute_instance_template" "instance_template" {
  name_prefix  = "instance-template-"
  machine_type = "e2-medium"
  region       = "us-central1"

  // boot disk
  disk {
    source_image = data.google_compute_image.my_image.self_link
  }
}

To have instances update to the latest on every scaling event or instance re-creation, use the family as the image for the disk, and it will use GCP's default behavior, setting the image for the template to the family:

resource "google_compute_instance_template" "instance_template" {
  name_prefix  = "instance-template-"
  machine_type = "e2-medium"
  region       = "us-central1"

  // boot disk
  disk {
    source_image = "debian-cloud/debian-11"
  }
}

Argument Reference

Note that changing any field for this resource forces a new resource to be created.

The following arguments are supported:


The disk block supports:

The source_image_encryption_key block supports:

The source_snapshot_encryption_key block supports:

The disk_encryption_key block supports:

The network_interface block supports:

The access_config block supports:

The ipv6_access_config block supports:

The alias_ip_range block supports:

The service_account block supports:

The scheduling block supports:

The guest_accelerator block supports:

The node_affinities block supports:

The reservation_affinity block supports:

The specific_reservation block supports:

The shielded_instance_config block supports:

The confidential_instance_config block supports:

The network_performance_config block supports:

The advanced_machine_features block supports:

Attributes Reference

In addition to the arguments listed above, the following computed attributes are exported:

Timeouts

This resource provides the following Timeouts configuration options: configuration options:

Import

Instance templates can be imported using any of these accepted formats:

In Terraform v1.5.0 and later, use an import block to import instance templates using one of the formats above. For example:

import {
  id = "projects/{{project}}/global/instanceTemplates/{{name}}"
  to = google_compute_instance_template.default
}

When using the terraform import command, instance templates can be imported using one of the formats above. For example:

$ terraform import google_compute_instance_template.default projects/{{project}}/global/instanceTemplates/{{name}}
$ terraform import google_compute_instance_template.default {{project}}/{{name}}
$ terraform import google_compute_instance_template.default {{name}}