Helm Dependencies: Difference between revisions
(157 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=External= | =External= | ||
* | * https://helm.sh/docs/topics/charts/#chart-dependencies | ||
* [https://helm.sh/docs/topics/charts/#scope-dependencies-and-values Scope, Dependencies and Values] | * [https://helm.sh/docs/topics/charts/#scope-dependencies-and-values Scope, Dependencies and Values] | ||
=Internal= | =Internal= | ||
* [[Helm_Concepts#Dependencies|Helm Concepts]] | * [[Helm_Concepts#Dependencies|Helm Concepts]] | ||
* [[Helm_Repositories|Helm Repositories]] | |||
* [[Third_Party_Helm_Charts|Third Party Helm Charts]] | * [[Third_Party_Helm_Charts|Third Party Helm Charts]] | ||
=Overview= | =Overview= | ||
All applications, maybe with the exception of the most trivial, depend on other runtime components, such as web servers, caches, databases, etc. Helm supports modularization via a dependency mechanism, which allows to formally specify, manage and deploy dependencies as part of a Helm [[Helm Concepts#Release|release]]. A Helm chart may declare dependencies, which are other Helm charts published in external repositories, conveniently packaged by people who presumably know the respective components well. The simples possible example is a chart A - the dependent - that declared its reliance on a chart B - the dependency - by specifying chart B's “coordinates” (name, version and repository URL) as part of its own metadata. The exact way in which the dependencies are declared has evolved across Helm releases. For Helm 2 charts, the dependencies are declared in a dedicated [[Helm_Chart_requirements.yaml|requirements.yaml]] file, while for Helm 3 chart, the dependencies are declared [[Helm_Chart_Chart.yaml#dependencies|as part of the chart manifest Chart.yaml]]. However, the way the dependencies are processed during installation has remained the same. | |||
At installation time, Helm becomes aware of the '''direct''' dependencies of the chart being installed, insures that those direct dependencies are available and uses them in the installation process. In reality, the actual sequence is more complicated, involving an intermediate [[#the_only_source_of_truth|chart/]] subdirectory and a [[Helm_dependency|helm dependency update]] command, but these are operational details, not relevant at this level. It is worth noting that unlike Maven, which actively walks the transitive dependency tree, Helm does not. This behavior is mitigated by the fact a properly built chart embeds its entire dependency tree, and this is possible and practical just because the chart metadata, and the dependency trees, are small. | |||
=How Helm Dependencies Work= | =How Helm Dependencies Work= | ||
Helm does not automatically handle transitive dependencies: | During the installation or upgrade process, the Helm client looks into the ./charts sub-directory of the chart being installed, and installs/upgrades the charts whose [[Helm_Concepts#Chart_Archive|chart archives]] are found in that subdirectory. | ||
<span id='the_only_source_of_truth'></span>{{Note|⚠️ The content of the [[Helm_Concepts#charts_Directory|charts/]] subdirectory is '''the one and only source of truth''' on dependencies to be installed or upgraded.}} | |||
If a dependency chart is not present in the charts/ subdirectory at the time of installation/upgrade, it is not installed/upgraded. All charts present in the charts/ subdirectory at the time of installation/upgraded are installed/upgraded. | |||
The "dependencies" element of [[Helm_Chart_Chart.yaml|Chart.yaml]] is a convenience feature that allows the chart author to specify the dependency list in a synthetic manner, by "coordinates": name, version and repository URL. However, listing the dependency coordinates in Chart.yaml is not sufficient, additional manual steps need to be performed: [[Helm_dependency|helm dependency update]], which is a step that downloads dependencies in the charts/ directory, based on their Chart.yaml "dependencies" specifications. | |||
{{Note|⚠️ This charts/ content management functionality ([[helm dependency]]) must be explicitly invoked and it is NOT automatically triggered during the installation or update process. However, some sanity checks are performed by [[helm install]], which fails if dependencies are declared in Chart.yaml but not present in charts/.}} | |||
<span id='Installation_and_De-Installation_Order'></span>When Helm installs or updates a chart that has dependencies, it will aggregate all Kubernetes objects declared by the chart '''and''' dependencies in a single set, sort the object by types, then by name, and create/update in that order. Also see [[Helm_Templates#Installation_and_De-Installation_Order|Installation and De-Installation Order]]. If a dependency is present in the charts/ subdirectory but not in the "dependencies" list from Chart.yaml, it will be considered a manually-managed dependency and it will be installed. | |||
Helm does not automatically handle transitive dependencies, in the same manner as [[Maven]], for example, does: it is not possible to specify that chart "a" depends on chart "b", only specify the chart "b" "coordinates" (name, version and repository URL) and expect Helm to automatically pull "b" during the installation process. In this situation. Maven would contact the dependency's repository and pull the artifact. If that artifact had its own dependencies, specified by coordinates, Maven would recursively pull those as well, contacting as many repositories as necessary. This is known as what Maven friends refer to as "downloading the Internet". | |||
Helm behaves differently. It expects instead a chart to '''embed all dependencies it needs, recursively'''. This decision was probably taken because the chart metadata is really small, especially when compressed. and the chart transitive dependency graphs are not large, so embedding the whole graph in an archive is feasible, which would not be in Maven's case. Indeed, for a situation where an "a" chart depends on a "b" chart, and the "b" chart depends on a "c" chart, the structure of the "a"'s chart archive is; | |||
<syntaxhighlight lang='text'> | |||
a | |||
├── Chart.yaml | |||
├── charts | |||
│ └── b | |||
│ ├── Chart.yaml | |||
│ ├── charts | |||
│ │ └── c | |||
│ │ ├── Chart.yaml | |||
│ │ ├── templates | |||
│ │ │ └── pod.yaml | |||
│ │ └── values.yaml | |||
│ ├── templates | |||
│ │ └── pod.yaml | |||
│ └── values.yaml | |||
├── templates | |||
│ └── pod.yaml | |||
└── values.yaml | |||
</syntaxhighlight> | |||
The enforcement of presence of dependencies happens when the chart is packaged with [[Helm_package#Packaging_and_Dependencies|helm package]] command. If a chart is packaged manually, and its dependencies are omitted while building the chart archive, the chart archive cannot be installed. An attempt to install a chart archive that does not embed dependencies produces: | |||
<syntaxhighlight lang='text'> | |||
Error: found in Chart.yaml, but missing in charts/ directory: some-dependency-chart | |||
</syntaxhighlight> | |||
For more details on how to package a chart with its dependencies, see: {{Internal|Helm_package#Packaging_and_Dependencies|Packaging and Dependencies}} | |||
=Subcharts= | |||
A charts stored in the "charts/" subdirectory is also known as a "subchart". | |||
=Dependency Declaration= | =Dependency Declaration= | ||
Line 23: | Line 67: | ||
... | ... | ||
dependencies: | dependencies: | ||
- name: # The name of the dependency | - name: 'b' # The name of the dependency | ||
version: # The version of the dependency | version: 1.0.0 # The version of the dependency | ||
repository: # Repository URL | repository: http://helm-example.com/charts # Repository URL | ||
condition: b.enabled, global.b.enabled # See Dependency Selective Installation below | |||
tags: # See Dependency Selective Installation below | |||
- tag1 | |||
- tag2 | |||
... | ... | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 32: | Line 80: | ||
<syntaxhighlight lang='yaml'> | <syntaxhighlight lang='yaml'> | ||
... | ... | ||
# 'a' Chart.yaml | |||
dependencies: | dependencies: | ||
- name: | - name: b | ||
version: 1.0.0 | version: 1.0.0 | ||
repository: | repository: http://helm-example.com/charts | ||
condition: b.enabled, global.b.enabled | |||
tags: | |||
- front-end | |||
- b | |||
... | ... | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=Dependencies and | Note that simply declaring the dependency in Chart.yaml is not sufficient. The dependency needs to be physically downloaded and placed in the charts/ subdirectory with: | ||
[[Helm_dependency#Dependency_Update|helm dependency update]] | |||
==Elements== | |||
===name=== | |||
The dependency [[Helm_Concepts#Chart_Name|chart name]]. The name must match the name in the dependency chart's Chart.yaml file. | |||
===version=== | |||
The dependency [[Helm_Concepts#Chart_Version|chart version]]. It could be a version or a version range. | |||
⚠️ When the chart is published locally, so there is single version that can be possibly exposed by the local unpacked chart, one may think that <code>version</code> is not required. This is not true. For more details see [[#Local_Repository_URL_and_version_Field|Local Repository URL and version Field]] below. | |||
===repository=== | |||
'repository' specifies the [[Helm_Repositories#Repository_URL|URL of the Helm repository]] to pull the dependency chart from. | |||
The value can be: | |||
* a [[#Full_URL|full URL]] | |||
* a [[#Repository_Name|repository name]] | |||
* a [[#Relative_or_Absolute_Filesystem_Path|relative or absolute filesystem path]] | |||
====Full URL==== | |||
The most common case is to use a [[Helm_Repositories#Repository_URL|full URL]] of the [[Helm_Repositories#Source_Repository|source repository]]: | |||
<syntaxhighlight lang='yaml'> | |||
... | |||
dependencies: | |||
- name: 'postgresql' | |||
version: '6.3.2' | |||
repository: 'https://kubernetes-charts.storage.googleapis.com' | |||
</syntaxhighlight> | |||
The repository can be [[Helm_Repositories#Unmanaged_Repository|unmanaged]], meaning that it was not previously locally added with the '[[Helm_repo#Add_a_New_Repository|helm repo add]]' command, or [[Helm_Repositories#Managed_.28Locally_Added.29_Repository|managed]]. Both situations are valid. In both cases, the dependency must be downloaded locally in the chart's ./charts directory with '[[Helm_dependency#Dependency_Update|helm dependencies update]]' command before installing the chart. | |||
====Repository Name==== | |||
A [[Helm_Repositories#Repository_Name|repository name]] can only be used with [[Helm_Repositories#Managed_.28Locally_Added.29_Repository|managed repositories]]: | |||
<syntaxhighlight lang='yaml'> | |||
... | |||
dependencies: | |||
- name: 'postgresql' | |||
version: '6.3.2' | |||
repository: '@some-repository' | |||
</syntaxhighlight> | |||
where "my-repository" as locally added with [[Helm_repo#Add_a_New_Repository|helm repo add]]: | |||
<syntaxhighlight lang='bash'> | |||
helm repo add some-repository https://kubernetes-charts.storage.googleapis.com | |||
</syntaxhighlight> | |||
====Relative or Absolute Filesystem Path==== | |||
Relative or absolute filesystem path URLs can be used to refer to dependencies that exist on the local filesystem: | |||
<syntaxhighlight lang='yaml'> | |||
- name: my-chart | |||
version: '1.0.0' | |||
repository: 'file:///tmp/charts/my-chart' | |||
</syntaxhighlight> | |||
<syntaxhighlight lang='yaml'> | |||
- name: my-chart | |||
version: '1.0.0' | |||
repository: 'file://../my-chart' | |||
</syntaxhighlight> | |||
When a relative path is used, it is considered relative to the dependent chart root directory. In case the dependency chart is not archived, but exist as an exploded directory on the file system, the file:// URL must point to the root directory of the chart - the one that contains [[Helm_Chart_Chart.yaml|Chart.yaml]]. If the dependency chart is retrieved locally, it is not required to have the repository added to helm by [[helm repo|helm repo add]]. For more details on local repository URLs, see [[#Local_Dependencies|Local Dependencies]] below. | |||
===aliases=== | |||
{{External|https://helm.sh/docs/topics/charts/#alias-field-in-dependencies}} | |||
Each element of the "dependencies" list allows for an optional "alias" attribute. | |||
===condition=== | |||
See [[#Conditions|Conditional Dependencies | Conditions]] below. | |||
=<span id='Dependencies_and_Values'></span>Configuring Dependencies= | |||
Dependency configuration values should be specified in the top chart [[Helm_Chart_values.yaml|values.yaml]], and should be prefixed with the dependency name. It is recommended to only override values in the top level chart, and not in any subchart. | |||
<font color=darkgray>TODO: | |||
* Example</font> | |||
=<span id='Relative_Repository_URLs'></span><span id='Local_Repository_URLs'></span>Local Dependencies= | |||
A chart may declare one or more of its dependencies using a '''local URL''', which can be relative or absolute, for the case where both the dependent chart and the dependency chart are unpacked and live on the same filesystem. This is often the case when two or more interdependent charts are developed and maintained in the same GitHub repository. The syntax in that case is: | |||
<syntaxhighlight lang='yaml'> | |||
dependencies: | |||
- name: b | |||
version: 1.0.0 | |||
repository: file://../b | |||
</syntaxhighlight> | |||
When the unpacked chart dependency is available locally, as part of the same GitHub repository, and referred via a relative file:// URL, development changes that involve modifications of both dependent and dependencies, as well as related application code can evolve quickly, as the change-deployment-test cycle does not require publishing and downloading from an external repository. Equally important, dependency chart changes do not require a version number increment in the dependent chart, as the changes are picked by Helm directly from the dependency’s source directory - version is not involved. From a logical perspective, the entire dependency tree is atomically changed, deployed and tested. | |||
However, this mechanism becomes a liability when the charts must be consumed by external operators that do not have access to, or do not want to use the GitHub repository. In such a situation: | |||
* The relationship between the specific instances of the dependency and the dependent must be specified by a valid dependency '''and''' dependent chart version pair (if the dependency evolves, it naturally must be given a higher version, but also the dependent that relies on the new version of the dependency must increase its version and specify the new dependency version, to communicate to its consumers that it has evolved). | |||
* The relative file:// URL that works in the context of the same filesystem/GitHub repository becomes meaningless and must be replaced with a valid artifact repository URL. | |||
* The chart artifacts, in form of packed archives, must be physically uploaded in the artifact repository. | |||
==<span id='Relative_Repository_URL_and_version_Field'></span><span id='Local_Repository_URL_and_version_Field'></span>Local Dependencies and <tt>version</tt> Field== | |||
Note that even if it seems unnecessary, as an unpacked chart can have just one and only one version, the "version" information in the dependent's chart is actually required, and it is matched against <code>../b/Chart.yaml</code>. | |||
If the dependency declaration does not contain <code>version</code>, [[Helm_dependency#Dependency_Update|helm dependency update]] fails with: | |||
<syntaxhighlight lang='text'> | |||
helm dependency update ./a | |||
[...] | |||
Saving 1 charts | |||
Save error occurred: dependency b has an invalid version/constraint format: improper constraint: | |||
Deleting newly downloaded charts, restoring pre-update state | |||
Error: dependency b has an invalid version/constraint format: improper constraint: | |||
</syntaxhighlight> | |||
If the dependency declaration contains a <code>version</code> declaration that does not match the version advertised by <code>../b/Chart.yaml</code>, [[Helm_dependency#Dependency_Update|helm dependency update]] fails with: | |||
<syntaxhighlight lang='text'> | |||
helm dependency update ./a | |||
[...] | |||
Saving 1 charts | |||
Save error occurred: can't get a valid version for dependency b | |||
Deleting newly downloaded charts, restoring pre-update state | |||
Error: can't get a valid version for dependency b | |||
</syntaxhighlight> | |||
=<span id='Dependency_Selective_Installation'></span>Conditional Dependencies (Dependency Selective Installation)= | |||
{{External|https://helm.sh/docs/topics/charts/#tags-and-condition-fields-in-dependencies}} | |||
All dependencies present in charts/ are installed by default. However, [[#Dependency_Declaration|tags]] and [[#Dependency_Declaration|conditions]] can be used to perform selective installation. Conditions or tags should be added to any dependencies that are optional. | |||
==Conditions== | |||
A condition is an arbitrary [[Helm Chart values.yaml|values.yaml]] YAML path with a boolean attached to it. This is different from a [[#Tags|tag]] which requires special syntax. The condition element may hold [[#Multiple_Conditions|more than one YAML path]], separated by comma. | |||
If such a path is exists and has YAML boolean true assigned to it, the corresponding condition evaluates true. String "true" is also evaluated as a true condition, but Helm issues a warning: "Condition path '...' for chart ... returned non-bool value", and this usage pattern is not recommended. | |||
⚠️ If the path does not exist, or if it exists and nothing is associated with it, the condition has no effect - it is equivalent to evaluating to true. This is a bit counter-intuitive, as one would expect that a non-existent path to evaluate to false. Also, if "false" is assigned to the path, or nothing is assigned to it, or the path does not exist, Helm will warn that the condition path has a non-boolean associated with it and '''will evaluate to true'''. | |||
The only safe way to prevent a conditional installation is to define the condition path and associate YAML boolean false to it. | |||
<syntaxhighlight lang='yaml'> | |||
... | |||
dependencies: | |||
- name: example-chart | |||
version: 1.0.0 | |||
repository: http://helm-example.com/charts | |||
condition: example-chart.enabled | |||
</syntaxhighlight> | |||
===Multiple Conditions=== | |||
More than one comma-delimited conditions can be specified. In this case, the conditions are evaluated in order and only the first valid path found in the list is evaluated. If no paths exist then the condition has no effect - it is equivalent with evaluating to true. | |||
<syntaxhighlight lang='yaml'> | |||
... | |||
dependencies: | |||
- name: example-chart | |||
version: 1.0.0 | |||
repository: http://helm-example.com/charts | |||
condition: example-chart.enabled, something-else.enabled | |||
</syntaxhighlight> | |||
The preferred form of a condition is: | |||
<syntaxhighlight lang='yaml'> | |||
condition: <dependency-name>.enabled | |||
</syntaxhighlight> | |||
It is turned in values.yaml as such: | |||
<syntaxhighlight lang='yaml'> | |||
<dependency-name>: | |||
enabled: true | |||
</syntaxhighlight> | |||
==Tags== | |||
Tags are list of labels associated with a specific dependency. The tags use a special syntax to be declared in [[Helm Chart values.yaml|values.yaml]] and they can be enabled or disabled in by specifying the tag and a boolean value. Also, the [[Helm_install#Overriding_Tags_and_Conditions|helm install --set]] parameter can be used to alter tag and condition values at installation time. | |||
When multiple subcharts together provide an optional or swappable feature, those charts should share the same tags. For example, if both chart-a and chart-b together provide performance optimizations for the main app in the chart, and are required to both be present when that feature is enabled, then they should both have a tags section like this: | |||
<syntaxhighlight lang='yaml'> | |||
tags: | |||
- optimizer | |||
</syntaxhighlight> | |||
This allows a user to turn that feature on and off with one tag. | |||
values.yaml: | |||
<syntaxhighlight lang='yaml'> | |||
tags: | |||
blue: true | |||
green: true | |||
</syntaxhighlight> | |||
Chart.yaml: | |||
<syntaxhighlight lang='yaml'> | |||
... | |||
dependencies: | |||
- name: example-chart | |||
version: 1.0.0 | |||
repository: http://helm-example.com/charts | |||
tags: | |||
- blue | |||
- green | |||
</syntaxhighlight> | |||
In a list, if at least one tag is true, the dependency is installed (logical OR). | |||
⚠️ If a tag is not declared, it is ignored - it behaves as it would evaluate to true, so the only reliable way to prevent installation based on a tag is to explicitly set it to YAML boolean false. | |||
=<span id='Packaging_and_Dependencies'></span>Packaging a Chart that Has Dependencies= | |||
{{Internal|Helm_package#Packaging_and_Dependencies|helm package | Packaging and Dependencies}} | |||
=Dependency Operations= | =Dependency Operations= | ||
* <code>[[Helm_pull|helm pull]]</code> | |||
* <code>[[Helm dependency|helm dependency]]</code> |
Latest revision as of 00:19, 6 February 2022
External
Internal
Overview
All applications, maybe with the exception of the most trivial, depend on other runtime components, such as web servers, caches, databases, etc. Helm supports modularization via a dependency mechanism, which allows to formally specify, manage and deploy dependencies as part of a Helm release. A Helm chart may declare dependencies, which are other Helm charts published in external repositories, conveniently packaged by people who presumably know the respective components well. The simples possible example is a chart A - the dependent - that declared its reliance on a chart B - the dependency - by specifying chart B's “coordinates” (name, version and repository URL) as part of its own metadata. The exact way in which the dependencies are declared has evolved across Helm releases. For Helm 2 charts, the dependencies are declared in a dedicated requirements.yaml file, while for Helm 3 chart, the dependencies are declared as part of the chart manifest Chart.yaml. However, the way the dependencies are processed during installation has remained the same.
At installation time, Helm becomes aware of the direct dependencies of the chart being installed, insures that those direct dependencies are available and uses them in the installation process. In reality, the actual sequence is more complicated, involving an intermediate chart/ subdirectory and a helm dependency update command, but these are operational details, not relevant at this level. It is worth noting that unlike Maven, which actively walks the transitive dependency tree, Helm does not. This behavior is mitigated by the fact a properly built chart embeds its entire dependency tree, and this is possible and practical just because the chart metadata, and the dependency trees, are small.
How Helm Dependencies Work
During the installation or upgrade process, the Helm client looks into the ./charts sub-directory of the chart being installed, and installs/upgrades the charts whose chart archives are found in that subdirectory.
⚠️ The content of the charts/ subdirectory is the one and only source of truth on dependencies to be installed or upgraded.
If a dependency chart is not present in the charts/ subdirectory at the time of installation/upgrade, it is not installed/upgraded. All charts present in the charts/ subdirectory at the time of installation/upgraded are installed/upgraded.
The "dependencies" element of Chart.yaml is a convenience feature that allows the chart author to specify the dependency list in a synthetic manner, by "coordinates": name, version and repository URL. However, listing the dependency coordinates in Chart.yaml is not sufficient, additional manual steps need to be performed: helm dependency update, which is a step that downloads dependencies in the charts/ directory, based on their Chart.yaml "dependencies" specifications.
⚠️ This charts/ content management functionality (helm dependency) must be explicitly invoked and it is NOT automatically triggered during the installation or update process. However, some sanity checks are performed by helm install, which fails if dependencies are declared in Chart.yaml but not present in charts/.
When Helm installs or updates a chart that has dependencies, it will aggregate all Kubernetes objects declared by the chart and dependencies in a single set, sort the object by types, then by name, and create/update in that order. Also see Installation and De-Installation Order. If a dependency is present in the charts/ subdirectory but not in the "dependencies" list from Chart.yaml, it will be considered a manually-managed dependency and it will be installed.
Helm does not automatically handle transitive dependencies, in the same manner as Maven, for example, does: it is not possible to specify that chart "a" depends on chart "b", only specify the chart "b" "coordinates" (name, version and repository URL) and expect Helm to automatically pull "b" during the installation process. In this situation. Maven would contact the dependency's repository and pull the artifact. If that artifact had its own dependencies, specified by coordinates, Maven would recursively pull those as well, contacting as many repositories as necessary. This is known as what Maven friends refer to as "downloading the Internet".
Helm behaves differently. It expects instead a chart to embed all dependencies it needs, recursively. This decision was probably taken because the chart metadata is really small, especially when compressed. and the chart transitive dependency graphs are not large, so embedding the whole graph in an archive is feasible, which would not be in Maven's case. Indeed, for a situation where an "a" chart depends on a "b" chart, and the "b" chart depends on a "c" chart, the structure of the "a"'s chart archive is;
a
├── Chart.yaml
├── charts
│ └── b
│ ├── Chart.yaml
│ ├── charts
│ │ └── c
│ │ ├── Chart.yaml
│ │ ├── templates
│ │ │ └── pod.yaml
│ │ └── values.yaml
│ ├── templates
│ │ └── pod.yaml
│ └── values.yaml
├── templates
│ └── pod.yaml
└── values.yaml
The enforcement of presence of dependencies happens when the chart is packaged with helm package command. If a chart is packaged manually, and its dependencies are omitted while building the chart archive, the chart archive cannot be installed. An attempt to install a chart archive that does not embed dependencies produces:
Error: found in Chart.yaml, but missing in charts/ directory: some-dependency-chart
For more details on how to package a chart with its dependencies, see:
Subcharts
A charts stored in the "charts/" subdirectory is also known as a "subchart".
Dependency Declaration
Dependencies are declared in Chart.yaml 'dependencies' section.
...
dependencies:
- name: 'b' # The name of the dependency
version: 1.0.0 # The version of the dependency
repository: http://helm-example.com/charts # Repository URL
condition: b.enabled, global.b.enabled # See Dependency Selective Installation below
tags: # See Dependency Selective Installation below
- tag1
- tag2
...
Example:
...
# 'a' Chart.yaml
dependencies:
- name: b
version: 1.0.0
repository: http://helm-example.com/charts
condition: b.enabled, global.b.enabled
tags:
- front-end
- b
...
Note that simply declaring the dependency in Chart.yaml is not sufficient. The dependency needs to be physically downloaded and placed in the charts/ subdirectory with:
helm dependency update
Elements
name
The dependency chart name. The name must match the name in the dependency chart's Chart.yaml file.
version
The dependency chart version. It could be a version or a version range.
⚠️ When the chart is published locally, so there is single version that can be possibly exposed by the local unpacked chart, one may think that version
is not required. This is not true. For more details see Local Repository URL and version Field below.
repository
'repository' specifies the URL of the Helm repository to pull the dependency chart from.
The value can be:
Full URL
The most common case is to use a full URL of the source repository:
...
dependencies:
- name: 'postgresql'
version: '6.3.2'
repository: 'https://kubernetes-charts.storage.googleapis.com'
The repository can be unmanaged, meaning that it was not previously locally added with the 'helm repo add' command, or managed. Both situations are valid. In both cases, the dependency must be downloaded locally in the chart's ./charts directory with 'helm dependencies update' command before installing the chart.
Repository Name
A repository name can only be used with managed repositories:
...
dependencies:
- name: 'postgresql'
version: '6.3.2'
repository: '@some-repository'
where "my-repository" as locally added with helm repo add:
helm repo add some-repository https://kubernetes-charts.storage.googleapis.com
Relative or Absolute Filesystem Path
Relative or absolute filesystem path URLs can be used to refer to dependencies that exist on the local filesystem:
- name: my-chart
version: '1.0.0'
repository: 'file:///tmp/charts/my-chart'
- name: my-chart
version: '1.0.0'
repository: 'file://../my-chart'
When a relative path is used, it is considered relative to the dependent chart root directory. In case the dependency chart is not archived, but exist as an exploded directory on the file system, the file:// URL must point to the root directory of the chart - the one that contains Chart.yaml. If the dependency chart is retrieved locally, it is not required to have the repository added to helm by helm repo add. For more details on local repository URLs, see Local Dependencies below.
aliases
Each element of the "dependencies" list allows for an optional "alias" attribute.
condition
See Conditional Dependencies | Conditions below.
Configuring Dependencies
Dependency configuration values should be specified in the top chart values.yaml, and should be prefixed with the dependency name. It is recommended to only override values in the top level chart, and not in any subchart.
TODO:
- Example
Local Dependencies
A chart may declare one or more of its dependencies using a local URL, which can be relative or absolute, for the case where both the dependent chart and the dependency chart are unpacked and live on the same filesystem. This is often the case when two or more interdependent charts are developed and maintained in the same GitHub repository. The syntax in that case is:
dependencies:
- name: b
version: 1.0.0
repository: file://../b
When the unpacked chart dependency is available locally, as part of the same GitHub repository, and referred via a relative file:// URL, development changes that involve modifications of both dependent and dependencies, as well as related application code can evolve quickly, as the change-deployment-test cycle does not require publishing and downloading from an external repository. Equally important, dependency chart changes do not require a version number increment in the dependent chart, as the changes are picked by Helm directly from the dependency’s source directory - version is not involved. From a logical perspective, the entire dependency tree is atomically changed, deployed and tested.
However, this mechanism becomes a liability when the charts must be consumed by external operators that do not have access to, or do not want to use the GitHub repository. In such a situation:
- The relationship between the specific instances of the dependency and the dependent must be specified by a valid dependency and dependent chart version pair (if the dependency evolves, it naturally must be given a higher version, but also the dependent that relies on the new version of the dependency must increase its version and specify the new dependency version, to communicate to its consumers that it has evolved).
- The relative file:// URL that works in the context of the same filesystem/GitHub repository becomes meaningless and must be replaced with a valid artifact repository URL.
- The chart artifacts, in form of packed archives, must be physically uploaded in the artifact repository.
Local Dependencies and version Field
Note that even if it seems unnecessary, as an unpacked chart can have just one and only one version, the "version" information in the dependent's chart is actually required, and it is matched against ../b/Chart.yaml
.
If the dependency declaration does not contain version
, helm dependency update fails with:
helm dependency update ./a
[...]
Saving 1 charts
Save error occurred: dependency b has an invalid version/constraint format: improper constraint:
Deleting newly downloaded charts, restoring pre-update state
Error: dependency b has an invalid version/constraint format: improper constraint:
If the dependency declaration contains a version
declaration that does not match the version advertised by ../b/Chart.yaml
, helm dependency update fails with:
helm dependency update ./a
[...]
Saving 1 charts
Save error occurred: can't get a valid version for dependency b
Deleting newly downloaded charts, restoring pre-update state
Error: can't get a valid version for dependency b
Conditional Dependencies (Dependency Selective Installation)
All dependencies present in charts/ are installed by default. However, tags and conditions can be used to perform selective installation. Conditions or tags should be added to any dependencies that are optional.
Conditions
A condition is an arbitrary values.yaml YAML path with a boolean attached to it. This is different from a tag which requires special syntax. The condition element may hold more than one YAML path, separated by comma.
If such a path is exists and has YAML boolean true assigned to it, the corresponding condition evaluates true. String "true" is also evaluated as a true condition, but Helm issues a warning: "Condition path '...' for chart ... returned non-bool value", and this usage pattern is not recommended.
⚠️ If the path does not exist, or if it exists and nothing is associated with it, the condition has no effect - it is equivalent to evaluating to true. This is a bit counter-intuitive, as one would expect that a non-existent path to evaluate to false. Also, if "false" is assigned to the path, or nothing is assigned to it, or the path does not exist, Helm will warn that the condition path has a non-boolean associated with it and will evaluate to true.
The only safe way to prevent a conditional installation is to define the condition path and associate YAML boolean false to it.
...
dependencies:
- name: example-chart
version: 1.0.0
repository: http://helm-example.com/charts
condition: example-chart.enabled
Multiple Conditions
More than one comma-delimited conditions can be specified. In this case, the conditions are evaluated in order and only the first valid path found in the list is evaluated. If no paths exist then the condition has no effect - it is equivalent with evaluating to true.
...
dependencies:
- name: example-chart
version: 1.0.0
repository: http://helm-example.com/charts
condition: example-chart.enabled, something-else.enabled
The preferred form of a condition is:
condition: <dependency-name>.enabled
It is turned in values.yaml as such:
<dependency-name>:
enabled: true
Tags
Tags are list of labels associated with a specific dependency. The tags use a special syntax to be declared in values.yaml and they can be enabled or disabled in by specifying the tag and a boolean value. Also, the helm install --set parameter can be used to alter tag and condition values at installation time.
When multiple subcharts together provide an optional or swappable feature, those charts should share the same tags. For example, if both chart-a and chart-b together provide performance optimizations for the main app in the chart, and are required to both be present when that feature is enabled, then they should both have a tags section like this:
tags:
- optimizer
This allows a user to turn that feature on and off with one tag.
values.yaml:
tags:
blue: true
green: true
Chart.yaml:
...
dependencies:
- name: example-chart
version: 1.0.0
repository: http://helm-example.com/charts
tags:
- blue
- green
In a list, if at least one tag is true, the dependency is installed (logical OR).
⚠️ If a tag is not declared, it is ignored - it behaves as it would evaluate to true, so the only reliable way to prevent installation based on a tag is to explicitly set it to YAML boolean false.