GCP Provider
The GCP provider is the first and currently only cloud provider for Astromesh Orbit. It maps your orbit.yaml configuration to Google Cloud managed services using Terraform.
Resource Mapping
Section titled “Resource Mapping”Every field in orbit.yaml maps to one or more GCP resources:
| orbit.yaml field | GCP Resource | Terraform Template |
|---|---|---|
spec.compute.runtime | Cloud Run v2 Service | cloud_run.tf.j2 |
spec.database | Cloud SQL for PostgreSQL | cloud_sql.tf.j2 |
spec.cache | Memorystore for Redis | memorystore.tf.j2 |
spec.secrets | Secret Manager | secrets.tf.j2 |
| (automatic) | Serverless VPC Connector | networking.tf.j2 |
| (automatic) | Service Account + IAM | iam.tf.j2 |
| (automatic) | GCS Bucket (Terraform state) | backend.tf.j2 |
spec.storage.rag_documents | GCS Bucket (RAG docs) | storage.tf.j2 |
spec.storage.artifact_registry | Artifact Registry | artifact_registry.tf.j2 |
spec.observability.dashboard | Cloud Monitoring dashboard | monitoring.tf.j2 |
spec.observability.tracing | OTel Collector sidecar | cloud_run.tf.j2 |
Automatic Resources
Section titled “Automatic Resources”Orbit provisions several resources automatically that are not user-configured. These are required for the stack to function securely:
VPC Connector
Section titled “VPC Connector”Cloud Run services need a Serverless VPC Access connector to communicate with Cloud SQL and Memorystore over private networking. Orbit creates one VPC connector for the runtime Cloud Run service.
Service Account
Section titled “Service Account”A dedicated service account astromesh-orbit@{'{project}'} is created with the minimum required IAM roles:
| Role | Purpose |
|---|---|
roles/cloudsql.client | Connect to Cloud SQL via Auth Proxy |
roles/redis.editor | Read/write to Memorystore |
roles/secretmanager.secretAccessor | Read secrets at runtime |
roles/run.invoker | Allow services to invoke each other |
roles/cloudtrace.agent, roles/monitoring.metricWriter | Export spans and metrics (only with spec.observability.tracing.enabled) |
The runtime Cloud Run service runs as this dedicated service account.
Database connection
Section titled “Database connection”The Cloud SQL instance has no public IP: it lives on the project’s default network through
private services access. Cloud Run reaches it through a Cloud SQL volume mounted at /cloudsql
(the built-in Auth Proxy socket), so no IP allowlist or certificates are involved.
The database user is astromesh, with a random 24-character password generated by Terraform.
The connection string, password included, is set as the runtime’s ASTROMESH_DATABASE_URL.
Private services access
Section titled “Private services access”Cloud SQL with a private IP needs a peering between the default network and Google’s service
network. When GOOGLE_APPLICATION_CREDENTIALS points at a service-account key, plan and
apply create it: an internal range google-managed-services (/20) and the peering. With
gcloud credentials Orbit skips this step, so create it once yourself:
gcloud compute addresses create google-managed-services --global \ --purpose=VPC_PEERING --prefix-length=20 --network=default --project my-project-123gcloud services vpc-peerings connect --service=servicenetworking.googleapis.com \ --ranges=google-managed-services --network=default --project my-project-123State Bucket
Section titled “State Bucket”Terraform state is stored in a GCS bucket named {'{project}'}-astromesh-orbit-state in the same region as the deployment. The bucket is created before Terraform initializes, with versioning enabled for state recovery.
Storage & RAG
Section titled “Storage & RAG”Two additional resources are provisioned by default via spec.storage (see Configuration):
- GCS bucket (
storage.tf.j2) — stages RAG source documents. The runtime receives its name asASTROMESH_RAG_BUCKET. Disable withspec.storage.rag_documents.enabled: false. - Artifact Registry (
artifact_registry.tf.j2) — a Docker repository (<metadata.name>-imagesby default) for custom Astromesh container images. Disable withspec.storage.artifact_registry.enabled: false.
Orbit does not provision a separate vector database for RAG. Cloud SQL for PostgreSQL supports the pgvector extension natively, so the existing Cloud SQL instance doubles as the RAG vector store — point a *.rag.yaml pipeline at it with vector_store.backend: pgvector.
Observability
Section titled “Observability”Cloud Run already reports request metrics to Cloud Monitoring and ships stdout/stderr to Cloud Logging at no extra cost — Orbit provisions nothing to get those. A Cloud Monitoring dashboard (monitoring.tf.j2) with four charts for astromesh-runtime — request count, p95 request latency, instance count, and CPU and memory utilization — is provisioned on by default; disable it with spec.observability.dashboard: false. orbit logs reads the Cloud Logging entries directly.
Cloud Trace is opt-in. Setting spec.observability.tracing.enabled: true adds an OpenTelemetry Collector sidecar to the runtime Cloud Run service and sets ASTROMESH_OTLP_ENABLED=1 on the runtime container, so the astromesh runtime exports OTLP spans to the sidecar, which forwards them to Cloud Trace under the deployment’s service account.
See Configuration for the full spec.observability schema.
Required GCP APIs
Section titled “Required GCP APIs”The following APIs must be enabled in your GCP project. orbit plan and orbit apply check them and fail with the gcloud services enable command for each missing one; Orbit does not enable them for you.
| API | Service | Enable Command |
|---|---|---|
run.googleapis.com | Cloud Run | gcloud services enable run.googleapis.com |
sqladmin.googleapis.com | Cloud SQL Admin | gcloud services enable sqladmin.googleapis.com |
redis.googleapis.com | Memorystore for Redis | gcloud services enable redis.googleapis.com |
secretmanager.googleapis.com | Secret Manager | gcloud services enable secretmanager.googleapis.com |
vpcaccess.googleapis.com | Serverless VPC Access | gcloud services enable vpcaccess.googleapis.com |
storage.googleapis.com | Cloud Storage | gcloud services enable storage.googleapis.com |
artifactregistry.googleapis.com | Artifact Registry | gcloud services enable artifactregistry.googleapis.com |
monitoring.googleapis.com | Cloud Monitoring | gcloud services enable monitoring.googleapis.com |
cloudtrace.googleapis.com | Cloud Trace | gcloud services enable cloudtrace.googleapis.com |
logging.googleapis.com | Cloud Logging | gcloud services enable logging.googleapis.com |
Enable all at once:
gcloud services enable \ run.googleapis.com \ sqladmin.googleapis.com \ redis.googleapis.com \ secretmanager.googleapis.com \ vpcaccess.googleapis.com \ storage.googleapis.com \ artifactregistry.googleapis.com \ monitoring.googleapis.com \ cloudtrace.googleapis.com \ logging.googleapis.com \ --project my-project-123Required IAM Permissions
Section titled “Required IAM Permissions”The user running orbit apply needs one of:
roles/owner— Full access (simplest for getting started)roles/editor+roles/iam.serviceAccountAdmin— Enough to create all resources and manage the service account
For the state bucket, the user also needs storage.buckets.create on the project. If the bucket already exists (e.g., from a previous deployment), this permission is not required.
Pre-Deploy Validation
Section titled “Pre-Deploy Validation”Running orbit plan triggers the GCP provider’s validate() method, which checks:
- Authentication —
gcloudis authenticated, orGOOGLE_APPLICATION_CREDENTIALSpoints to a service-account key file - Project — The GCP project exists and the credentials can read it
- APIs — All 10 required APIs are enabled
IAM permissions and quotas are not checked up front; Terraform reports them if they fall short. If validation fails, Orbit prints each failed check with its remediation and exits with code 1:
Validating... FAILED
OK Authenticated as you@example.com OK Project my-project-123 found FAIL sqladmin.googleapis.com not enabled -> gcloud services enable sqladmin.googleapis.com --project=my-project-123Post-Provisioning
Section titled “Post-Provisioning”After a successful orbit apply, Orbit writes every Terraform output to .orbit/orbit.env, upper-cased:
RUNTIME_URL=https://{runtime_cloud_run_url}DB_CONNECTION_NAME={project}:{region}:{name}-dbREDIS_HOST={memorystore_ip}RAG_BUCKET={project}-{name}-rag-docsARTIFACT_REGISTRY_REPO={region}-docker.pkg.dev/{project}/{name}-imagesThe file is for you (scripts, local development against the deployed stack); the runtime container gets its own configuration from the Cloud Run template, not from this file.
What the runtime receives
Section titled “What the runtime receives”The Cloud Run service runs spec.images.runtime on port 8000, as the astromesh-orbit service
account, with these environment variables:
| Variable | Value | When |
|---|---|---|
ASTROMESH_DATABASE_URL | postgresql+asyncpg://astromesh:<password>@/astromesh?host=/cloudsql/<connection> | Always |
ASTROMESH_REDIS_URL | redis://<memorystore host>:<port> | Always |
ASTROMESH_RAG_BUCKET | The RAG documents bucket | storage.rag_documents.enabled |
ASTROMESH_OTLP_ENABLED=1, OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 | Points the runtime at the sidecar | observability.tracing.enabled |
Everything in spec.env | As written | Always |
With tracing on, a second container, otel-collector (1 vCPU, 512 Mi), receives OTLP on 4317
and exports traces to Cloud Trace; the runtime container starts after it.
Security notes
Section titled “Security notes”- Secrets in plain configuration. The database password travels inside
ASTROMESH_DATABASE_URL, andspec.envvalues are plain environment variables. Anyone who can read the Cloud Run service’s configuration can read them. - Secret Manager entries are not wired.
<name>-jwt-secretand<name>-fernet-keyare created but not passed to the container. deletion_protection = falseon Cloud SQL, soorbit destroydeletes the database. Its automated backups go with it.
Region Selection
Section titled “Region Selection”Choose a region close to your users. The init wizard offers eight (us-central1, us-east1, us-west1, europe-west1, europe-west4, asia-east1, asia-southeast1, southamerica-east1); orbit.yaml accepts any region where all the services exist.
| Region | Location | Notes |
|---|---|---|
us-central1 | Iowa, USA | Lowest cost, most services available |
us-east1 | South Carolina, USA | Good for East Coast US |
europe-west1 | Belgium | GDPR-friendly, European users |
europe-west4 | Netherlands | Alternative European region |
asia-east1 | Taiwan | Asia-Pacific users |
southamerica-east1 | São Paulo, Brazil | South American users |
All resources (Cloud Run, Cloud SQL, Memorystore, VPC Connector) are deployed in the same region to minimize latency and avoid cross-region networking costs.
State Management
Section titled “State Management”Terraform state is stored remotely in GCS. Key details:
- No locking — Orbit runs every OpenTofu/Terraform command with
-lock=false, so twoapplyruns against the same deployment at once are not serialized. Run one at a time. - Prefix — State lives under
metadata.nameinside the bucket. - Versioning — The bucket has versioning enabled, allowing recovery from accidental state corruption.
- Cleanup —
orbit destroydoes not delete the state bucket. It contains the record of what was destroyed. Delete it manually after confirming everything is torn down:gsutil rm -r gs://{'{project}'}-astromesh-orbit-state.
What’s Next
Section titled “What’s Next”- CLI Reference — All commands with flags and examples
- Configuration — Full
orbit.yamlschema reference