The composition-dynamic-controller is an operator that is instantiated by the core-provider to manage the Custom Resources whose Custom Resource Definition is generated by the core-provider.
The Composition Dynamic Controller (CDC) is a specialized Kubernetes operator that orchestrates the end-to-end lifecycle of Krateo compositions. Acting as the reconciliation engine for Composition custom resources, it bridges declarative application definitions with Helm’s packaging system through intelligent automation. The Chart Inspector serves as its "safety advisor," enabling proactive decision-making via dry-run analysis.
-
Reconciliation Trigger
- Watches for changes to
CompositionCRs or Helm chart versions. - Invokes the Chart Inspector to simulate installations/upgrades before execution.
- Watches for changes to
-
Dry-Run Analysis Phase (Chart Inspector)
helm install --dry-run=server <chart> --version <ver> # Returns:
- Resource Manifest List: All Kubernetes objects (Deployments, CRDs, etc.) the chart would create along with filename to .
- Dependency Graph: Order of operations (e.g., CRDs before custom resources).
-
RBAC Auto-Provisioning (CDC)
- Dynamically generates least-privilege Roles/ClusterRoles based on the Inspector’s output.
- Ensures the CDC’s service account has exactly the permissions needed—no more, no less.
-
Atomic Execution (CDC)
- Proceeds with
helm install/upgradeonly after successful dry-run and RBAC setup.
- Proceeds with
| Feature | CDC’s Role | Chart Inspector’s Contribution |
|---|---|---|
| Version-Sensitive Reconciliation | Detects chart version drift; rolls forward/back. | Identifies version-specific resource changes during dry-run. |
| Atomic Upgrades | Ensures all-or-nothing upgrades. | Pre-flights resource compatibility (e.g., CRD schema changes). |
| Self-Healing | Corrects configuration drift. | Provides baseline "desired state" for comparison. |
| Declarative Enforcement | Continuously reconciles actual vs. desired state. | Supplies the desired state before cluster changes. |
| Secure RBAC | Generates minimal required permissions. | Audits chart manifests for required API operations. |
-
Safety Net
- The Chart Inspector’s dry-run prevents "helm surprises" (e.g., undeclared CRD creations or namespace pollution).
- Example: Blocks a chart upgrade if the new version requires a
ClusterRolethe CDC isn’t authorized to manage.
-
GitOps Compliance
- The CDC enforces declarative intent by reconciling against the dry-run’s output, not just Helm’s last-applied state.
- Self-healing kicks in if manual changes violate the composition’s definition.
-
Multi-Tenancy Ready
- RBAC is scoped per-composition, isolating teams/projects.
- The Inspector’s resource listing ensures no cross-tenant leakage (e.g., a composition can’t create resources in forbidden namespaces).
- Scenario: A Helm chart v1.2.0 introduces a new
CustomResourceDefinition(CRD). - CDC+Inspector Flow:
- Dry-run detects the new CRD and its required API group permissions.
- CDC creates a
ClusterRolegrantingcreate/get/listfor the CRD. - Upgrade proceeds only after the CRD and RBAC are confirmed active.
- Result: Zero downtime; no "helm upgrade failed: CRD missing" errors.
The composition-dynamic-controller inject labels and values into the installed resources and in the helm chart release values. This values contains informations about the composition resource associated with the helm release. The values are injected in the following way:
| Helm Chart Release Values | Installed Resources Labels | Description |
|---|---|---|
global.compositionId |
krateo.io/composition-id |
The composition resource uid |
global.compositionName |
krateo.io/composition-name |
The composition resource name |
global.compositionNamespace |
krateo.io/composition-namespace |
The composition resource namespace |
global.compositionInstalledVersion |
krateo.io/composition-installed-version |
The version of the composition resource installed. This value changes if the chart version is upgraded |
global.compositionApiVersion |
not injected | The api version of the composition resource. This values is deprecated but is mainteined for backward compatibility. |
global.compositionGroup |
krateo.io/composition-group |
The group of the composition resource. |
global.compositionResource |
krateo.io/composition-resource |
The plural name of the composition resource. |
global.compositionKind |
krateo.io/composition-kind |
The kind of the composition resource. |
global.krateoNamespace |
krateo.io/krateo-namespace |
The namespace where Krateo is installed. This value is used to identify the Krateo resources in the cluster. |
global.gracefullyPaused |
not injected | This value is set to true if the annotation krateo.io/gracefully-paused is set on the composition resource. This value is used to pause the reconciliation of the composition resource only after the value is injected in the helm release values with a successful helm upgrade. Read the paragraph below for more details. |
The global.gracefullyPaused value provides a way to gracefully pause both the composition resource and all Krateo resources within its Helm chart.
- Trigger: Set the annotation
krateo.io/gracefully-pausedon the composition resource - Activation: The pause takes effect only after the next successful Helm upgrade injects this value into the chart
- Scope: Pauses both the composition reconciliation AND any Krateo resources in the chart that respect the
krateo.io/pausedannotation
- Graceful pause: Temporarily halt all composition-related activity without resource deletion
- Coordinated pause: Ensure both the composition and its managed resources pause simultaneously
- Safe maintenance: Pause operations during maintenance windows
| Annotation | Scope | When it takes effect |
|---|---|---|
krateo.io/gracefully-paused |
Composition + chart resources | After next Helm upgrade |
krateo.io/paused |
Composition only | Immediately |
Example: Use krateo.io/gracefully-paused when you need to pause an entire application stack, or krateo.io/paused for immediate composition-only pausing.
To include the pause in a resource included in the chart, you can use the krateo.io/paused annotation on the resource. This will ensure that the resource is paused when the composition is paused.
apiVersion: git.krateo.io/v1alpha1
kind: Repo
metadata:
name: {{ include "fireworks-app.fullname" . }}-repo
labels:
{{- include "fireworks-app.labels" . | nindent 4 }}
annotations:
krateo.io/paused: "{{ default false (and .Values.global .Values.global.gracefullyPaused) }}"
spec:
...NOTE: Operators implemented without the Krateo runtime may handle "pause" semantics differently (different annotation keys, immediate vs. delayed behavior, or custom fields). Before templating a pause for a non‑Krateo controller, review that operator's API and controller behavior and adapt the Helm template to map
global.gracefullyPausedto the operator's expected pause mechanism.
This is an example of how to include the pause in a non-Krateo resource included in the chart. In this case, we use an ArgoCD Application as an example.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: {{ .Release.Name }}
namespace: {{ .Values.argocd.namespace }}
labels:
{{- include "github-scaffolding.labels" . | nindent 4 }}
spec:
project: {{ .Values.argocd.application.project | default "default" }}
source:
repoURL: {{ include "github-scaffolding.toRepoUrl" . }}
targetRevision: {{ .Values.git.toRepo.branch }}
path: {{ .Values.argocd.application.source.path }}
destination:
server: {{ .Values.argocd.application.destination.server }}
namespace: {{ .Values.argocd.application.destination.namespace }}
{{- /* Normalize flags */ -}}
{{- $hasPaused := and .Values.global (hasKey .Values.global "gracefullyPaused") -}}
{{- $paused := and $hasPaused (eq (toString .Values.global.gracefullyPaused) "true") -}}
{{- $syncEnabled := default false .Values.argocd.application.syncEnabled -}}
{{- if $paused }}
syncPolicy: {}
{{- else if $syncEnabled }}
syncPolicy:
automated:
prune: {{ default false .Values.argocd.application.syncPolicy.automated.prune }}
selfHeal: {{ default false .Values.argocd.application.syncPolicy.automated.selfHeal }}
syncOptions:
- CreateNamespace=true
{{- else }}
syncPolicy: {}
{{- end }}The composition-dynamic-controller injects a global.gracefullyPaused boolean into Helm release values after a successful upgrade. When true, chart templates can use this flag to disable automated behavior for non‑Krateo resources (for example emit syncPolicy: {} in an Argo CD Application) and to set krateo.io/paused on Krateo resources, ensuring a coordinated pause across the composition and all included resources.
These enviroment varibles can be changed in the Deployment of the composition-dynamic-controller we need to tweak.
| Name | Description | Default Value | Notes |
|---|---|---|---|
| COMPOSITION_CONTROLLER_DEBUG | dump verbose output | false | |
| COMPOSITION_CONTROLLER_WORKERS | number of workers | 1 | |
| COMPOSITION_CONTROLLER_RESYNC_INTERVAL | resync interval | 3m | |
| COMPOSITION_CONTROLLER_GROUP | resource api group | populated by core-provider |
|
| COMPOSITION_CONTROLLER_VERSION | resource api version | populated by core-provider |
|
| COMPOSITION_CONTROLLER_RESOURCE | resource plural name | populated by core-provider |
|
| COMPOSITION_CONTROLLER_SA_NAME | cdc deployment ServiceAccount name | populated by core-provider |
|
| COMPOSITION_CONTROLLER_SA_NAMESPACE | cdc deployment ServiceAccount namespace | populated by core-provider |
|
| URL_PLURALS | NOT USED from version 0.17.1 - URL to krateo pluraliser service | http://snowplow.krateo-system.svc.cluster.local:8081/api-info/names |
Ignored from version 0.17.1 |
| URL_CHART_INSPECTOR | url to chart inspector | http://chart-inspector.krateo-system.svc.cluster.local:8081/ |
|
| KRATEO_NAMESPACE | namespace where krateo is installed | krateo-system | |
| HELM_REGISTRY_CONFIG_PATH | default helm config path | /tmp | |
| HELM_MAX_HISTORY | Max Helm History | 3 | |
| COMPOSITION_CONTROLLER_MAX_ERROR_RETRY_INTERVAL | The maximum interval between retries when an error occurs. This should be less than the half of the poll interval. | 0m | |
| COMPOSITION_CONTROLLER_MIN_ERROR_RETRY_INTERVAL | The minimum interval between retries when an error occurs. This should be less than max-error-retry-interval. | 1m | |
| COMPOSITION_CONTROLLER_METRICS_SERVER_PORT | The port where the metrics server will be listening. If not set, the metrics server is disabled. |

