Helm-sourced services

Source manifests from a helm repository registered anywhere

You can also source manifests from a https or OCI-compatible helm repository. This is very useful for provisioning kubernetes add-ons, which are usually packaged using helm, or occasionally for complex release processes where Helm's versioning independent of git can be valuable.

yaml
apiVersion: deployments.plural.sh/v1alpha1
kind: ServiceDeployment
metadata:
  name: nginx
  namespace: infra
spec:
  namespace: ingress-nginx
  name: ingress-nginx
  cluster: k3s
  helm:
    version: 4.4.x
    chart: ingress-nginx
    url: https://kubernetes.github.io/ingress-nginx
    values:
      # in-line helm values, will be stored encrypted at rest
      controller:
        image:
          digest: null
          digestChroot: null
        admissionWebhooks:
          enabled: false

Dynamic Helm Configuration via luaScript

Plural supports runtime configuration generation via Lua scripting. This feature allows Helm deployments to dynamically compute values and valuesFiles, enabling powerful CI/CD workflows and context-aware configuration.

yaml
apiVersion: deployments.plural.sh/v1alpha1
kind: ServiceDeployment
metadata:
  name: nginx
  namespace: infra
spec:
  namespace: ingress-nginx
  name: ingress-nginx
  cluster: k3s
  helm:
    version: 4.4.x
    chart: ingress-nginx
    url: https://kubernetes.github.io/ingress-nginx
    luaScript: |
      -- Lua code returning:
      -- { values: table<string, any>, valuesFiles: list<string> }
      values = {}
      values["appName"] = "MyApplication"
      values["version"] = "1.2.3"
      values["debug"] = true
      values["maxConnections"] = 100

      valuesFiles = {"config.json", "secrets.yaml"}

For more information, see Dynamic Helm Configuration with Lua Scripts.

Dynamic Helm Configuration via pythonScript

The same values / valuesFiles overlay is available from a sandboxed Python script. The sandbox does not expose OS, filesystem, or network access. The only host callback is k8s_object_meta, which reads cached Kubernetes object metadata (uid, name, namespace, and labels) from the agent. Cluster-scoped objects use an empty namespace. A cache miss returns None.

Scripts can also call warn(message) to report non-fatal problems back to the service. See Reporting Warnings.

yaml
apiVersion: deployments.plural.sh/v1alpha1
kind: ServiceDeployment
metadata:
  name: observe
  namespace: infra
spec:
  namespace: observe
  name: observe
  cluster: k3s
  helm:
    version: 1.x.x
    chart: observe
    url: https://example.invalid/charts
    pythonScript: |
      ns = k8s_object_meta("", "v1", "Namespace", "", "kube-system")
      if ns:
          values["observeClusterId"] = ns["uid"]
          values["label"] = ns["labels"]["kubernetes.io/metadata.name"]
      else:
          warn("kube-system namespace not found in the agent cache, observeClusterId will not be set")