Skip to main content

How to Add a New API

Adding a new Cloud Run service behind the gateway requires changes in up to four repos. Work through these steps in order.

Step 1 — Create the Cloud Run service

In iac-access (or a new dedicated IaC repo):

  • Deploy the service to europe-west1 for co-location with the gateway VM.
  • Grant roles/run.invoker to the gateway service account:
resource "google_cloud_run_v2_service_iam_member" "gateway_invoker" {
project = var.iac_project
location = var.location
name = google_cloud_run_v2_service.my_new_service.name
role = "roles/run.invoker"
member = "serviceAccount:cf-tunnel-gateway@${var.iac_project}.iam.gserviceaccount.com"
}
hcl
  • Set Cloud Run ingress to INTERNAL_AND_CLOUD_LOAD_BALANCING (or INTERNAL) — the service must not be publicly reachable.

Apply this change first so the Cloud Run URI is available before the gateway references it.


Step 2 — Add the route in cf-proxy

In iac-api-gateway/gateway/:

main.tf — add a data source to read the new service's URI:

data "google_cloud_run_v2_service" "my_new_service" {
name = "svc-my-new-service"
location = var.location
project = var.iac_project
}
hcl

vm.tf — add the hostname→URL mapping to routes_json:

locals {
routes_json = jsonencode({
(local.cf_admin_internal_domain) = data.google_cloud_run_v2_service.admin.uri
(local.cf_public_internal_domain) = data.google_cloud_run_v2_service.public.uri
# Add your new entry:
"my-new-api-internal-${var.iac_environment}.${var.cf_zone_name}" = data.google_cloud_run_v2_service.my_new_service.uri
})
}
hcl

Changing routes_json updates the startup script. Terraform will create a new instance template, and the MIG's PROACTIVE update policy will replace the VM automatically on apply.


Step 3 — Add a tunnel ingress rule

In iac-api-gateway/gateway/tunnel.tf, add a new rule before the catch-all:

resource "cloudflare_zero_trust_tunnel_cloudflared_config" "gateway" {
# ...
config = {
ingress = [
{ hostname = local.cf_admin_internal_domain, service = "http://localhost:8080" },
{ hostname = local.cf_public_internal_domain, service = "http://localhost:8080" },
# Add your new rule before the catch-all:
{
hostname = "my-new-api-internal-${var.iac_environment}.${var.cf_zone_name}"
service = "http://localhost:8080"
},
{ service = "http_status:404" }, # catch-all — must stay last
]
}
}
hcl

Ingress rule changes are live-updated to cloudflared without a VM restart (because config_src = "cloudflare").


Step 4 — Add a DNS record

In iac-api-gateway/gateway/dns.tf:

resource "cloudflare_dns_record" "my_new_api_internal" {
count = var.enable_dns_switch ? 1 : 0

zone_id = var.cf_zone_id
name = "my-new-api-internal-${var.iac_environment}"
type = "CNAME"
content = "${cloudflare_zero_trust_tunnel_cloudflared.gateway.id}.cfargotunnel.com"
ttl = 1
proxied = true
comment = "Managed by Terraform (iac-api-gateway/gateway) — my new API origin"
}
hcl

Step 5 — Create or update the Worker

In platform-api-gateway/workers/:

Either create a new Worker directory (copy an existing one as a template) or add a route to an existing Worker.

Required wrangler.toml elements:

[env.dev.vars]
ORIGIN_URL = "https://my-new-api-internal-dev.eigenoid.services"
ALLOWED_ORIGIN = "https://my-portal-dev.eigenoid.com" # adjust per audience

[[env.dev.secrets_store_secrets]]
binding = "INTERNAL_AUTH_TOKEN"
store_id = "e30a2aceebe34a80a10da2cc6bb208c4"
secret_name = "gateway-dev-internal-auth-token"
toml

Required Worker behavior:

  • Strip x-internal-auth-token from incoming client requests (prevent spoofing).
  • Resolve INTERNAL_AUTH_TOKEN via await env.INTERNAL_AUTH_TOKEN.get() — it is a SecretsStoreSecret, not a plain string.
  • Set X-Internal-Auth-Token: <token> on the proxied request.
  • Proxy only to the fixed ORIGIN_URL — never use a client-supplied URL.

Step 6 — Apply changes

Changes in iac-api-gateway are deployed through the standard Terraflow pipeline:

1. Open a PR in iac-api-gateway
→ Automatic terraform plan (dev)
→ Review the plan output in the PR comment

2. Comment /terraflow apply on the PR
→ Applies to dev

3. Merge the PR

4. Promote to qa/prd via workflow_dispatch

Changes in platform-api-gateway are deployed by Workers Builds CI on push to the dev branch.


Checklist

□ Cloud Run service deployed in europe-west1
□ roles/run.invoker granted to cf-tunnel-gateway@{project}.iam.gserviceaccount.com
□ Cloud Run ingress set to INTERNAL or INTERNAL_AND_CLOUD_LOAD_BALANCING
□ data source added in main.tf
□ Hostname→URL entry added to routes_json in vm.tf
□ Ingress rule added to tunnel.tf (before catch-all)
□ CNAME record added to dns.tf
□ Worker created or updated with correct ORIGIN_URL and secrets_store_secrets binding
□ /terraflow apply run on iac-api-gateway PR (dev)
□ Worker deployed (push to dev branch)
□ Smoke test: curl through the Worker, check cf-proxy logs