Terraform is an infrastructure as code tool that lets you provision and manage Google Cloud infrastructure with declarative configuration files. The Terraform provider for Google Cloud, the Google Cloud provider, lets you provision and manage Google Cloud resources, including Compute Engine. This article covers the end-to-end workflow for creating a Compute Engine VM instance with Terraform, the core google_compute_instance resource, and the Terraform Google Modules for creating instances from templates and instance templates.
Quickstart workflow for a VM instance
The official quickstart for creating a VM instance using Terraform walks through the complete lifecycle from project selection to connection and cleanup. The workflow starts in Cloud Shell, where an online terminal with the gcloud CLI and Terraform is already set up.
Roles required to select or create a project are documented in the quickstart. 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 requires the Project Creator role, roles/resourcemanager.projectCreator, which contains the resourcemanager.projects.create permission. Project creation uses the command:
gcloud projects create PROJECT_ID
Replace PROJECT_ID with a name for the Google Cloud project you are creating.
The configuration file that defines the Google Cloud resources you want to create is main.tf. This file describes the google_compute_instance resource, which is the Terraform resource for the Compute Engine VM instance.
Verify Terraform is available:
terraform
The output should be similar to:
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:
terraform init
The output should be similar to:
Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/google..
Initialize prepares your workspace so Terraform can apply your configuration.
Verify syntax and preview changes:
terraform plan
This command takes the following actions:
- Verifies that the syntax of
main.tfis correct - Shows a preview of the resources that will be created
The output should be similar to:
Plan: 1 to add, 0 to change, 0 to destroy. Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
Apply the configuration:
terraform apply
When prompted, enter yes. Terraform calls Google Cloud APIs to create the VM instance defined in the main.tf file. The output should be similar to:
Apply complete! Resources: 1 added, 0 changed, 0 destroyed
Connect to the VM instance:
gcloud compute ssh --zone=us-central1-a my-vm
Clean up:
terraform destroy
When prompted, enter yes. The output should be similar to:
Destroy complete! Resources: 1 destroyed.
To avoid incurring charges to your Google Cloud account for the resources used, delete the Google Cloud project with the resources.
Core googlecomputeinstance resource definition
Terraform has a declarative and configuration-oriented syntax, which you can use to describe the infrastructure that you want to provision in your Google Cloud project. After you author this configuration in one or more Terraform configuration files, you can use the Terraform CLI to apply this configuration to your Compute Engine resources.
The steps Terraform works through are:
- You describe the infrastructure you want to provision in a Terraform configuration file. You don't need to write code describing how to provision the infrastructure. Terraform provisions the infrastructure for you.
- You run the
terraform plancommand, which evaluates your configuration and generates an execution plan. You can review the plan and make changes as needed.
The quickstart example configures google_compute_instance with the following properties:
nameis set tomy-vmmachine_typeis set ton1-standard-1zoneis set tous-central1-aboot_disksets the boot disk for the instancenetwork_interfaceis set to use the default network in your Google Cloud project
The resource definition in main.tf is the authoritative description of the VM. The file defines the Google Cloud resources that you want to create.
The configuration pattern can be expressed as:
```hcl
resource "googlecomputeinstance" "vm" {
name = "my-vm"
machine_type = "n1-standard-1"
zone = "us-central1-a"
boot_disk {
# boot disk configuration
}
network_interface {
# default network
}
}
```
Resource property reference
| Property | Description | Example Value |
|---|---|---|
| name | Instance name | my-vm |
| machine_type | Machine type for the instance | n1-standard-1 |
| zone | Zone for placement | us-central1-a |
| boot_disk | Boot disk for the instance | configured |
| network_interface | Network interface, default network | default network |
Terraform Google Modules for compute instances
HashiCorp Terraform is an infrastructure-as-code tool that lets you provision and manage cloud infrastructure. Terraform provides plugins called providers that let you interact with cloud providers and other APIs. You can use the Terraform provider for Google Cloud to provision and manage Google Cloud resources, including Compute Engine.
This page introduces you to using Terraform with Compute Engine, including an introduction to how Terraform works and some resources to help you get started using Terraform with Google Cloud. You'll also find links to Terraform reference docs for Compute Engine, code examples, and guides for using Terraform to provision Compute Engine resources.
Module for compute instances from template
This module is used to create compute instances, and only compute instances, using google_compute_instance_from_template, with no instance groups.
Name, description, type, default and required values for key inputs are documented.
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| access_config | Access configurations, i.e. IPs via which the VM instance can be accessed via the Internet. | list(object({ | [] | no |
| addhostnamesuffix | Adds a suffix to the hostname | bool | true | no |
| aliasipranges | Optional An array of alias IP ranges for this network interface. Can only be specified for network interfaces on subnet-mode networks. | list(object({ | [] | no |
| deletion_protection | Enable deletion protection on this instance. Note: you must disable deletion protection before removing the resource, or the instance cannot be deleted and the Terraform run will not complete successfully. | bool | false | no |
| hostname | Hostname of instances | string | "" | no |
| hostnamesuffixseparator | Separator character to compose hostname when addhostnamesuffix is set to true. | string | "-" | no |
| instance_template | Instance template self_link used to create compute instances | string | n/a | yes |
| ipv6accessconfig | IPv6 access configurations. Currently a max of 1 IPv6 access configuration is supported. If not specified, the instance will have no external IPv6 Internet access |
The module accepts an instance template self_link to create compute instances from that template. Access configurations control IPs via which the VM instance can be accessed via the Internet. Deletion protection defaults to false and must be disabled before removal to allow instance deletion. Hostname suffix addition defaults to true with separator "-".
Instance template submodule
This submodule allows you to create a google_compute_instance_template resource, which is used as the basis for the other instance, managed, and unmanaged instance groups submodules.
Name, description, type, default and required values for key inputs are documented.
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| access_config | Access configurations, i.e. IPs via which the VM instance can be accessed via the Internet. | list(object({ | [] | no |
| additional_disks | List of maps of additional disks. See documentation for disk_name | list(object({ | [] | no |
| additional_networks | Additional network interface details for GCE, if any. | list(object({ | [] | no |
| additionalnetworksstr | Additional network interface details for GCE provided as a JSON-encoded string. Expected format: '[{"network":"vpc-1","subnetwork":"sub-1"}]' | string | "[]" | no |
| aliasiprange | An array of alias IP ranges for this network interface. Can only be specified for network interfaces on subnet-mode networks. | |||
| service_account | Service account to attach to the instance | object({ | null | no |
| serviceaccountproject_roles | Roles to grant to the newly created cloud run SA in specified project. Should be used with createserviceaccount set to true and no input for service_account | list(string) | [] | no |
| shieldedinstanceconfig | Not used unless enableshieldedvm is true. Shielded VM configuration for the instance. | object({ | { | no |
| source_image | Source disk image. If neither sourceimage nor sourceimage_family is specified, defaults to the latest public Rocky Linux 9 optimized for GCP image. | string | "" | no |
| sourceimagefamily | Source image family. If neither sourceimage nor sourceimage_family is specified, defaults to the latest public Rocky Linux 9 optimized for GCP image. | string | "rocky-linux-9-optimized-gcp" | no |
| sourceimageproject | Project where the source image comes from. The default project contains Rocky Linux images. | string | "rocky-linux-cloud" | no |
| spot | Provision a SPOT instance | bool | false | no |
| spotinstancetermination_action | Action to take when Compute Engine preempts a Spot VM |
The instance template defaults are significant for provisioning. The source image family defaults to rocky-linux-9-optimized-gcp. The source image project defaults to rocky-linux-cloud. If neither source_image nor source_image_family is specified, defaults to the latest public Rocky Linux 9 optimized for GCP image.
Spot provisioning defaults to false. Additional disks, additional networks, and alias IP ranges can be specified to customize the template. Service account attachment is optional and can be configured with project roles.
Configuration lifecycle and operational notes
Working with Terraform and Compute Engine follows a repeatable cycle. You author the configuration, run terraform plan to validate syntax and preview changes, then terraform apply to create or update infrastructure. The provider calls Google Cloud APIs to realize the declared state.
The quickstart demonstrates connecting after creation with gcloud compute ssh --zone=us-central1-a my-vm. Cleanup uses terraform destroy to remove previously-created infrastructure.
When using the instance template module, modifying the list will cause the instance to recreate. Currently a max of 1 resource policy is supported. Deletion protection must be disabled before removal, otherwise the instance cannot be deleted and the Terraform run will not complete successfully.
The module for compute instances from template has no instance groups, which simplifies single-instance provisioning. For fleet scenarios, the instance template submodule provides the basis for managed and unmanaged instance groups.
Conclusion
Terraform provisioning of Google Compute Engine VM instances combines declarative configuration with provider-driven API calls to deliver repeatable infrastructure. The quickstart pattern of creating main.tf with a google_compute_instance resource, initializing with terraform init, planning with terraform plan, and applying with terraform apply provides a complete lifecycle. The example configuration uses my-vm with n1-standard-1 machine type in us-central1-a, with boot disk and default network interface.
Module-based workflows offer additional abstraction. The compute instance from template module centralizes inputs such as access_config, add_hostname_suffix, deletion_protection, hostname, hostname_suffix_separator, and instance_template, enabling reuse across environments. The instance template submodule governs the template definition with defaults for Rocky Linux 9 optimized for GCP images, source image family rocky-linux-9-optimized-gcp, source image project rocky-linux-cloud, and optional spot provisioning.
Operational best practices include verifying Terraform availability, reviewing plans before apply, and using terraform destroy for cleanup to avoid charges. The combination of direct resource definitions and modular templates gives teams both fine-grained control and reusable patterns for Compute Engine VM provisioning with Terraform.
Sources
- https://docs.cloud.google.com/docs/terraform/create-vm-instance
- https://github.com/terraform-google-modules/terraform-google-vm/blob/master/modules/compute_instance/README.md
- https://github.com/terraform-google-modules/terraform-google-vm/blob/master/modules/instance_template/README.md
- https://docs.cloud.google.com/compute/docs/terraform