Last modified July 2, 2025
App configuration reference
The Giant Swarm’s app platform allows you to easily install apps across your entire fleet of clusters. The platform fully support helm as a general tool to deploy your applications as well as the official Giant Swarm app catalog.
The apps are packaged as helm charts. Those charts rely on values to be set in order to fill in placeholders in templates. By configuring your app you set the values that become available to the templates when they’re deployed.
Configuration levels
There are three levels of configuration:
- Catalog: Configuration provided by the publisher of the
Appcatalog. - Cluster: Configuration provided by the cluster admin.
- User: Configuration provided by the user installing an
App.
Each level overrides the previous one. As a user you aren’t expected to edit configuration at the catalog or cluster level. However, user level configuration can override both catalog and cluster level configuration.
Besides, there is a list of extra configuration layers with special priority field that you can control the level around which they will be applied to the core configurations. Head to the extra configuration layers section to learn more about them.
Each level of configuration - same applies to extra configuration layers - has two types of values that you can provide:
- Configuration values: Configuration provided as a
ConfigMapresource. - Secret values: Configuration and credentials provided as a
Secretresource.
All values are gathered together and merged into the final values object that will become available to the chart template.
Values are merged in the following order:
Catalogconfiguration valuesCatalogsecret valuesClusterconfiguration valuesClustersecret valuesUserconfiguration valuesUsersecret values
If no value is provided then the default in the chart’s values file (values.yaml) is used.
Note: Attempting to change configuration at any other level is risky because your changes might be overwritten by an operator.
General notes about app configuration
When using app platform, it’s important to remember, that most of the configuration changes in kubernetes are asynchronous and only eventually consistent. This also applies to App resources and theirs configuration. To better understand that, let’s use an example where you update the application version in the App resource from version v1.0.0 to v2.0.0 and the same time you update the ConfigMap referenced by the App resource (let’s call the ConfigMap before the change configMap v1 and after the change configMap v2).
As these changes are completely independent for kubernetes, the following scenario is possible:
- The
Appresource is in versionv1.0.0andConfigMapis inv1 - Both
Appresource and the referencedConfigMapare edited - The application’s version change is already processed, so the application runs in
v2.0.0with aConfigMapv1 - After some time, the
ConfigMapchange is processed, the application will now run inv2.0.0with aConfigMapin versionv2
Obviously, it can also happen that the ConfigMap is updated first, then the application version. The time between one and the other change being processed is usually very short, still it’s important to understand, that such situations might and will happen.
Example of values merging
Given a chart with a values.yaml that contains the following content:
colors:
background: "black"
foreground: "white"
# This is a secret, so we leave it blank in the Chart's values.yaml since
# it's specific to the deployment and there is no sane default.
secretColor: ""
Now you create an App resource that references a user level ConfigMap and a user level secret:
apiVersion: application.giantswarm.io/v1alpha1
kind: App
metadata:
name: hello-world
namespace: i5h93
spec:
catalog: giantswarm-playground
...
name: hello-world-app
namespace: hello-world-app
userConfig:
configMap:
name: hello-world-user-values
namespace: i5h93
secret:
name: hello-world-user-secrets
namespace: i5h93
...
The hello-world-user-values ConfigMap contains the following content:
apiVersion: v1
kind: configmap
metadata:
name: hello-world-user-values
namespace: i5h93
data:
values: |
colors:
background: "red"
The hello-world-user-secrets secret contains this:
apiVersion: v1
kind: secret
metadata:
name: hello-world-user-secrets
namespace: i5h93
data:
values: "Y29sb3I6CiAgc2VjcmV0Q29sb3I6ICJibHVlIgo="
Note: when Base64 decoding the string .data.values field in the secret, you’ll get this:
colors:
secretColor: "blue"
Then the resulting values applied to the helm chart will be:
colors:
background: "red"
foreground: "white"
secretColor: "blue"
As you can see, we made an override for .colors.background, changing it from black to red, and set the .colors.secretColor value to blue using values from the secret.
You can use these values throughout your chart using the normal templating of helm charts:
# hello-world-app/helm/chart/hello-world/templates/colors-configmap.yaml
apiVersion: v1
kind: configmap
metadata:
name: hello-world-configmap
namespace: {{ .Release.Namespace }}
labels:
app: hello-world
data:
background: {{.Values.colors.background}}
foreground: {{.Values.colors.foreground}}
# hello-world-app/helm/chart/hello-world/templates/colors-secret.yaml
apiVersion: v1
kind: secret
metadata:
name: hello-world-secret
namespace: {{ .Release.Namespace }}
labels:
app: hello-world
data:
secretColor: {{.Values.colors.secretColor | b64enc | quote}}
Note: If you uploaded your secret as individual plain values and want to use one of those values in an actual templated secret, then you have to base64 encode it to comply with how kubernetes stores secrets. Our API only encodes the entire secrets value string. It doesn’t individually encode each value.
How configuration values are stored
Configuration for apps are stored as ConfigMaps and Secrets, which are referenced by name and namespace in various spec fields of the App and Catalog custom resource.
Our operators act on those resources to ensure the actual state ends up looking like the desired state. More information is available in our general overview of the app platform.
| Configuration Level | Where to set it | Fields to set |
|---|---|---|
catalog | Catalog CR | .spec.config.configMap.name |
.spec.config.configMap.namespace | ||
.spec.config.secret.name | ||
.spec.config.secret.namespace | ||
| - | - | - |
app | App CR | .spec.config.configMap.name |
.spec.config.configMap.namespace | ||
.spec.config.secret.name | ||
.spec.config.secret.namespace | ||
| - | - | - |
user | App CR | .spec.userConfig.configMap.name |
.spec.userConfig.configMap.namespace | ||
.spec.userConfig.secret.name | ||
.spec.userConfig.secret.namespace |
Extra configuration layers
You can set a list of extra configuration layers via .spec.extraConfigs. For example:
spec:
catalog: giantswarm-test
extraConfigs:
- name: hello-world-extra-values-pre-cluster
namespace: i5h93
- kind: secret
name: hello-world-extra-secrets-pre-cluster
namespace: i5h93
- name: hello-world-extra-values-pre-user
namespace: i5h93
priority: 75
- kind: secret
name: hello-world-extra-secrets-post-user
namespace: i5h93
priority: 125
The name and namespace fields are required for each entry. However, note that it’s optional to set kind. It defaults to configMap. It’s also optional to set priority. It defaults to 25.
The three configuration levels all have an assigned priority value bound to them behind the scenes:
- Catalog has priority
0. - Cluster has priority
50. - User has priority
100.
The priority field for spec.extraConfigs entries must be set to a numerical value between (inclusively) 1 and 150.
This extends the example of values merging section.
The base upon we merge all other layers is always the Catalog layer. That’s why it has priority set to 0 and you can only set priority value starting from 1.
Then for each kind (configMap, secret) we look up each entry and merge them in the following way:
- The Catalog is the base.
- All
spec.extraConfigsentry withprioritygreater than the Catalog level and lower than or equal to the Cluster level are merged. - The Cluster level configurations are merged.
- All
spec.extraConfigsentry withprioritygreater than the Cluster level and lower than or equal to the User level are merged. - The User level configurations are merged.
- All
spec.extraConfigsentry withprioritygreater than the User level and lower than or equal to the maximum level of150are merged.
In case of multiple spec.extraConfigs entries with the same priority level, the order on the list is binding, with the item lower on the list being merged later (overriding those higher on the list).
Example of merging extra configuration
Let’s take the following example with just ConfigMaps to make it simple. The same merging algorithm applies for secrets as well.
apiVersion: application.giantswarm.io/v1alpha1
kind: App
metadata:
name: hello-world
namespace: i5h93
spec:
name: hello-world-app
namespace: kube-system
catalog: giantswarm
config:
configMap:
name: hello-world-values
namespace: i5h93
extraConfigs:
- kind: configMap
name: hello-world-post-user
namespace: i5h93
priority: 125
- kind: configMap
name: hello-world-pre-user
namespace: i5h93
priority: 75
- kind: configMap
name: hello-world-pre-cluster
namespace: i5h93
- kind: configMap
name: hello-world-final
namespace: i5h93
priority: 125
- kind: configMap
name: hello-world-high-priority
namespace: i5h93
priority: 10
userConfig:
configMap:
name: hello-world-app-user-values
namespace: i5h93
The merge order for ConfigMaps (with P as the indicated or calculated priority) will be:
Catalog(P = 0)Configmap:hello-world-high-priority(P = 10)Configmap:hello-world-pre-cluster(P = 25)Configmap:hello-world-values(P = 50)Configmap:hello-world-pre-user(P = 75)Configmap:hello-world-app-user-values(P = 100)Configmap:hello-world-post-user(P = 125, position in the list: `1)Configmap:hello-world-final(P = 125, position in the list: 4)
Format of values in ConfigMap and Secret
The ConfigMap and Secret must contain a .data.values key, under which all configuration values are kept, as a string of valid YAML. For secrets, the string must be base64 encoded, as is required by kubernetes.
In this context, the secret is used to populate the values file with secret information, it’s not used to create secrets on the workload cluster.
Example ConfigMap
apiVersion: v1
kind: configmap
metadata:
name: hello-world-user-values
namespace: i5h93
data:
values: |
colors:
background: "red"
Example secret
apiVersion: v1
kind: secret
metadata:
name: hello-world-user-secrets
namespace: i5h93
data:
values: "Y29sb3I6CiAgc2VjcmV0Q29sb3I6ICJibHVlIgo="
Applying configuration values
There are many approaches to apply resources in kubernetes, which go beyond the scope of this article. You can test the examples by running kubectl apply to the platform API. For more advanced use cases, we advocate using GitOps to maintain your configuration in a Git repositories always in sync with your clusters.
Note: Depending on your installation you might not have access to the platform API yet. Please contact your account engineer if you would like more information about that or follow the getting started page to learn how to configure it.
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!