Self-managed engineering project · Public delivery and live GCP inventory verified 24 July 2026
Hybrid-Cloud k3s Backup and Static Delivery
A self-managed hybrid-cloud project that answers one question: how can a local k3s platform gain static delivery and off-site backup without adding unnecessary always-on compute?
The site is static, but the platform still needs a credible release path, encrypted Kubernetes metadata backups, scoped Google Cloud access, and an operational trail. Running a VM, GKE cluster, or Cloud Run service for those needs would add cost and another failure domain.
Implemented solution
Firebase Hosting serves the static files; a k3s CronJob collects allowlisted configuration without requesting Secret objects and records only ConfigMap names and keys, then compresses and age-encrypts the archive before uploading it to private Cloud Storage through Workload Identity Federation. Terraform owns cloud controls, while Kustomize owns the Kubernetes workload and RBAC.
Outcome
The repository contains a repeatable static release and a backup path whose remote object size, encryption boundary, logs, retention, and restore inspection can be checked separately. A read-only GCP inventory on 24 July 2026 confirmed active Firebase, WIF, private storage, monitoring, and snapshot controls with no VM, GKE, Cloud Run, or Cloud SQL runtime. The design avoids always-on application compute while leaving old snapshots, an Artifact Registry repository, and the default network for explicit cleanup review.
Technical and operational context
The project separates static delivery, private recovery data, cloud identity, and operator-owned restore work while applying Terraform, Kubernetes, Bash, IAM, monitoring, and cost reasoning in context.
Architecture
The deployment plane moves from Git through the dev-only workflow to Firebase Hosting. The data plane moves from allowlisted k3s configuration through Secret-object exclusion, ConfigMap key-only inventory, compression, age encryption, federated authentication, private Cloud Storage, and structured monitoring. Management and cost controls stay in Terraform.
Git repository
Validation workflow
Firebase Hosting
Public HTTPS
Local k3s
Encrypted backup CronJob
Private Cloud Storage
Monitoring and budget controls
Architecture visual
A sanitized visual of the hybrid-cloud deployment and backup architecture.
Firebase Hosting serves the static files; a k3s CronJob collects allowlisted configuration without requesting Secret objects and records only ConfigMap names and keys, then compresses and age-encrypts the archive before uploading it to private Cloud Storage through Workload Identity Federation. Terraform owns cloud controls, while Kustomize owns the Kubernetes workload and RBAC.
Keeps static hosting separate from the private backup data plane
Uses projected Kubernetes identity and scoped Workload Identity Federation instead of a committed cloud key
Verifies the uploaded encrypted object and emits structured status for operators
Applies lifecycle, Artifact Registry cleanup, monitoring, uptime, and budget controls
Documents rollback and restore inspection without treating archive listing as a live restore
Key decisions and trade-offs
Static hosting instead of continuously running compute
Firebase fits a site made of static files, images, JSON, a PDF, and a service worker. It avoids paying for compute whose only job would be to serve already-built assets; the tradeoff is dependence on a managed hosting control plane.
Federated identity instead of service-account keys
Projected Kubernetes tokens exchange for short-lived Google credentials scoped to the backup or registry task. This avoids distributing a permanent service-account key to the cluster. The tradeoff is an extra issuer, audience, and public-JWKS dependency that must be maintained when signing keys rotate.
Backup evidence instead of backup assumptions
Remote-size comparison answers whether the encrypted upload arrived with the expected byte count; decrypt-and-list inspection answers whether the archive can be opened. Keeping those gates separate avoids a misleading backup-success boolean. Application data and restore execution remain manual, separately owned work.
Rollback-aware migration
The active site is Firebase Hosting; the former Cloud Run and load-balancer path is historical. This prevents two incompatible architectures from appearing current. The cleanup record preserves the old relationships, but rollback now requires reviewed manual reconstruction and fresh DNS/TLS checks rather than an automatic switch.
Security, reliability, and observability
Private backup boundary
The collector excludes Secret objects and ConfigMap values, encrypts the archive before upload, and keeps Cloud Storage private. Workload specifications can still contain literals, so every archive remains sensitive.
Short-lived cloud access
Projected Kubernetes tokens are exchanged through Workload Identity Federation for scoped Google credentials, avoiding a permanent service-account key in the cluster while making issuer and JWKS maintenance explicit.
Separate operational signals
Upload-size comparison, decrypt-and-list inspection, scheduled-job status, storage lifecycle, monitoring, and budget controls provide distinct evidence. None is promoted into a claim that application recovery was completed.
Infrastructure concepts demonstrated
CronJobs
ServiceAccounts
RBAC
NetworkPolicy
Projected tokens
Artifact Registry authentication
Backup and restore
Published evidence
Sanitized delivery and cloud verification
Sanitized live output
public route: HTTPS 200
www: canonical redirect
active runtime: no VM, GKE, Cloud Run, or Cloud SQL found
federation: one active WIF pool/provider
user-managed service-account keys: none
backup bucket: private, uniform access, versioned, lifecycle managed
archive evidence: encrypted upload and decrypt/list verified
resource restore: not performed
Validation
Checks shown here are project-specific; no portfolio-wide claim is applied automatically.
Terraform configuration and state review
Kustomize render review
Read-only Cloud Asset inventory on 24 July 2026 confirmed Firebase, one active WIF pool/provider, three Cloud Storage buckets, three alert policies, three log metrics, one dashboard, and one uptime check
No VM, GKE, Cloud Run, Cloud SQL, or user-managed service-account key was present in the active portfolio project on 24 July 2026
The private backup bucket had uniform access, enforced public-access prevention, versioning, and four lifecycle rules
Kubernetes CronJob last-success time observed on 16 July 2026
Recorded encrypted upload with remote-size comparison on 15 July 2026
Recorded decrypt-and-list inspection of a 4,973-byte test archive; no resource apply
Firebase apex, www redirect, catalogue, case-study route, security headers, and an unknown-route 404 checked on 24 July 2026
Evidence and links
Links are limited to public-safe source material and sanitized evidence. Credentials, state, plans, identifiers, private topology, and backup contents are intentionally excluded.
Validation, monitoring, cost checks, and operator handoff.
Lessons learned
Static delivery and private recovery data need different trust, caching, and ownership boundaries even when they share one repository.
A decrypt-and-list check removes useful uncertainty, but it must not be described as a restore or an application-recovery drill.
Federated identity removes long-lived cloud keys from the cluster while adding issuer, audience, and JWKS dependencies that recovery plans must retain.
Limitations
The archive contains selected Kubernetes configuration, not application data, persistent volumes, databases, or every bootstrap dependency.
Allowlisting omits Secret objects and ConfigMap data, but literal values can still exist in workload specifications; the archive must be treated as sensitive and remain encrypted.
Notification delivery, billing ownership, and DNS-provider state require account-level checks outside the repository.
Ten ready snapshots, one Artifact Registry repository, and the provider-created default network remain as reviewable migration residue; the live inventory does not prove they are safe to delete.
The recorded recovery check decrypts and lists an archive; it does not apply manifests to a cluster.
Next improvement
Automate a disposable restore environment and publish signed restore-drill evidence without exposing cluster or cloud identifiers.