Skip to content
GCP Project Consolidation — HubOps / Deliveries

GCP Project Consolidation — HubOps / Deliveries

Andi Lamprecht Andi Lamprecht ·· 9 min read· Draft
StatusDraft
ClassificationINTERNAL
Scopedroneup-deliveries, droneup-deliveries-dev, droneup-hubops-dev, droneup-hubops-prod, mongodb-hubops-service
Date2026-03-30
SourceAutomated analysis via repository code search, cross-checked against local copies of droneup-hubops-infrastructure, hubops-mission-service, hubops-delivery-react-native, and pe-tfc-automation

Executive Summary

The HubOps / Delivery platform is spread across five GCP projects because the migration from the original “Deliveries” projects to the newer “HubOps” projects was never completed. Today:

  • Firestore + Firebase Auth remain in the legacy droneup-deliveries / droneup-deliveries-dev projects.
  • Compute (GKE), PubSub, Secret Manager, CloudSQL, Redis run in droneup-hubops-dev / droneup-hubops-prod.
  • mongodb-hubops-service is a standalone project with no active code references — a likely abandoned MongoDB Atlas peering project.
  • Every HubOps microservice carries cross-project IAM bindings so it can reach the legacy Firestore, adding operational and cost overhead.

Recommendation: consolidate the five projects into two (droneup-hubops-dev and droneup-hubops-prod) through a phased migration. Delete mongodb-hubops-service immediately.

This document is an analysis + recommendation. Adoption requires an ADR in content/docs/HubOps/ADR/ once the platform team agrees on the target state and migration ownership.

1. Current State

1.1 Project Inventory

GCP ProjectStatusActive ResourcesRecommendation
droneup-deliveriesLegacyFirestore, Cloud Functions, GCS, PubSub, Firebase AuthMigrate to droneup-hubops-prod, then delete
droneup-deliveries-devLegacyFirestore, Cloud Functions, GCS, PubSubMigrate to droneup-hubops-dev, then delete
droneup-hubops-devActiveGKE, CloudSQL, PubSub, GSM, RedisKeep — absorb droneup-deliveries-dev resources
droneup-hubops-prodActiveGKE, CloudSQL, PubSub, GSM, RedisKeep — absorb droneup-deliveries resources
mongodb-hubops-serviceAbandonedNone foundDelete immediately

1.2 Dependency Map

    graph TB
    subgraph compute["Primary Compute (HubOps)"]
        HP["droneup-hubops-prod<br/>GKE • PubSub • GSM<br/>CloudSQL • Redis"]
        HD["droneup-hubops-dev<br/>GKE • PubSub • GSM<br/>CloudSQL • Redis"]
    end
    subgraph legacy["Legacy Firestore / Firebase"]
        DP["droneup-deliveries<br/>Firestore • Cloud Functions<br/>GCS • PubSub • Firebase Auth"]
        DD["droneup-deliveries-dev<br/>Firestore • Cloud Functions<br/>GCS • PubSub"]
    end
    HP -- "Firestore reads<br/>(cross-project IAM)" --> DP
    HD -- "Firestore reads<br/>(cross-project IAM)" --> DD
    MH["mongodb-hubops-service<br/>NO ACTIVE USE"]
  

2. Project-by-Project Breakdown

droneup-deliveries (prod — legacy Firestore/Firebase)
Resource TypeDetails
Firestore DBPrimary production Firestore — used by nearly all HubOps prod services
Cloud Functionsdeliveries-live-function (invoked via PubSub and from the mobile app)
GCS Bucketsdroneup-deliveries-fsb (Firestore backup), deliveries-live-sf-data
PubSub Topicsemail-notifications, sms-notifications, hub-active, suspensions, deliveries-live-store0001, deliveries-test-store0000
Firebase AuthUsed by hubops-delivery-react-native mobile app

Services depending on this project (prod Firestore):

