# Kubernetes Configuration Management for VorgabenUI Django

This document describes how to manage Django configuration using Kubernetes secrets and ConfigMaps.

## Overview

Django configuration has been moved to Kubernetes-native resources for improved security and flexibility:

### **Secrets** (for sensitive data)
- `VORGABENUI_SECRET` - Django SECRET_KEY
- Future: Database passwords, API keys, etc.

### **ConfigMaps** (for non-sensitive configuration)
- `DEBUG` - Debug mode setting
- `DJANGO_ALLOWED_HOSTS` - Allowed hostnames
- `DJANGO_SETTINGS_MODULE` - Settings module path
- Application configuration settings

This approach ensures that:

1. Sensitive data is not stored in version control
2. Configuration is environment-specific
3. Non-sensitive settings are easily manageable
4. Follows Kubernetes best practices
5. Includes fallback for local development

## Files Changed

### VorgabenUI/settings.py
- Replaced hardcoded `SECRET_KEY` with `VORGABENUI_SECRET` environment variable lookup
- Added fallback secret key for local development (only works when DEBUG=True)
- Added warning when fallback key is used

### Files Created/Updated

#### **Configuration Resources**
- `argocd/configmap.yaml` - Django configuration (DEBUG, ALLOWED_HOSTS, etc.)
- `templates/configmap.yaml` - ConfigMap template (excluded from ArgoCD)
- `templates/secret.yaml` - Secret template (excluded from ArgoCD deployment)
- `argocd/secret.yaml` - ArgoCD-specific secret template with ignore annotation

#### **Deployment Configuration**
- `argocd/deployment.yaml` - Updated with Secret and ConfigMap environment variables
- `.argocdignore` - ArgoCD ignore patterns for templates and scripts

#### **Deployment Scripts**
- `scripts/deploy-argocd-secret.sh` - ArgoCD-specific script to deploy secrets
- `scripts/deploy-argocd-configmap.sh` - ArgoCD-specific script to deploy ConfigMap

#### **Application Code**
- `VorgabenUI/settings.py` - Updated to use environment variables from ConfigMap

#### **Examples and Documentation**
- `k8s/django-secret.yaml` - Updated for consistency (vorgabenui namespace)
- `k8s/django-deployment-example.yaml` - Updated example deployment
- `scripts/deploy-django-secret.sh` - Updated with new defaults

## Usage

### 1. Deploy ConfigMap (ArgoCD Production)

**Deploy configuration first** (required before the application starts):

```bash
# Deploy ConfigMap to vorgabenui namespace
./scripts/deploy-argocd-configmap.sh

# Verify existing ConfigMap
./scripts/deploy-argocd-configmap.sh --verify-only

# Dry run to see what would happen
./scripts/deploy-argocd-configmap.sh --dry-run

# Get help
./scripts/deploy-argocd-configmap.sh --help
```

### 2. Deploy the Secret (ArgoCD Production)

**Deploy secret second** (contains sensitive SECRET_KEY):

```bash
# Deploy secret to vorgabenui namespace
./scripts/deploy-argocd-secret.sh

# Verify existing secret
./scripts/deploy-argocd-secret.sh --verify-only

# Dry run to see what would happen
./scripts/deploy-argocd-secret.sh --dry-run

# Get help
./scripts/deploy-argocd-secret.sh --help
```

### 3. Deploy Resources for Other Environments

For development or other environments, use the general scripts:

```bash
# Deploy ConfigMap to vorgabenui namespace (default)
./scripts/deploy-django-secret.sh  # (includes ConfigMap deployment)

# Deploy to specific namespace
./scripts/deploy-django-secret.sh -n development

# Get help
./scripts/deploy-django-secret.sh --help
```

### 4. Environment Variable Configuration

The ArgoCD deployment (`argocd/deployment.yaml`) is configured with:

**Secret Variables:**
```yaml
env:
# Secret configuration
- name: VORGABENUI_SECRET
  valueFrom:
    secretKeyRef:
      name: vorgabenui-secrets
      key: vorgabenui_secret
```

**ConfigMap Variables:**
```yaml
# ConfigMap configuration
- name: DEBUG
  valueFrom:
    configMapKeyRef:
      name: django-config
      key: DEBUG
- name: DJANGO_ALLOWED_HOSTS
  valueFrom:
    configMapKeyRef:
      name: django-config
      key: DJANGO_ALLOWED_HOSTS
- name: DJANGO_SETTINGS_MODULE
  valueFrom:
    configMapKeyRef:
      name: django-config
      key: DJANGO_SETTINGS_MODULE
```

