Files
vgui-cicd/docs/kubernetes-secrets.md
Adrian A. Baumann e8f34f7fa5
Some checks failed
Build containers when image tags change / build-if-image-changed (., web, containers, main container, git.baumann.gr/adebaumann/vui) (push) Successful in 39s
Build containers when image tags change / build-if-image-changed (data-loader, loader, initContainers, init-container, git.baumann.gr/adebaumann/vui-data-loader) (push) Successful in 4s
SonarQube Scan / SonarQube Trigger (push) Failing after 47s
Django options pulled out into configmap; Docker build should now succeed despite no ENV-var with secret
2026-01-15 16:34:56 +01:00

13 KiB

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):

# 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):

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

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

env:
# Secret configuration
- name: VORGABENUI_SECRET
  valueFrom:
    secretKeyRef:
      name: vorgabenui-secrets
      key: vorgabenui_secret

ConfigMap Variables:

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

kubectl get configmap django-config -n vorgabenui
kubectl describe configmap django-config -n vorgabenui

Check Secret:

kubectl get secrets vorgabenui-secrets -n vorgabenui
kubectl describe secret vorgabenui-secrets -n vorgabenui

Check Django pods can access configuration:

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

# 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:
    # 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):

    ./scripts/deploy-argocd-configmap.sh
    
  2. Secret second (contains sensitive data):

    ./scripts/deploy-argocd-secret.sh
    
  3. Application deployment (ArgoCD will sync this automatically):

    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.