GCP for DevOps — Terraform GCP Basics

2 minute read

Terraform GCP Basics

Terraform uses the Google provider (hashicorp/google) to create and manage GCP resources declaratively.

Install Terraform

# macOS
$ brew install terraform

# Verify
$ terraform version

Terraform v1.7.0

Authentication Methods

Method Use Case Command
Application Default Credentials (ADC) Local development gcloud auth application-default login
Service Account Key CI/CD pipelines GOOGLE_APPLICATION_CREDENTIALS=key.json
Workload Identity Federation GitHub Actions, GitLab CI OIDC token exchange
# ADC — simplest for local dev
$ gcloud auth application-default login

# Service Account (CI/CD)
$ export GOOGLE_APPLICATION_CREDENTIALS="/path/to/sa-key.json"

First Terraform Configuration

# main.tf
terraform {
  required_version = ">= 1.5"

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

provider "google" {
  project = "my-project-id"
  region  = "us-central1"
  zone    = "us-central1-a"
}

# Create a VPC
resource "google_compute_network" "vpc" {
  name                    = "my-vpc"
  auto_create_subnetworks = false
}

# Create a subnet
resource "google_compute_subnetwork" "subnet" {
  name          = "my-subnet"
  ip_cidr_range = "10.0.1.0/24"
  region        = "us-central1"
  network       = google_compute_network.vpc.id
}

# Create a VM
resource "google_compute_instance" "vm" {
  name         = "my-vm"
  machine_type = "e2-micro"
  zone         = "us-central1-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-12"
      size  = 20
    }
  }

  network_interface {
    subnetwork = google_compute_subnetwork.subnet.id
    access_config {}  # Ephemeral public IP
  }

  tags = ["http-server"]
}

Terraform Workflow

# Initialize (download providers)
$ terraform init

Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/google versions matching "~> 5.0"...
- Installing hashicorp/google v5.20.0...
Terraform has been successfully initialized!

# Preview changes
$ terraform plan

Plan: 3 to add, 0 to change, 0 to destroy.

# Apply changes
$ terraform apply

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

# View current state
$ terraform show

# Destroy all resources
$ terraform destroy

Variables

# variables.tf
variable "project_id" {
  description = "GCP project ID"
  type        = string
}

variable "region" {
  description = "GCP region"
  type        = string
  default     = "us-central1"
}

variable "environment" {
  description = "Environment name"
  type        = string
  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "Environment must be dev, staging, or prod."
  }
}
# terraform.tfvars
project_id  = "my-project-id"
region      = "us-central1"
environment = "dev"

Outputs

# outputs.tf
output "vm_ip" {
  description = "External IP of the VM"
  value       = google_compute_instance.vm.network_interface[0].access_config[0].nat_ip
}

output "vpc_id" {
  description = "VPC network ID"
  value       = google_compute_network.vpc.id
}
$ terraform output vm_ip

"34.123.45.67"

Data Sources

Read existing resources without managing them.

# Look up the default compute service account
data "google_compute_default_service_account" "default" {}

# Look up a project
data "google_project" "current" {}

# Use data source values
output "project_number" {
  value = data.google_project.current.number
}

Common Mistakes

Mistake Why It’s Wrong Fix
Hardcoding project ID in provider Can’t reuse across projects Use variables
No version constraints Breaking changes on provider update Pin with ~> 5.0
Using SA keys in production Security risk, rotation burden Use Workload Identity Federation
No .gitignore for Terraform State and secrets committed Ignore .terraform/, *.tfstate*
Running apply without plan Unexpected changes Always review plan output

Quick Reference

Command Description
terraform init Initialize and download providers
terraform plan Preview changes
terraform apply Apply changes
terraform destroy Destroy all resources
terraform output Show output values
terraform fmt Format HCL files
terraform validate Validate configuration

Next → Google Provider

Updated: