Last modified July 2, 2026

Add a HelmRelease to a workload cluster

This guide shows how to deploy an application to a workload cluster using a Flux HelmRelease and OCIRepository, managed through GitOps. For the conceptual overview, see App management. For an imperative version that applies resources directly to the cluster, see Deploying an application via a Flux HelmRelease.

If you have existing GitOps deployments using Giant Swarm App custom resources, the equivalent guide is Add a new App to a workload cluster. Flux HelmRelease is the recommended path for new deployments.

Common steps

Export environment variables

The management cluster, the organization, the workload cluster, and the resource name are needed throughout. Export them once:

export MC_NAME=CODENAME
export ORG_NAME=ORGANIZATION
export WC_NAME=CLUSTER_NAME
export APP_NAME="${WC_NAME}-APP_NAME"

Set up the directory structure

Create a new directory in the apps directory of your workload cluster, named after the HelmRelease:

cd management-clusters/${MC_NAME}/organizations/${ORG_NAME}/workload-clusters/${WC_NAME}/mapi/apps
mkdir ${APP_NAME}
cd ${APP_NAME}

Render the OCIRepository and HelmRelease

Set the chart variables:

export CHART_URL=oci://gsoci.azurecr.io/charts/giantswarm/CHART_NAME
export CHART_VERSION=CHART_VERSION
export APP_NAMESPACE=APP_NAMESPACE

Render the OCIRepository manifest with --export so it lands as YAML in your repository:

flux create source oci ${APP_NAME} \
  --url ${CHART_URL} \
  --tag ${CHART_VERSION} \
  --namespace org-${ORG_NAME} \
  --interval 60m \
  --export > ocirepository.yaml

Render the HelmRelease manifest:

flux create helmrelease ${APP_NAME} \
  --namespace org-${ORG_NAME} \
  --chart-ref OCIRepository/${APP_NAME} \
  --kubeconfig-secret-ref ${WC_NAME}-kubeconfig \
  --target-namespace ${APP_NAMESPACE} \
  --label giantswarm.io/cluster=${WC_NAME} \
  --release-name ${APP_NAME} \
  --interval 60m \
  --export > helmrelease.yaml

The --kubeconfig-secret-ref flag tells Flux to install the chart into the workload cluster (not the management cluster). The Secret follows the <cluster>-kubeconfig naming convention and is created for you alongside the cluster.

Note: Including ${WC_NAME} in the resource name avoids collisions between clusters running the same chart inside the same organization.

Add configuration

Most charts need configuration values. Pass them through the HelmRelease using a ConfigMap (for non-secret values) and a Secret (for credentials).

Non-secret values

Create configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: ${APP_NAME}-values
  namespace: org-${ORG_NAME}
data:
  values.yaml: |
    # Your chart values here
    image:
      tag: v1.2.3    

Reference it in helmrelease.yaml by adding a valuesFrom entry:

spec:
  valuesFrom:
    - kind: ConfigMap
      name: ${APP_NAME}-values

Encrypted secrets

For credentials and other sensitive values, create secret.enc.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: ${APP_NAME}-secret
  namespace: org-${ORG_NAME}
stringData:
  values.yaml: |
    database:
      password: changeme    

Encrypt it with sops using the workload cluster’s GPG key before committing:

gpg --import management-clusters/${MC_NAME}/.sops.keys/.sops.${WC_NAME}.asc
sops --encrypt --in-place secret.enc.yaml

For more on secrets encrypted with sops in GitOps, see the gitops-template docs.

Add the Secret to helmrelease.yaml next to the ConfigMap entry:

spec:
  valuesFrom:
    - kind: ConfigMap
      name: ${APP_NAME}-values
    - kind: Secret
      name: ${APP_NAME}-secret

Flux merges the entries in order, with later ones overriding earlier ones. See the Flux HelmRelease values reference for the full semantics.

Wire up Kustomization

Edit kustomization.yaml in the apps folder to include the new files:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  ...
  - ${APP_NAME}/ocirepository.yaml
  - ${APP_NAME}/helmrelease.yaml
  - ${APP_NAME}/configmap.yaml
  - ${APP_NAME}/secret.enc.yaml

If you’ve completed the workload cluster configuration guide, all the Flux resources needed to reconcile this directory are already in place. Commit the changes and Flux applies them on its next reconciliation.

Next steps

Once the HelmRelease is reconciled, common follow-ups are updating its version or values, and letting Flux pick up new chart versions via a SemVer range on the OCIRepository. Companion guides for those workflows are coming as part of the HelmRelease migration. For now, see the Flux HelmRelease documentation for the full API and patterns.

For the App CR equivalent of this guide, see Add a new App to a workload cluster.