Last modified December 17, 2025
App bundle reference
App bundle definition
As stated in the app platform overview, all managed apps are packaged, maintained, and offered as helm charts, and it’s no different for app bundles. What makes them special compared to solitary apps is that the bundle helm chart, instead of carrying regular resources composing the actual application, carries App custom resources which, once delivered and consumed by the app platform, install the expected applications and their resources.
In other words, an app bundle can be thought of as a meta package. It doesn’t install anything in the workload cluster on its own, but instead requests the installation of certain pre-defined applications.
The distinction between solitary and bundle apps is depicted in the figure below.

The A1 app’s helm chart consists of end resources representing the actual application. Upon installing this app, these resources are created in the workload cluster directly. On the other side is a bundle helm chart carrying the A1-A4 App custom resources. Installing this bundle results in the creation of these nested App custom resources in the management cluster. These App custom resources are then picked up and reconciled by the app platform, which only then results in creating end resources in the workload cluster.
As already hinted, the direct consequence of nesting App custom resources inside a helm chart is how the app is installed. Installing a solitary app for the workload cluster doesn’t result in creating any resources in the management cluster. In contrast, the bundle app is first installed in the management cluster, where it creates the nested App custom resources. These are then, in the second step, installed in the workload cluster. More about this in the App Bundle installation.
App bundle installation
High-level overview
The solitary app installation process has already been clearly depicted in the app platform overview. The bundle installation process is very similar except it involves one extra layer, and hence extra controllers.
This layer consists of the management cluster’s app and chart operators. Their purpose is to install applications and controllers designed to provide management layer functionality. These may be leveraged to install app bundles.
The figure below depicts the process. Note, however, that some parts present in the App Platform Overview figure, like pulling the tarball archive, have been omitted for brevity.

When an App custom resource for the bundle is created within the management cluster, it’s first picked up by the management cluster’s app operator, which is called, by convention, unique. It resides in the protected giantswarm namespace, but in principle operates the same way the workload cluster’s app operators do.
Essentially, it reconciles the App custom resource by creating a corresponding Chart custom resource in the giantswarm namespace. This is then picked up by the management cluster’s chart operator also residing in that namespace. The chart operator then installs the app resources, which in this case are nested App custom resources to be created in the workload cluster namespace. Once delivered, the nested App custom resources are picked up by the workload cluster’s app operator and installed in the well-known way.
Is it possible to install app bundles without involving the management cluster layer
No, at least not in the current implementation form. The reason is that app bundles install `App` custom resources that are understood only by the management clusters. Attempting to install them directly to the workload cluster would result in an error. This is because the corresponding `App` custom resource definition isn't available there, which means Kubernetes cannot understand the submitted objects.Now, obviously to leverage this management cluster layer, the bundle App custom resource must be configured in a certain way which is slightly different compared to the solitary apps. Find more details in the Technical Details paragraph.
Technical details
Naming the bundle’s App resource
The first, not so obvious, consequence of installing a bundle in a management cluster before its nested apps are installed in the workload cluster is the requirement for name uniqueness. When a given app bundle is to be installed for more than one workload cluster, each App custom resource instance must be given a unique name within the management cluster.
It becomes natural for solitary apps (for example, the [Hello World app]) that when you need to install it twice in the workload cluster, both App custom resource instances must be named uniquely. It’s natural because both live under the same namespace. Even if we could break them into separate namespaces, this uniqueness would still be required because both apps target the same workload cluster and must be distinguished by its operators.
It’s less obvious for the bundle apps, because these are usually scattered across the namespaces for the corresponding workload clusters from the very beginning. This gives the impression they’re isolated, which we already know to not be the case. Not complying with this rule results in apps competing over certain resources, and hence conflicting.
Let’s walk through an example to understand it better.
Imagine that a user has two workload clusters created, the WC1 and the WC2, on the management cluster. The user then installs, via the App custom resource called just bundle, an app bundle in the WC1 cluster. Everything works perfectly so far, see the figure below.

