Skip to content

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.

Every field in orbit.yaml maps to one or more GCP resources:

orbit.yaml fieldGCP ResourceTerraform Template
spec.compute.runtimeCloud Run v2 Servicecloud_run.tf.j2
spec.compute.cloud_apiCloud Run v2 Servicecloud_run.tf.j2
spec.compute.studioCloud Run v2 Servicecloud_run.tf.j2
spec.databaseCloud SQL for PostgreSQLcloud_sql.tf.j2
spec.cacheMemorystore for Redismemorystore.tf.j2
spec.secretsSecret Managersecrets.tf.j2
(automatic)Serverless VPC Connectornetworking.tf.j2
(automatic)Service Account + IAMiam.tf.j2
(automatic)GCS Bucket (Terraform state)backend.tf.j2

Orbit provisions several resources automatically that are not user-configured. These are required for the stack to function securely:

Cloud Run services need a Serverless VPC Access connector to communicate with Cloud SQL and Memorystore over private networking. Orbit creates one VPC connector shared by all three Cloud Run services.

A dedicated service account astromesh-orbit@{'{project}'} is created with the minimum required IAM roles:

RolePurpose
roles/cloudsql.clientConnect to Cloud SQL via Auth Proxy
roles/redis.editorRead/write to Memorystore
roles/secretmanager.secretAccessorRead secrets at runtime
roles/run.invokerAllow services to invoke each other

All Cloud Run services run as this dedicated service account.

Cloud Run connects to Cloud SQL using the built-in Cloud SQL Auth Proxy sidecar (--add-cloudsql-instances flag). This means:

  • No public IP on the database instance
  • Connections are encrypted and authenticated via IAM
  • No need to manage SSL certificates or IP allowlists

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.

The following APIs must be enabled in your GCP project. Orbit checks for these during orbit plan and offers to enable them automatically.

APIServiceEnable Command
run.googleapis.comCloud Rungcloud services enable run.googleapis.com
sqladmin.googleapis.comCloud SQL Admingcloud services enable sqladmin.googleapis.com
redis.googleapis.comMemorystore for Redisgcloud services enable redis.googleapis.com
secretmanager.googleapis.comSecret Managergcloud services enable secretmanager.googleapis.com
vpcaccess.googleapis.comServerless VPC Accessgcloud services enable vpcaccess.googleapis.com

Enable all at once:

Terminal window
gcloud services enable \
run.googleapis.com \
sqladmin.googleapis.com \
redis.googleapis.com \
secretmanager.googleapis.com \
vpcaccess.googleapis.com \
--project my-project-123

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.

Running orbit plan triggers the GCP provider’s validate() method, which checks:

  1. Authenticationgcloud CLI is authenticated with valid credentials
  2. Project — The GCP project exists and the user has access
  3. Permissions — The user has roles/owner or roles/editor
  4. APIs — All 5 required APIs are enabled
  5. Quotas — Sufficient quota for Cloud SQL instances and Cloud Run services

If validation fails, Orbit provides clear error messages with remediation commands:

✗ API 'sqladmin.googleapis.com' is not enabled
Remediation: Run the following command:
gcloud services enable sqladmin.googleapis.com --project my-project-123
Or allow Orbit to enable it automatically? [y/N]:

After a successful orbit apply, Orbit reads Terraform outputs and generates .orbit/orbit.env with all connection details:

ASTROMESH_DATABASE_URL=postgresql+asyncpg://astromesh:***@/astromesh?host=/cloudsql/{connection_name}
ASTROMESH_REDIS_URL=redis://{memorystore_ip}:6379
ASTROMESH_CLOUD_DATABASE_URL=postgresql+asyncpg://cloudapi:***@/astromesh_cloud?host=/cloudsql/{connection_name}
ASTROMESH_CLOUD_RUNTIME_URL=https://{runtime_cloud_run_url}
ASTROMESH_CLOUD_JWT_SECRET=projects/{project}/secrets/jwt-secret/versions/latest

These variables are injected into the Cloud Run services as environment variables. You can also source this file locally for development against the deployed infrastructure.

Choose a region close to your users. Common choices:

RegionLocationNotes
us-central1Iowa, USALowest cost, most services available
us-east1South Carolina, USAGood for East Coast US
europe-west1BelgiumGDPR-friendly, European users
europe-west4NetherlandsAlternative European region
asia-northeast1Tokyo, JapanAsia-Pacific 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.

Terraform state is stored remotely in GCS. Key details:

  • Locking — GCS natively supports Terraform state locking. Concurrent orbit apply calls are safely serialized.
  • Versioning — The bucket has versioning enabled, allowing recovery from accidental state corruption.
  • Cleanuporbit destroy does 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.