RepositoryHow it uses droneup-deliveries
hubops-mission-serviceFIREBASE_PROJECT_ID: "droneup-deliveries" (verified in values-prod.yml:24)
hubops-mission-plannerFIREBASE_PROJECT_ID: "droneup-deliveries"
hubops-walmart-deliveries-serviceFIRESTORE_PROJECT_ID: "droneup-deliveries-prod" ¹
hubops-firestore-apiFIRESTORE_PROJECT_ID: "droneup-deliveries-prod" ¹
hubops-order-serviceFIREBASE_PROJECT_ID: "droneup-deliveries"
hubops-reservation-serviceFIREBASE_PROJECT_ID: "droneup-deliveries"
hubops-weather-cacheFIREBASE_PROJECT_ID: "droneup-deliveries"
hubops-bucket-populatorFIRESTORE_PROJECT_ID + FIREBASE_PROJECT_ID = droneup-deliveries
hubops-delivery-api-v2FIRESTORE_PROJECT_ID: "droneup-deliveries"
acs-bucket-populatorFIRESTORE_PROJECT_ID: droneup-deliveries
hubops-delivery-react-nativeFirebase Auth + cloudfunctions.net/deliveries-activeUser (verified in src/api/auth/auth.api.ts:13-16)
da-composer-pipelinesSRC_PROJECT_ID = 'droneup-deliveries' (Airflow DAG: Firestore → BigQuery)
terraform-google-flightopsPubSub integration with deliveries-live-function
terraform-google-pubsub-hubopsPubSub module referencing deliveries_project_name

¹ Some services use droneup-deliveries-prod as a string alias — this either resolves to droneup-deliveries or reflects inconsistent naming. Reconcile during Phase 1.

Cross-project IAM bindings into droneup-deliveries (from pe-gcp-service-accounts):

  • acs-delivery-api-prod@droneup-hubops-prodroles/datastore.user
  • acs-bucket-populator@droneup-hubops-prodroles/datastore.viewer
  • hubops-api@droneup-hubops-prodroles/datastore.user, roles/storage.objectAdmin, ServiceAccountPubSub
  • hubops-weather-cache-svc-acc@droneup-hubops-prodroles/datastore.user
  • hubops-wm-deliveries@droneup-hubops-prodroles/datastore.viewer
  • hubops-firebase-svc-account@droneup-hubops-prodroles/datastore.user
  • hubops-mission-service@droneup-hubops-prodroles/datastore.user
  • hubops-gcp-functions@droneup-hubops-prodroles/datastore.user, ServiceAccountPubSub
  • terraform-cloud@droneup-hubops-prodroles/admin
droneup-deliveries-dev (dev — legacy Firestore/Firebase)
Resource TypeDetails
Firestore DBDev / sandbox Firestore — used by all HubOps dev and sandbox services
Cloud Functionsdeliveries-dev-function
GCS Bucketsdroneup-deliveries-dev-fsb (Firestore backup)
PubSub Topicsdeliveries-dev-store0001, email-notifications, sms-notifications, hub-active, suspensions

Services depending on this project (dev Firestore):

RepositoryHow it uses droneup-deliveries-dev
hubops-mission-serviceFIREBASE_PROJECT_ID: "droneup-deliveries-dev" (verified in values-dev.yml:24, values-sandbox.yml:29)
hubops-mission-plannerFIREBASE_PROJECT_ID: "droneup-deliveries-dev"
hubops-firestore-apiFIRESTORE_PROJECT_ID: "droneup-deliveries-dev" (dev + sandbox)
hubops-order-serviceFIREBASE_PROJECT_ID: "droneup-deliveries-dev" (dev + sandbox)
hubops-reservation-serviceFIREBASE_PROJECT_ID: "droneup-deliveries-dev" (dev + sandbox)
hubops-weather-cacheFIREBASE_PROJECT_ID: "droneup-deliveries-dev" (sandbox)
hubops-bucket-populatorFIRESTORE_PROJECT_ID + FIREBASE_PROJECT_ID = droneup-deliveries-dev
hubops-delivery-api-v2FIRESTORE_PROJECT_ID: "droneup-deliveries-dev" (dev + sandbox)
hubops-systems-checkHardcoded ProjectID: "droneup-deliveries-dev" in Go source
hubops-gcp-functionsFirebase emulator configured with --project droneup-deliveries-dev
hubops-delivery-react-nativeAuth URL routing keyed on projectId === 'droneup-deliveries-dev' (verified in src/store/auth/actions.ts:21, src/api/orders/orders.api.ts:50)
acs-bucket-populatorFIRESTORE_PROJECT_ID: droneup-deliveries-dev (sandbox)
acs-local-composeFIRESTORE_PROJECT_ID=droneup-deliveries-dev

