Connect Cloud Run Services to VPC via Terraform
Introduction
In this guide, we'll walk through setting up two Cloud Run services - a public frontend and a private backend - using Terraform. We'll use Google Artifact Registry to store our Docker images. This setup demonstrates how to create a secure, scalable microservices architecture on Google Cloud Platform.
Prerequisites
A Google Cloud Platform account
gcloud
CLI installed and configuredTerraform installed
Docker installed
Git installed
Getting Started
Clone my demo repository:
git clone git@github.com:finnng/demo-cloud-run-vpc.git cd demo-cloud-run-vpc
Set up your Google Cloud project:
export PROJECT_ID=your-project-id gcloud config set project $PROJECT_ID
Enable necessary APIs:
gcloud services enable run.googleapis.com artifactregistry.googleapis.com compute.googleapis.com
Create a Google Artifact Registry repository:
gcloud artifacts repositories create cloud-run-demo --repository-format=docker --location=us-central1
Building and Pushing Docker Images
Build and push the backend image:
cd backend docker build --platform linux/amd64 -t us-central1-docker.pkg.dev/$PROJECT_ID/cloud-run-demo/backend:v1 . docker push us-central1-docker.pkg.dev/$PROJECT_ID/cloud-run-demo/backend:v1 cd ..
Build and push the frontend image:
cd frontend docker build --platform linux/amd64 -t us-central1-docker.pkg.dev/$PROJECT_ID/cloud-run-demo/frontend:v1 . docker push us-central1-docker.pkg.dev/$PROJECT_ID/cloud-run-demo/frontend:v1 cd ..
--platform linux/amd64
Especially when you are using Mac M1 chip.Configuring Terraform
Update
terraform.tfvars
with your project details:project_id = "your-project-id" region = "us-central1" frontend_image = "us-central1-docker.pkg.dev/your-project-id/cloud-run-demo/frontend:v1" backend_image = "us-central1-docker.pkg.dev/your-project-id/cloud-run-demo/backend:v1"
Initialize Terraform:
terraform init
Plan and apply the Terraform configuration:
terraform plan terraform apply
Understanding the Configuration
Let's look at some key parts of our Terraform configuration:
VPC and Connector Setup
resource "google_compute_network" "vpc_network" {
name = "cloud-run-network"
auto_create_subnetworks = false
}
resource "google_vpc_access_connector" "connector" {
name = "vpc-con"
ip_cidr_range = "10.8.0.0/28"
network = google_compute_network.vpc_network.name
region = var.region
}
This creates a VPC network and a connector, allowing our Cloud Run services to communicate securely.
Backend Service
resource "google_cloud_run_v2_service" "backend" {
name = "backend"
location = var.region
template {
containers {
image = var.backend_image
}
service_account = google_service_account.demo_backend_sa.email
vpc_access {
connector = google_vpc_access_connector.connector.id
egress = "PRIVATE_RANGES_ONLY"
}
}
ingress = "INGRESS_TRAFFIC_INTERNAL_ONLY"
}
Note the egress = "PRIVATE_RANGES_ONLY"
setting, which allows the backend to make external API calls while maintaining security.
Frontend Service
resource "google_cloud_run_v2_service" "frontend" {
name = "frontend"
location = var.region
template {
containers {
image = var.frontend_image
env {
name = "BACKEND_URL"
value = google_cloud_run_v2_service.backend.uri
}
}
service_account = google_service_account.demo_frontend_sa.email
vpc_access {
connector = google_vpc_access_connector.connector.id
egress = "ALL_TRAFFIC"
}
}
}
The frontend service is configured to access the backend securely through the VPC connector.
Testing the Setup
After applying the Terraform configuration, you can test your setup:
Get the URLs:
terraform output frontend_url terraform output backend_url
Open the URL in a web browser. You should see the frontend HTML, that means the frontend is publicly access.
To verify the backend is private, try accessing its URL directly (you can find it in the GCP Console). It should not be publicly accessible.
Now try to let call https://{frontend_url}/request-backend. This request is call to backend and backend make an external call to https://example.com and return the html. You should see the website content of example.com
Cleaning Up
To avoid incurring charges, remember to destroy the resources when you're done:
terraform destroy
Conclusion
This guide demonstrates how to set up a secure microservices architecture using Cloud Run and Terraform. By keeping the backend private and allowing the frontend to communicate with it through a VPC, we've created a scalable and secure setup.
Remember to always consider security best practices, especially in production environments. Regularly review and update your configurations to maintain cloud security standards.
Happy coding, and enjoy exploring Cloud Run and Terraform!
Subscribe to my newsletter
Read articles from Nguyen Engineer directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Nguyen Engineer
Nguyen Engineer
👋 Hi, I’m Nguyen, or you can call me Finn 💾 Vimmer ❤️ Gopher 📍I'm based in Da nang, Vietnam ⚙️ I love working with Go and Typescript ⚙️ I love both building distributed systems and the artistry of creating a single binary that efficiently uses minimal resources to accomplish as much as possible.