For other deployments, see `k8s/django-deployment-example.yaml` for a complete example.

### 5. Verify the Deployment

**Check ConfigMap:**
```bash
kubectl get configmap django-config -n vorgabenui
kubectl describe configmap django-config -n vorgabenui
```

**Check Secret:**
```bash
kubectl get secrets vorgabenui-secrets -n vorgabenui
kubectl describe secret vorgabenui-secrets -n vorgabenui
```

**Check Django pods can access configuration:**
```bash
# Check secret variable
kubectl exec -n vorgabenui deployment/django -- printenv VORGABENUI_SECRET

# Check ConfigMap variables
kubectl exec -n vorgabenui deployment/django -- printenv DEBUG
kubectl exec -n vorgabenui deployment/django -- printenv DJANGO_ALLOWED_HOSTS

# Check all environment variables
kubectl exec -n vorgabenui deployment/django -- printenv | grep -E "(VORGABENUI|DEBUG|DJANGO)"
```

## Development Environment

### Local Development with Fallback

The application now includes a fallback secret key for local development. When running locally:

1. **Automatic fallback**: If `VORGABENUI_SECRET` is not set and `DEBUG=True`, a fallback key is used automatically
2. **Warning message**: The application will log a warning when using the fallback key (except during builds)
3. **Production safety**: Fallback only works when `DEBUG=True` or in build environments

### Docker Build Support

The Django settings are designed to work seamlessly during Docker builds:

1. **Build environment detection**: Automatically detects Docker builds, CI environments
2. **Fallback activation**: Uses fallback key during build without requiring environment variables
3. **No build-time secrets**: No need to provide `VORGABENUI_SECRET` during `docker build`
4. **Runtime security**: Production containers still require the proper environment variable

**Supported build environments:**
- Docker builds (`DOCKER_BUILDKIT`)
- CI environments (`CI`)
- GitHub Actions (`GITHUB_ACTIONS`)
- Gitea Actions (`GITEA_ACTIONS`)
- Local development (`DEBUG=True`)

### Manual Environment Variable

You can still set the environment variable manually:

```bash
# Option 1: Export the variable
export VORGABENUI_SECRET="your-development-key-here"
python manage.py runserver

# Option 2: Use a .env file (recommended)
echo "VORGABENUI_SECRET=your-development-key-here" > .env
# Then load it in your settings or use python-dotenv
```

### Development vs Production

- **Local Development**: Fallback key works automatically when `DEBUG=True`
- **Production**: Must have `VORGABENUI_SECRET` environment variable set, no fallback

## ArgoCD Integration and Exclusions

### Preventing ArgoCD from Deploying Secret Templates

This setup includes multiple approaches to prevent ArgoCD from trying to deploy the secret template:

#### 1. Template Directory (`templates/`)
- Secret template moved to `templates/` directory
- ArgoCD deployment script automatically uses this location
- Excluded via `.argocdignore` file

#### 2. ArgoCD Ignore Annotation
- `argocd/secret.yaml` has `argocd.argoproj.io/ignore: "true"` annotation
- Provides fallback if templates directory approach fails

#### 3. `.argocdignore` File
- Global exclusion patterns for templates, scripts, and documentation
- Prevents ArgoCD from syncing non-deployment files

### ArgoCD Sync Behavior
- ArgoCD will sync only the actual deployment files (`deployment.yaml`, `ingress.yaml`, etc.)
- Secret templates are excluded and must be deployed manually using the deployment script
- This ensures secrets are created outside of GitOps workflow for security

## Security Considerations

1. **Never commit the actual SECRET_KEY** - Only templates and scripts are in version control
2. **Use different keys per environment** - Production, staging, and development should all have unique keys
3. **Rotate keys regularly** - Run the deployment script periodically to generate new keys
4. **Limit access** - Use Kubernetes RBAC to control who can access secrets
5. **ArgoCD exclusion** - Secret templates are excluded from ArgoCD to prevent empty/template secrets from being deployed

## Troubleshooting

### Django fails to start with "VORGABENUI_SECRET environment variable is required"

This means the environment variable is not set in your pod and fallback conditions aren't met. Check:

