Terraform and OpenTofu on Google Cloud: Getting Started with the Google Provider

· 1 min read · Terraform & OpenTofu Tutorials

Google Cloud with Terraform #

Terraform and OpenTofu manage Google Cloud with the google provider. The workflow is the same as for AWS and Azure. Google Cloud organizes everything in projects.

Authentication #

Install the gcloud CLI and create application default credentials:

$ gcloud auth login
$ gcloud auth application-default login
$ gcloud config set project my-project-id

In CI/CD use workload identity federation with OIDC (the equivalent of OIDC with AWS), not downloaded service account keys.

Provider #

providers.tf
terraform {
  required_version = ">= 1.6"

  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 6.0"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
}

variable "project_id" {
  type = string
}

variable "region" {
  type    = string
  default = "europe-west1"
}

Enable the APIs #

Each Google Cloud service must be enabled in the project before use. Do it with Terraform so that the configuration is complete:

apis.tf
resource "google_project_service" "apis" {
  for_each = toset([
    "compute.googleapis.com",
    "storage.googleapis.com",
  ])

  service            = each.key
  disable_on_destroy = false
}

This uses for_each. Make other resources depend on it (depends_on = [google_project_service.apis]) to avoid errors on the first apply.

A VPC network and a subnet #

network.tf
resource "google_compute_network" "main" {
  name                    = "ditwl-demo"
  auto_create_subnetworks = false

  depends_on = [google_project_service.apis]
}

resource "google_compute_subnetwork" "private" {
  name                     = "ditwl-demo-private"
  region                   = var.region
  network                  = google_compute_network.main.id
  ip_cidr_range            = "10.0.1.0/24"
  private_ip_google_access = true
}

resource "google_compute_firewall" "ssh_iap" {
  name    = "ditwl-demo-allow-ssh-iap"
  network = google_compute_network.main.name

  allow {
    protocol = "tcp"
    ports    = ["22"]
  }

  source_ranges = ["35.235.240.0/20"] # Identity-Aware Proxy range
}

In Google Cloud a VPC network is global, and subnets are regional. Firewall rules apply at the network level and use tags or service accounts instead of security groups attached to instances.

A Cloud Storage bucket #

storage.tf
resource "google_storage_bucket" "data" {
  name                        = "${var.project_id}-ditwl-data"
  location                    = var.region
  uniform_bucket_level_access = true
  public_access_prevention    = "enforced"

  versioning {
    enabled = true
  }

  lifecycle_rule {
    condition {
      age = 90
    }
    action {
      type          = "SetStorageClass"
      storage_class = "NEARLINE"
    }
  }

  depends_on = [google_project_service.apis]
}

Remote state in GCS #

backend.tf
terraform {
  backend "gcs" {
    bucket = "my-project-tfstate"
    prefix = "demo"
  }
}

The bucket must exist before init and should have versioning enabled. GCS provides locking. See backends.

Run it #

$ tofu init
$ tofu apply -var project_id=my-project-id
$ tofu destroy -var project_id=my-project-id

Compare with AWS #

AWS Google Cloud
Account / Organizations Project / Folders and organization
VPC (regional) VPC network (global)
EC2 Compute Engine
S3 Cloud Storage
IAM role IAM role binding and service accounts
KMS Cloud KMS
EKS GKE
Lambda Cloud Functions / Cloud Run

Production-ready modules are in the Cloud Foundation Toolkit. Read next project structure and best practices.

#Terraform #OpenTofu #Gcp