Scaling Google Cloud Infrastructure with Reusable Terraform Modules
These articles are AI-generated summaries. Please check the original sources for full details.
Terraform Modules for Reusable GCP Infrastructure (With a Real VPC Module Example)
Terraform modules encapsulate infrastructure logic into discrete units comprising variables, outputs, and resources. By moving beyond copy-pasted code, engineers can manage VPCs, subnets, and firewalls through clean, input-driven interfaces.
Why This Matters
In high-scale engineering environments, manual infrastructure replication leads to configuration drift and increased operational overhead. Using generic modules that avoid hardcoded regions or CIDRs allows for composable architecture, while caution with authoritative IAM resources prevents accidental access revocation during automated deployments.
Key Insights
- A standard Terraform module requires a structure of variables.tf for inputs, outputs.tf for resource exposure, and main.tf for resource definition.
- Dynamic subnet creation is achieved using the for_each meta-argument to iterate over a list of subnet objects including CIDR and region data.
- Input validation within the variables.tf file, such as restricting routing_mode to REGIONAL or GLOBAL, catches configuration errors before deployment.
- Module versioning via Git tags (e.g., ?ref=v1.0.0) allows teams to pin specific versions, ensuring production stability while testing new changes in dev.
- Composable architecture is preferred over monolithic ‘platform modules’ by splitting logic into specialized components like modules/vpc and modules/cloud_sql.
Working Examples
Core logic for a reusable GCP VPC module using for_each for subnet management.
resource "google_compute_network" "this" { project = var.project_id name = var.vpc_name auto_create_subnetworks = false routing_mode = var.routing_mode } resource "google_compute_subnetwork" "this" { for_each = { for s in var.subnets : s.name => s } project = var.project_id name = each.value.name ip_cidr_range = each.value.cidr region = each.value.region network = google_compute_network.this.id private_ip_google_access = each.value.private_google_access }
Calling the VPC module from an environment-specific directory.
module "vpc" { source = "../../modules/vpc" project_id = var.project_id vpc_name = "dev-vpc" subnets = [{ name = "dev-us-central1-public", region = "us-central1", cidr = "10.10.0.0/24", private_google_access = true }] }
Practical Applications
- Use case: Standardizing networking across dev and prod by calling a central VPC module with different CIDR blocks. Pitfall: Hardcoding environment names or project IDs inside the module folder makes it non-reusable.
- Use case: Automated firewall management where rules are passed as a list of objects to the network module. Pitfall: Implementing authoritative IAM resources which can remove existing project permissions unexpectedly.
- Use case: Version-controlled infrastructure updates where the prod environment is pinned to a specific Git ref while dev uses the latest master. Pitfall: Neglecting to use version pins, leading to breaking changes in production when a shared module is updated.
References:
Continue reading
Next article
Optimizing API Architecture: Processing 1 Billion Requests for $40
Related Content
Mastering Terraform: Scaling Infrastructure as Code for Multi-Cloud Deployments
Terraform manages AWS, GCP, and 3000+ providers via HCL, enabling automated S3 and CloudFront deployments while eliminating manual console configuration errors.
Provisioning AWS Networking with Terraform: A Hands-on Infrastructure as Code Guide
Learn to build a production-ready AWS VPC using Terraform to automate networking with public and private subnets, supporting up to 65,536 addresses.
Terraform Modules: Refactoring Azure VM Deployments for Reusability
Refactor Azure VM deployments into reusable Terraform modules to reduce duplication and improve infrastructure consistency.