ConfigMap Hot-Reload
When you create a LogicFlowDefinition, the operator writes the assembled workflow YAML into a
dedicated ConfigMap. That ConfigMap is then mounted into every pod of the target
LogicFlowRuntime. Understanding how mounting and propagation work explains both the latency you
should expect after a definition update and why adding a new definition triggers a pod rollout.
One ConfigMap Per Definition
The LogicFlowDefinition controller creates a ConfigMap named lfd-<definition-name> in the same
namespace. For example, LogicFlowDefinition/payment-processor-v1-0-0 produces:
apiVersion: v1
kind: ConfigMap
metadata:
name: lfd-payment-processor-v1-0-0
namespace: checkout
data:
payment-processor-v1-0-0.yaml: |
document:
dsl: "1.0.0"
namespace: checkout
name: payment-processor
version: "1.0.0"
do:
- processPayment:
...
The LogicFlowRuntime controller reconciles the Deployment to mount each such ConfigMap as its
own directory inside the pods.
Directory Mounts, Not subPath Mounts
Each ConfigMap is mounted as a directory (not a subPath), at the path:
/deployments/workflows/<configmap-name>/
For the example above, the file appears at:
/deployments/workflows/lfd-payment-processor-v1-0-0/payment-processor-v1-0-0.yaml
The corresponding volume and volumeMount in the Deployment look like this:
volumes:
- name: lfd-payment-processor-v1-0-0
configMap:
name: lfd-payment-processor-v1-0-0
volumeMounts:
- name: lfd-payment-processor-v1-0-0
mountPath: /deployments/workflows/lfd-payment-processor-v1-0-0 (1)
| 1 | No subPath is specified — this is a full directory mount. |
Why Not subPath?
subPath mounts are convenient when you want a file to appear at a precise path, but they have a
critical limitation: the kubelet does not update subPath-mounted files when the ConfigMap
changes. The pod must be restarted manually to see the new content.
Directory mounts do not have this limitation. The kubelet automatically propagates ConfigMap updates to all directory-mounted volumes within approximately 1–2 minutes.
|
The 1–2 minute propagation delay is controlled by |
How the Runner Scans for Workflow Files
The Quarkus Flow Runner includes a WorkflowFileWatcher component that polls
/deployments/workflows every 5 seconds for workflow YAML files (if enabled at image build time).
Symlink Handling and followSymlinks
Kubernetes ConfigMap directory mounts use an atomic update mechanism: the kubelet writes new
content into a timestamped directory (e.g. ..2026_08_20_12_34_56.789012345) and then updates a
..data symlink to point to it. The files visible at the top level of the mounted directory are
themselves symlinks that point through ..data/ to the real files.
Quarkus Flow Runner 1.0.0 defaults followSymlinks=false in its file scanner. This means it
skips the ..data/ symlink directory and reads only the regular files from the timestamped
directory. This eliminates a duplicate-detection problem that occurred in earlier versions when
both the symlinks and their targets were scanned.
You do not need to configure this behaviour — the 1.0.0-minimal and 1.0.0-standard images
both ship with the correct default.
What Triggers a Pod Rollout vs. In-Place Reload
| Event | Pod rollout? | Reason |
|---|---|---|
Creating a new |
Yes |
A new volume and volumeMount are added to the Deployment spec. The Deployment controller performs a rolling update. |
Updating the workflow content in an existing |
No |
The operator writes new content into the existing ConfigMap. The kubelet propagates the change to the mounted directory. The runner’s file watcher detects the new file content within ~5s of kubelet propagation (total latency: up to ~2 min). |
Deleting a |
Yes |
The volume and volumeMount are removed from the Deployment spec, triggering a rolling update. |
End-to-End Update Flow
The following sequence describes what happens when you update an existing workflow definition.
Because LogicFlowDefinition is immutable, "updating" means creating a new CR version, but the
content-propagation path below applies to any ConfigMap data change the operator makes.
1. Operator writes new YAML into ConfigMap lfd-payment-processor-v1-0-0. 2. Kubelet detects the ConfigMap change via its sync loop (up to ~1-2 min). 3. Kubelet writes new content into a new timestamped directory inside the mounted volume and updates the ..data symlink atomically. 4. WorkflowFileWatcher polls /deployments/workflows every 5s and detects a changed file in the timestamped directory. 5. Quarkus Flow Runner reloads the workflow definition in place — no pod restart needed.
Implications for Operations
-
Zero-downtime content updates: Changing workflow logic in an existing
LogicFlowDefinitiondoes not restart pods. Existing in-flight instances continue on the old definition until they complete; new instances pick up the updated definition after the runner reloads it. -
Rolling restarts on add/remove: Adding or removing a
LogicFlowDefinitiontriggers a Deployment rollout. In durable mode, the strictmaxUnavailable: 1, maxSurge: 0strategy means pods are replaced one at a time. -
Validation: Malformed workflow YAML will be rejected by the runner’s scanner. The pod continues to serve other workflow definitions; the invalid file is logged and skipped.