# 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 -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.