Skip to content

Creating first custom chart and summary about files present in charts

Deekshith SN edited this page Apr 8, 2021 · 7 revisions

assume you want to create your own custom chart rather than using existing charts on repository then we can make use of helm create command

helm create my_chartname

when we execute above command it will create folder with name my_chartname and the folder my_chartname contains all standard files like template folder, NOTES.txt, values.yaml and many more.

my_chartname/
  Chart.yaml          # A YAML file containing information about the chart
  LICENSE             # OPTIONAL: A plain text file containing the license for the chart
  README.md           # OPTIONAL: A human-readable README file
  values.yaml         # The default configuration values for this chart
  values.schema.json  # OPTIONAL: A JSON Schema for imposing a structure on the values.yaml file
  charts/             # A directory containing any charts upon which this chart depends.
  crds/               # Custom Resource Definitions
  templates/          # A directory of templates that, when combined with values,
                      # will generate valid Kubernetes manifest files.
  templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes

Summary about each file inside helm chart

The Chart.yaml File

The Chart.yaml file is required for a chart. It contains the following fields:

apiVersion: The chart API version (required)
name: The name of the chart (required)
version: A SemVer 2 version (required)
kubeVersion: A SemVer range of compatible Kubernetes versions (optional)
description: A single-sentence description of this project (optional)
type: The type of the chart (optional)
keywords:
  - A list of keywords about this project (optional)
home: The URL of this projects home page (optional)
sources:
  - A list of URLs to source code for this project (optional)
dependencies: # A list of the chart requirements (optional)
  - name: The name of the chart (nginx)
    version: The version of the chart ("1.2.3")
    repository: (optional) The repository URL ("https://example.com/charts") or alias ("@repo-name")
    condition: (optional) A yaml path that resolves to a boolean, used for enabling/disabling charts (e.g. subchart1.enabled )
    tags: # (optional)
      - Tags can be used to group charts for enabling/disabling together
    import-values: # (optional)
      - ImportValues holds the mapping of source values to parent key to be imported. Each item can be a string or pair of child/parent sublist items.
    alias: (optional) Alias to be used for the chart. Useful when you have to add the same chart multiple times
maintainers: # (optional)
  - name: The maintainers name (required for each maintainer)
    email: The maintainers email (optional for each maintainer)
    url: A URL for the maintainer (optional for each maintainer)
icon: A URL to an SVG or PNG image to be used as an icon (optional).
appVersion: The version of the app that this contains (optional). Needn't be SemVer. Quotes recommended.
deprecated: Whether this chart is deprecated (optional, boolean)
annotations:
  example: A list of annotations keyed by name (optional).

The template folder

this folder has all the manifest files like deployment, config maps, secrets and many other kubernetes manifest files

values.yaml

mention all the values that are referred in the template folder

values.schema.json

Sometimes, a chart maintainer might want to define a structure on their values. This can be done by defining a schema in the values.schema.json file. A schema is represented as a JSON Schema. It might look something like this:

{
  "$schema": "https://json-schema.org/draft-07/schema#",
  "properties": {
    "image": {
      "description": "Container Image",
      "properties": {
        "repo": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      },
      "type": "object"
    },
    "name": {
      "description": "Service name",
      "type": "string"
    },
    "port": {
      "description": "Port",
      "minimum": 0,
      "type": "integer"
    },
    "protocol": {
      "type": "string"
    }
  },
  "required": [
    "protocol",
    "port"
  ],
  "title": "Values",
  "type": "object"
}

LICENSE, README and NOTES

A LICENSE is a plain text file containing the license for the chart. The chart can contain a license as it may have programming logic in the templates and would therefore not be configuration only. There can also be separate license(s) for the application installed by the chart, if required.

A README for a chart should be formatted in Markdown (README.md), and should generally contain:

  • A description of the application or service the chart provides
  • Any prerequisites or requirements to run the chart
  • Descriptions of options in values.yaml and default values
  • Any other information that may be relevant to the installation or configuration of the chart

When hubs and other user interfaces display details about a chart that detail is pulled from the content in the README.md file.

The chart can also contain a short plain text templates/NOTES.txt file that will be printed out after installation, and when viewing the status of a release. This file is evaluated as a template, and can be used to display usage notes, next steps, or any other information relevant to a release of the chart. For example, instructions could be provided for connecting to a database, or accessing a web UI. Since this file is printed to STDOUT when running helm install or helm status, it is recommended to keep the content brief and point to the README for greater detail.

The Chrats folder

In Helm, one chart may depend on any number of other charts. These dependencies can be dynamically linked using the dependencies field in Chart.yaml or brought in to the charts/ directory and managed manually.

Managing Dependencies with the dependencies field

The charts required by the current chart are defined as a list in the dependencies field.

dependencies:
  - name: apache
    version: 1.2.3
    repository: https://example.com/charts
  - name: mysql
    version: 3.2.1
    repository: https://another.example.com/charts
  • The name field is the name of the chart you want.
  • The version field is the version of the chart you want.
  • The repository field is the full URL to the chart repository. Note that you must also use helm repo add to add that repo locally.
  • You might use the name of the repo instead of URL
$ helm repo add fantastic-charts https://fantastic-charts.storage.googleapis.com
dependencies:
  - name: awesomeness
    version: 1.0.0
    repository: "@fantastic-charts"

