Skip to content

Resource Deployment Order - depends-on

Deploying resources and having them ready are two different things. Whether Sveltos deploys a Helm chart, a Kustomize overlay, or a set of plain YAML manifests, the deployment is considered done as soon as the resources are created in the managed cluster. What they need to actually work may still be starting: for an add-on like cert-manager, its pods and webhooks. A ClusterProfile that depends on cert-manager can then deploy against something that is not ready yet, and fail.

Sveltos solves this with two fields:

  1. dependsOn makes a ClusterProfile wait for another ClusterProfile. Applications that need cert-manager can list a central cert-manager ClusterProfile in dependsOn, so it is deployed first.
  2. validateHealths defines what "ready" means for a ClusterProfile. Sveltos sets the ClusterProfile as provisioned, and lets the ones depending on it proceed, only once all its health checks pass. Each check sets featureID to say what it follows: Helm for Helm charts, Kustomize for Kustomize overlays, or Resources for plain YAML manifests.

There are four ways to define a health check:

Check What it evaluates Use it when
Lua A resource in the managed cluster You need full scripting to decide if a resource is healthy
CEL A resource in the managed cluster A short expression is enough
Metrics A Prometheus query Health depends on live signals like an error rate
Job The outcome of a Kubernetes Job You need an active probe like a smoke test

The rest of this page goes through each check, using cert-manager as the running example, and ends with a ClusterProfile that depends on it.

Note

validateHealths decides when a ClusterProfile is ready. To monitor a ClusterProfile after deployment and check for unhealthy resources, use healthMonitoring. It does not hold the deployment; it only reports.

Health Validations with Lua/CEL

Explore the examples listed below and get an understanding of how to use Lua/CEL to craft validateHealths conditions.

Lua Health Validation

With Lua, Sveltos evaluates the evaluate() function against each resource selected by the validateHealths entry (available as obj), and the function returns whether the resource is healthy and a message explaining why not.

The ClusterProfile below will deploy cert-manager in any cluster matching the label selector env=fv and subsequently wait for all deployments in the cert-manager namespace to reach a healthy state (active replicas matching requested replicas) before setting the ClusterProfile as provisioned.

---
apiVersion: config.projectsveltos.io/v1beta1
kind: ClusterProfile
metadata:
  name: cert-manager
spec:
  clusterSelector:
    matchLabels:
      env: fv
  syncMode: Continuous
  helmCharts:
  - repositoryURL:    https://charts.jetstack.io
    repositoryName:   jetstack
    chartName:        jetstack/cert-manager
    chartVersion:     v1.13.2
    releaseName:      cert-manager
    releaseNamespace: cert-manager
    helmChartAction:  Install
    values: |
      installCRDs: true
  validateHealths:
  - name: deployment-health
    featureID: Helm
    group: "apps"
    version: "v1"
    kind: "Deployment"
    namespace: cert-manager
    script: |
      function evaluate()
        local hs = {healthy = false, message = "available replicas not matching requested replicas"}
        if obj.status and obj.status.availableReplicas ~= nil and obj.status.availableReplicas == obj.spec.replicas then
          hs.healthy = true
        end
        return hs
      end

CEL Health Validation

Alternatively, you can use Common Expression Language (CEL), which offers a more concise way to define the same health rule. The example below uses a CEL expression to check if the availableReplicas are equal to the requested replicas. The result is the same as the Lua script, providing a healthy and succinct way to validate the state of your deployments.

---
apiVersion: config.projectsveltos.io/v1beta1
kind: ClusterProfile
metadata:
  name: cert-manager
spec:
  clusterSelector:
    matchLabels:
      env: fv
  syncMode: Continuous
  helmCharts:
  - repositoryURL:    https://charts.jetstack.io
    repositoryName:   jetstack
    chartName:        jetstack/cert-manager
    chartVersion:     v1.13.2
    releaseName:      cert-manager
    releaseNamespace: cert-manager
    helmChartAction:  Install
    values: |
      installCRDs: true
  validateHealths:
  - name: deployment-health
    featureID: Helm
    group: "apps"
    version: "v1"
    kind: "Deployment"
    namespace: cert-manager
    evaluateCEL:
    - name: deployment_replicas
      rule: resource.status.availableReplicas == resource.spec.replicas

Example: Combine with dependsOn

In the example below, the ClusterProfile deploys traefik to clusters with the label set to env:fv only after the cert-manager deployment finishes successfully. Take a look at the ClusterProfile examples listed above.

---
apiVersion: config.projectsveltos.io/v1beta1
kind: ClusterProfile
metadata:
  name: traefik
