# ── Marketing Stage — us-central1 ───────────────────────────────────────────── # Stage environment for the marketing site. Single region only (us-central1). # Uses the :stage Docker image tag with test Stripe keys. # Access is gated via Cloudflare Access (OAuth, @neurontechnologies.ai only). # The Cloud Run direct URL is available but obscure; Cloudflare is the front door. resource "google_cloud_run_v2_service" "stage_us" { name = "marketing-stage-us" location = "us-central1" project = var.project_id ingress = "INGRESS_TRAFFIC_ALL" labels = { "managed-by" = "terraform" "project" = "neuron-marketing" "env" = "stage" } template { service_account = google_service_account.marketing.email scaling { min_instance_count = 0 max_instance_count = 5 } containers { image = "us-central1-docker.pkg.dev/${var.project_id}/neuron-marketing/marketing:stage" resources { limits = { cpu = "1" memory = "512Mi" } cpu_idle = true } env { name = "NODE_ENV" value = "staging" } env { name = "STRIPE_PUBLISHABLE_KEY" value = "pk_test_51TPoHwJak4gXxYZLPBDH5g53qOICo0Bzy4S6YYWw723rnD5ZGOfhoT5bIvB00o4gW47yknEz9SeQimUclrDT2txm00aYsPDech" } env { name = "GCS_SHARE_BUCKET" value = "neuron-shares-stage" } env { name = "STRIPE_PRICE_FAMILY_CHILD" value_source { secret_key_ref { secret = "stripe-price-family-child" version = "latest" } } } env { name = "NEURON_ORIGIN" value = "https://stage.neurontechnologies.ai" } env { name = "SUPABASE_ANON_KEY" value = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im9jb2pzZ2hhb25sdHVuaWRrenB3Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3Nzc2NDIxNjgsImV4cCI6MjA5MzIxODE2OH0.e0FVFw1aahnrBVvnkR5R8a-RxCx095U8o_gsk7Quq3E" } env { name = "SUPABASE_SERVICE_KEY" value_source { secret_key_ref { secret = "supabase-service-key" version = "latest" } } } env { name = "NEURON_LLM_0_FORMAT" value = "anthropic" } env { name = "NEURON_LLM_0_MODEL" value = "claude-sonnet-4-5" } env { name = "NEURON_LLM_0_URL" value = "https://api.anthropic.com/v1/messages" } env { name = "NEURON_LLM_0_KEY" value_source { secret_key_ref { secret = "anthropic-api-key" version = "latest" } } } env { name = "ANTHROPIC_API_KEY" value_source { secret_key_ref { secret = "anthropic-api-key" version = "latest" } } } env { name = "STRIPE_SECRET_KEY" value_source { secret_key_ref { secret = "stripe-secret-key-stage" version = "latest" } } } env { name = "STRIPE_WEBHOOK_SECRET" value_source { secret_key_ref { secret = "stripe-webhook-secret-stage" version = "latest" } } } env { name = "STRIPE_PRICE_PROFESSIONAL" value_source { secret_key_ref { secret = "stripe-price-professional-stage" version = "latest" } } } env { name = "STRIPE_PRICE_FOUNDING" value_source { secret_key_ref { secret = "stripe-price-founding-stage" version = "latest" } } } env { name = "DOCUSEAL_WEBHOOK_TOKEN" value_source { secret_key_ref { secret = "docuseal-webhook-token" version = "latest" } } } ports { container_port = 8080 name = "http1" } startup_probe { http_get { path = "/api/health" port = 8080 } initial_delay_seconds = 15 timeout_seconds = 5 period_seconds = 10 failure_threshold = 10 } liveness_probe { http_get { path = "/api/health" port = 8080 } initial_delay_seconds = 20 timeout_seconds = 5 period_seconds = 30 failure_threshold = 3 } } } traffic { type = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST" percent = 100 } depends_on = [google_project_iam_member.marketing_secret_accessor] } # Allow unauthenticated requests (Cloudflare Access is the gate, not Cloud Run auth) resource "google_cloud_run_v2_service_iam_member" "stage_us_noauth" { project = var.project_id location = "us-central1" name = google_cloud_run_v2_service.stage_us.name role = "roles/run.invoker" member = "allUsers" } # Grant stage service account access to stage secrets resource "google_secret_manager_secret_iam_member" "stage_stripe_key" { secret_id = "stripe-secret-key-stage" role = "roles/secretmanager.secretAccessor" member = "serviceAccount:${google_service_account.marketing.email}" } resource "google_secret_manager_secret_iam_member" "stage_webhook_secret" { secret_id = "stripe-webhook-secret-stage" role = "roles/secretmanager.secretAccessor" member = "serviceAccount:${google_service_account.marketing.email}" } resource "google_secret_manager_secret_iam_member" "stage_price_founding" { secret_id = "stripe-price-founding-stage" role = "roles/secretmanager.secretAccessor" member = "serviceAccount:${google_service_account.marketing.email}" } resource "google_secret_manager_secret_iam_member" "stage_price_professional" { secret_id = "stripe-price-professional-stage" role = "roles/secretmanager.secretAccessor" member = "serviceAccount:${google_service_account.marketing.email}" }