# Azure AKS Example Values for the RegScale Orchestration Hub Helm Chart
#
# This example deploys the Orchestration Hub on Azure AKS with Azure SQL, an
# in-cluster Redis instance installed by the chart, Workload Identity for pod
# identity, and an nginx ingress.
#
# Download and use:
#   curl -O https://regscale.github.io/helm/roh-azure-values.yaml
#   helm install roh regscale/regscale-orchestration-hub \
#     --namespace regscale --create-namespace -f roh-azure-values.yaml
#
# Replace every REPLACE- placeholder before installing. Full procedure:
#   https://regscale.github.io/helm/roh-setup.html
#
# Cluster prerequisites this file assumes:
#   - KEDA (workers.scaling.mode is keda below)
#   - An nginx ingress controller (app.ingress.className is nginx below)
#   - Prometheus Operator CRDs (monitoring options are enabled below)

# ---------------------------------------------------------------------------
# Core wiring. Both values are required.
# ---------------------------------------------------------------------------

# Address of the core RegScale instance. ROH delegates authentication to it.
# Use the in-cluster service DNS name where core runs in the same cluster; the
# core chart names its Service <release>-svc.
regscaleUrl: "http://regscale-svc.regscale.svc.cluster.local"

# Core 6.34 fails every ROH login that it does not see as HTTPS. This proxy (in the
# chart) forwards to regscaleUrl with X-Forwarded-Proto: https, and ROH calls it. It
# does nothing for an https regscaleUrl. Also set ForwardedHeaders on core: see
# roh-setup.md, "Make core see ROH logins as HTTPS".
coreProxy:
  enabled: true

# Synqly Embedded is on by default (chart 0.3.0). Either add
#   -f values-synqly.yaml
# (roh-setup.md, "Synqly Embedded"), or turn it off here:
# synqly:
#   enabled: false

# Namespaces this deployment's Redis keys. Must be unique per deployment: two
# deployments sharing a Redis instance with the same prefix consume each
# other's queued jobs.
prefixNamespace: "REPLACE-unique-name"

# ---------------------------------------------------------------------------
# Secrets
# ---------------------------------------------------------------------------
# Create the Secret before installing, so credentials are not recorded in
# shell history or Helm release metadata. Required keys:
#
#   SECRET_KEY               at least 32 characters
#   SECRETS_ENCRYPTION_KEY   exactly 32 characters, and cannot be rotated
#   DATABASE_URL             mssql+pymssql://user:pass@host:1433/db
#   REDIS_URL                redis://:PASSWORD@<release>-redis-master:6379/0
#   METRICS_TOKEN            any value
#   REDIS_PASSWORD           the same password embedded in REDIS_URL
#
# REDIS_PASSWORD is read by both the Bitnami Redis subchart and the KEDA
# trigger, which cannot extract it from REDIS_URL.
#
# kubectl create secret generic roh-secrets --namespace regscale \
#   --from-literal=SECRET_KEY="$(openssl rand -hex 32)" \
#   --from-literal=SECRETS_ENCRYPTION_KEY="$(openssl rand -hex 16)" \
#   --from-literal=METRICS_TOKEN="$(openssl rand -hex 32)" \
#   --from-literal=DATABASE_URL='mssql+pymssql://roh:REPLACE@REPLACE.database.windows.net:1433/roh' \
#   --from-literal=REDIS_URL='redis://:REPLACE-redis-password@roh-redis-master:6379/0' \
#   --from-literal=REDIS_PASSWORD='REPLACE-redis-password'
secrets:
  existingSecret: "roh-secrets"

# ---------------------------------------------------------------------------
# Database: Azure SQL
# ---------------------------------------------------------------------------
# The connection string is supplied through DATABASE_URL in the Secret above.
# The in-cluster SQL Server option is for development and test only.
database:
  incluster:
    enabled: false

# ---------------------------------------------------------------------------
# Redis: in-cluster, installed by the chart
# ---------------------------------------------------------------------------
# The Bitnami subchart reads its password from the Secret above rather than
# generating one, so the subchart and the chart-rendered REDIS_URL agree.
#
# To use Azure Cache for Redis instead, set mode to managed, enabled to false,
# and managed.url to the connection string. Cluster mode must be disabled,
# because Celery's Kombu library does not support Redis OSS cluster mode. Use
# the rediss:// scheme for a TLS-only endpoint; the chart derives KEDA's
# enableTLS setting from it.
redis:
  mode: incluster
  enabled: true
  auth:
    enabled: true
    existingSecret: roh-secrets
    existingSecretPasswordKey: REDIS_PASSWORD
  master:
    persistence:
      enabled: true
      size: 8Gi
    configuration: |-
      maxmemory-policy noeviction

# ---------------------------------------------------------------------------
# Application tier
# ---------------------------------------------------------------------------
app:
  replicaCount: 2

  # REQUIRED. The application image entrypoint is supervisord, which must start
  # as root in order to change to the service account user. Without this
  # override both replicas enter CrashLoopBackOff reporting
  # "Can't drop privilege as nonroot user".
  #
  # capabilities.drop must be set to an empty list explicitly. Helm replaces
  # list values rather than merging them, but only where the key is supplied;
  # omitting it leaves drop: [ALL] in effect, which removes the SETUID and
  # SETGID capabilities supervisord requires.
  #
  # This applies to the application tier only. The worker and scheduler tiers
  # retain the chart's hardened defaults.
  podSecurityContext:
    runAsNonRoot: false
    runAsUser: 0
    runAsGroup: 0
    fsGroup: 0
  securityContext:
    runAsNonRoot: false
    runAsUser: 0
    allowPrivilegeEscalation: true
    readOnlyRootFilesystem: false
    capabilities:
      drop: []

  resources:
    limits: {cpu: 2, memory: 4Gi}
    requests: {cpu: 1, memory: 2Gi}

  # Requires an nginx ingress controller. websocket: true adds the long
  # proxy read timeout needed by the /api/v1/executions stream.
  ingress:
    enabled: true
    className: nginx
    websocket: true
    hosts:
      - host: REPLACE-roh.example.com
        paths:
          - {path: /, pathType: Prefix}

# ---------------------------------------------------------------------------
# Workers
# ---------------------------------------------------------------------------
# Queue-depth autoscaling with KEDA, which is a cluster prerequisite. Pools
# with min 0 consume no resources while idle, at the cost of a cold start on
# the next job. Do not reduce gracePeriod below the longest expected job
# duration: scale-down drains workers rather than terminating running jobs.
workers:
  scaling:
    mode: keda
  queues:
    cli_tasks:   {min: 0, max: 12, queueLength: 4}
    coordinator: {min: 0, max: 6,  queueLength: 2}
    priority:    {min: 1, max: 2,  queueLength: 5}
    celery:      {min: 0, max: 1,  queueLength: 5}

# ---------------------------------------------------------------------------
# Pod identity: Workload Identity
# ---------------------------------------------------------------------------
# Used for storage and Key Vault access. The database uses SQL authentication
# rather than Entra ID.
serviceAccount:
  annotations:
    azure.workload.identity/client-id: "REPLACE-client-id"

# ---------------------------------------------------------------------------
# Monitoring
# ---------------------------------------------------------------------------
# Requires the Prometheus Operator CRDs. Set all three to false to install
# without Prometheus.
monitoring:
  serviceMonitor: {enabled: true}
  alertRules: {enabled: true}
  dashboards: {enabled: true}
