Get startedSign in

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 helms versioning independent of git can be valuable. The path here requires creation of a Flux HelmRepository CR first, then the service, e.g.:

yaml
# the Cluster resource should ideally be defined in separate files in your infra repo
apiVersion: deployments.plural.sh/v1alpha1
kind: Cluster
metadata:
  name: k3s
  namespace: infra
spec:
  handle: k3s
---
apiVersion: deployments.plural.sh/v1alpha1
kind: ServiceDeployment
metadata:
  name: nginx
  namespace: infra
spec:
  namespace: ingress-nginx
  name: ingress-nginx
  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
    repository:
      namespace: infra
      name: nginx # referenced helm repository above
  clusterRef:
    kind: Cluster
    name: k3s
    namespace: infra

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
  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"}
    repository:
      namespace: infra
      name: nginx # referenced helm repository above
  clusterRef:
    kind: Cluster
    name: k3s
    namespace: infra

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

Multi-Source Helm

Say you want to source the helm templates from an upstream helm repository, but the values files from a Git repository. In that case, you can define a multi-sourced service, which has both a git and helm repository defined. It would look like so:

yaml
apiVersion: deployments.plural.sh/v1alpha1
kind: GitReposiotry
metadata:
  name: infra
  namespace: infra
spec:
  url: https://github.com/pluralsh/my-infra-repo.git # replace w/ your own repo
---
apiVersion: deployments.plural.sh/v1alpha1
kind: ServiceDeployment
metadata:
  name: nginx
  namespace: infra
spec:
  namespace: ingress-nginx
  name: ingress-nginx
  repositoryRef:
    kind: GitRepository
    name: infra # points to the CRD above
    namespace: infra
  git: 
    ref: main
    folder: helm # where helm values files are stored
  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
    valuesFiles:
    - ingress-nginx.values.yaml # using helm/ingress-nginx.values.yaml as our values file
  clusterRef:
    kind: Cluster
    name: k3s
    namespace: infra

Helm Repositories Stored in Git