Terraform GCP Compute Instance: Provisioning, Templates and Safe Updates

Terraform provides an infrastructure as code approach for building, changing, and managing Google Cloud Compute Engine VM instances and the supporting networking resources required to run them. The Google Cloud provider for Terraform lets you provision and manage Google Cloud infrastructure with declarative configuration. A typical workflow begins with authentication to Google Cloud and a VPC network, then writing and validating Terraform configuration, initializing a working directory, and planning and applying changes to create infrastructure. The same workflow is used to change infrastructure by adding a Google Compute Engine VM instance to a VPC by referencing the VPC in its configuration using arguments, modifying the instance by adding tags, and implementing destructive changes. Destroying Google Cloud infrastructure managed by Terraform follows plan evaluation and confirmation.

Minimum Configuration for Compute Instance with VPC and Firewall

A sample Terraform configuration for creating a compute instance and its VPC network and firewall rules in GCP represents the minimum configuration to demonstrate the Continuous Deployment pipeline of any Web application on GCP compute instances using Docker and GitHub workflows.

Authentication is established using the gcloud CLI. The commands used are:

  • gcloud init
  • gcloud auth application-default login

The gcp_config.sh script is used for creating the required resources and enabling minimum permissions and services to support the repository needs. The script creates a GCS bucket and IAM service account. Run the following command to process with the configuration of your project:

  • ./config.sh

Note that this configuration shell script applies the following operations. You can follow the steps below to config the GCP project instead of using the shell script. Bucket name must be globally unique.

Creating a VM Instance with Terraform

A quickstart for creating a VM instance using Terraform teaches how to use Terraform to create a Compute Engine Virtual Machine instance and connect to that VM instance. Hashicorp Terraform is an Infrastructure as code tool that lets you provision and manage cloud infrastructure. Terraform provider for Google Cloud lets you provision and manage Google Cloud infrastructure.

Before you begin, an online terminal with the gcloud CLI and Terraform already set up can be activated with Cloud Shell. Roles required to select or create a project include:

  • Select a project: Selecting a project doesn't require a specific IAM role, you can select any project that you've been granted a role on
  • Create a project: To create a project, you need the Project Creator role, roles/resourcemanager.projectCreator, which contains the resourcemanager.projects.create permission

Create a Google Cloud project with:

gcloud projects create PROJECT_ID

Replace PROJECT_ID with a name for the Google Cloud project you are creating.

This file defines the Google Cloud resources that you want to create. The file main.tf can be inspected with cat main.tf. The output is similar to the following.

This file describes the googlecomputeinstance resource, which is the Terraform resource for the Compute Engine VM instance. googlecomputeinstance is configured to have the following properties:

  • name is set to my-vm
  • machine_type is set to n1-standard-1
  • zone is set to us-central1-a
  • boot_disk sets the boot disk for the instance
  • network_interface is set to use the default network in your Google Cloud project

Create the Compute Engine VM instance. In Cloud Shell, run the following command to verify that Terraform is available:

terraform

The output should be similar to the following:

Usage: terraform [global options] <subcommand> [args] The available commands for execution are listed below. The primary workflow commands are given first, followed by less common or more advanced commands. Main commands: init Prepare your working directory for other commands validate Check whether the configuration is valid plan Show changes required by the current configuration apply Create or update infrastructure destroy Destroy previously-created infrastructure

Initialize Terraform by running the following command. This command prepares your workspace so Terraform can apply your configuration.

terraform init

The output should be similar to the following:

Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/google..

The core resource properties for a basic VM are summarized below.

| Property | Example Value | Description |
| name | my-vm | Identifier for the instance |
| machinetype | n1-standard-1 | Compute Engine machine type |
| zone | us-central1-a | Location zone for the instance |
| boot
disk | configured | Boot disk for the instance |
| network_interface | default network | Network interface attachment |

Terraform Workflow for GCP

Install Terraform on Mac, Linux, or Windows by downloading the binary or using a package manager such as Homebrew or Chocolatey. Then create a Docker container locally by following a quick-start tutorial to check that Terraform installed correctly.

Build infrastructure tasks include:

  • Authenticate to Google Cloud and create a VPC network
  • Write and validate Terraform configuration
  • Initialize a configuration directory
  • Plan and apply a configuration to create infrastructure

Change infrastructure tasks include:

  • Add a Google Compute Engine VM instance to a VPC by referencing the VPC in its configuration using arguments
  • Modify the instance by adding tags
  • Implement a destructive change

Destroy infrastructure tasks include:

  • Destroy Google Cloud infrastructure managed by Terraform
  • Evaluate the plan and confirm the destruction

Define input variables tasks include:

  • Declare your GCP credential location, infrastructure region and zone as variables
  • Reference these variables in Terraform configuration
  • Define them using command line flags, environment variables, .tfvars files or default values

Query data with output values tasks include:

  • Output the public IP of your Google Cloud instance using output variables
  • Read about using outputs to query specific data from Terraform state

| Command | Purpose |
| terraform init | Prepare working directory for other commands |
| terraform validate | Check whether configuration is valid |
| terraform plan | Show changes required by current configuration |
| terraform apply | Create or update infrastructure |
| terraform destroy | Destroy previously-created infrastructure |

Instance Templates and Immutable Behavior

Since instance templates are immutable in GCP, Terraform cannot update them in place. It has to destroy the old one and create a new one, which will fail if a MIG is still using it.

