| name | deploying |
| description | Guides deployment of Race Condition to a GCP project. Use when deploying to the cloud, setting up infrastructure with Terraform, or troubleshooting a deployment. This is for cloud deployment -- for local development, use the getting-started skill instead.
|
Deploying Race Condition
This skill walks through a cloud deploy of Race Condition to a GCP project:
Terraform for the infra, Cloud Run and Agent Engine for the app, then a
verification pass once it's up. The phases are gated. If a phase fails, stop
and fix it. Don't try to push past it.
For local dev setup, use the getting-started skill instead.
Phase 1: prerequisites check
HARD GATE: Do not proceed until all prerequisites are confirmed.
Required tools
GCP authentication
Check who you're logged in as:
gcloud auth list
There should be an active account. If not:
gcloud auth login --update-adc
Then set up Application Default Credentials separately (yes, this is a
second login; gcloud and ADC use different token stores):
gcloud auth application-default login
GCP project
Ask the developer for their GCP project ID. Verify:
gcloud projects describe PROJECT_ID
Requirements:
- Billing must be enabled on the project
- The authenticated user must have Owner or Editor role
Set the project:
gcloud config set project PROJECT_ID
Phase 2: feature selection
Ask the developer which optional features they want on. Each one costs
something, so explain the tradeoff before enabling it.
| Feature | Extra cost | What it enables |
|---|
| AlloyDB | ~$200/mo | Route memory with vector embeddings (replaces Cloud SQL) |
| GKE runner cluster | ~$300/mo | GPU-powered runner agents on Kubernetes |
| Cloud Run runner | ~$0 idle, scales with load | LLM-powered runner agents on Cloud Run (alternative to GKE) |
| Maps API key | Per-request pricing | Real map data for route planning (Maps, Places, Weather) |
| Monitoring alerts | Free (alerting only) | Email alerts for Redis memory, NAT egress, etc. |
Base infrastructure runs about $91/month (Redis, Cloud SQL, Cloud NAT).
Compute scales to zero when idle, so the rest is usage-based. Each
simulation costs around $3-4 in Gemini API calls.
Generate infra/terraform.tfvars from the developer's answers:
project_id = "your-project-id"
db_initial_password = "change-me-to-a-secure-password"
region = "us-central1"
# Optional features
enable_alloydb = false
enable_gke = false
enable_runner_cloudrun = false
enable_maps_api_key = false
enable_monitoring = false
alert_email = "" # required only when enable_monitoring = true
# Developer access (optional)
developers = [
"user:developer@example.com",
]
Swap in the real project ID. Remind the developer to pick a strong
db_initial_password and not commit the file; it should be gitignored.
HARD GATE: infra/terraform.tfvars must exist with the correct project ID
before proceeding.
Phase 3: infrastructure provisioning
Run these in order. Each step must succeed before the next.
Step 1: initialize Terraform
make infra-init
This downloads providers and initializes the Terraform backend.
Step 2: review the plan
make infra-plan
Show the plan output to the developer. The plan lists every GCP resource
that will be created (Cloud Run, Redis, VPC, NAT, etc.).
HARD GATE: Explicit confirmation from the developer before applying.
Step 3: apply infrastructure
make infra-apply
This takes 5-15 minutes depending on which features are on. AlloyDB and
GKE each add another 5-10 minutes on top.
Step 4: verify outputs
make infra-output
Check the outputs include the things you'll need downstream:
- Artifact Registry repository URL
- Redis instance connection
- Cloud SQL or AlloyDB connection (whichever you picked)
- VPC connector name
Step 5: configure Docker for Artifact Registry
gcloud auth configure-docker REGION-docker.pkg.dev
Swap REGION for your deployment region (default: us-central1).
Phase 4: application deployment
The whole app deploys via one Cloud Build job (cloudbuild-bootstrap.yaml).
It builds container images in parallel, pushes them to Artifact Registry,
runs Terraform to deploy the Cloud Run services and IAM with those image
tags, and deploys the Agent Engine agents in parallel. Plan for 20-30
minutes start to finish.
Two equivalent entry points:
bash scripts/deploy.sh
make deploy PROJECT_ID=PROJECT_ID REGION=us-central1
Both entry points end with gcloud builds submit --config cloudbuild-bootstrap.yaml .... Monitor a running build:
gcloud builds log --stream BUILD_ID
The build ID prints at the start of the deploy.
HARD GATE: Deployment must complete without errors before proceeding.
Phase 5: post-deploy verification
1. Check Cloud Run services
gcloud run services list --project=PROJECT_ID --region=REGION
Every service should be "Ready". Cloud Run names use dashes:
gateway
admin
tester
frontend
dash
runner-autopilot
runner-cloudrun (only if enable_runner_cloudrun = true)
2. Open the frontend
Grab the URL from the frontend service and open it. The 3D simulation
should load.
3. Open the admin dashboard
The admin Cloud Run service hosts the admin-dash UI; grab its URL for
the service health view.
4. Verify Agent Engine agents
There is no gcloud subcommand for Agent Engines. List them via the
Vertex AI REST API:
TOKEN=$(gcloud auth application-default print-access-token)
BASE="https://aiplatform.googleapis.com"
curl -sS -H "Authorization: Bearer $TOKEN" \
"$BASE/v1beta1/projects/PROJECT_ID/locations/REGION/reasoningEngines" \
| python3 -c 'import json,sys; [print(e["displayName"]) for e in json.load(sys.stdin).get("reasoningEngines", [])]'
You'll see something like (the exact list depends on what's enabled):
planner
simulator
planner_with_eval
planner_with_memory
simulator_with_failure
HARD GATE: All services must be running and accessible before moving on to
the optional steps.
Phase 6: optional post-deploy steps
Only the sections that match features enabled in Phase 2 apply here. Skip
the rest.
Maps API key (if enabled)
Terraform created the key and stored it in Secret Manager, but the API
restrictions still have to be applied by hand in the Cloud Console:
- Go to APIs & Services > Credentials in the Cloud Console
- Find the key named
maps-places-weather-key
- Under API restrictions, select Restrict key and add:
- Maps JavaScript API
- Places API (New)
- Weather API
- Save. The key value is already in Secret Manager and the planner agent
reads it from there.
AlloyDB (if enabled)
Seed the database with the schema and initial route data:
bash agents/planner_with_memory/alloydb/deploy_alloydb.sh
This creates the tables, installs pgvector, and loads the seed routes.
Check the admin dashboard once it finishes; the planner-with-memory
agent should show as connected.
GKE runner (if enabled)
When enable_gke = true in infra/terraform.tfvars, the GKE cluster and
the runner-on-GKE workload are both provisioned by Terraform during
make infra-apply (via the gke-model-serving and gke-runner modules).
There's no separate deploy step for the runner image; it ships with the
cluster.
Once the cluster is up:
- Get the runner's Internal Load Balancer IP from
make infra-output
(or kubectl get svc -n runner runner-gke).
- Set
RUNNER_GKE_INTERNAL_URL=http://<ILB_IP> on the gateway Cloud Run
service. Either do it in the Cloud Console or run
gcloud run services update gateway --update-env-vars=....
Monitoring (if enabled)
Terraform creates the alert policies but doesn't wire up any notification
channels. That part is on you:
- Go to Monitoring > Alerting in the Cloud Console.
- Create a notification channel (email, Slack, PagerDuty, whatever).
- Edit each alert policy to point at it.
The policies cover Redis memory usage, NAT gateway egress, and Cloud Run
error rates.
Troubleshooting
| Problem | Cause | Fix |
|---|
| "Permission denied" on any step | Missing Owner/Editor role | Grant the role in IAM, or ask a project admin |
| "API not enabled" errors | Terraform should enable APIs, but propagation can lag | gcloud services enable API_NAME --project=PROJECT_ID |
| "Quota exceeded" | Default quotas too low for the deployment | Request increases at Cloud Console > IAM & Admin > Quotas |
| "VPC connector not found" during deploy | Infrastructure not fully provisioned | Wait for make infra-apply to finish, then retry |
| Agent Engine deploy fails | Wrong location configured | Verify GOOGLE_CLOUD_LOCATION is set to the region (e.g., us-central1), not global |
| Cloud Build timeout | Large images or slow network | Retry the same make deploy / bash scripts/deploy.sh invocation -- cloudbuild-bootstrap.yaml is idempotent |
| "Already exists" on re-deploy | Previous partial deploy left resources | Run make deploy again -- it is idempotent |
Teardown
The one-command path:
./scripts/teardown.sh
It mirrors scripts/deploy.sh's UX: pick the project, pick the region,
type destroy to confirm. The script then:
- Deletes every Vertex AI Agent Engine in that project + region (REST
API, since
gcloud has no AE subcommand).
- Runs
terraform init -reconfigure against the GCS state bucket
(gs://${PROJECT_ID}-tf-state, prefix oss/state).
- Runs
terraform destroy -auto-approve with the same vars
deploy.sh used.
- Optionally deletes the state bucket itself (asks at the end;
default keep, so a redeploy stays fast).
Total wall time is around 3-5 minutes.
Manual fallback
If you need to drive teardown by hand (debugging the script, partial
cleanup, etc.), the same operations broken out:
TOKEN=$(gcloud auth application-default print-access-token)
BASE="https://aiplatform.googleapis.com"
curl -sS -H "Authorization: Bearer $TOKEN" \
"$BASE/v1beta1/projects/PROJECT_ID/locations/REGION/reasoningEngines" \
| python3 -c 'import json,sys; [print(e["name"]) for e in json.load(sys.stdin).get("reasoningEngines", [])]' \
| while read name; do
curl -sS -X DELETE -H "Authorization: Bearer $TOKEN" \
"$BASE/v1beta1/${name}?force=true" >/dev/null
done
cd infra
terraform init -reconfigure \
-backend-config="bucket=PROJECT_ID-tf-state" \
-backend-config="prefix=oss/state"
terraform destroy -auto-approve \
-var "project_id=PROJECT_ID" \
-var "region=REGION"
gcloud storage rm --recursive "gs://PROJECT_ID-tf-state" --project=PROJECT_ID
What teardown does NOT remove
- The GCP project itself — delete it from the Cloud Console if you want
every trace gone.
- Artifact Registry images — pennies per month at this scale; kept so
a future redeploy is fast.
- Cloud Build history and logs.