Skip to content

Instantly share code, notes, and snippets.

@imjasonh
Last active October 28, 2021 05:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save imjasonh/026aab65d99506b2f0a59e5196944b00 to your computer and use it in GitHub Desktop.
Save imjasonh/026aab65d99506b2f0a59e5196944b00 to your computer and use it in GitHub Desktop.
Terraform config for GCPing

Setup

Prerequisites: Install Terraform and ko

$ terraform init
$ terraform apply -var image=$(KO_DOCKER_REPO=gcr.io/gcping-1369 ko publish ./cmd/ping/)
////// providers.tf
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "3.48.0"
}
google-beta = {
source = "hashicorp/google-beta"
version = "3.48.0"
}
}
}
provider "google" {
project = var.project
}
provider "google-beta" {
project = var.project
}
////// variables.tf
variable "image" {
type = string
}
variable "project" {
type = string
default = "gcping-1369"
}
variable "domain" {
type = string
default = "global.gcping.com."
}
# TODO: generate this
# https://github.com/hashicorp/terraform-provider-google/issues/7850
variable "regions" {
type = list(string)
description = "deploy to regions"
default = [
"asia-east1",
"asia-east2",
"asia-northeast1",
"asia-northeast2",
"asia-northeast3",
"asia-south1",
"asia-southeast1",
"asia-southeast2",
"australia-southeast1",
"europe-north1",
"europe-west1",
"europe-west2",
"europe-west3",
"europe-west4",
"europe-west6",
"northamerica-northeast1",
"southamerica-east1",
"us-central1",
"us-east1",
"us-east4",
"us-west1"
]
}
////// gcping.tf
# Enable Cloud Run API.
resource "google_project_service" "run" {
service = "run.googleapis.com"
}
# Deploy ${image} to each region.
resource "google_cloud_run_service" "default" {
for_each = toset(var.regions)
name = each.key
location = each.key
metadata {
annotations = {
"run.googleapis.com/launch-stage" = "BETA"
}
}
template {
metadata {
annotations = {
"autoscaling.knative.dev/minScale" = "1"
"autoscaling.knative.dev/maxScale" = "10"
"run.googleapis.com/launch-stage" = "BETA"
}
}
spec {
containers {
image = var.image
env {
name = "REGION"
value = each.key
}
}
}
}
traffic {
percent = 100
latest_revision = true
}
depends_on = [google_project_service.run]
}
# Make each service invokable by all users.
resource "google_cloud_run_service_iam_member" "allUsers" {
for_each = toset(var.regions)
service = google_cloud_run_service.default[each.key].name
location = each.key
role = "roles/run.invoker"
member = "allUsers"
depends_on = [google_cloud_run_service.default]
}
# Print regional Cloud Run service URLs.
output "urls" {
value = {
for svc in google_cloud_run_service.default :
svc.name => svc.status[0].url
}
}
////// lb.tf
# Print the global LB's IP address, to plug into DNS.
output "global-ip" {
value = google_compute_global_forwarding_rule.default.ip_address
}
resource "google_compute_global_forwarding_rule" "default" {
name = "global-rule"
target = google_compute_target_https_proxy.default.id
port_range = "443"
}
resource "google_compute_managed_ssl_certificate" "default" {
provider = google-beta
name = "ssl-cert"
managed {
domains = [var.domain]
}
}
resource "google_dns_managed_zone" "zone" {
provider = google-beta
name = "dnszone"
dns_name = var.domain
}
resource "google_dns_record_set" "set" {
provider = google-beta
name = var.domain
type = "A"
ttl = 3600
managed_zone = google_dns_managed_zone.zone.name
rrdatas = [google_compute_global_forwarding_rule.default.ip_address]
}
resource "google_compute_target_https_proxy" "default" {
provider = google-beta
name = "https-proxy"
url_map = google_compute_url_map.default.id
ssl_certificates = [google_compute_managed_ssl_certificate.default.id]
}
resource "google_compute_url_map" "default" {
provider = google-beta
name = "url-map"
default_service = google_compute_backend_service.default.id
}
// Create a regional network endpoint group (NEG) for each regional Cloud Run service.
resource "google_compute_region_network_endpoint_group" "default" {
for_each = toset(var.regions)
name = "default"
network_endpoint_type = "SERVERLESS"
region = each.key
cloud_run {
service = google_cloud_run_service.default[each.key].name
}
}
# Create a global backend service with a backend for each regional NEG.
resource "google_compute_backend_service" "default" {
name = "cloudrun-backend-service" # TODO: rename
enable_cdn = true
# Add a backend for each regional NEG.
dynamic "backend" {
for_each = google_compute_region_network_endpoint_group.default
content {
group = backend.value["id"]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment