Blueberry IDP – Ephemeral Environment Manager
Internal Developer Platform for managing Kubernetes environments with GitOps automation
Automated ephemeral environments for development and testing
Architectural Components
Layer | Component | Purpose |
---|---|---|
Compute | GKE Autopilot |
Server-less Kubernetes cluster that runs all workloads. Billed only for pod resources actually used.
≈ $25–$40 / month for always-on system components; ephemeral apps cost only the CPU/RAM they request. |
GitOps | ArgoCD (App-of-Apps) | Declarative delivery of every environment. One root Application manages sub-Applications, one per PR/feature branch. |
Persistence | Firestore + GCS | Firestore stores environment metadata (state, owner, timestamps, URLs). GCS keeps build artifacts and logs. |
AuthN/AuthZ | Firebase Auth | Free tier covers ≈ 10k active users/month – ideal for internal & external collaborators. |
Cache/Realtime | Redis | Fast lookups & pub/sub for UI updates. Deployed as a Helm sub-chart. |
IaC | Terraform | Creates base infrastructure: GKE cluster, ArgoCD install, GCS bucket, Firestore, and Firebase project linkage. |
Frontend | HTMX + Alpine.js | Server-side rendered interface with reactive components for real-time environment management. |
Backend | Python FastAPI | RESTful API with async operations, real-time SSE, and comprehensive environment lifecycle management. |
High-Level Architecture
Core Workflows
1. Creating an Environment
- 1. Client/CI sends
POST /api/environments
with environment specification - 2.
EnvironmentService.create_environment
:- • Generates unique IDs & names (e.g.,
pr-42
) - • Renders Jinja2 ArgoCD Application manifest
- • Creates Application CR in Kubernetes
- • Persists metadata in Firestore & caches in Redis
- • Generates unique IDs & names (e.g.,
- 3. ArgoCD detects the new Application and syncs it
- 4. Kubernetes namespace + workload Helm chart is deployed
- 5. Environment URL is returned and displayed in UI
Complete environment creation workflow showing authentication, validation, ArgoCD integration, and resource provisioning with error handling.
This diagram shows the complete flow including authentication, validation, ArgoCD sync waves, and error handling paths
2. Deleting an Environment
- 1. Client triggers
DELETE /api/environments/{env_id}
- 2.
EnvironmentService.delete_environment
removes the ArgoCD Application - 3. ArgoCD's cascading deletion removes all Kubernetes resources
- 4. Firestore record is archived and cache evicted
3. Infrastructure Bootstrap
# Inside blueberry-terraform/
terraform init -backend-config="backend/dev.tfvars"
terraform workspace select dev || terraform workspace new dev
terraform apply -var-file="variables/dev.auto.tfvars" -auto-approve
Sets up GKE Autopilot, ArgoCD, Firestore, GCS, Firebase, and Redis.
REST API (FastAPI)
Method | Path | Description |
---|---|---|
POST | /api/environments | Create a new ephemeral environment |
GET | /api/environments | List environments (supports pagination & filters) |
GET | /api/environments/{env_id} | Retrieve one environment |
DELETE | /api/environments/{env_id} | Tear down an environment |
SSE | /api/events/environments | Server-Sent Events stream for real-time status |
GET | /api/repositories | Manage connected Git repositories |
GET | /api/config-sets | Manage reusable configuration templates |
GET | /api/tokens | Manage API tokens for programmatic access |
Data Models (Pydantic)
from pydantic import BaseModel, HttpUrl, Field
from datetime import datetime
from typing import Optional, Literal
class EnvironmentCreate(BaseModel):
name: str = Field(..., example="pr-42")
repository_id: str = Field(..., description="Connected repository ID")
branch: str = Field(default="main")
config_set_id: Optional[str] = Field(None, description="Configuration template")
ttl_hours: int = Field(default=72, ge=1, le=168)
helm_values_override: Optional[dict] = Field(None)
class EnvironmentResponse(BaseModel):
id: str
name: str
status: Literal["pending", "ready", "failed", "deleting", "terminated"]
urls: list[str]
created_at: datetime
expires_at: Optional[datetime]
terminated_at: Optional[datetime]
git: GitInfo
kubernetes: KubernetesInfo
Local Development
Prerequisites
1. GCP Authentication
Set up credentials to access Firestore and other GCP services:
# Recommended: Use gcloud CLI
gcloud auth application-default login
gcloud config set project YOUR_PROJECT_ID
See Authentication Setup for detailed instructions.
2. Environment Variables
Copy .env.example
to .env
and configure:
PROJECT_ID=your-gcp-project
FIREBASE_API_KEY=your-firebase-api-key
FIREBASE_PROJECT=your-firebase-project
ENVIRONMENT=development
3. Run Development Server
# Using Make (recommended)
make dev
# Or manually
uvicorn blueberry.app:app --reload --host 0.0.0.0 --port 8000
Common Issues
- 500 Error on Config Sets page: Configure GCP credentials. See the authentication guide.
- Firebase Auth errors: Ensure Firebase API key is correctly set in
.env
. - Kubernetes connection issues: Verify
kubeconfig
access to your development cluster.
Why Firebase Auth?
Firebase Authentication provides a robust solution that supports password authentication, SSO, and anonymous auth, making it ideal for both internal engineers and external contributors.
✅ Benefits
- • Free tier: 10k monthly active users
- • Multiple authentication providers
- • Built-in security features
- • Easy integration with GCP services
🔧 Supported Providers
- • Email/Password authentication
- • Google OAuth integration
- • GitHub OAuth (configurable)
- • Custom SAML providers
Quick Links
Happy shipping with Blueberry! 🫐