Helm Subchart order of execution in an umbrella chart

Z Y . picture Z Y . · May 23, 2018 · Viewed 13.3k times · Source

I have an umbrella chart with multiple sub-charts, I simply want to make sure that subchart1 runs before subchart2, etc. How can we define the order of subchart execution?

Seems like hook-weights only apply relative to the chart that declares them.

Answer

VASャ picture VASャ · May 24, 2018

Here is a part of the Helm documentation related to execution order of charts:

The above sections explain how to specify chart dependencies, but how does this affect chart installation using helm install and helm upgrade?

Suppose that a chart named "A" creates the following Kubernetes objects

namespace "A-Namespace"
statefulset "A-StatefulSet"
service "A-Service"

Furthermore, A is dependent on chart B that creates objects

namespace "B-Namespace"
replicaset "B-ReplicaSet"
service "B-Service"

After installation/upgrade of chart A a single Helm release is created/modified. The release will create/update all of the above Kubernetes objects in the following order:

A-Namespace
B-Namespace
A-StatefulSet
B-ReplicaSet
A-Service
B-Service

This is because when Helm installs/upgrades charts, the Kubernetes objects from the charts and all its dependencies are aggregrated into a single set; then sorted by type followed by name; and then created/updated in that order.
Hence a single release is created with all the objects for the chart and its dependencies.

The install order of Kubernetes types is given by the enumeration InstallOrder in kind_sorter.go (Helm v2 source file).

Part of kind_sorter.go (Helm v3 source) is related to install charts:

var InstallOrder KindSortOrder = []string{
    "Namespace",
    "NetworkPolicy",
    "ResourceQuota",
    "LimitRange",
    "PodSecurityPolicy",
    "PodDisruptionBudget",
    "Secret",
    "ConfigMap",
    "StorageClass",
    "PersistentVolume",
    "PersistentVolumeClaim",
    "ServiceAccount",
    "CustomResourceDefinition",
    "ClusterRole",
    "ClusterRoleList",
    "ClusterRoleBinding",
    "ClusterRoleBindingList",
    "Role",
    "RoleList",
    "RoleBinding",
    "RoleBindingList",
    "Service",
    "DaemonSet",
    "Pod",
    "ReplicationController",
    "ReplicaSet",
    "Deployment",
    "HorizontalPodAutoscaler",
    "StatefulSet",
    "Job",
    "CronJob",
    "Ingress",
    "APIService",
}

There is a workaround, that can change the default behaviour, shared by elementalvoid in this issue:

I've been setting my services, secrets, and configmaps as pre-install hooks to achieve this behavior.

Example:

apiVersion: v1
kind: Service
metadata:
  name: foo
  annotations:
    "helm.sh/hook": "pre-install"

--

It is possible to define a weight for a hook which will help build a deterministic executing order. Weights are defined using the following annotation:

  annotations:
    "helm.sh/hook-weight": "5"

Hook weights can be positive or negative numbers but must be represented as strings. When Tiller starts the execution cycle of hooks of a particular Kind it will sort those hooks in ascending order.

More detailed information about hooks can be found here (v2 doc, v3 doc) and in the source file (helm v2 source, helm v3 source)