Using nameprefix for safe updates is the solution. Combined with the createbefore_destroy lifecycle rule, safe updates are achieved.

An instance template with safe update strategy is defined as follows:

resource "google_compute_instance_template" "web_safe" { name_prefix = "web-server-" machine_type = "e2-medium" region = var.region # This is critical - create the new template before destroying the old one lifecycle { create_before_destroy = true } disk { source_image = "debian-cloud/debian-12" auto_delete = true boot = true disk_size_gb = 20 disk_type = "pd-balanced" } network_interface { network = google_compute_network.main.id subnetwork = google_compute_subnetwork.main.id } metadata = { enable-oslogin = "TRUE" } tags = ["http-server"] }

With name_prefix, Terraform appends a random suffix to each template name, like web-server-abc123. This is not optional for production use. Without it, template updates will fail if anything references the old template.

| Attribute | Value in Example | Role |
| nameprefix | web-server- | Prefix for template name with random suffix |
| machine
type | e2-medium | Instance machine type |
| region | var.region | Deployment region |
| lifecycle.createbeforedestroy | true | Create new before destroying old |
| disk.sourceimage | debian-cloud/debian-12 | Boot image |
| disk.disk
sizegb | 20 | Boot disk size |
| disk.disk
type | pd-balanced | Disk type |
| tags | http-server | Network tag |

Best Practices for Production Instance Templates

Use custom service accounts. Never use the default Compute Engine service account in production. Create a dedicated service account with only the permissions your application needs.

Enable Shielded VM features. Secure boot, vTPM, and integrity monitoring add security with no performance cost.

Keep startup scripts in separate files. For anything beyond a few lines, use file() to load scripts from the filesystem. This keeps your Terraform code readable and lets you test scripts independently.

Use labels consistently. Labels are how you track costs, filter resources, and apply policies. Standardize on a labeling scheme across your team.

Instance templates are a foundational piece of GCP infrastructure. They are simple on the surface but have enough configuration options to handle everything from basic web servers to GPU-equipped ML workers. The key things to remember are: use name_prefix for safe updates, keep instances private when possible, and use dedicated service accounts.

Module Building Blocks and API Requirements

This is a collection of opinionated submodules that can be used as building blocks to provision VMs in GCP.

This module is meant for use with Terraform 0.13+ and tested using Terraform 1.0+. If you find incompatibilities using Terraform >=0.13, please open an issue. If you haven't upgraded and need a Terraform 0.12.x-compatible version of this module, the last released version intended for Terraform 0.12.x is v5.1.0.

Examples of how to use these modules can be found in the examples folder.

The following APIs must be enabled on your project:

  • compute.googleapis.com
  • iam.googleapis.com

See also the project_services module, optional.

distributionpolicyzones cannot be changed during use. If you have changed them yourself or used to have a default value, then you'll have to force recreate a MIG group yourself.

For running the integration test cases, please refer to the CONTRIBUTING documentation. The service account used to execute tests for this module should have the following roles.

| Requirement | Detail |
| Terraform version | 0.13+ supported, tested on 1.0+ |
| Terraform 0.12.x version | v5.1.0 |
| Required APIs | compute.googleapis.com, iam.googleapis.com |
| Immutable field | distributionpolicyzones |

Conclusion

Terraform GCP compute instance work spans from a minimal sample configuration that creates a compute instance with its VPC network and firewall rules, through authentication with gcloud init and gcloud auth application-default login, to project bootstrapping with gcpconfig.sh and ./config.sh where bucket name must be globally unique. The core VM definition uses googlecomputeinstance with properties such as name set to my-vm, machinetype set to n1-standard-1, zone set to us-central1-a, bootdisk and networkinterface set to use the default network. Initialization with terraform init and the primary commands init, validate, plan, apply, destroy form the operational loop for building, changing and destroying infrastructure.

Instance templates introduce immutability constraints in GCP. Updates require destruction and recreation, which fails if a Managed Instance Group still references the old template. Safe updates rely on nameprefix combined with lifecycle createbeforedestroy = true, as demonstrated by the websafe template with machinetype e2-medium, region var.region, disk sourceimage debian-cloud/debian-12, disksizegb 20, disktype pd-balanced, networkinterface referencing googlecomputenetwork.main.id and googlecomputesubnetwork.main.id, metadata enable-oslogin TRUE, and tags http-server. Production hardening is achieved by using custom service accounts instead of the default Compute Engine service account, enabling Shielded VM features including secure boot, vTPM and integrity monitoring, keeping startup scripts in separate files loaded with file(), and applying consistent labels for cost tracking and policy enforcement.

Module building blocks provide opinionated submodules for VM provisioning, require Terraform 0.13+ with v5.1.0 being the last 0.12.x release, mandate enabling compute.googleapis.com and iam.googleapis.com, and highlight that distributionpolicyzones cannot be changed during use. Together these patterns give a complete path from initial VM creation to safe template evolution and scalable instance group usage.

Sources

  1. github.com/warestack/terraform-gcp-compute-instance
  2. oneuptime.com/blog/post/2026-02-23-how-to-create-gcp-instance-templates-with-terraform/view
  3. docs.cloud.google.com/docs/terraform/create-vm-instance
  4. github.com/terraform-google-modules/terraform-google-vm
  5. developer.hashicorp.com/terraform/tutorials/gcp-get-started

Related Posts