Cross-project IAM bindings into droneup-deliveries-dev:

  • acs-delivery-api-dev@droneup-hubops-devroles/datastore.user
  • acs-bucket-populator-dev@droneup-hubops-devroles/datastore.viewer
  • hubops-api-dev@droneup-hubops-devroles/datastore.user, roles/storage.objectAdmin, ServiceAccountPubSub
  • hubops-weather-cache-svc-acc@droneup-hubops-devroles/datastore.user
  • terraform-cloud@droneup-hubops-devroles/admin
  • Several SAs in droneup-deliveries-dev itself: hubops-dbupdate, hubops-auth-service, hubops-publicapi-deliveries, location-availability-service
droneup-hubops-dev (primary compute — dev)
Resource TypeDetails
GKE Clusterdroneup-hubops-dev (us-east1)
CloudSQLPostgreSQL instances for control-plane, walmart-deliveries, GIS backend, etc.
PubSubAll dev/sandbox topics (missions, orders, control-plane, status updates, weather cache)
Secret ManagerAll dev/sandbox secrets for HubOps services
RedisMemorystore (172.19.0.12:6379)
Shared VPC Subnetdroneup-hubops-dev-gke-subnet (in droneup-shared-prod)
Cloudflare TunnelZero-trust access configured

Services deployed to this GKE cluster (dev / sandbox): hubops-mission-service, hubops-mission-planner, hubops-walmart-deliveries-service, hubops-firestore-api, hubops-order-service, hubops-reservation-service, hubops-weather-cache, hubops-bucket-populator, hubops-delivery-api-v2, hubops-control-plane, hubops-status-manager, hubops-systems-check, hubops-gcp-functions, groundinfrasvc-backend.

droneup-hubops-prod (primary compute — prod)
Resource TypeDetails
GKE Clusterdroneup-hubops-prod (us-east1)
CloudSQLhubops-cloudsql-prod, hubops-faa-prod, hubops-controlplane-prod (verified in droneup-hubops-infrastructure/main.tf) — all created under var.project_name for the prod project
PubSubAll prod topics
Secret ManagerAll prod secrets
RedisMemorystore (172.18.0.20:6379)
Shared VPC Subnetdroneup-hubops-prod-gke-subnet
Cloudflare TunnelZero-trust access configured
Artifact RegistryService accounts have reader access into pe-tools-main

Warning

The original analysis flagged a suspicious DB_HOST: "droneup-hubops-dev:us-east1:hubops-cloudsql-prod-f5326ae7" value in hubops-walmart-deliveries-service prod config, suggesting the prod CloudSQL instance might physically reside in the dev project. A terraform review of droneup-hubops-infrastructure did not find an instance named hubops-cloudsql-prod-f5326ae7; actual prod instances (hubops-cloudsql-prod, hubops-faa-prod, hubops-controlplane-prod) are created under the prod project. The helm value is likely stale and should be reconciled as part of Phase 0 before migration begins.

Services deployed (prod): same list as dev, in the services namespace.

mongodb-hubops-service
FindingDetails
Code referencesFound only in pe-gcp-service-accounts/modules/prod/main.tf as part of a bulk org-wide project list
Active servicesNone found
Terraform managementListed alongside other legacy / abandoned projects
Likely purposeProbably created for a MongoDB Atlas ↔ GCP peering for HubOps that never shipped

