Wire Stripe billing secrets and env vars into Soma Cloud Run

- stripe-billing.tf: Secret Manager resources for all billing IDs:
  meters (input/output), plan prices (free/professional/founding),
  overage prices per plan per token type
- cloud-run-soma.tf: inject all 13 Stripe env vars into the Soma service
  via Secret Manager secret_key_ref; add billing secrets to depends_on
This commit is contained in:
Will Anderson
2026-04-29 04:34:13 -05:00
parent e5c9fd1287
commit d9ac977fef
2 changed files with 274 additions and 0 deletions
+147
View File
@@ -287,6 +287,138 @@ resource "google_cloud_run_v2_service" "soma_us" {
value = "claude-sonnet-4-5"
}
# ── Stripe billing ────────────────────────────────────────────────────────
env {
name = "STRIPE_SECRET_KEY"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_secret_key.secret_id
version = "latest"
}
}
}
env {
name = "STRIPE_WEBHOOK_SECRET"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_webhook_secret.secret_id
version = "latest"
}
}
}
env {
name = "STRIPE_PRICE_FREE_PLAN"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_price_free_plan.secret_id
version = "latest"
}
}
}
env {
name = "STRIPE_PRICE_PROFESSIONAL_PLAN"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_price_professional_plan.secret_id
version = "latest"
}
}
}
env {
name = "STRIPE_PRICE_FOUNDING_PLAN"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_price_founding_plan.secret_id
version = "latest"
}
}
}
env {
name = "STRIPE_METER_ID_INPUT_TOKENS"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_meter_id_input_tokens.secret_id
version = "latest"
}
}
}
env {
name = "STRIPE_METER_ID_OUTPUT_TOKENS"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_meter_id_output_tokens.secret_id
version = "latest"
}
}
}
env {
name = "STRIPE_PRICE_FREE_INPUT_OVERAGE"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_price_free_input_overage.secret_id
version = "latest"
}
}
}
env {
name = "STRIPE_PRICE_FREE_OUTPUT_OVERAGE"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_price_free_output_overage.secret_id
version = "latest"
}
}
}
env {
name = "STRIPE_PRICE_PROFESSIONAL_INPUT_OVERAGE"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_price_professional_input_overage.secret_id
version = "latest"
}
}
}
env {
name = "STRIPE_PRICE_PROFESSIONAL_OUTPUT_OVERAGE"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_price_professional_output_overage.secret_id
version = "latest"
}
}
}
env {
name = "STRIPE_PRICE_FOUNDING_INPUT_OVERAGE"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_price_founding_input_overage.secret_id
version = "latest"
}
}
}
env {
name = "STRIPE_PRICE_FOUNDING_OUTPUT_OVERAGE"
value_source {
secret_key_ref {
secret = google_secret_manager_secret.stripe_price_founding_output_overage.secret_id
version = "latest"
}
}
}
ports {
container_port = 8080
name = "http1"
@@ -331,6 +463,21 @@ resource "google_cloud_run_v2_service" "soma_us" {
google_secret_manager_secret_version.soma_node_secret,
google_secret_manager_secret_version.soma_key_secret,
google_secret_manager_secret_version.soma_anthropic_api_key,
# Stripe billing secrets — must exist before Cloud Run deploy.
# Versions are populated by provision_stripe_billing.py.
google_secret_manager_secret.stripe_secret_key,
google_secret_manager_secret.stripe_webhook_secret,
google_secret_manager_secret.stripe_price_free_plan,
google_secret_manager_secret.stripe_price_professional_plan,
google_secret_manager_secret.stripe_price_founding_plan,
google_secret_manager_secret.stripe_meter_id_input_tokens,
google_secret_manager_secret.stripe_meter_id_output_tokens,
google_secret_manager_secret.stripe_price_free_input_overage,
google_secret_manager_secret.stripe_price_free_output_overage,
google_secret_manager_secret.stripe_price_professional_input_overage,
google_secret_manager_secret.stripe_price_professional_output_overage,
google_secret_manager_secret.stripe_price_founding_input_overage,
google_secret_manager_secret.stripe_price_founding_output_overage,
]
}
+127
View File
@@ -0,0 +1,127 @@
# ── Stripe Billing — Secret Manager resources ─────────────────────────────────
#
# Secrets are created here as empty shell resources. Values are populated by:
# scripts/provision_stripe_billing.py --env live
# scripts/provision_stripe_billing.py --env test
#
# The provisioning script creates the secret versions via gcloud CLI after
# calling the Stripe API to create the meters, products, and prices.
#
# DO NOT hardcode secret values here.
# ── Stripe core secrets (existing — registered here for Terraform management) ──
resource "google_secret_manager_secret" "stripe_secret_key" {
secret_id = "stripe-secret-key"
project = var.project_id
replication { auto {} }
lifecycle {
ignore_changes = [replication]
}
}
resource "google_secret_manager_secret" "stripe_webhook_secret" {
secret_id = "stripe-webhook-secret"
project = var.project_id
replication { auto {} }
lifecycle {
ignore_changes = [replication]
}
}
# ── Plan flat price IDs ────────────────────────────────────────────────────────
resource "google_secret_manager_secret" "stripe_price_free_plan" {
secret_id = "stripe-price-free-plan"
project = var.project_id
replication { auto {} }
}
resource "google_secret_manager_secret" "stripe_price_professional_plan" {
secret_id = "stripe-price-professional-plan"
project = var.project_id
replication { auto {} }
}
resource "google_secret_manager_secret" "stripe_price_founding_plan" {
secret_id = "stripe-price-founding-plan"
project = var.project_id
replication { auto {} }
}
# ── Billing Meter IDs ─────────────────────────────────────────────────────────
resource "google_secret_manager_secret" "stripe_meter_id_input_tokens" {
secret_id = "stripe-meter-id-input-tokens"
project = var.project_id
replication { auto {} }
}
resource "google_secret_manager_secret" "stripe_meter_id_output_tokens" {
secret_id = "stripe-meter-id-output-tokens"
project = var.project_id
replication { auto {} }
}
# ── Overage price IDs — Free plan ─────────────────────────────────────────────
resource "google_secret_manager_secret" "stripe_price_free_input_overage" {
secret_id = "stripe-price-free-input-overage"
project = var.project_id
replication { auto {} }
}
resource "google_secret_manager_secret" "stripe_price_free_output_overage" {
secret_id = "stripe-price-free-output-overage"
project = var.project_id
replication { auto {} }
}
# ── Overage price IDs — Professional plan ─────────────────────────────────────
resource "google_secret_manager_secret" "stripe_price_professional_input_overage" {
secret_id = "stripe-price-professional-input-overage"
project = var.project_id
replication { auto {} }
}
resource "google_secret_manager_secret" "stripe_price_professional_output_overage" {
secret_id = "stripe-price-professional-output-overage"
project = var.project_id
replication { auto {} }
}
# ── Overage price IDs — Founding Member plan ──────────────────────────────────
resource "google_secret_manager_secret" "stripe_price_founding_input_overage" {
secret_id = "stripe-price-founding-input-overage"
project = var.project_id
replication { auto {} }
}
resource "google_secret_manager_secret" "stripe_price_founding_output_overage" {
secret_id = "stripe-price-founding-output-overage"
project = var.project_id
replication { auto {} }
}
# ── Secret accessor grants for Soma SA ────────────────────────────────────────
# soma_secret_accessor already has roles/secretmanager.secretAccessor on the
# project, so new secrets are automatically accessible. No per-secret grants needed.
# ── Outputs ───────────────────────────────────────────────────────────────────
output "stripe_billing_secrets" {
description = "Stripe billing secret IDs — populate via provision_stripe_billing.py"
value = {
stripe_secret_key = google_secret_manager_secret.stripe_secret_key.secret_id
stripe_webhook_secret = google_secret_manager_secret.stripe_webhook_secret.secret_id
stripe_price_free_plan = google_secret_manager_secret.stripe_price_free_plan.secret_id
stripe_price_professional_plan = google_secret_manager_secret.stripe_price_professional_plan.secret_id
stripe_price_founding_plan = google_secret_manager_secret.stripe_price_founding_plan.secret_id
stripe_meter_id_input_tokens = google_secret_manager_secret.stripe_meter_id_input_tokens.secret_id
stripe_meter_id_output_tokens = google_secret_manager_secret.stripe_meter_id_output_tokens.secret_id
}
}