Environment Configuration
Manage deployment environments across the Olympus Cloud platform.
Overview
Olympus Cloud uses three primary environments:
| Environment | Purpose | Domain | GCP Project |
|---|---|---|---|
| Development | Development and testing | *.dev.olympuscloud.ai | olympuscloud-dev |
| Staging | Pre-production validation | *.staging.olympuscloud.ai | olympuscloud-staging |
| Production | Live customer traffic | *.olympuscloud.ai | olympuscloud-prod |
Environment Hierarchy
┌─────────────────────────────────────────────────────────────────┐
│ Production │
│ • Real customer data • Full redundancy │
│ • High availability • Strict change control │
├─────────────────────────────────────────────────────────────────┤
│ Staging │
│ • Production-like config • Integration testing │
│ • Synthetic data • Performance testing │
├─────────────────────────────────────────────────────────────────┤
│ Development │
│ • Rapid iteration • Unit testing │
│ • Feature branches • GCP dev project │
└─────────────────────────────────────────────────────────────────┘
Configuration Files
Terraform Variables
# environments/dev/terraform.tfvars
project_id = "olympuscloud-dev"
environment = "dev"
region = "us-central1"
# Compute
cloud_run_min_instances = 0
cloud_run_max_instances = 10
# Database
spanner_instance_config = "regional-us-central1"
spanner_processing_units = 100
# Networking
enable_private_networking = false
# environments/staging/terraform.tfvars
project_id = "olympuscloud-staging"
environment = "staging"
region = "us-central1"
cloud_run_min_instances = 1
cloud_run_max_instances = 20
spanner_instance_config = "regional-us-central1"
spanner_processing_units = 500
enable_private_networking = true
# environments/prod/terraform.tfvars
project_id = "olympuscloud-prod"
environment = "prod"
region = "us-central1"
cloud_run_min_instances = 2
cloud_run_max_instances = 100
spanner_instance_config = "nam3" # Multi-region
spanner_processing_units = 2000
enable_private_networking = true
Application Configuration
# config/environments/development.yaml
environment: development
log_level: debug
database:
instance: dev-olympus-spanner
database: olympus-db
pool_size: 10
cache:
host: ${REDIS_HOST} # Memorystore private IP
port: 6378
tls: true
features:
debug_mode: true
mock_payments: true
seed_data: true
# config/environments/production.yaml
environment: production
log_level: info
database:
instance: prod-olympus-spanner
database: olympus-db
pool_size: 50
cache:
host: redis.olympuscloud.internal
port: 6379
tls: true
# TLS Note: Memorystore uses a private CA. All services skip CA
# verification while keeping encryption active. See below.
features:
debug_mode: false
mock_payments: false
seed_data: false
Google Cloud Memorystore uses a private self-signed CA not in any public trust store. All services automatically skip CA verification while keeping TLS encryption active. This is safe because connections travel over private VPC within Google's network.
- Rust: Uses
#insecureURL fragment (tls-rustls-insecurefeature) - Go: Sets
TLSConfig.InsecureSkipVerify = trueforrediss://URLs - Python: Sets
ssl_cert_reqs = ssl.CERT_NONEforrediss://URLs
No REDIS_CA_CERT environment variable is needed. Connection strings use rediss:// protocol (note the double s) to enable TLS.
Secrets Management
Google Secret Manager
# Create secret
echo -n "secret-value" | gcloud secrets create api-key \
--project olympuscloud-prod \
--data-file=-
# Add version
echo -n "new-secret-value" | gcloud secrets versions add api-key \
--project olympuscloud-prod \
--data-file=-
# Access secret
gcloud secrets versions access latest \
--secret api-key \
--project olympuscloud-prod
Secret Structure
projects/olympuscloud-prod/secrets/
├── database-password
├── jwt-signing-key
├── stripe-api-key
├── stripe-webhook-secret
├── sendgrid-api-key
├── cloudflare-api-token
├── sentry-dsn
└── encryption-master-key
Environment-Specific Secrets
# Development
gcloud secrets create stripe-api-key-dev \
--project olympuscloud-dev
# Staging
gcloud secrets create stripe-api-key-staging \
--project olympuscloud-staging
# Production
gcloud secrets create stripe-api-key-prod \
--project olympuscloud-prod
Application Access
// src/config.rs
use google_cloud_secretmanager::client::SecretManagerServiceClient;
pub async fn load_secret(name: &str) -> Result<String> {
let client = SecretManagerServiceClient::new().await?;
let secret_name = format!(
"projects/{}/secrets/{}/versions/latest",
std::env::var("GCP_PROJECT")?,
name
);
let response = client.access_secret_version(&secret_name).await?;
let payload = response.payload.ok_or(Error::NoPayload)?;
String::from_utf8(payload.data)
.map_err(|e| Error::InvalidSecret(e.to_string()))
}
Feature Flags
Configuration
# config/feature_flags.yaml
flags:
voice_ordering:
description: "Enable voice AI ordering"
default: false
environments:
development: true
staging: true
production: false
new_checkout:
description: "New checkout flow"
default: false
rollout:
staging: 100
production: 10 # 10% rollout
ai_recommendations:
description: "AI-powered menu recommendations"
default: true
tenant_overrides:
- tenant_id: "enterprise-customer"
enabled: true
Implementation
// src/features.rs
pub struct FeatureFlags {
config: FeatureConfig,
environment: Environment,
}
impl FeatureFlags {
pub fn is_enabled(&self, flag: &str, ctx: &RequestContext) -> bool {
let flag_config = match self.config.flags.get(flag) {
Some(f) => f,
None => return false,
};
// Check tenant override
if let Some(overrides) = &flag_config.tenant_overrides {
if let Some(override_) = overrides.iter()
.find(|o| o.tenant_id == ctx.tenant_id)
{
return override_.enabled;
}
}
// Check environment setting
if let Some(env_setting) = flag_config.environments.get(&self.environment) {
return *env_setting;
}
// Check rollout percentage
if let Some(rollout) = flag_config.rollout.get(&self.environment) {
let hash = hash_user(&ctx.user_id);
return (hash % 100) < *rollout;
}
flag_config.default
}
}
Database Configuration
All environments use live Cloud Spanner instances in GCP. There is no local emulator.
Cloud Spanner Instances
| Environment | GCP Project | Instance Name | Database |
|---|---|---|---|
| Dev | olympuscloud-dev | dev-olympus-spanner | olympus-db |
| Staging | olympuscloud-staging | staging-olympus-spanner | olympus-db |
| Prod | olympuscloud-prod | prod-olympus-spanner | olympus-db |
Terraform Configuration
# Cloud Spanner configuration (all environments)
resource "google_spanner_instance" "olympus" {
name = "${var.environment}-olympus-spanner"
config = var.spanner_instance_config
display_name = "Olympus ${title(var.environment)}"
processing_units = var.spanner_processing_units
labels = {
environment = var.environment
}
}
resource "google_spanner_database" "olympus" {
instance = google_spanner_instance.olympus.name
name = "olympus-db"
deletion_protection = var.environment == "prod"
ddl = [
file("${path.module}/schema/tenants.sql"),
file("${path.module}/schema/locations.sql"),
file("${path.module}/schema/orders.sql"),
]
}
Network Configuration
All environments use Cloud Run with VPC connectors. There is no Docker/localhost networking.
VPC Configuration
# VPC configuration
resource "google_compute_network" "olympus" {
name = "olympus-${var.environment}"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "services" {
name = "services-${var.environment}"
ip_cidr_range = "10.0.0.0/20"
network = google_compute_network.olympus.id
region = var.region
private_ip_google_access = true
}
# VPC Connector for Cloud Run
resource "google_vpc_access_connector" "connector" {
name = "olympus-connector-${var.environment}"
region = var.region
ip_cidr_range = "10.8.0.0/28"
network = google_compute_network.olympus.name
}
Deployment Workflow
Development
# Run tests
make test
# Deploy to dev environment
make deploy-dev
Staging
# Deploy to staging (automatic on PR merge to develop)
git push origin develop
# Manual staging deployment
make deploy-staging
Production
Production deployments require explicit approval. Never bypass the staging validation step. All changes must pass quality gates in staging before promotion to production. Running make deploy-prod without CONFIRM=yes is a safety check -- do not script around it.
# Production deployment (requires approval)
git push origin main
# Manual production deployment
make deploy-prod CONFIRM=yes
Promotion Flow
Feature Branch
│
▼
develop (auto-deploy to dev)
│
▼
staging (auto-deploy on merge)
│
▼
main (deploy with approval)
│
▼
Production
Environment Variables
Required Variables
| Variable | Dev | Staging | Prod | Description |
|---|---|---|---|---|
ENVIRONMENT | development | staging | production | Current environment |
GCP_PROJECT | olympuscloud-dev | olympuscloud-staging | olympuscloud-prod | GCP project |
LOG_LEVEL | debug | info | info | Logging verbosity |
SPANNER_INSTANCE | dev-olympus-spanner | staging-olympus-spanner | prod-olympus-spanner | Database instance |
Service URLs
| Variable | Dev | Staging | Prod |
|---|---|---|---|
API_GATEWAY_URL | https://dev.api.olympuscloud.ai/api/v1 | https://staging.api.olympuscloud.ai/api/v1 | https://api.olympuscloud.ai/api/v1 |
PLATFORM_SERVICE_URL | Internal Cloud Run URL | Internal Cloud Run URL | Internal Cloud Run URL |
COMMERCE_SERVICE_URL | Internal Cloud Run URL | Internal Cloud Run URL | Internal Cloud Run URL |
Monitoring by Environment
Alert Thresholds
| Metric | Dev | Staging | Prod |
|---|---|---|---|
| Error rate | None | > 5% | > 1% |
| Latency (p99) | None | > 1s | > 500ms |
| CPU utilization | None | > 90% | > 80% |
| Memory utilization | None | > 90% | > 85% |
Log Retention
| Environment | Retention | Archive |
|---|---|---|
| Development | 7 days | None |
| Staging | 30 days | None |
| Production | 90 days | 7 years (compliance) |
Troubleshooting
Environment Mismatch
# Verify current environment
echo $ENVIRONMENT
# Check GCP project
gcloud config get-value project
# Verify service configuration
gcloud run services describe platform-service \
--format "value(spec.template.spec.containers[0].env)"
Connection Issues
# Test database connectivity
# Instance names: dev-olympus-spanner, staging-olympus-spanner, prod-olympus-spanner
gcloud spanner databases execute-sql olympus-db \
--instance ${ENVIRONMENT}-olympus-spanner \
--sql "SELECT 1"
# Test service connectivity
curl -v https://${ENVIRONMENT}.api.olympuscloud.ai/health
Related Documentation
- Cloud Run Deployment - Service deployment
- Edge Workers - Cloudflare deployment
- Logging - Log configuration