Once you have defined dependencies, you can run helm dependency update and it will use your dependency file to download all the specified charts into your charts/ directory for you.

When helm dependency update retrieves charts, it will store them as chart archives in the charts/ directory. So for the example above, one would expect to see the following files in the charts directory:

charts/
  apache-1.2.3.tgz
  mysql-3.2.1.tgz

Alias field in dependencies

In addition to the other fields above, each requirements entry may contain the optional field alias.

Adding an alias for a dependency chart would put a chart in dependencies using alias as name of new dependency.

One can use alias in cases where they need to access a chart with other name(s).

parentchart/Chart.yaml

dependencies:
  - name: subchart
    repository: http://localhost:10191
    version: 0.1.0
    alias: new-subchart-1
  - name: subchart
    repository: http://localhost:10191
    version: 0.1.0
    alias: new-subchart-2
  - name: subchart
    repository: http://localhost:10191
    version: 0.1.0

In the above example we will get 3 dependencies in all for parentchart:

subchart
new-subchart-1
new-subchart-2

The manual way of achieving this is by copy/pasting the same chart in the charts/ directory multiple times with different names.

Tags and Condition fields in dependencies

In addition to the other fields above, each requirements entry may contain the optional fields tags and condition.

All charts are loaded by default. If tags or condition fields are present, they will be evaluated and used to control loading for the chart(s) they are applied to.

Condition - The condition field holds one or more YAML paths (delimited by commas). If this path exists in the top parent's values and resolves to a boolean value, the chart will be enabled or disabled based on that boolean value. Only the first valid path found in the list is evaluated and if no paths exist then the condition has no effect.

Tags - The tags field is a YAML list of labels to associate with this chart. In the top parent's values, all charts with tags can be enabled or disabled by specifying the tag and a boolean value.

# parentchart/Chart.yaml

dependencies:
  - name: subchart1
    repository: http://localhost:10191
    version: 0.1.0
    condition: subchart1.enabled, global.subchart1.enabled
    tags:
      - front-end
      - subchart1
  - name: subchart2
    repository: http://localhost:10191
    version: 0.1.0
    condition: subchart2.enabled,global.subchart2.enabled
    tags:
      - back-end
      - subchart2
# parentchart/values.yaml

subchart1:
  enabled: true
tags:
  front-end: false
  back-end: true

In the above example all charts with the tag front-end would be disabled but since the subchart1.enabled path evaluates to 'true' in the parent's values, the condition will override the front-end tag and subchart1 will be enabled.

Since subchart2 is tagged with back-end and that tag evaluates to true, subchart2 will be enabled. Also note that although subchart2 has a condition specified, there is no corresponding path and value in the parent's values so that condition has no effect.

Using the CLI with Tags and Conditions The --set parameter can be used as usual to alter tag and condition values.

helm install --set tags.front-end=true --set subchart2.enabled=false

Tags and Condition Resolution

  • Conditions (when set in values) always override tags. The first condition path that exists wins and subsequent ones for that chart are ignored.
  • Tags are evaluated as 'if any of the chart's tags are true then enable the chart'.
  • Tags and conditions values must be set in the top parent's values.
  • The tags: key in values must be a top level key. Globals and nested tags: tables are not currently supported.

Importing Child Values via dependencies

In some cases it is desirable to allow a child chart's values to propagate to the parent chart and be shared as common defaults. An additional benefit of using the exports format is that it will enable future tooling to introspect user-settable values.

The keys containing the values to be imported can be specified in the parent chart's dependencies in the field import-values using a YAML list. Each item in the list is a key which is imported from the child chart's exports field.

To import values not contained in the exports key, use the child-parent format. Examples of both formats are described below.

Using the exports format If a child chart's values.yaml file contains an exports field at the root, its contents may be imported directly into the parent's values by specifying the keys to import as in the example below:

# parent's Chart.yaml file

dependencies:
  - name: subchart
    repository: http://localhost:10191
    version: 0.1.0
    import-values:
      - data

# child's values.yaml file

exports:
  data:
    myint: 99

Since we are specifying the key data in our import list, Helm looks in the exports field of the child chart for data key and imports its contents.

The final parent values would contain our exported field:

# parent's values

myint: 99

Please note the parent key data is not contained in the parent's final values. If you need to specify the parent key, use the 'child-parent' format.

Using the child-parent format To access values that are not contained in the exports key of the child chart's values, you will need to specify the source key of the values to be imported (child) and the destination path in the parent chart's values (parent).

The import-values in the example below instructs Helm to take any values found at child: path and copy them to the parent's values at the path specified in parent:

# parent's Chart.yaml file

dependencies:
  - name: subchart1
    repository: http://localhost:10191
    version: 0.1.0
    ...
    import-values:
      - child: default.data
        parent: myimports

In the above example, values found at default.data in the subchart1's values will be imported to the myimports key in the parent chart's values as detailed below:

# parent's values.yaml file

myimports:
  myint: 0
  mybool: false
  mystring: "helm rocks!"
# subchart1's values.yaml file

default:
  data:
    myint: 999
    mybool: true

The parent chart's resulting values would be:

# parent's final values

myimports:
  myint: 999
  mybool: true
  mystring: "helm rocks!"

The parent's final values now contains the myint and mybool fields imported from subchart1.