[INFRA-008] infra: Set up environment management

This commit is contained in:
senke 2025-12-25 21:37:06 +01:00
parent ea08661fa6
commit 441937d1e3
11 changed files with 637 additions and 3 deletions

View file

@ -11482,8 +11482,19 @@
"description": "Configure separate dev, staging, and production environments",
"owner": "devops",
"estimated_hours": 4,
"status": "todo",
"files_involved": [],
"status": "completed",
"files_involved": [
"k8s/environments/namespaces.yaml",
"k8s/environments/development/configmap.yaml",
"k8s/environments/development/deployment-overrides.yaml",
"k8s/environments/staging/configmap.yaml",
"k8s/environments/staging/deployment-overrides.yaml",
"k8s/environments/production/configmap.yaml",
"k8s/environments/production/deployment-overrides.yaml",
"k8s/environments/ingress-dev.yaml",
"k8s/environments/ingress-staging.yaml",
"k8s/environments/README.md"
],
"implementation_steps": [
{
"step": 1,
@ -11503,7 +11514,17 @@
"Unit tests",
"Integration tests"
],
"notes": ""
"notes": "",
"completed_at": "2025-12-25T21:36:58.166183",
"validation": {
"yaml_syntax": "All manifests validated",
"environments": "Development, Staging, and Production environments configured",
"namespaces": "Separate namespaces for each environment with labels",
"configmaps": "Environment-specific ConfigMaps with different settings",
"deployment_overrides": "Environment-specific replica counts and resource limits",
"ingress": "Separate ingress configurations for dev (no SSL), staging (staging SSL), and production (production SSL)",
"documentation": "k8s/environments/README.md with deployment, promotion, and troubleshooting instructions"
}
},
{
"id": "INFRA-009",

295
k8s/environments/README.md Normal file
View file

@ -0,0 +1,295 @@
# Environment Management
This directory contains Kubernetes configurations for managing separate development, staging, and production environments.
## Overview
The Veza platform uses three distinct environments:
- **Development**: Local development and testing
- **Staging**: Pre-production testing and validation
- **Production**: Live production environment
## Structure
```
k8s/environments/
├── namespaces.yaml # Namespace definitions for all environments
├── development/
│ ├── configmap.yaml # Development-specific configuration
│ └── deployment-overrides.yaml # Development deployment overrides
├── staging/
│ ├── configmap.yaml # Staging-specific configuration
│ └── deployment-overrides.yaml # Staging deployment overrides
├── production/
│ ├── configmap.yaml # Production-specific configuration
│ └── deployment-overrides.yaml # Production deployment overrides
├── ingress-dev.yaml # Development ingress (no SSL)
├── ingress-staging.yaml # Staging ingress (staging SSL)
└── README.md # This file
```
## Environment Differences
### Development
- **Replicas**: 1 per service
- **Resources**: Minimal (for local development)
- **Logging**: DEBUG level
- **SSL**: Disabled
- **Rate Limiting**: Disabled
- **Profiling**: Enabled
- **CORS**: Localhost origins allowed
### Staging
- **Replicas**: 2 per service
- **Resources**: Medium
- **Logging**: INFO level
- **SSL**: Let's Encrypt staging certificates
- **Rate Limiting**: Enabled (200 req/min)
- **Profiling**: Disabled
- **CORS**: Staging domains only
- **CDN**: Enabled (staging CDN)
### Production
- **Replicas**: 3+ per service
- **Resources**: High (with autoscaling)
- **Logging**: WARN level
- **SSL**: Let's Encrypt production certificates
- **Rate Limiting**: Enabled (100 req/min)
- **Profiling**: Disabled
- **CORS**: Production domains only
- **CDN**: Enabled (production CDN)
- **Monitoring**: Full monitoring and alerting
## Deployment
### 1. Create Namespaces
```bash
kubectl apply -f k8s/environments/namespaces.yaml
```
### 2. Deploy Environment-Specific ConfigMaps
```bash
# Development
kubectl apply -f k8s/environments/development/configmap.yaml
# Staging
kubectl apply -f k8s/environments/staging/configmap.yaml
# Production
kubectl apply -f k8s/environments/production/configmap.yaml
```
### 3. Deploy Base Resources
Deploy base resources (deployments, services) to each namespace:
```bash
# Development
kubectl apply -f k8s/backend-api/ -n veza-development
kubectl apply -f k8s/frontend/ -n veza-development
kubectl apply -f k8s/chat-server/ -n veza-development
# Staging
kubectl apply -f k8s/backend-api/ -n veza-staging
kubectl apply -f k8s/frontend/ -n veza-staging
kubectl apply -f k8s/chat-server/ -n veza-staging
# Production
kubectl apply -f k8s/backend-api/ -n veza-production
kubectl apply -f k8s/frontend/ -n veza-production
kubectl apply -f k8s/chat-server/ -n veza-production
```
### 4. Apply Environment Overrides
```bash
# Development
kubectl apply -f k8s/environments/development/deployment-overrides.yaml
# Staging
kubectl apply -f k8s/environments/staging/deployment-overrides.yaml
# Production
kubectl apply -f k8s/environments/production/deployment-overrides.yaml
```
### 5. Deploy Ingress
```bash
# Development (no SSL)
kubectl apply -f k8s/environments/ingress-dev.yaml
# Staging (staging SSL)
kubectl apply -f k8s/environments/ingress-staging.yaml
# Production (production SSL - already in k8s/ingress.yaml)
kubectl apply -f k8s/ingress.yaml
```
## Configuration
### Environment Variables
Each environment has different configuration values:
#### Development
- `APP_ENV=development`
- `LOG_LEVEL=DEBUG`
- `ENABLE_PROFILING=true`
- `RATE_LIMIT_ENABLED=false`
#### Staging
- `APP_ENV=staging`
- `LOG_LEVEL=INFO`
- `ENABLE_PROFILING=false`
- `RATE_LIMIT_ENABLED=true`
- `RATE_LIMIT_LIMIT=200`
#### Production
- `APP_ENV=production`
- `LOG_LEVEL=WARN`
- `ENABLE_PROFILING=false`
- `RATE_LIMIT_ENABLED=true`
- `RATE_LIMIT_LIMIT=100`
### Secrets
Each environment should have its own secrets:
```bash
# Development secrets
kubectl create secret generic veza-secrets \
--from-literal=database-url=postgres://dev_user:dev_pass@dev-db:5432/veza_dev \
--from-literal=jwt-secret=dev-secret-key-min-32-chars \
-n veza-development
# Staging secrets
kubectl create secret generic veza-secrets \
--from-literal=database-url=postgres://staging_user:staging_pass@staging-db:5432/veza_staging \
--from-literal=jwt-secret=staging-secret-key-min-32-chars \
-n veza-staging
# Production secrets
kubectl create secret generic veza-secrets \
--from-literal=database-url=postgres://prod_user:prod_pass@prod-db:5432/veza_prod \
--from-literal=jwt-secret=production-secret-key-min-32-chars \
-n veza-production
```
## Verification
### Check Namespaces
```bash
kubectl get namespaces | grep veza
```
### Check Resources per Environment
```bash
# Development
kubectl get all -n veza-development
# Staging
kubectl get all -n veza-staging
# Production
kubectl get all -n veza-production
```
### Check ConfigMaps
```bash
kubectl get configmap veza-config -n veza-development -o yaml
kubectl get configmap veza-config -n veza-staging -o yaml
kubectl get configmap veza-config -n veza-production -o yaml
```
## Environment Promotion
### Promote from Development to Staging
```bash
# Tag images
docker tag veza-backend-api:dev veza-backend-api:staging
docker tag veza-frontend:dev veza-frontend:staging
# Push to registry
docker push veza-backend-api:staging
docker push veza-frontend:staging
# Update deployments
kubectl set image deployment/veza-backend-api \
backend-api=veza-backend-api:staging \
-n veza-staging
kubectl set image deployment/veza-frontend \
frontend=veza-frontend:staging \
-n veza-staging
```
### Promote from Staging to Production
```bash
# Tag images
docker tag veza-backend-api:staging veza-backend-api:production
docker tag veza-frontend:staging veza-frontend:production
# Push to registry
docker push veza-backend-api:production
docker push veza-frontend:production
# Update deployments
kubectl set image deployment/veza-backend-api \
backend-api=veza-backend-api:production \
-n veza-production
kubectl set image deployment/veza-frontend \
frontend=veza-frontend:production \
-n veza-production
```
## Best Practices
1. **Separate Secrets**: Never share secrets between environments
2. **Resource Limits**: Set appropriate resource limits per environment
3. **Monitoring**: Enable monitoring in staging and production
4. **Backups**: Configure backups for staging and production
5. **SSL**: Use staging certificates in staging, production in production
6. **CORS**: Restrict CORS origins per environment
7. **Logging**: Use appropriate log levels per environment
8. **Rate Limiting**: Enable in staging and production, disable in dev
## Troubleshooting
### Check Environment Configuration
```bash
# View environment config
kubectl get configmap veza-config -n veza-development -o jsonpath='{.data.app-env}'
# Check pod environment variables
kubectl exec -it deployment/veza-backend-api -n veza-development -- env | grep APP_ENV
```
### Switch Between Environments
```bash
# Set default namespace
kubectl config set-context --current --namespace=veza-development
# Or use -n flag
kubectl get pods -n veza-staging
```
### Compare Configurations
```bash
# Compare configmaps
diff <(kubectl get configmap veza-config -n veza-staging -o yaml) \
<(kubectl get configmap veza-config -n veza-production -o yaml)
```

View file

@ -0,0 +1,16 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: veza-config
namespace: veza-development
data:
app-env: "development"
api-url: "http://veza-backend-api:8080"
cors-allowed-origins: "http://localhost:3000,http://localhost:5173,http://localhost:5176"
log-level: "DEBUG"
enable-debug: "true"
enable-profiling: "true"
rate-limit-enabled: "false"
database-pool-size: "5"
redis-ttl: "3600" # 1 hour

View file

@ -0,0 +1,54 @@
# Development environment overrides
# These values override the base deployment for development
apiVersion: apps/v1
kind: Deployment
metadata:
name: veza-backend-api
namespace: veza-development
spec:
replicas: 1 # Single replica for dev
template:
spec:
containers:
- name: backend-api
env:
- name: APP_ENV
value: "development"
- name: LOG_LEVEL
value: "DEBUG"
- name: ENABLE_PROFILING
value: "true"
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: veza-frontend
namespace: veza-development
spec:
replicas: 1 # Single replica for dev
template:
spec:
containers:
- name: frontend
env:
- name: VITE_APP_ENV
value: "development"
- name: VITE_API_URL
value: "http://localhost:8080"
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "128Mi"

View file

@ -0,0 +1,32 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: veza-ingress-dev
namespace: veza-development
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false" # No SSL in dev
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
spec:
rules:
- host: dev.veza.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: veza-frontend
port:
number: 80
- host: api-dev.veza.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: veza-backend-api
port:
number: 8080

View file

@ -0,0 +1,38 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: veza-ingress-staging
namespace: veza-staging
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-staging # Use staging issuer
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- hosts:
- staging.veza.com
- api-staging.veza.com
secretName: veza-tls-staging
rules:
- host: staging.veza.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: veza-frontend
port:
number: 80
- host: api-staging.veza.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: veza-backend-api
port:
number: 8080

View file

@ -0,0 +1,32 @@
# Namespaces for different environments
---
apiVersion: v1
kind: Namespace
metadata:
name: veza-development
labels:
name: veza-development
environment: development
tier: development
---
apiVersion: v1
kind: Namespace
metadata:
name: veza-staging
labels:
name: veza-staging
environment: staging
tier: staging
---
apiVersion: v1
kind: Namespace
metadata:
name: veza-production
labels:
name: veza-production
environment: production
tier: production

View file

@ -0,0 +1,22 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: veza-config
namespace: veza-production
data:
app-env: "production"
api-url: "http://veza-backend-api:8080"
cors-allowed-origins: "https://app.veza.com,https://veza.com"
log-level: "WARN"
enable-debug: "false"
enable-profiling: "false"
rate-limit-enabled: "true"
rate-limit-limit: "100"
rate-limit-window: "60"
database-pool-size: "20"
redis-ttl: "86400" # 24 hours
cdn-enabled: "true"
cdn-base-url: "https://cdn.veza.com"
monitoring-enabled: "true"
alerting-enabled: "true"

View file

@ -0,0 +1,52 @@
# Production environment overrides
# These values override the base deployment for production
apiVersion: apps/v1
kind: Deployment
metadata:
name: veza-backend-api
namespace: veza-production
spec:
replicas: 3 # 3+ replicas for production
template:
spec:
containers:
- name: backend-api
env:
- name: APP_ENV
value: "production"
- name: LOG_LEVEL
value: "WARN"
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2000m"
memory: "2Gi"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: veza-frontend
namespace: veza-production
spec:
replicas: 3 # 3+ replicas for production
template:
spec:
containers:
- name: frontend
env:
- name: VITE_APP_ENV
value: "production"
- name: VITE_API_URL
value: "https://api.veza.com"
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"

View file

@ -0,0 +1,20 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: veza-config
namespace: veza-staging
data:
app-env: "staging"
api-url: "http://veza-backend-api:8080"
cors-allowed-origins: "https://staging.veza.com,https://staging-app.veza.com"
log-level: "INFO"
enable-debug: "false"
enable-profiling: "false"
rate-limit-enabled: "true"
rate-limit-limit: "200"
rate-limit-window: "60"
database-pool-size: "10"
redis-ttl: "7200" # 2 hours
cdn-enabled: "true"
cdn-base-url: "https://cdn-staging.veza.com"

View file

@ -0,0 +1,52 @@
# Staging environment overrides
# These values override the base deployment for staging
apiVersion: apps/v1
kind: Deployment
metadata:
name: veza-backend-api
namespace: veza-staging
spec:
replicas: 2 # 2 replicas for staging
template:
spec:
containers:
- name: backend-api
env:
- name: APP_ENV
value: "staging"
- name: LOG_LEVEL
value: "INFO"
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "1Gi"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: veza-frontend
namespace: veza-staging
spec:
replicas: 2 # 2 replicas for staging
template:
spec:
containers:
- name: frontend
env:
- name: VITE_APP_ENV
value: "staging"
- name: VITE_API_URL
value: "https://api-staging.veza.com"
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"