Files
household-bot/infra/terraform/README.md

4.2 KiB

Terraform Infrastructure (WHE-28)

This directory contains baseline IaC for deploying the household bot platform on GCP.

Provisioned resources

  • Artifact Registry Docker repository
  • Cloud Run service: bot API (public webhook endpoint)
  • Cloud Run service: mini app (public web UI)
  • Cloud Scheduler jobs for reminder triggers
  • Runtime and scheduler service accounts with least-privilege bindings
  • Secret Manager secrets (IDs only, secret values are added separately)
  • Optional GitHub OIDC Workload Identity setup for deploy automation

Architecture (v1)

  • bot-api: Telegram webhook + app API endpoints
  • mini-app: front-end delivery
  • scheduler: triggers bot-api reminder endpoints using OIDC tokens

Prerequisites

  • Terraform >= 1.8
  • Authenticated GCP CLI context (gcloud auth application-default login for local)
  • Enabled billing on the target GCP project

Usage

  1. Initialize:
terraform -chdir=infra/terraform init -backend-config="bucket=<terraform-state-bucket>"
  1. Prepare variables:
cp infra/terraform/terraform.tfvars.example infra/terraform/terraform.tfvars
  1. Plan:
terraform -chdir=infra/terraform plan
  1. Apply:
terraform -chdir=infra/terraform apply
  1. Add secret values (after apply):
echo -n "<telegram-bot-token>" | gcloud secrets versions add telegram-bot-token --data-file=- --project <project_id>
echo -n "<value>" | gcloud secrets versions add telegram-webhook-secret --data-file=- --project <project_id>
echo -n "<value>" | gcloud secrets versions add scheduler-shared-secret --data-file=- --project <project_id>

If you configure optional secret IDs such as app_database_url_secret_id, worker_database_url_secret_id, or openai_api_key_secret_id, add versions for those secrets as well.

If GitHub OIDC deploy access is enabled, keep telegram_bot_token_secret_id aligned with the real bot token secret name so CD can read it and sync Telegram commands automatically.

Environments

Recommended approach:

  • Keep one state per environment (dev/prod) using separate backend configs or workspaces
  • Use terraform.tfvars per environment (dev.tfvars, prod.tfvars)
  • Keep project_id separate for dev/prod when possible
  • Keep non-secret bot config in *.tfvars:
    • optional bot_purchase_parser_model
    • optional bot_assistant_model
    • optional bot_assistant_router_model
    • optional assistant runtime knobs: bot_assistant_timeout_ms, bot_assistant_memory_max_turns, bot_assistant_rate_limit_burst, bot_assistant_rate_limit_burst_window_ms, bot_assistant_rate_limit_rolling, bot_assistant_rate_limit_rolling_window_ms
    • optional bot_mini_app_allowed_origins
    • optional alert_notification_emails
    • runtime DB URLs should stay split: APP_DATABASE_URL for authenticated request flows and WORKER_DATABASE_URL for background workers

Alerting baseline

Terraform can also provision a minimal monitoring baseline for the bot:

  • email notification channels from alert_notification_emails
  • log-based metrics for:
    • telegram.bot_error
    • payment.ingest_failed
    • purchase.ingest_failed
    • assistant.reply_failed
    • scheduler.reminder.dispatch_failed
  • an alert policy for Cloud Run 5xx responses on the bot API service
  • one alert policy per structured bot failure event above

If you use email channels, Google Cloud will send a one-time confirmation email for each address. The notification channel will not deliver alerts until that confirmation step is completed.

CI validation

CI runs:

  • terraform -chdir=infra/terraform fmt -check -recursive
  • terraform -chdir=infra/terraform init -backend=false
  • terraform -chdir=infra/terraform validate

Notes

  • Scheduler jobs default to paused = true and dry_run = true to prevent accidental sends before live reminder delivery is ready.
  • Bot API is public to accept Telegram webhooks; scheduler endpoint should still verify app-level auth.
  • bot_mini_app_allowed_origins cannot be auto-derived in Terraform because the bot and mini app Cloud Run services reference each other; set it explicitly once the mini app URL is known.
  • DATABASE_URL is migration-only and should not be injected into the bot runtime service.