1. **Secret exists**: `kubectl get secret vorgabenui-secrets -n vorgabenui`
2. **Deployment references secret correctly**: Check `argocd/deployment.yaml` env section
3. **Pod has environment variable**: `kubectl exec <pod-name> -n vorgabenui -- env | grep VORGABENUI_SECRET`
4. **For local development**: Ensure `DEBUG=True` to use the fallback key
5. **For Docker builds**: Build should work automatically with fallback

### Docker build fails with SECRET_KEY error

This should no longer happen with the updated settings. If you still see issues:

1. **Check build environment variables**: Build should detect `DOCKER_BUILDKIT=1`
2. **Verify settings changes**: Ensure the updated `settings.py` is being used
3. **Force environment detection**: Set `CI=1` during build if needed
4. **Use explicit DEBUG**: Set `DEBUG=True` during build as fallback

### Secret deployment fails

Check that:

1. You have kubectl access to the cluster
2. You have permission to create secrets in the `vorgabenui` namespace
3. Python3 is available for key generation
4. The ArgoCD secret template exists: `argocd/secret.yaml`

### Key rotation

To rotate the SECRET_KEY:

1. **For ArgoCD production**: Run `./scripts/deploy-argocd-secret.sh` again
2. **For other environments**: Run `./scripts/deploy-django-secret.sh` again  
3. Restart your Django pods to pick up the new key:
   ```bash
   # For ArgoCD production
   kubectl rollout restart deployment/django -n vorgabenui
   
   # For other environments
   kubectl rollout restart deployment/your-django-deployment -n your-namespace
   ```

## Script Options

### ArgoCD Production Scripts

#### **ConfigMap Script (`deploy-argocd-configmap.sh`)**

Deploy Django configuration (non-sensitive):

- `--verify-only` - Only verify existing ConfigMap, don't deploy
- `--dry-run` - Show what would be deployed without applying
- `-h, --help` - Show help message

Configuration is hardcoded for ArgoCD:
- Namespace: `vorgabenui`
- ConfigMap name: `django-config`
- ConfigMap file: `argocd/configmap.yaml`

#### **Secret Script (`deploy-argocd-secret.sh`)**

Deploy sensitive configuration:

- `--verify-only` - Only verify existing secret, don't create new one
- `--dry-run` - Show what would be done without making changes  
- `-h, --help` - Show help message

Configuration is hardcoded for ArgoCD:
- Namespace: `vorgabenui`
- Secret name: `vorgabenui-secrets`
- Secret key: `vorgabenui_secret`
- Template location: `templates/secret.yaml` (excluded from ArgoCD)

### General Script (`deploy-django-secret.sh`)

For development and other environments:

- `-n, --namespace NAMESPACE` - Target Kubernetes namespace (default: vorgabenui)
- `-s, --secret-name NAME` - Secret name (default: vorgabenui-secrets)
- `-k, --key-name NAME` - Secret key name (default: vorgabenui_secret)
- `-h, --help` - Show help message

Environment variables:
- `NAMESPACE` - Override default namespace

## Migration from Hardcoded Key

### Migration from Old Setup

If you're migrating from the previous `DJANGO_SECRET_KEY` setup:

1. **Deploy the new secret** using `./scripts/deploy-argocd-secret.sh`
2. **Update any existing deployments** to use `VORGABENUI_SECRET` instead of `DJANGO_SECRET_KEY`
3. **Test locally** - the fallback key should work automatically in DEBUG mode
4. **Deploy the updated application** - ArgoCD deployment is already configured

### Migration from Hardcoded Key

If you're migrating from a completely hardcoded key:

1. **Backup your current key** (in case you need to rollback)
2. **Deploy the secret first** using the deployment script
3. **Apply the updated ArgoCD deployment** (already done in this setup)
4. **Test thoroughly** - local development should work with fallback
5. **Deploy the updated settings.py** after confirming the secret works

The ArgoCD deployment (`argocd/deployment.yaml`) now includes the environment variable configuration, so Django will automatically pick up the secret after deployment.

## Deployment Order

**Critical: Deploy resources in this order:**

1. **ConfigMap first** (required for Django to start):
   ```bash
   ./scripts/deploy-argocd-configmap.sh
   ```

2. **Secret second** (contains sensitive data):
   ```bash
   ./scripts/deploy-argocd-secret.sh
   ```

3. **Application deployment** (ArgoCD will sync this automatically):
   ```bash
   kubectl apply -f argocd/deployment.yaml
   # OR let ArgoCD sync from Git
   ```

If you deploy in the wrong order, Django pods will fail to start because they require both the ConfigMap and Secret to be available.