Terraform Pipeline

Infrastructure as Code — Azure · AWS · GCP

Concept

Terraform is the universal IaC tool across all three clouds. Same HCL syntax regardless of provider, but state management, CI/CD integration, and authentication patterns differ.

State Backend
Azure Storage Account (blob)
S3 + DynamoDB (locking)
GCS Bucket (object versioning)
State Locking
Blob lease (automatic)
DynamoDB table
GCS object lock (automatic)
Auth
az login / Service Principal (ARM_*)
AWS CLI profile / IAM Role (AWS_*)
gcloud auth / Service Account (GOOGLE_CREDENTIALS)
Provider
azurerm
aws
google / google-beta

Terraform GCS Backend

# backend.tf
terraform {
  backend "gcs" {
    bucket = "tfstate-prod-bucket"
    prefix = "gke-cluster"
  }
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 5.0"
    }
  }
}

GitHub Actions Terraform CI/CD

name: Terraform CI/CD
on:
  pull_request: { paths: ["terraform/**"] }
  push: { branches: [main], paths: ["terraform/**"] }

jobs:
  terraform:
    runs-on: ubuntu-latest
    permissions: { id-token: write, contents: read, pull-requests: write }
    steps:
    - uses: actions/checkout@v4
    - uses: hashicorp/setup-terraform@v3
    - uses: google-github-actions/auth@v2
      with:
        workload_identity_provider: ${{ vars.WIF_PROVIDER }}
        service_account: ${{ vars.TF_SA }}
    - run: terraform fmt -check -recursive
    - run: terraform init
    - run: terraform validate
    - run: terraform plan -out=tfplan -input=false
    - run: terraform apply -auto-approve tfplan
      if: github.ref == "refs/heads/main"

Backend Comparison

○ Azure — Azure State

terraform {
  backend "azurerm" {
    storage_account_name = "tfstate"
    container_name = "tfstate"
    key = "prod.tfstate"
  }
}

Blob lease = automatic state locking.

○ AWS — AWS State

terraform {
  backend "s3" {
    bucket = "tfstate-prod"
    key = "env:/terraform.tfstate"
    region = "us-east-1"
    dynamodb_table = "tf-lock"
  }
}

Requires separate DynamoDB table for locking.

○ GCP — GCP State

terraform {
  backend "gcs" {
    bucket = "tfstate-prod"
    prefix = "gke-cluster"
  }
}

Object versioning + auto-locking via GCS.