diff --git a/charts/dataingestion-service/values.yaml b/charts/dataingestion-service/values.yaml index 02ecf5fa3..4d29b04c6 100644 --- a/charts/dataingestion-service/values.yaml +++ b/charts/dataingestion-service/values.yaml @@ -69,13 +69,16 @@ compare: port: 8085 ingress: - enabled: true + enabled: false className: "nginx" tls: - secretName: "data.EXAMPLE_DOMAIN" hosts: - "data.EXAMPLE_DOMAIN" +traefikIngress: + enabled: false + resources: {} autoscaling: diff --git a/charts/modernization-api/values.yaml b/charts/modernization-api/values.yaml index 3618d89e9..d982cb41e 100644 --- a/charts/modernization-api/values.yaml +++ b/charts/modernization-api/values.yaml @@ -41,7 +41,7 @@ pageBuilder: enabled: "false" ingress: - enabled: true + enabled: false className: "nginx" tls: - secretName: app.EXAMPLE_DOMAIN @@ -56,6 +56,13 @@ istioGatewayIngress: certificateName: "" certificateIssuerName: "letsencrypt-production" +traefikIngress: + enabled: false + bodySizeLimit: + # Max request body size in bytes (100MB — matches NGINX proxy-body-size: 100m) + maxRequestBodyBytes: 104857600 + + mTLS: enabled: true diff --git a/charts/nbs-ingress/Chart.yaml b/charts/nbs-ingress/Chart.yaml new file mode 100644 index 000000000..887dda2be --- /dev/null +++ b/charts/nbs-ingress/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: nbs-ingress +description: NBS7 Ingress routing resources — decoupled from application charts +type: application +version: 1.0.0 +appVersion: "1.0.0" \ No newline at end of file diff --git a/charts/nbs-ingress/README.md b/charts/nbs-ingress/README.md new file mode 100644 index 000000000..523355243 --- /dev/null +++ b/charts/nbs-ingress/README.md @@ -0,0 +1,47 @@ +# NBS7 Ingress Chart + +Standalone Helm chart that manages all NBS7 ingress routing, decoupled from application charts. + +## Why a Separate Chart? + +The ingress resources were previously embedded in `modernization-api` and `dataingestion-service` Helm charts. This created a coupling problem: upgrading the ingress controller (e.g., NGINX → Traefik) required upgrading the application charts, which could pull in unwanted application changes for STLTs on older NBS7 versions. + +This chart allows: +- Deploying Traefik ingress independently of NBS7 application version +- STLTs to choose their ingress provider (NGINX or Traefik) without changing application charts +- Centralized management of all routing rules in one place + +## Usage + +### Deploy with Traefik (default) + +```bash +helm install nbs-ingress ./charts/nbs-ingress \ + --set appHost=app.example.com \ + --set dataHost=data.example.com +``` + +### Deploy with NGINX + +```bash +helm install nbs-ingress ./charts/nbs-ingress \ + --set traefik.enabled=false \ + --set nginx.enabled=true \ + --set appHost=app.example.com \ + --set dataHost=data.example.com +``` + +### Switch from NGINX to Traefik + +```bash +helm upgrade nbs-ingress ./charts/nbs-ingress \ + --set traefik.enabled=true \ + --set nginx.enabled=false +``` + +## Important Notes + +- **Disable ingress in application charts** when using this chart. Set `ingress.enabled: false` in both `modernization-api` and `dataingestion-service` values. +- **Deploy this chart after application charts** so the backend services exist. +- **Only enable one provider** at a time (`nginx` or `traefik`). +- The Traefik controller itself is deployed separately via `charts/traefik/values.yaml`. \ No newline at end of file diff --git a/charts/nbs-ingress/templates/_helpers.tpl b/charts/nbs-ingress/templates/_helpers.tpl new file mode 100644 index 000000000..bbc95195a --- /dev/null +++ b/charts/nbs-ingress/templates/_helpers.tpl @@ -0,0 +1,45 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "nbs-ingress.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "nbs-ingress.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "nbs-ingress.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "nbs-ingress.labels" -}} +app: NBS +type: Ingress +helm.sh/chart: {{ include "nbs-ingress.chart" . }} +app.kubernetes.io/name: {{ include "nbs-ingress.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: ingress +{{- end }} diff --git a/charts/nbs-ingress/templates/nginx-ingress.yaml b/charts/nbs-ingress/templates/nginx-ingress.yaml new file mode 100644 index 000000000..a9c54f770 --- /dev/null +++ b/charts/nbs-ingress/templates/nginx-ingress.yaml @@ -0,0 +1,241 @@ +{{/* +NGINX Ingress - Main application routes +Only rendered when nginx.enabled is true. +Preserves the existing NGINX routing for STLTs that haven't migrated to Traefik. +*/}} +{{- if .Values.nginx.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "nbs-ingress.fullname" . }}-main + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} + annotations: + cert-manager.io/cluster-issuer: {{ .Values.tls.clusterIssuer | quote }} + nginx.ingress.kubernetes.io/configuration-snippet: | + more_set_headers "X-Frame-Options: Allow"; + more_set_headers "Cross-Origin-Opener-Policy: same-origin"; + nginx.ingress.kubernetes.io/service-upstream: "true" + nginx.ingress.kubernetes.io/use-regex: "true" +spec: + ingressClassName: nginx + tls: + - secretName: {{ .Values.appHost }} + hosts: + - {{ .Values.appHost }} + rules: + - host: {{ .Values.appHost }} + http: + paths: + - path: "/auth/realms/nbs-users/" + pathType: Prefix + backend: + service: + name: {{ .Values.app.keycloak.serviceName }} + port: + name: {{ .Values.app.keycloak.portName }} + - path: "/auth/robots.txt" + pathType: Exact + backend: + service: + name: {{ .Values.app.keycloak.serviceName }} + port: + name: {{ .Values.app.keycloak.portName }} + - path: "/auth/js/" + pathType: Prefix + backend: + service: + name: {{ .Values.app.keycloak.serviceName }} + port: + name: {{ .Values.app.keycloak.portName }} + - path: "/auth/resources/" + pathType: Prefix + backend: + service: + name: {{ .Values.app.keycloak.serviceName }} + port: + name: {{ .Values.app.keycloak.portName }} + - path: /favicon.ico + pathType: Prefix + backend: + service: + name: {{ .Values.app.gateway.serviceName }} + port: + number: {{ .Values.app.gateway.port }} + - path: "/" + pathType: Prefix + backend: + service: + name: {{ .Values.app.gateway.serviceName }} + port: + number: {{ .Values.app.gateway.port }} +--- +# NGINX Ingress - Cached static assets +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "nbs-ingress.fullname" . }}-cached + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} + annotations: + cert-manager.io/cluster-issuer: {{ .Values.tls.clusterIssuer | quote }} + nginx.ingress.kubernetes.io/configuration-snippet: | + more_set_headers "X-Frame-Options: Allow"; + more_set_headers "Cross-Origin-Opener-Policy: same-origin"; + more_set_headers "Cache-Control: max-age=1209600, immutable"; + nginx.ingress.kubernetes.io/service-upstream: "true" + nginx.ingress.kubernetes.io/use-regex: "true" +spec: + ingressClassName: nginx + tls: + - secretName: {{ .Values.appHost }} + hosts: + - {{ .Values.appHost }} + rules: + - host: {{ .Values.appHost }} + http: + paths: + - path: "/(.+)\\.(jpg|svg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|ttf|woff|woff2)$" + pathType: ImplementationSpecific + backend: + service: + name: {{ .Values.app.gateway.serviceName }} + port: + number: {{ .Values.app.gateway.port }} +--- +# NGINX Ingress - Data Ingestion +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "nbs-ingress.fullname" . }}-dataingestion + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} + annotations: + cert-manager.io/cluster-issuer: {{ .Values.tls.clusterIssuer | quote }} +spec: + ingressClassName: nginx + tls: + - secretName: {{ .Values.dataHost }} + hosts: + - {{ .Values.dataHost }} + rules: + - host: {{ .Values.dataHost }} + http: + paths: + {{- if .Values.data.ingestion.enabled }} + - path: "/ingestion/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.ingestion.serviceName }} + port: + number: {{ .Values.data.ingestion.port }} + {{- end }} + {{- if .Values.data.dataProcessing.enabled }} + - path: "/rti/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.dataProcessing.serviceName }} + port: + number: {{ .Values.data.dataProcessing.port }} + {{- end }} + {{- if .Values.data.nnd.enabled }} + - path: "/extraction/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.nnd.serviceName }} + port: + number: {{ .Values.data.nnd.port }} + {{- end }} + {{- if .Values.data.srteData.enabled }} + - path: "/data/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.srteData.serviceName }} + port: + number: {{ .Values.data.srteData.port }} + {{- end }} + {{- if .Values.data.dataExtraction.enabled }} + - path: "/data-extraction/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.dataExtraction.serviceName }} + port: + number: {{ .Values.data.dataExtraction.port }} + {{- end }} + {{- if .Values.data.caseNotification.enabled }} + - path: "/case-notification/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.caseNotification.serviceName }} + port: + number: {{ .Values.data.caseNotification.port }} + {{- end }} + {{- if .Values.data.xmlHl7Parser.enabled }} + - path: "/hl7-parser/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.xmlHl7Parser.serviceName }} + port: + number: {{ .Values.data.xmlHl7Parser.port }} + {{- end }} + {{- if .Values.data.reporting.enabled }} + - path: "/reporting/person-svc/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.reporting.person.serviceName }} + port: + number: {{ .Values.data.reporting.person.port }} + - path: "/reporting/organization-svc/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.reporting.organization.serviceName }} + port: + number: {{ .Values.data.reporting.organization.port }} + - path: "/reporting/investigation-svc/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.reporting.investigation.serviceName }} + port: + number: {{ .Values.data.reporting.investigation.port }} + - path: "/reporting/observation-svc/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.reporting.observation.serviceName }} + port: + number: {{ .Values.data.reporting.observation.port }} + - path: "/reporting/post-processing-svc/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.reporting.postProcessing.serviceName }} + port: + number: {{ .Values.data.reporting.postProcessing.port }} + - path: "/reporting/ldfdata-svc/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.reporting.ldfdata.serviceName }} + port: + number: {{ .Values.data.reporting.ldfdata.port }} + {{- end }} + {{- if .Values.data.compare.enabled }} + - path: "/comparison/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.compare.serviceName }} + port: + number: {{ .Values.data.compare.port }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/nbs-ingress/templates/nifi-ingress.yaml b/charts/nbs-ingress/templates/nifi-ingress.yaml new file mode 100644 index 000000000..be52c9100 --- /dev/null +++ b/charts/nbs-ingress/templates/nifi-ingress.yaml @@ -0,0 +1,95 @@ +{{/* +NiFi Ingress — only rendered when nifi.enabled is true. +NiFi serves HTTPS on port 8443 internally, requiring special backend handling. + +NGINX: Uses backend-protocol, upstream-vhost, and proxy-redirect annotations. +Traefik: Uses ServersTransport CRD for HTTPS backend + headers middleware for upstream-vhost. +*/}} + +{{- if .Values.nifi.enabled }} + +{{/* ========== TRAEFIK PATH ========== */}} +{{- if .Values.traefik.enabled }} +# ServersTransport — HTTPS backend connection to NiFi +apiVersion: traefik.io/v1alpha1 +kind: ServersTransport +metadata: + name: {{ include "nbs-ingress.fullname" . }}-nifi-transport + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} +spec: + insecureSkipVerify: true +--- +# Middleware — Set Host header to localhost:8443 (NiFi validates Host) +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: {{ include "nbs-ingress.fullname" . }}-nifi-headers + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} +spec: + headers: + customRequestHeaders: + Host: "localhost:8443" +--- +# IngressRoute — NiFi routing with HTTPS backend via ServersTransport +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: {{ include "nbs-ingress.fullname" . }}-nifi + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} + annotations: + cert-manager.io/cluster-issuer: {{ .Values.tls.clusterIssuer | quote }} +spec: + entryPoints: + - websecure + routes: + - match: "Host(`{{ .Values.nifi.host }}`)" + kind: Rule + services: + - name: {{ .Values.nifi.serviceName }} + port: {{ .Values.nifi.port }} + serversTransport: {{ include "nbs-ingress.fullname" . }}-nifi-transport + scheme: https + middlewares: + - name: {{ include "nbs-ingress.fullname" . }}-nifi-headers + namespace: {{ .Release.Namespace }} + tls: + secretName: {{ .Values.nifi.host }} +{{- end }} + +{{/* ========== NGINX PATH ========== */}} +{{- if .Values.nginx.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "nbs-ingress.fullname" . }}-nifi + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} + annotations: + cert-manager.io/cluster-issuer: {{ .Values.tls.clusterIssuer | quote }} + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + nginx.ingress.kubernetes.io/upstream-vhost: "localhost:8443" + nginx.ingress.kubernetes.io/proxy-redirect-from: "https://localhost:8443" + nginx.ingress.kubernetes.io/proxy-redirect-to: "https://{{ .Values.nifi.host }}" +spec: + ingressClassName: nginx + tls: + - secretName: {{ .Values.nifi.host }} + hosts: + - {{ .Values.nifi.host }} + rules: + - host: {{ .Values.nifi.host }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ .Values.nifi.serviceName }} + port: + number: {{ .Values.nifi.port }} +{{- end }} + +{{- end }} \ No newline at end of file diff --git a/charts/nbs-ingress/templates/traefik-ingress-dataingestion.yaml b/charts/nbs-ingress/templates/traefik-ingress-dataingestion.yaml new file mode 100644 index 000000000..c1d2dfd41 --- /dev/null +++ b/charts/nbs-ingress/templates/traefik-ingress-dataingestion.yaml @@ -0,0 +1,142 @@ +{{/* +Traefik Ingress - Data Ingestion and Reporting Service routes +Only rendered when traefik.enabled is true. +Includes body-size-limit middleware for large ECR uploads. +*/}} +{{- if .Values.traefik.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "nbs-ingress.fullname" . }}-dataingestion + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} + annotations: + cert-manager.io/cluster-issuer: {{ .Values.tls.clusterIssuer | quote }} + traefik.ingress.kubernetes.io/router.middlewares: {{ .Release.Namespace }}-body-size-limit@kubernetescrd +spec: + ingressClassName: traefik + tls: + - secretName: {{ .Values.dataHost }} + hosts: + - {{ .Values.dataHost }} + rules: + - host: {{ .Values.dataHost }} + http: + paths: + {{- if .Values.data.ingestion.enabled }} + - path: "/ingestion/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.ingestion.serviceName }} + port: + number: {{ .Values.data.ingestion.port }} + {{- end }} + {{- if .Values.data.reporting.enabled }} + - path: "/reporting/person-svc/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.reporting.person.serviceName }} + port: + number: {{ .Values.data.reporting.person.port }} + - path: "/reporting/organization-svc/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.reporting.organization.serviceName }} + port: + number: {{ .Values.data.reporting.organization.port }} + - path: "/reporting/investigation-svc/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.reporting.investigation.serviceName }} + port: + number: {{ .Values.data.reporting.investigation.port }} + - path: "/reporting/observation-svc/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.reporting.observation.serviceName }} + port: + number: {{ .Values.data.reporting.observation.port }} + - path: "/reporting/post-processing-svc/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.reporting.postProcessing.serviceName }} + port: + number: {{ .Values.data.reporting.postProcessing.port }} + - path: "/reporting/ldfdata-svc/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.reporting.ldfdata.serviceName }} + port: + number: {{ .Values.data.reporting.ldfdata.port }} + {{- end }} + {{- if .Values.data.dataProcessing.enabled }} + - path: "/rti/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.dataProcessing.serviceName }} + port: + number: {{ .Values.data.dataProcessing.port }} + {{- end }} + {{- if .Values.data.nnd.enabled }} + - path: "/extraction/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.nnd.serviceName }} + port: + number: {{ .Values.data.nnd.port }} + {{- end }} + {{- if .Values.data.srteData.enabled }} + - path: "/data/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.srteData.serviceName }} + port: + number: {{ .Values.data.srteData.port }} + {{- end }} + {{- if .Values.data.dataExtraction.enabled }} + - path: "/data-extraction/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.dataExtraction.serviceName }} + port: + number: {{ .Values.data.dataExtraction.port }} + {{- end }} + {{- if .Values.data.caseNotification.enabled }} + - path: "/case-notification/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.caseNotification.serviceName }} + port: + number: {{ .Values.data.caseNotification.port }} + {{- end }} + {{- if .Values.data.xmlHl7Parser.enabled }} + - path: "/hl7-parser/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.xmlHl7Parser.serviceName }} + port: + number: {{ .Values.data.xmlHl7Parser.port }} + {{- end }} + {{- if .Values.data.compare.enabled }} + - path: "/comparison/" + pathType: Prefix + backend: + service: + name: {{ .Values.data.compare.serviceName }} + port: + number: {{ .Values.data.compare.port }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/nbs-ingress/templates/traefik-ingress-main.yaml b/charts/nbs-ingress/templates/traefik-ingress-main.yaml new file mode 100644 index 000000000..56edbb0dc --- /dev/null +++ b/charts/nbs-ingress/templates/traefik-ingress-main.yaml @@ -0,0 +1,69 @@ +{{/* +Traefik Ingress - Main application routes (KeyCloak + NBS Gateway) +Only rendered when traefik.enabled is true. +*/}} +{{- if .Values.traefik.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "nbs-ingress.fullname" . }}-main + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} + annotations: + cert-manager.io/cluster-issuer: {{ .Values.tls.clusterIssuer | quote }} + traefik.ingress.kubernetes.io/router.middlewares: {{ .Release.Namespace }}-nbs-custom-headers@kubernetescrd,{{ .Release.Namespace }}-body-size-limit@kubernetescrd +spec: + ingressClassName: traefik + tls: + - secretName: {{ .Values.appHost }} + hosts: + - {{ .Values.appHost }} + rules: + - host: {{ .Values.appHost }} + http: + paths: + # KeyCloak auth routes + - path: "/auth/realms/nbs-users/" + pathType: Prefix + backend: + service: + name: {{ .Values.app.keycloak.serviceName }} + port: + name: {{ .Values.app.keycloak.portName }} + - path: "/auth/robots.txt" + pathType: Exact + backend: + service: + name: {{ .Values.app.keycloak.serviceName }} + port: + name: {{ .Values.app.keycloak.portName }} + - path: "/auth/js/" + pathType: Prefix + backend: + service: + name: {{ .Values.app.keycloak.serviceName }} + port: + name: {{ .Values.app.keycloak.portName }} + - path: "/auth/resources/" + pathType: Prefix + backend: + service: + name: {{ .Values.app.keycloak.serviceName }} + port: + name: {{ .Values.app.keycloak.portName }} + # NBS Gateway routes + - path: /favicon.ico + pathType: Prefix + backend: + service: + name: {{ .Values.app.gateway.serviceName }} + port: + number: {{ .Values.app.gateway.port }} + - path: "/" + pathType: Prefix + backend: + service: + name: {{ .Values.app.gateway.serviceName }} + port: + number: {{ .Values.app.gateway.port }} +{{- end }} \ No newline at end of file diff --git a/charts/nbs-ingress/templates/traefik-ingressroute-cached.yaml b/charts/nbs-ingress/templates/traefik-ingressroute-cached.yaml new file mode 100644 index 000000000..97e2a8cf3 --- /dev/null +++ b/charts/nbs-ingress/templates/traefik-ingressroute-cached.yaml @@ -0,0 +1,27 @@ +{{/* +Traefik IngressRoute - Cached static assets with regex path matching +Uses IngressRoute CRD because regex paths cannot be expressed with standard Ingress pathType. +Only rendered when traefik.enabled is true. +*/}} +{{- if .Values.traefik.enabled }} +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: {{ include "nbs-ingress.fullname" . }}-cached + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} +spec: + entryPoints: + - websecure + routes: + - match: "Host(`{{ .Values.appHost }}`) && PathRegexp(`^/(?!auth|ecr-viewer|orchestration).+\\.(jpg|svg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|ttf|woff|woff2)$`)" + kind: Rule + services: + - name: {{ .Values.app.gateway.serviceName }} + port: {{ .Values.app.gateway.port }} + middlewares: + - name: nbs-cached-headers + namespace: {{ .Release.Namespace }} + tls: + secretName: {{ .Values.appHost }} +{{- end }} \ No newline at end of file diff --git a/charts/nbs-ingress/templates/traefik-middlewares.yaml b/charts/nbs-ingress/templates/traefik-middlewares.yaml new file mode 100644 index 000000000..21f690948 --- /dev/null +++ b/charts/nbs-ingress/templates/traefik-middlewares.yaml @@ -0,0 +1,52 @@ +{{/* +Traefik Middleware CRDs - Response headers, body size limits, cached headers +Only rendered when traefik.enabled is true. +*/}} +{{- if .Values.traefik.enabled }} +# ============================================================================= +# Custom Response Headers +# ============================================================================= +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: nbs-custom-headers + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} +spec: + headers: + customResponseHeaders: + X-Frame-Options: "Allow" + Cross-Origin-Opener-Policy: "same-origin" +--- +# ============================================================================= +# Body Size Limit (100MB — matches NGINX proxy-body-size: 100m) +# ============================================================================= +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: body-size-limit + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} +spec: + buffering: + maxRequestBodyBytes: {{ int64 (.Values.middlewares.bodySizeLimit.maxRequestBodyBytes | default 104857600) }} + memRequestBodyBytes: {{ int64 (.Values.middlewares.bodySizeLimit.memRequestBodyBytes | default 10485760) }} + maxResponseBodyBytes: 0 + memResponseBodyBytes: 1048576 +--- +# ============================================================================= +# Cached Asset Headers (adds Cache-Control for static assets) +# ============================================================================= +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: nbs-cached-headers + labels: + {{- include "nbs-ingress.labels" . | nindent 4 }} +spec: + headers: + customResponseHeaders: + X-Frame-Options: "Allow" + Cross-Origin-Opener-Policy: "same-origin" + Cache-Control: "max-age=1209600, immutable" +{{- end }} \ No newline at end of file diff --git a/charts/nbs-ingress/values.yaml b/charts/nbs-ingress/values.yaml new file mode 100644 index 000000000..5677f3db1 --- /dev/null +++ b/charts/nbs-ingress/values.yaml @@ -0,0 +1,131 @@ +# ============================================================================= +# NBS7 Ingress Chart - values.yaml +# ============================================================================= +# This chart manages all ingress routing for NBS7, decoupled from +# application charts (modernization-api, dataingestion-service). +# +# Only one ingress provider should be enabled at a time. +# ============================================================================= + +# ----------------------------------------------------------------------------- +# INGRESS PROVIDER SELECTION +# ----------------------------------------------------------------------------- +# Enable exactly one provider: +nginx: + enabled: false + +traefik: + enabled: true + +# ----------------------------------------------------------------------------- +# HOSTNAMES +# ----------------------------------------------------------------------------- +# Replace these with your environment-specific hostnames +appHost: "app.EXAMPLE_DOMAIN" +dataHost: "data.EXAMPLE_DOMAIN" + +# ----------------------------------------------------------------------------- +# TLS +# ----------------------------------------------------------------------------- +tls: + clusterIssuer: "letsencrypt-production" + +# ----------------------------------------------------------------------------- +# TRAEFIK MIDDLEWARE CONFIGURATION +# ----------------------------------------------------------------------------- +middlewares: + # Body size limit (matches NGINX proxy-body-size: 100m) + bodySizeLimit: + maxRequestBodyBytes: 104857600 + memRequestBodyBytes: 10485760 + +# ----------------------------------------------------------------------------- +# NIFI +# ----------------------------------------------------------------------------- +# NiFi is optional — most deployments don't expose it externally. +# Enable only if you need external access to the NiFi UI. +# NiFi serves HTTPS on port 8443 internally. +nifi: + enabled: false + host: "nifi.EXAMPLE_DOMAIN" + serviceName: "nifi-efs" + port: 8443 + +# ----------------------------------------------------------------------------- +# BACKEND SERVICES +# ----------------------------------------------------------------------------- +# These match the service names and ports deployed by the application charts. +# Only change these if your application charts use non-default names/ports. + +app: + # NBS Gateway + gateway: + serviceName: "nbs-gateway-svc" + port: 8000 + # KeyCloak + keycloak: + serviceName: "keycloak" + portName: "http" + +data: + # Data Ingestion Service + ingestion: + enabled: true + serviceName: "dataingestion-service" + port: 8081 + # Reporting Services + reporting: + enabled: false + person: + serviceName: "person-reporting-service" + port: 8091 + organization: + serviceName: "organization-reporting-service" + port: 8092 + investigation: + serviceName: "investigation-reporting-service" + port: 8093 + observation: + serviceName: "observation-reporting-service" + port: 8094 + postProcessing: + serviceName: "post-processing-reporting-service" + port: 8095 + ldfdata: + serviceName: "ldfdata-reporting-service" + port: 8096 + # Data Processing + dataProcessing: + enabled: true + serviceName: "data-processing-service" + port: 8082 + # NND Service + nnd: + enabled: false + serviceName: "nnd-service" + port: 8083 + # SRTE Data Service + srteData: + enabled: true + serviceName: "srte-data-service" + port: 8084 + # Data Extraction + dataExtraction: + enabled: true + serviceName: "data-extraction-service" + port: 8090 + # Case Notification + caseNotification: + enabled: false + serviceName: "case-notification-service" + port: 8089 + # XML HL7 Parser + xmlHl7Parser: + enabled: true + serviceName: "xml-hl7-parser-service" + port: 8088 + # Data Compare API + compare: + enabled: false + serviceName: "data-compare-api-service" + port: 8097 \ No newline at end of file diff --git a/charts/nbs6-ingress/Chart.yaml b/charts/nbs6-ingress/Chart.yaml new file mode 100644 index 000000000..e6155900d --- /dev/null +++ b/charts/nbs6-ingress/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: nbs6-ingress +description: NBS6 (Classic/WildFly) Ingress routing — decoupled from the nbs6 application chart +type: application +version: 1.0.0 +appVersion: "1.0.0" \ No newline at end of file diff --git a/charts/nbs6-ingress/README.md b/charts/nbs6-ingress/README.md new file mode 100644 index 000000000..b0ab8714e --- /dev/null +++ b/charts/nbs6-ingress/README.md @@ -0,0 +1,34 @@ +# NBS6 Ingress Chart + +Standalone Helm chart for NBS6 (Classic/WildFly) ingress routing, decoupled from the `nbs6` application chart. + +## Overview + +This chart is for CDC and Montana environments that run NBS6 in a container alongside NBS7. It manages the ingress routing for the `app-classic` hostname independently of the NBS6 application chart version. + +## Usage + +### Deploy with Traefik (default) + +```bash +helm install nbs6-ingress ./charts/nbs6-ingress \ + --set host=app-classic.example.com \ + --set serviceName=nbs6-service +``` + +### Deploy with NGINX + +```bash +helm install nbs6-ingress ./charts/nbs6-ingress \ + --set traefik.enabled=false \ + --set nginx.enabled=true \ + --set host=app-classic.example.com \ + --set serviceName=nbs6-service +``` + +## Important Notes + +- The `serviceName` must match the NBS6 Helm release service name (`-service`) +- The NBS6 service exposes port 443 (HTTPS) which maps to WildFly on targetPort 7001 +- Disable `ingress.enabled` in the NBS6 application chart when using this chart +- NBS6 has its own middleware CRDs (`nbs6-custom-headers`, `nbs6-cached-headers`) separate from the NBS7 `nbs-ingress` chart middlewares \ No newline at end of file diff --git a/charts/nbs6-ingress/templates/_helpers.tpl b/charts/nbs6-ingress/templates/_helpers.tpl new file mode 100644 index 000000000..1a91799cd --- /dev/null +++ b/charts/nbs6-ingress/templates/_helpers.tpl @@ -0,0 +1,45 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "nbs6-ingress.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "nbs6-ingress.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "nbs6-ingress.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "nbs6-ingress.labels" -}} +app: NBS +type: Ingress +helm.sh/chart: {{ include "nbs6-ingress.chart" . }} +app.kubernetes.io/name: {{ include "nbs6-ingress.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: ingress +{{- end }} diff --git a/charts/nbs6-ingress/templates/ingress-cached.yaml b/charts/nbs6-ingress/templates/ingress-cached.yaml new file mode 100644 index 000000000..bf1761897 --- /dev/null +++ b/charts/nbs6-ingress/templates/ingress-cached.yaml @@ -0,0 +1,62 @@ +{{/* +NBS6 (Classic/WildFly) Ingress — Cached static assets +Regex path excludes /auth and matches common static file extensions. +*/}} + +{{/* ========== TRAEFIK PATH ========== */}} +{{- if .Values.traefik.enabled }} +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: {{ include "nbs6-ingress.fullname" . }}-cached + labels: + {{- include "nbs6-ingress.labels" . | nindent 4 }} +spec: + entryPoints: + - websecure + routes: + - match: "Host(`{{ .Values.host }}`) && PathRegexp(`^/(?!auth).+\\.(jpg|svg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|ttf|woff|woff2)$`)" + kind: Rule + services: + - name: {{ .Values.serviceName }} + port: {{ .Values.servicePort }} + middlewares: + - name: nbs6-cached-headers + namespace: {{ .Release.Namespace }} + tls: + secretName: {{ .Values.host }} +{{- end }} + +{{/* ========== NGINX PATH ========== */}} +{{- if .Values.nginx.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "nbs6-ingress.fullname" . }}-cached + labels: + {{- include "nbs6-ingress.labels" . | nindent 4 }} + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/service-upstream: "true" + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/configuration-snippet: | + more_set_headers "X-Frame-Options: Allow"; + more_set_headers "Cross-Origin-Opener-Policy: same-origin"; + more_set_headers "Cache-Control: max-age=1209600, immutable"; +spec: + tls: + - secretName: {{ .Values.host }} + hosts: + - {{ .Values.host }} + rules: + - host: {{ .Values.host }} + http: + paths: + - path: '/(?!auth).+\.(jpg|svg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|ttf|woff|woff2)$' + pathType: ImplementationSpecific + backend: + service: + name: {{ .Values.serviceName }} + port: + number: {{ .Values.servicePort }} +{{- end }} \ No newline at end of file diff --git a/charts/nbs6-ingress/templates/ingress.yaml b/charts/nbs6-ingress/templates/ingress.yaml new file mode 100644 index 000000000..2b9b60c72 --- /dev/null +++ b/charts/nbs6-ingress/templates/ingress.yaml @@ -0,0 +1,66 @@ +{{/* +NBS6 (Classic/WildFly) Ingress — Main routes +Service: {{ .Release.Name }}-service (port 443 → targetPort 7001) +*/}} + +{{/* ========== TRAEFIK PATH ========== */}} +{{- if .Values.traefik.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "nbs6-ingress.fullname" . }}-main + labels: + {{- include "nbs6-ingress.labels" . | nindent 4 }} + annotations: + cert-manager.io/cluster-issuer: {{ .Values.tls.clusterIssuer | quote }} + traefik.ingress.kubernetes.io/router.middlewares: {{ .Release.Namespace }}-nbs6-custom-headers@kubernetescrd +spec: + ingressClassName: traefik + tls: + - secretName: {{ .Values.host }} + hosts: + - {{ .Values.host }} + rules: + - host: {{ .Values.host }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ .Values.serviceName }} + port: + number: {{ .Values.servicePort }} +{{- end }} + +{{/* ========== NGINX PATH ========== */}} +{{- if .Values.nginx.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "nbs6-ingress.fullname" . }}-main + labels: + {{- include "nbs6-ingress.labels" . | nindent 4 }} + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/service-upstream: "true" + nginx.ingress.kubernetes.io/configuration-snippet: | + more_set_headers "X-Frame-Options: Allow"; + more_set_headers "Cross-Origin-Opener-Policy: same-origin"; +spec: + tls: + - secretName: {{ .Values.host }} + hosts: + - {{ .Values.host }} + rules: + - host: {{ .Values.host }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ .Values.serviceName }} + port: + number: {{ .Values.servicePort }} +{{- end }} \ No newline at end of file diff --git a/charts/nbs6-ingress/templates/middlewares.yaml b/charts/nbs6-ingress/templates/middlewares.yaml new file mode 100644 index 000000000..650acdb97 --- /dev/null +++ b/charts/nbs6-ingress/templates/middlewares.yaml @@ -0,0 +1,32 @@ +{{/* +NBS6 Traefik Middleware CRDs +Only rendered when traefik.enabled is true. +*/}} +{{- if .Values.traefik.enabled }} +# Custom Response Headers for NBS6 +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: nbs6-custom-headers + labels: + {{- include "nbs6-ingress.labels" . | nindent 4 }} +spec: + headers: + customResponseHeaders: + X-Frame-Options: "Allow" + Cross-Origin-Opener-Policy: "same-origin" +--- +# Cached Asset Headers for NBS6 +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: nbs6-cached-headers + labels: + {{- include "nbs6-ingress.labels" . | nindent 4 }} +spec: + headers: + customResponseHeaders: + X-Frame-Options: "Allow" + Cross-Origin-Opener-Policy: "same-origin" + Cache-Control: "max-age=1209600, immutable" +{{- end }} \ No newline at end of file diff --git a/charts/nbs6-ingress/values.yaml b/charts/nbs6-ingress/values.yaml new file mode 100644 index 000000000..e0de3fa00 --- /dev/null +++ b/charts/nbs6-ingress/values.yaml @@ -0,0 +1,33 @@ +# ============================================================================= +# NBS6 Ingress Chart - values.yaml +# ============================================================================= +# Manages ingress routing for the NBS6 (Classic/WildFly) application, +# decoupled from the nbs6 application chart. +# +# Only one ingress provider should be enabled at a time. +# ============================================================================= + +# ----------------------------------------------------------------------------- +# INGRESS PROVIDER SELECTION +# ----------------------------------------------------------------------------- +nginx: + enabled: false + +traefik: + enabled: true + +# ----------------------------------------------------------------------------- +# NBS6 SERVICE CONFIGURATION +# ----------------------------------------------------------------------------- +# The nbs6 chart creates a service named -service +# (e.g., if helm release is "nbs6", service is "nbs6-service") +# Port 443 maps to targetPort 7001 (WildFly) +host: "app-classic.EXAMPLE_DOMAIN" +serviceName: "nbs6-service" +servicePort: 80 + +# ----------------------------------------------------------------------------- +# TLS +# ----------------------------------------------------------------------------- +tls: + clusterIssuer: "letsencrypt-production" \ No newline at end of file diff --git a/charts/traefik/README.md b/charts/traefik/README.md new file mode 100644 index 000000000..d0273485f --- /dev/null +++ b/charts/traefik/README.md @@ -0,0 +1,40 @@ +# Traefik Ingress Controller + +Traefik v3.x replaces the NGINX Ingress Controller for NBS7 Kubernetes deployments. + +[https://doc.traefik.io/traefik/migrate/nginx-to-traefik/] + +## Deployment + +### AWS (EKS) + +```bash +helm repo add traefik https://traefik.github.io/charts +helm repo update +helm install traefik-crds traefik/traefik-crds --namespace traefik --create-namespace +helm install traefik traefik/traefik --namespace traefik --values values.yaml --skip-crds +``` + +### Azure (AKS) + +```bash +helm repo add traefik https://traefik.github.io/charts +helm repo update +helm install traefik-crds traefik/traefik-crds --namespace traefik --create-namespace +helm install traefik traefik/traefik --namespace traefik --values values-azure.yaml --skip-crds --set service.spec.loadBalancerIP=XX.XX.XX.XX +``` + +## Files + +| File | Description | +|------|-------------| +| `values.yaml` | Helm values for AWS (EKS) with NLB | +| `values-azure.yaml` | Helm values for Azure (AKS) with internal load balancer | + +## Verification + +```bash +kubectl get pods -n traefik +kubectl get svc -n traefik +kubectl get ingressclass +``` \ No newline at end of file diff --git a/charts/traefik/values-azure.yaml b/charts/traefik/values-azure.yaml new file mode 100644 index 000000000..5dd24a8af --- /dev/null +++ b/charts/traefik/values-azure.yaml @@ -0,0 +1,123 @@ +# Traefik Ingress Controller - Azure (AKS) Configuration +# Replaces: charts/nginx-ingress/values-azure.yaml +# Chart: traefik/traefik (v3.6.x) + +nodeSelector: + kubernetes.io/os: linux + +deployment: + enabled: true + kind: Deployment + replicas: 1 + podAnnotations: + linkerd.io/inject: enabled + +ingressClass: + enabled: true + isDefaultClass: true + +providers: + kubernetesCRD: + enabled: true + allowCrossNamespace: false + allowEmptyServices: true + kubernetesIngress: + enabled: true + allowEmptyServices: true + publishedService: + enabled: true + +ports: + traefik: + port: 9000 + expose: + default: false + protocol: TCP + + web: + port: 8000 + expose: + default: true + exposedPort: 80 + protocol: TCP + forwardedHeaders: + insecure: true + transport: + respondingTimeouts: + readTimeout: "300s" + writeTimeout: "300s" + idleTimeout: "300s" + + websecure: + port: 8443 + expose: + default: true + exposedPort: 443 + protocol: TCP + http: + tls: {} + forwardedHeaders: + insecure: true + transport: + respondingTimeouts: + readTimeout: "300s" + writeTimeout: "300s" + idleTimeout: "300s" + + metrics: + port: 9100 + expose: + default: false + protocol: TCP + +service: + enabled: true + type: LoadBalancer + spec: + externalTrafficPolicy: "Local" + loadBalancerIP: XX.XX.XX.XX #Populate your private IP here OR by passing it to your helm command + annotations: + #For private IP and private cluster use the following: + service.beta.kubernetes.io/azure-load-balancer-internal: "true" + service.beta.kubernetes.io/azure-load-balancer-internal-health-probe-request-path: "/ping" + prometheus.io/scrape: "true" + prometheus.io/port: "9100" + prometheus.io/path: /metrics + +additionalArguments: + - "--serversTransport.forwardingTimeouts.dialTimeout=300s" + - "--serversTransport.forwardingTimeouts.responseHeaderTimeout=300s" + - "--serversTransport.forwardingTimeouts.idleConnTimeout=300s" + - "--entryPoints.websecure.http.tls" + +metrics: + prometheus: + entryPoint: metrics + addEntryPointsLabels: true + addRoutersLabels: true + addServicesLabels: true + +logs: + general: + level: INFO + access: + enabled: true + +ingressRoute: + dashboard: + enabled: true + entryPoints: ["traefik"] + +resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "500m" + memory: "512Mi" + +rbac: + enabled: true + +# Run the following helm command after updating the load balancer IP: +# helm upgrade --install traefik traefik/traefik --namespace traefik -f values-azure.yaml --set service.spec.loadBalancerIP=XX.XX.XX.XX \ No newline at end of file diff --git a/charts/traefik/values.yaml b/charts/traefik/values.yaml new file mode 100644 index 000000000..e98d25b4b --- /dev/null +++ b/charts/traefik/values.yaml @@ -0,0 +1,127 @@ +# Traefik Ingress Controller - AWS (EKS) Configuration +# Replaces: charts/nginx-ingress/values.yaml +# Chart: traefik/traefik (v3.6.x) + +nodeSelector: + kubernetes.io/os: linux + +deployment: + enabled: true + kind: Deployment + replicas: 1 + podAnnotations: + linkerd.io/inject: enabled + +ingressClass: + enabled: true + isDefaultClass: true + +providers: + kubernetesCRD: + enabled: true + allowCrossNamespace: false + allowEmptyServices: true + kubernetesIngress: + enabled: true + allowEmptyServices: true + publishedService: + enabled: true + +ports: + traefik: + port: 9000 + expose: + default: false + protocol: TCP + +# HTTP entrypoint + web: + port: 8000 + expose: + default: true + exposedPort: 80 + protocol: TCP + forwardedHeaders: + insecure: true + transport: + respondingTimeouts: + readTimeout: "300s" + writeTimeout: "300s" + idleTimeout: "300s" + +# HTTPS entrypoint + websecure: + port: 8443 + expose: + default: true + exposedPort: 443 + protocol: TCP + http: + tls: {} + forwardedHeaders: + insecure: true + transport: + respondingTimeouts: + readTimeout: "300s" + writeTimeout: "300s" + idleTimeout: "300s" + +# Metrics port for Prometheus scraping + metrics: + port: 9100 + expose: + default: false + protocol: TCP + +service: + enabled: true + type: LoadBalancer + annotations: + service.beta.kubernetes.io/aws-load-balancer-type: nlb + prometheus.io/scrape: "true" + prometheus.io/port: "9100" + prometheus.io/path: /metrics + # Optional: Assign Elastic IPs to the NLB for static IP addresses + # Allocate EIPs in AWS first, then reference their allocation IDs: + # service.beta.kubernetes.io/aws-load-balancer-eip-allocations: eipalloc-xxxxxxxxx,eipalloc-yyyyyyyyy + # + # Optional: Restrict inbound traffic to specific CIDRs + # service.beta.kubernetes.io/aws-load-balancer-source-ranges: "XX.XX.XX.XX/24" + +additionalArguments: + - "--serversTransport.forwardingTimeouts.dialTimeout=300s" + - "--serversTransport.forwardingTimeouts.responseHeaderTimeout=300s" + - "--serversTransport.forwardingTimeouts.idleConnTimeout=300s" + - "--entryPoints.websecure.http.tls" + +metrics: + prometheus: + entryPoint: metrics + addEntryPointsLabels: true + addRoutersLabels: true + addServicesLabels: true + +logs: + general: + level: INFO + access: + enabled: true + +# DASHBOARD +# Traefik includes a built-in dashboard - useful for debugging routes +# Do NOT expose externally in production +ingressRoute: + dashboard: + enabled: true + entryPoints: ["traefik"] + +resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "500m" + memory: "512Mi" + +rbac: + enabled: true \ No newline at end of file