Terraform as a Service with Google Cloud's Infrastructure Manager

Somebody who likes to code
Search for a command to run...

Somebody who likes to code
No comments yet. Be the first to comment.
Google processes tens of thousands of code changes every day across a codebase of hundreds of millions of lines. The secret isn't magic tooling — it's a documented, principled approach to code review

Amazon Simple Notification Service (SNS) looks straightforward on the surface — publish a message, deliver it to subscribers — but the gap between a topic that "works in dev" and one that is productio

Amazon Simple Queue Service (SQS) is deceptively simple to get started with, but surprisingly easy to misconfigure in ways that cause silent message loss, runaway costs, duplicate processing storms, o

HTTP API is the right default choice for the majority of .NET serverless workloads. At 70% less cost than REST API, lower latency, and native JWT authorization, it covers most production requirements

AWS Lambda has become a cornerstone of modern serverless architectures, but writing a function that "just works" is very different from writing one that is performant, cost-effective, secure, and read

GCP (Google Cloud Platform) Infrastructure Manager is a fully managed infrastructure-as-code (IaC) service that allows us to provision, manage, and orchestrate Google Cloud resources using Terraform. It provides a managed way to use Terraform with GCP, eliminating the need for us to manage the state ourselves. Think of it as Terraform-as-a-Service living directly within our GCP project. Instead of running terraform apply on our environment and worrying about where to store the state file, we hand our Terraform code to Infrastructure Manager, and it handles the rest.
GCP Infrastructure Manager doesn't have direct charges. Instead, it charges for Cloud Build execution and Cloud Storage. Cloud Build includes 2,500 free build-minutes each month before charging begins and Cloud Storage has a free tier with 5 GB of standard storage per month.
Let's create a practical example that deploys a free-tier VM with NGINX exposed to the internet, executed locally using Infrastructure Manager.
Google Cloud CLI installed and authenticated.
We need to enable the Infrastructure Manager API, the Compute Engine API, and the Cloud Storage API:
gcloud services enable config.googleapis.com
gcloud services enable compute.googleapis.com
gcloud services enable storage.googleapis.com
Create a terraform/main.tf file with the following content:
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = ">= 4.34.0"
}
}
}
resource "google_compute_instance" "free_tier_vm" {
project = var.project_id
machine_type = "e2-micro"
zone = "us-central1-a"
name = "my-first-vm"
boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
}
}
network_interface {
network = "default"
access_config {}
}
tags = ["http-server"]
metadata = {
startup-script = file("${path.module}/startup-script.sh")
}
}
resource "google_compute_firewall" "allow_http" {
project = var.project_id
name = "allow-http-ingress"
network = "default"
allow {
protocol = "tcp"
ports = ["80"]
}
target_tags = ["http-server"]
source_ranges = ["0.0.0.0/0"]
}
variable "project_id" {
type = string
description = "The GCP project ID to deploy resources into."
}
output "vm_external_ip" {
description = "The external IP address of the web server VM."
value = google_compute_instance.free_tier_vm.network_interface[0].access_config[0].nat_ip
}
This Terraform script creates a basic web server using free-tier resources. Here's what it does:
google_compute_instance: Creates an e2-micro VM instance (free-tier eligible) deployed in us-central1-a (free-tier region) . The boot_disk block defines the main disk that contains the operating system (specified by the image property) used to start the VM instance. The network_interface block automatically assigns an internal (private) IP address in the default VPC network. The access_config block instructs GCP to assign an external (public) IP address. By default, this IP address is ephemeral (changes when VM restarts). The tags property is used by the firewall rule to identify the VM instance. The startup_script property defines a script that runs automatically when the VM starts up for the first time.
google_compute_firewall: Creates a rule named allow-http-ingress that opens TCP port 80 (HTTP) for incoming traffic, allowing access from anywhere on the internet (0.0.0.0/0). This rule applies only to instances tagged with http-server.
Create the terraform/startup-script.sh with the following content:
#!/bin/bash
set -e
echo "=== Startup script started at $(date) ==="
apt-get update -y
apt-get install -y nginx
systemctl start nginx
systemctl enable nginx
echo "=== Startup script completed at $(date) ==="
Windows line endings could produce errors. Ensure the file uses Unix line endings (
LF, notCRLF).
Infrastructure Manager requires a service account with specific IAM roles:
gcloud iam service-accounts create infra-manager-sa --display-name=infra-manager-sa --project=<MY_PROJECT_ID>
gcloud projects add-iam-policy-binding <MY_PROJECT_ID> --member="serviceAccount:infra-manager-sa@<MY_PROJECT_ID>.iam.gserviceaccount.com" --role="roles/admin"
Now, we can use the following command to deploy our VM:
gcloud infra-manager deployments apply my-first-deployment --location=us-central1 --local-source=./terraform --input-values=project_id=<MY_PROJECT_ID> --service-account=projects/<MY_PROJECT_ID>/serviceAccounts/infra-manager-sa@<MY_PROJECT_ID>.iam.gserviceaccount.com
After the command finishes, we can check the public IP of the VM with the following command:
gcloud compute instances describe my-first-vm --zone=us-central1-a --format="value(networkInterfaces[0].accessConfigs[0].natIP)"
To avoid any charges and clean up resources, run:
gcloud infra-manager deployments delete my-deployment --location=us-central1
The official documentation offers more details about the commands used.
You can find all the code here. Thanks, and happy coding.