Skip to content

Commit e73f93c

Browse files
Added tls termination at a pod level for qtodo (#149)
* Added tls termination at a pod level for qtodo Signed-off-by: Andrew Block <andy.block@gmail.com> * Add qtodo e2e documentation Signed-off-by: Manuel Lorenzo <mlorenzofr@redhat.com> --------- Signed-off-by: Andrew Block <andy.block@gmail.com> Signed-off-by: Manuel Lorenzo <mlorenzofr@redhat.com> Co-authored-by: Manuel Lorenzo <mlorenzofr@redhat.com>
1 parent b3bb684 commit e73f93c

7 files changed

Lines changed: 101 additions & 10 deletions

File tree

charts/qtodo/templates/_helpers.tpl

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,24 @@ Generate the JWT Audience
3737
{{- else }}
3838
{{- print .Values.app.vault.audience }}
3939
{{- end }}
40-
{{- end }}
40+
{{- end }}
41+
42+
{{/*
43+
Returns true if the termination is secure (https) and false otherwise
44+
*/}}
45+
{{- define "qtodo.isSecureTermination" }}
46+
{{- if or (eq .Values.app.route.termination "reencrypt") (eq .Values.app.route.termination "passthrough") }}
47+
true
48+
{{- end }}
49+
{{- end }}
50+
51+
{{/*
52+
Returns the port the application should list on
53+
*/}}
54+
{{- define "qtodo.app.port" -}}
55+
{{- if include "qtodo.isSecureTermination" . -}}
56+
{{ .Values.app.securePort }}
57+
{{- else -}}
58+
{{ .Values.app.insecurePort }}
59+
{{- end -}}
60+
{{- end -}}

charts/qtodo/templates/app-deployment.yaml

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ spec:
198198
image: {{ template "qtodo.image" (dict "value" .Values.app.images.main "context" $ "useRegistry" true) }}
199199
imagePullPolicy: {{ .Values.app.images.main.pullPolicy }}
200200
ports:
201-
- containerPort: 8080
202-
name: http
201+
- containerPort: {{ template "qtodo.app.port" . }}
202+
name: {{ if (include "qtodo.isSecureTermination" .) }}https{{ else }}http{{ end }}
203203
protocol: TCP
204204
envFrom:
205205
- configMapRef:
@@ -219,7 +219,17 @@ spec:
219219
- name: QUARKUS_HTTP_HOST
220220
value: '0.0.0.0'
221221
- name: QUARKUS_HTTP_PORT
222-
value: '8080'
222+
value: {{ .Values.app.insecurePort | quote }}
223+
{{- if include "qtodo.isSecureTermination" . }}
224+
- name: QUARKUS_HTTP_SSL_PORT
225+
value: {{ .Values.app.securePort | quote }}
226+
- name: QUARKUS_TLS_KEY_STORE_PEM_QTODO_CERT
227+
value: /certs/tls.crt
228+
- name: QUARKUS_TLS_KEY_STORE_PEM_QTODO_KEY
229+
value: /certs/tls.key
230+
- name: QUARKUS_HTTP_INSECURE_REQUESTS
231+
value: 'disabled'
232+
{{- end }}
223233
- name: QUARKUS_HIBERNATE_ORM_SCHEMA_MANAGEMENT_STRATEGY
224234
value: 'drop-and-create'
225235
{{- if not .Values.app.spire.enabled }}
@@ -273,6 +283,11 @@ spec:
273283
- name: ztvp-trusted-ca
274284
mountPath: /etc/pki/ca-trust/extracted/pem
275285
readOnly: true
286+
{{- end }}
287+
{{- if include "qtodo.isSecureTermination" . }}
288+
- name: tls-certs
289+
mountPath: /certs
290+
readOnly: true
276291
{{- end }}
277292
resources: {}
278293
serviceAccountName: qtodo
@@ -304,4 +319,9 @@ spec:
304319
configMap:
305320
name: qtodo-truststore-java
306321
{{- end }}
322+
{{- if include "qtodo.isSecureTermination" . }}
323+
- name: tls-certs
324+
secret:
325+
secretName: {{ .Values.app.tls.secret }}
326+
{{- end }}
307327
{{- end }}

charts/qtodo/templates/app-route.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ metadata:
77
name: qtodo
88
spec:
99
port:
10-
targetPort: 8080-tcp
10+
targetPort: {{ printf "%s-tcp" (include "qtodo.app.port" .) }}
1111
tls:
1212
insecureEdgeTerminationPolicy: Redirect
13-
termination: edge
13+
termination: {{ .Values.app.route.termination }}
1414
to:
1515
kind: Service
1616
name: qtodo

charts/qtodo/templates/app-service.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@ kind: Service
33
metadata:
44
annotations:
55
argocd.argoproj.io/sync-wave: '51'
6+
{{- if eq .Values.app.tls.serviceServing true }}
7+
service.beta.openshift.io/serving-cert-secret-name: {{ .Values.app.tls.secret | quote }}
8+
{{- end }}
69
labels:
710
app: qtodo
811
name: qtodo
912
namespace: qtodo
1013
spec:
1114
ports:
12-
- name: 8080-tcp
13-
port: 8080
15+
- name: {{ printf "%s-tcp" (include "qtodo.app.port" .) }}
16+
port: {{ template "qtodo.app.port" . }}
1417
protocol: TCP
15-
targetPort: 8080
18+
targetPort: {{ template "qtodo.app.port" . }}
1619
selector:
1720
app: qtodo
1821
sessionAffinity: None

charts/qtodo/templates/qtodo-network-policy.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ spec:
1717
# to generate the correct ACLs for host-network ingress traffic.
1818
- ports:
1919
- protocol: TCP
20-
port: 8080
20+
port: {{ include "qtodo.app.port" . }}
2121
from:
2222
- namespaceSelector:
2323
matchLabels:

charts/qtodo/values.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ global:
1515
# QTodo application configuration
1616
app:
1717
name: qtodo
18+
insecurePort: 8080
19+
securePort: 8443
1820
images:
1921
main:
2022
name: quay.io/validatedpatterns/qtodo
@@ -62,10 +64,19 @@ app:
6264
name: "oidc-client-secret"
6365
vaultPath: "secret/data/apps/qtodo/qtodo-oidc-client"
6466

67+
# Route configuration
68+
route:
69+
termination: reencrypt
70+
6571
spire:
6672
enabled: true # Enable SPIFFE + OIDC integration by default
6773
sidecars: true
6874

75+
# TLS Configuration
76+
tls:
77+
secret: qtodo-tls
78+
serviceServing: true
79+
6980
# Vault configuration for SPIFFE integration
7081
# Uses SPIFFE JWT to authenticate and fetch DB password
7182
vault:

docs/multi-tier.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,40 @@ Switch back to the qtodo application and enter the username and password on the
4545
Once you have authenticated to RHBK, you will be instructed to change the temporary password and set a more permanent password. Once complete, you will be redirected to the qtodo application verifying the OIDC based authentication functions properly.
4646

4747
Feel free to add new items to the list of todos. By being able to add and remove items from the page, the integration between the Quarkus application and the backend PostgreSQL database using credentials sourced from HashiCorp Vault was successful.
48+
49+
## TLS Termination Options
50+
51+
The qtodo application uses `reencrypt` TLS termination on the OpenShift Route by default, ensuring that traffic is encrypted end-to-end from the client to the pod. Ingress TLS communication is terminated at the OpenShift Router and reencrypted with a certificate generated using the [Service Serving Certificate feature](https://docs.redhat.com/en/documentation/openshift_container_platform/4.21/html/security_and_compliance/configuring-certificates#add-service-serving).
52+
53+
### Configuration
54+
55+
The qtodo Helm chart provides options to control how and where TLS communication is terminated:
56+
57+
* **`app.route.termination`** — Specifies the TLS termination type for the OpenShift Route
58+
* `reencrypt` (default) — TLS is terminated at the Router and reencrypted to the pod using the certificate specified in `app.tls.secret`
59+
* `passthrough` — TLS traffic passes through the Router without decryption and is terminated at the pod
60+
* `edge` — TLS is terminated at the Router; backend communication uses HTTP
61+
62+
* **`app.securePort`** — The HTTPS port used by the application (default: `8443`)
63+
* Used when `app.route.termination` is set to `reencrypt` or `passthrough`
64+
65+
* **`app.insecurePort`** — The HTTP port used by the application (default: `8080`)
66+
* Used when `app.route.termination` is set to `edge` or when TLS is disabled
67+
68+
* **`app.tls.secret`** — Name of the Kubernetes Secret containing the TLS certificate and key (default: `qtodo-tls`)
69+
* Used for pod-level TLS termination with `reencrypt` or `passthrough` routes
70+
71+
* **`app.tls.serviceServing`** — Enable automatic certificate generation via Service Serving Certificates (default: `true`)
72+
* When enabled, OpenShift automatically generates and rotates the certificate in `app.tls.secret`
73+
* When using custom certificates (e.g., for `passthrough` mode), set this to `false` and provide your own certificate in the secret
74+
75+
### Termination Types
76+
77+
| Termination Type | TLS at Router | TLS to Pod | Certificate Source | Use Case |
78+
| --- | --- | --- | --- | --- |
79+
| `reencrypt` (default) | Yes | Yes | Service Serving Certificate | End-to-end encryption with automatic cert rotation |
80+
| `passthrough` | No | Yes | User-provided in `app.tls.secret` | Custom certificates or strict no-decrypt requirement |
81+
| `edge` | Yes | No | Route certificate | Legacy apps without TLS support |
82+
83+
> [!NOTE]
84+
> When using `passthrough` termination with custom certificates, ensure the certificate's Subject Alternative Name (SAN) matches the Route hostname. The Service Serving Certificate feature cannot be used in this mode.

0 commit comments

Comments
 (0)