spec:
  clusterSelector:
    matchLabels:
      env: fv
  syncMode: Continuous
  helmCharts:
  - repositoryURL:    https://traefik.github.io/charts
    repositoryName:   traefik
    chartName:        traefik/traefik
    chartVersion:     "41.5.0"
    releaseName:      traefik
    releaseNamespace: traefik
    helmChartAction:  Install
  dependsOn:
  - cert-manager

Metric-Based Health Validation

In addition to checking Kubernetes resource state, validateHealths entries can query a Prometheus-compatible metrics endpoint to gate deployment on live application signals. For example, Sveltos can confirm an error rate is below a threshold before considering a release healthy.

How does it work?

Add a metricSource field with the URL of the Prometheus endpoint, and one or more metricQueries. Each query is a named PromQL expression that must return a scalar value. Sveltos evaluates each query and exposes the results as a global metrics table inside the Lua evaluate() function. The key of each entry is the name given to the query.

validateHealths:
- name: error-rate-low
  featureID: Helm
  metricSource:
    url: http://prometheus-server.monitoring.svc:9090
  metricQueries:
  - name: errorRate
    query: >-
      sum(rate(http_requests_errors_total{namespace="my-app"}[5m]))
      /
      sum(rate(http_requests_total{namespace="my-app"}[5m]))
  script: |
    function evaluate()
      if metrics["errorRate"] > 0.05 then
        return {healthy = false, message = "error rate above 5%: " .. metrics["errorRate"]}
      end
      return {healthy = true, message = ""}
    end

The check above prevents Sveltos from marking the Helm feature as healthy until the error rate falls at or below 5 %. If the check fails, Sveltos retries according to the normal requeue interval. No deployment progress is marked until healthy = true is returned.

Push mode vs. pull mode

Mode Who queries the endpoint
Push The addon-controller running in the management cluster. The metricSource.url must be reachable from the management cluster.
Pull The sveltos-applier agent running inside the managed cluster. The URL is resolved via in-cluster DNS, so a cluster-local Prometheus service name (e.g. http://prometheus-server.monitoring.svc:9090) works without any external exposure.

Combining metrics with resource checks

A single validateHealths entry supports only one evaluation path. To combine Kubernetes resource state with a metric check, add two entries under validateHealths: one using script or evaluateCEL against resource state, and one using metricSource + metricQueries. Both must pass before the feature is considered healthy.

Job-Based Health Validation

Enterprise Feature

The job-based Health Validations feature is part of the Enterprise offering. Contact us at support@projectsveltos.io to explore license options.

The Lua, CEL, and metric checks above all evaluate state that already exists in the managed cluster. jobCheck instead runs an active probe: Sveltos deploys a Kubernetes Job into the managed cluster and uses the Job's own Complete/Failed outcome as the check result. This is useful when the check itself needs to do something — a smoke test, a synthetic transaction, a connectivity probe from inside the cluster — rather than inspect a field.

How does it work?

Set jobCheck.jobRef to a ConfigMap or Secret containing the Job manifest. Sveltos deploys it into the managed cluster, waits for it to reach Complete or Failed (up to jobCheck.timeout, which defaults to 5 minutes when unset), then deletes it. On failure, the check's message comes from the Job's own status conditions.

Job-based health check

ConfigMap with smoke-test Job

apiVersion: v1
kind: ConfigMap
metadata:
  name: cert-manager-smoke-test
  namespace: cert-manager
data:
  job.yaml: |
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: cert-manager-smoke-test
      namespace: cert-manager
    spec:
      backoffLimit: 0
      template:
        spec:
          restartPolicy: Never
          containers:
          - name: probe
            image: curlimages/curl:8.11.0
            command: ["curl", "-sf", "http://cert-manager-webhook.cert-manager.svc:443/healthz"]

ClusterProfile validateHealths

    validateHealths:
    - name: cert-manager-smoke-test
      featureID: Helm
      jobCheck:
        jobRef:
          kind: ConfigMap
          namespace: cert-manager
          name: cert-manager-smoke-test
        timeout: 2m

Note

The second example does not contain the complete ClusterProfile. Take a look at earlier sections to get an understanding of what the complete ClusterProfile looks like.

The jobCheck is mutually exclusive with script and evaluateCEL on the same validateHealths entry. A single entry runs either an active Job probe or a Lua/CEL evaluation, but not both. To combine a Job probe with a resource or a metric check, add separate entries under validateHealths, the same way described above for combining metrics with resource checks.