Skip to content

Photon Indexer

GCS bucket + service account + Workload Identity binding that back the multilingual Photon geocoder index pipeline.

Manually provisioned — not Terraform-managed

These resources live outside Terraform on purpose, so terraform destroy can never wipe a planet index (each rebuild is ~$500 of compute, ~5 days wall-clock). There is no infrastructure/gcp/photon_indexer.tf — the file was removed when the resources moved to manual bootstrap.

To (re)create from scratch, follow bootstrap → Step 2. To build and upload an index, follow Building the Photon multilang index.

Resources

Resource Identifier Purpose
Bucket development-485000-photon-index-usc1 (us-central1, STANDARD, uniform access) Holds versioned planet/region index tarballs + latest-* aliases that Photon pods poll
Service account photon-indexer@development-485000.iam.gserviceaccount.com Identity used by local index builds (via ADC) and the (suspended) in-cluster CronJob to write tarballs
Bucket IAM roles/storage.objectAdmin to the SA above Lets the indexer upload new tarballs and overwrite latest-* aliases
Bucket IAM roles/storage.objectViewer to allUsers Required — rtuszik/photon-docker fetches the index over plain HTTP with no auth
Workload Identity roles/iam.workloadIdentityUser binding GCP SA → serviceAccount:development-485000.svc.id.goog[platform/photon-indexer] Lets the K8s SA platform/photon-indexer impersonate the GCP SA when the CronJob is un-suspended
Org policy override iam.allowedPolicyMemberDomains set to allowAll: true, project-scoped Unblocks the allUsers binding (the org otherwise forbids it)

The public base URL https://storage.googleapis.com/development-485000-photon-index-usc1 is the contract Photon pods, K8s manifests, and scripts/photon-index-local.sh hardcode. Don't rename.

Bucket retention and lifecycle

  • Retention policy: 100 years. Set on the bucket itself, so even an accidental gcloud storage rm is blocked. Can only be relaxed with gcloud storage buckets update --no-retention-policy.
  • Lifecycle: NEARLINE transition at 35 days. Cost optimisation — old indexes are read rarely.
  • No delete lifecycle. Old indexes stay forever. Cleanup, if ever needed, is a deliberate gcloud storage rm against specific objects.

Don't try to clean up the bucket

Combined with the retention policy, the no-delete lifecycle means there is no automated path to removing an index. That is the design — rebuilding a planet index costs days and hundreds of dollars. Manual cleanup is the only path, and you should be very sure before doing it.

Org policy override gotcha

The iam.allowedPolicyMemberDomains override is project-scoped, not bucket-scoped. Any bucket in development-485000 can be made publicly readable. Acceptable today because the project is single-tenant — re-evaluate if prod ever moves to its own project.