The flow of actions can be thought of as an unbroken link. The continuity of this link is a guarantee of delivering end resources. Now let’s assume the user wants to install the same app bundle, but for the WC2 cluster this time.
The user creates an App custom resource in the WC2 namespace and names it bundle as well. This is a problem, because globally, the bundle app is already installed in the management cluster, so a corresponding Chart custom resource with the name bundle already exists. Creating another app of the same name causes the unique app operator to re-assign this Chart custom resource to the new instance of the app. This effectively breaks the aforementioned link for the old one. See this in the figure below.

The broken link doesn’t result in removing the first instance. However, it does cause the Chart custom resource to be continuously switched between apps, leading to continuous re-deployments and instability. Due to this, it’s required that the bundle App custom resources are named uniquely. This results in the creation of a separate set of corresponding resources and an effectively unique deployment link. See the figure below.
How to best make the names unique
It's a common practice to either prepend or append the workload cluster name to the `App` custom resource name, for example creating `wc1-bundle` or `bundle-wc1`.
Configuring the bundle’s App resource for the unique app operator
Once unique names are ensured, the App custom resource must be configured to be installed in the management cluster by the unique app operator. This is done by means of the app-operator.giantswarm.io/version: 0.0.0 label and the .spec.kubeConfig.inCluster: true field. See the snippet below (note some fields have been removed for brevity).
apiVersion: application.giantswarm.io/v1alpha1
kind: App
metadata:
labels:
app-operator.giantswarm.io/version: 0.0.0
name: bundle-wc1
...
spec:
...
kubeConfig:
inCluster: true
name: bundle-app
...
These two settings ensure this App custom resource is picked up and reconciled by the unique app operator. When kubectl-gs is used, both of these fields are set correctly when templating an app with the --in-cluster flag. See kubectl gs template app for details, so there is no need to remember this.
Is it possible to install any app in the management cluster
No, but it will work for some apps. The management cluster's chart operator uses a limited set of permissions when installing user-requested apps. It prohibits the creation of certain cluster-scoped resources such as `ClusterRole`, `ClusterRoleBinding`, or custom resource definitions, and access to certain namespaces like `kube-system`. When the app being requested is limited to the namespace you have access to and doesn't require cluster-scoped resource creation, installing it within the management cluster should work.Configuring target workload cluster for the nested apps
Once the App custom resource name and configuration for unique App Operator are taken care of, the only thing left is to configure the bundle. This ensures that nested App custom resources are placed into the correct workload cluster namespace, with the correct configuration. This requires two steps.
Firstly, the App custom resource’s .metadata.namespace and .spec.namespace fields must be equal — that is, they must reference the same namespace. Let’s consider the snippet from the previous paragraph and enrich it with these settings.
apiVersion: application.giantswarm.io/v1alpha1
kind: App
metadata:
labels:
app-operator.giantswarm.io/version: 0.0.0
name: bundle-wc1
namespace: wc1
spec:
...
kubeConfig:
inCluster: true
name: bundle-app
namespace: wc1
...
Secondly, each app bundle Helm chart exposes the clusterName and organization configuration options in its values.yaml file, as shown below.
clusterName: ""
organization: ""
...
If no further customization is needed, it’s obligatory to, at minimum, fill in these two fields and provide such a values.yaml as user configuration to the App custom resource. Let’s go back to the example and enrich it further.
apiVersion: application.giantswarm.io/v1alpha1
kind: App
metadata:
labels:
app-operator.giantswarm.io/version: 0.0.0
name: bundle-wc1
namespace: wc1
spec:
...
kubeConfig:
inCluster: true
name: bundle-app
namespace: wc1
userConfig:
configMap:
name: bundle-wc1-userconfig
namespace: wc1
...
---
apiVersion: v1
data:
values: |
clusterName: wc1
organization: testorg
kind: ConfigMap
metadata:
name: bundle-wc1-userconfig
namespace: wc1
Please refer to App configuration to understand how the user configuration works, and to the kubectl gs template app reference to understand how you can automate this process.
At this point, the bundle’s App custom resource carries all the information to be successfully installed.
Need help, got feedback?
We listen to your Slack support channel. You can also reach us at support@giantswarm.io. And of course, we welcome your pull requests!