Last modified November 29, 2024
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
App
catalog. - 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
ConfigMap
resource. - Secret values: Configuration and credentials provided as a
Secret
resource.
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:
Catalog
configuration valuesCatalog
secret valuesCluster
configuration valuesCluster
secret valuesUser
configuration valuesUser
secret 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
App
resource is in versionv1.0.0
andConfigMap
is inv1
- Both
App
resource and the referencedConfigMap
are edited - The application’s version change is already processed, so the application runs in
v2.0.0
with aConfigMap
v1
- After some time, the
ConfigMap
change is processed, the application will now run inv2.0.0
with aConfigMap
in 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.extraConfigs
entry withpriority
greater than the Catalog level and lower than or equal to the Cluster level are merged. - The Cluster level configurations are merged.
- All
spec.extraConfigs
entry withpriority
greater than the Cluster level and lower than or equal to the User level are merged. - The User level configurations are merged.
- All
spec.extraConfigs
entry withpriority
greater than the User level and lower than or equal to the maximum level of150
are 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!