Conclusion: abandoned — delete immediately after a GCP console sanity check.


3. Recommendations

Phase 0 — Quick Wins Immediate

No code changes. Low-risk cleanup; executable independently of the full consolidation.
#ActionEffortSavings / Benefit
1Delete mongodb-hubops-service after confirming GCP console shows no resourcesLowEliminates billing for an idle project
2Clean up legacy PubSub topics in droneup-deliveries / -dev with no live subscribers (e.g. deliveries-test-store0000)LowMinor cost + hygiene
3Verify the DB_HOST in hubops-walmart-deliveries-service prod config — reconcile against actual CloudSQL instances found in droneup-hubops-infrastructureLow (investigation)Removes risk of prod pointing at a ghost instance

Phase 1 — Consolidate Deliveries into HubOps Medium-term

The core problem: Firestore stayed in the old droneup-deliveries* projects while everything else moved to droneup-hubops*. The migration was never finished.

#ActionDetails
4Migrate Firestore data droneup-deliveriesdroneup-hubops-prod and droneup-deliveries-devdroneup-hubops-devgcloud firestore export / import. Every consumer already reads FIREBASE_PROJECT_ID / FIRESTORE_PROJECT_ID from env, so the cutover is a values-file change + redeploy.
5Migrate Cloud Functions (deliveries-live-function, deliveries-dev-function) to Cloud Run in the hubops projects, or rewrite as GKE servicesThe mobile app calls cloudfunctions.net/deliveries-activeUser — will need a URL update (or a redirect proxy in the interim).
6Complete Firebase Auth → Frontegg migration (already partially done)Some services reference both auth0 and Frontegg. Finish the migration so Firebase Auth can be retired.
7Move GCS buckets (droneup-deliveries-fsb, droneup-deliveries-dev-fsb) to hubops projectsgsutil or Storage Transfer Service
8Update all service configs — FIREBASE_PROJECT_ID / FIRESTORE_PROJECT_ID env vars across ~15 repositoriesBulk of the work. Coordinate with deployment windows.
9Update da-composer-pipelines — the Airflow DAG (composer/dags/hubops/hubops.py) exports from SRC_PROJECT_ID = 'droneup-deliveries'Must change in sync with cutover
10Remove cross-project IAM bindings in pe-gcp-service-accounts and legacy TFC workspaces (du-deliveries, du-deliveries-dev — verified in pe-tfc-automation/legacy_tfc.tf)Clean up after migration, before project deletion

Exit criterion: both droneup-deliveries and droneup-deliveries-dev can be deleted with no active references.

Phase 2 — Target State (2 projects) Final

    graph TB
    subgraph target["Target: 2 GCP projects"]
        direction LR
        HP["droneup-hubops-prod<br/>GKE • Firestore • Firebase Auth<br/>PubSub • GSM • CloudSQL<br/>Redis • GCS"]
        HD["droneup-hubops-dev<br/>GKE • Firestore • Firebase Auth<br/>PubSub • GSM • CloudSQL<br/>Redis • GCS"]
    end
    subgraph deleted["Deleted"]
        DD["droneup-deliveries"]
        DE["droneup-deliveries-dev"]
        MH["mongodb-hubops-service"]
    end
    style deleted fill:#fee,stroke:#c33,stroke-dasharray:5
  

Estimated cost reduction from eliminating three GCP projects:

  • Three sets of project-level charges (logging, monitoring)
  • Cross-project network egress (Firestore reads from hubops → deliveries)
  • Unused Cloud Functions billing
  • Unused GCS storage for legacy backups
  • IAM surface area — fewer service accounts to rotate and audit

4. Repositories Affected

Phase 0

None — GCP Console and Terraform operations only.

Phase 1 — config + Terraform changes

