Files
vgui-cicd/docs/kubernetes-secrets.md
Adrian A. Baumann ffda7ca601
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 2m9s
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 9s
SonarQube Scan / SonarQube Trigger (push) Failing after 2m29s
SECRET_KEY now uses a kubernetes secret with a fallback value for local testing
2026-01-15 16:04:25 +01:00

8.4 KiB

Kubernetes Secret Management for VorgabenUI Django

This document describes how to manage Django's SECRET_KEY using Kubernetes secrets with the VORGABENUI_SECRET environment variable.

Overview

The Django SECRET_KEY has been moved from hardcoded configuration to a Kubernetes secret for improved security. This change ensures that:

  1. The SECRET_KEY is not stored in version control
  2. Different environments can use different keys
  3. Key rotation is easier to manage
  4. Follows Kubernetes security 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

  • templates/secret.yaml - Secret template (excluded from ArgoCD deployment)
  • argocd/secret.yaml - ArgoCD-specific secret template with ignore annotation
  • argocd/deployment.yaml - Updated with environment variable configuration
  • scripts/deploy-argocd-secret.sh - ArgoCD-specific script to deploy secrets
  • .argocdignore - ArgoCD ignore patterns for templates and scripts
  • 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 the Secret (ArgoCD Production)

For the ArgoCD production deployment, use the dedicated script:

# 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

2. Deploy Secret for Other Environments

For development or other environments, use the general script:

# Deploy to vorgabenui namespace (default)
./scripts/deploy-django-secret.sh

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

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

3. Environment Variable Configuration

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

env:
- name: VORGABENUI_SECRET
  valueFrom:
    secretKeyRef:
      name: vorgabenui-secrets
      key: vorgabenui_secret

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

4. Verify the Deployment

Check that the secret was created:

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

Check that Django pods can access the secret:

kubectl exec -n vorgabenui deployment/django -- printenv VORGABENUI_SECRET

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
  3. Production safety: Fallback only works when DEBUG=True or DEBUG env var is set

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 DEBUG=False. Check:

  1. The secret exists: kubectl get secret vorgabenui-secrets -n vorgabenui
  2. The deployment references the secret correctly
  3. The pod has the environment variable: kubectl exec <pod-name> -n vorgabenui -- env | grep VORGABENUI_SECRET
  4. For local development, ensure DEBUG=True to use the fallback key

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 Script (deploy-argocd-secret.sh)

This script is specifically for ArgoCD production deployment:

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