Photo by Eric Er on Unsplash

On this page

This chapter follows Infrastructure as Code with Terraform. You need a GCP project with billing enabled, the Google Cloud SDK (gcloud), and Terraform 1.x installed.

Prepare the workstation

Install Terraform from developer.hashicorp.com/terraform/downloads or your package manager. Confirm the binary:

Terminal window
terraform version

Log in for Application Default Credentials and set your project:

Terminal window
gcloud auth application-default login
gcloud config set project YOUR_PROJECT_ID

Enable APIs Terraform will call (one-time per project):

Terminal window
gcloud services enable storage.googleapis.com compute.googleapis.com

Create a working directory for this tutorial, for example ~/terraform-gcp-intro.

Configure providers and backend (local state)

Create versions.tf to pin Terraform and the Google provider:

versions.tf
terraform {
required_version = ">= 1.5.0"
required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
provider "google" {
project = var.project_id
region = var.region
}

For learning, state stays local in terraform.tfstate. Before team use, move state to a GCS backend as described in State data in Terraform.

Add variables.tf:

variables.tf
variable "project_id" {
type = string
description = "GCP project ID"
}
variable "region" {
type = string
default = "europe-west1"
description = "Default region for regional resources"
}
variable "bucket_name" {
type = string
description = "Globally unique GCS bucket name"
}

Create terraform.tfvars (do not commit secrets here; project id and bucket name are fine):

terraform.tfvars
project_id = "YOUR_PROJECT_ID"
bucket_name = "YOUR_UNIQUE_BUCKET_NAME"

Create a Cloud Storage bucket

Add main.tf with a single bucket:

main.tf
resource "google_storage_bucket" "tutorial" {
name = var.bucket_name
location = var.region
uniform_bucket_level_access = true
force_destroy = true
}

Add outputs.tf:

outputs.tf
output "bucket_url" {
value = google_storage_bucket.tutorial.url
description = "Base URL of the tutorial bucket"
}

Initialize and apply:

Terminal window
cd ~/terraform-gcp-intro
terraform init
terraform fmt -recursive
terraform validate
terraform plan
terraform apply

Open the bucket URL from terraform output bucket_url or verify in the Cloud Console. State now records the bucket resource id.

Add a VPC and a small VM

Extend main.tf with networking and a minimal instance:

main.tf
resource "google_storage_bucket" "tutorial" {
name = var.bucket_name
location = var.region
uniform_bucket_level_access = true
force_destroy = true
}
resource "google_compute_network" "vpc" {
name = "terraform-tutorial-vpc"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "subnet" {
name = "terraform-tutorial-subnet"
ip_cidr_range = "10.0.1.0/24"
region = var.region
network = google_compute_network.vpc.id
}
resource "google_compute_instance" "vm" {
name = "terraform-tutorial-vm"
machine_type = "e2-micro"
zone = "${var.region}-b"
boot_disk {
initialize_params {
image = "debian-cloud/debian-12"
}
}
network_interface {
network = google_compute_network.vpc.id
subnetwork = google_compute_subnetwork.subnet.id
}
tags = ["terraform-tutorial"]
}

Run plan again. Terraform should propose the network, subnet, and VM without recreating the bucket unless you changed it:

Terminal window
terraform plan
terraform apply

Inspect resources in the console or with gcloud compute instances list.

Clean up

When you are finished experimenting, destroy managed resources:

Terminal window
terraform destroy

Confirm when prompted. force_destroy = true on the bucket allows deletion even if objects exist—appropriate for a sandbox, not for production data stores.

Next: HCL structure in Terraform explains blocks, expressions, and meta-arguments in depth.

Search articles

Type a word to search published articles.

Open the search page