RepositoryChange Needed
hubops-mission-serviceUpdate FIREBASE_PROJECT_ID in values-dev.yml, values-sandbox.yml, values-prod.yml
hubops-mission-plannerUpdate FIREBASE_PROJECT_ID in values-dev.yml, values-prod.yml
hubops-walmart-deliveries-serviceUpdate FIRESTORE_PROJECT_ID in values-prod.yml (and reconcile DB_HOST per Phase 0 #3)
hubops-firestore-apiUpdate FIRESTORE_PROJECT_ID in all values-*.yml
hubops-order-serviceUpdate FIREBASE_PROJECT_ID in all values-*.yml
hubops-reservation-serviceUpdate FIREBASE_PROJECT_ID in all values-*.yml
hubops-weather-cacheUpdate FIREBASE_PROJECT_ID in all values-*.yml
hubops-bucket-populatorUpdate FIRESTORE_PROJECT_ID + FIREBASE_PROJECT_ID in all values-*.yml
hubops-delivery-api-v2Update FIRESTORE_PROJECT_ID in all values-*.yml
hubops-systems-checkCode change — hardcoded ProjectID: "droneup-deliveries-dev" in internal/database/firestore.go
hubops-gcp-functionsUpdate Firebase emulator --project flag in Makefile
hubops-delivery-react-nativeCode changedroneup-deliveries fallback in src/api/auth/auth.api.ts:13; deliveries-activeUser URL in src/api/auth/auth.api.ts:16; dev-vs-prod routing in src/store/auth/actions.ts, src/api/orders/orders.api.ts
acs-bucket-populatorUpdate FIRESTORE_PROJECT_ID in all values-*.yml
acs-local-composeUpdate FIRESTORE_PROJECT_ID in podman-compose.yml
da-composer-pipelinesUpdate SRC_PROJECT_ID in composer/dags/hubops/hubops.py
pe-gcp-service-accountsRemove all droneup-deliveries* service accounts and cross-project role bindings
pe-gcp-iamRemove droneup-deliveries / droneup-deliveries-dev from live_projects / dev_projects
pe-tfc-automationRemove du-deliveries / du-deliveries-dev workspace definitions in legacy_tfc.tf
droneup-hubops-infrastructureRemove legacy/droneup-deliveries* folders (including legacy-deliveries-service-accounts.tf) after migration completes
pe-terraform-iascArchive droneup-deliveries folder
terraform-google-flightopsUpdate function_project_name defaults
terraform-google-pubsub-hubopsUpdate deliveries_project_name parameter

5. Risks and Mitigations

RiskMitigation
Firestore migration downtimeUse export/import in a maintenance window. Because all consumers read the project ID from env, the cutover is a coordinated redeploy, not a code change.
Firebase Auth user disruptionFirebase Auth users exist per-project. Plan explicit user migration or complete the move to Frontegg first (already in progress).
Mobile app update requiredhubops-delivery-react-native hardcodes cloudfunctions.net URLs — requires an app-store release. Stand up a redirect/proxy to bridge the cutover while users update.
Data analytics pipeline breakageda-composer-pipelines reads droneup-deliveries Firestore directly — must be updated in sync with the cutover.
Terraform state conflictsLegacy TFC workspaces in pe-tfc-automation reference droneup-deliveries* — migrate or delete the states before deleting the projects.
Stale DB_HOST in prod helm configReconcile before Phase 1 (see Phase 0 #3) so the walmart deliveries service is verifiably pointing at the correct CloudSQL instance.

6. References

7. Next Steps

  1. Review with the HubOps platform team and name a migration owner.
  2. Execute Phase 0 this sprint (deletion of mongodb-hubops-service, PubSub cleanup, DB_HOST reconciliation).
  3. Open an ADR under content/docs/HubOps/ADR/ capturing the consolidation decision once target state is agreed.
  4. Plan Phase 1 as a multi-sprint initiative — migration runbook, Frontegg completion, mobile app release schedule, analytics pipeline cutover.
Last updated on