github.com/cloudposse/helm@v2.2.3+incompatible/docs/charts.md (about)

     1  # Charts
     2  
     3  Helm uses a packaging format called _charts_. A chart is a collection of files
     4  that describe a related set of Kubernetes resources. A single chart
     5  might be used to deploy something simple, like a memcached pod, or
     6  something complex, like a full web app stack with HTTP servers,
     7  databases, caches, and so on.
     8  
     9  Charts are created as files laid out in a particular directory tree,
    10  then they can be packaged into versioned archives to be deployed.
    11  
    12  This document explains the chart format, and provides basic guidance for
    13  building charts with Helm.
    14  
    15  ## The Chart File Structure
    16  
    17  A chart is organized as a collection of files inside of a directory. The
    18  directory name is the name of the chart (without versioning information). Thus,
    19  a chart describing Wordpress would be stored in the `wordpress/` directory.
    20  
    21  Inside of this directory, Helm will expect a structure that matches this:
    22  
    23  ```
    24  wordpress/
    25    Chart.yaml          # A YAML file containing information about the chart
    26    LICENSE             # OPTIONAL: A plain text file containing the license for the chart
    27    README.md           # OPTIONAL: A human-readable README file
    28    values.yaml         # The default configuration values for this chart
    29    charts/             # OPTIONAL: A directory containing any charts upon which this chart depends.
    30    templates/          # OPTIONAL: A directory of templates that, when combined with values,
    31                        # will generate valid Kubernetes manifest files.
    32    templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes
    33  ```
    34  
    35  Helm reserves use of the `charts/` and `templates/` directories, and of
    36  the listed file names. Other files will be left as they are.
    37  
    38  ## The Chart.yaml File
    39  
    40  The `Chart.yaml` file is required for a chart. It contains the following fields:
    41  
    42  ```yaml
    43  name: The name of the chart (required)
    44  version: A SemVer 2 version (required)
    45  description: A single-sentence description of this project (optional)
    46  keywords:
    47    - A list of keywords about this project (optional)
    48  home: The URL of this project's home page (optional)
    49  sources:
    50    - A list of URLs to source code for this project (optional)
    51  maintainers: # (optional)
    52    - name: The maintainer's name (required for each maintainer)
    53      email: The maintainer's email (optional for each maintainer)
    54  engine: gotpl # The name of the template engine (optional, defaults to gotpl)
    55  icon: A URL to an SVG or PNG image to be used as an icon (optional).
    56  ```
    57  
    58  If you are familiar with the `Chart.yaml` file format for Helm Classic, you will
    59  notice that fields specifying dependencies have been removed. That is because
    60  the new Chart format expresses dependencies using the `charts/` directory.
    61  
    62  Other fields will be silently ignored.
    63  
    64  ### Charts and Versioning
    65  
    66  Every chart must have a version number. A version must follow the
    67  [SemVer 2](http://semver.org/) standard. Unlike Helm Classic, Kubernetes
    68  Helm uses version numbers as release markers. Packages in repositories
    69  are identified by name plus version.
    70  
    71  For example, an `nginx` chart whose version field is set to `version:
    72  1.2.3` will be named:
    73  
    74  ```
    75  nginx-1.2.3.tgz
    76  ```
    77  
    78  More complex SemVer 2 names are also supported, such as
    79  `version: 1.2.3-alpha.1+ef365`. But non-SemVer names are explicitly
    80  disallowed by the system.
    81  
    82  **NOTE:** Whereas Helm Classic and Deployment Manager were both
    83  very GitHub oriented when it came to charts, Kubernetes Helm does not
    84  rely upon or require GitHub or even Git. Consequently, it does not use
    85  Git SHAs for versioning at all.
    86  
    87  The `version` field inside of the `Chart.yaml` is used by many of the
    88  Helm tools, including the CLI and the Tiller server. When generating a
    89  package, the `helm package` command will use the version that it finds
    90  in the `Chart.yaml` as a token in the package name. The system assumes
    91  that the version number in the chart package name matches the version number in
    92  the `Chart.yaml`. Failure to meet this assumption will cause an error.
    93  
    94  ## Chart LICENSE, README and NOTES
    95  
    96  Charts can also contain files that describe the installation, configuration, usage and license of a
    97  chart. A README for a chart should be formatted in Markdown (README.md), and should generally
    98  contain:
    99  
   100  - A description of the application or service the chart provides
   101  - Any prerequisites or requirements to run the chart
   102  - Descriptions of options in `values.yaml` and default values
   103  - Any other information that may be relevant to the installation or configuration of the chart
   104  
   105  The chart can also contain a short plain text `templates/NOTES.txt` file that will be printed out
   106  after installation, and when viewing the status of a release. This file is evaluated as a
   107  [template](#templates-and-values), and can be used to display usage notes, next steps, or any other
   108  information relevant to a release of the chart. For example, instructions could be provided for
   109  connecting to a database, or accessing a web UI. Since this file is printed to STDOUT when running
   110  `helm install` or `helm status`, it is recommended to keep the content brief and point to the README
   111  for greater detail.
   112  
   113  ## Chart Dependencies
   114  
   115  In Helm, one chart may depend on any number of other charts. These
   116  dependencies are expressed explicitly by copying the dependency charts
   117  into the `charts/` directory.
   118  
   119  A dependency can be either a chart archive (`foo-1.2.3.tgz`) or an
   120  unpacked chart directory. But its name cannot start with `_` or `.`.
   121  Such files are ignored by the chart loader.
   122  
   123  **Note:** The `dependencies:` section of the `Chart.yaml` from Helm
   124  Classic has been completely removed.
   125  
   126  For example, if the Wordpress chart depends on the Apache chart, the
   127  Apache chart (of the correct version) is supplied in the Wordpress
   128  chart's `charts/` directory:
   129  
   130  ```
   131  wordpress:
   132    Chart.yaml
   133    requirements.yaml
   134    # ...
   135    charts/
   136      apache/
   137        Chart.yaml
   138        # ...
   139      mysql/
   140        Chart.yaml
   141        # ...
   142  ```
   143  
   144  The example above shows how the Wordpress chart expresses its dependency
   145  on Apache and MySQL by including those charts inside of its `charts/`
   146  directory.
   147  
   148  **TIP:** _To drop a dependency into your `charts/` directory, use the
   149  `helm fetch` command or use a `requirements.yaml` file_
   150  
   151  ### Managing Dependencies with `requirements.yaml`
   152  
   153  While Helm will allow you to manually manage your dependencies, the
   154  preferred method of declaring dependencies is by using a
   155  `requirements.yaml` file inside of your chart.
   156  
   157  A `requirements.yaml` file is a simple file for listing your
   158  dependencies.
   159  
   160  ```yaml
   161  dependencies:
   162    - name: apache
   163      version: 1.2.3
   164      repository: http://example.com/charts
   165    - name: mysql
   166      version: 3.2.1
   167      repository: http://another.example.com/charts
   168  ```
   169  
   170  - The `name` field is the name of the chart you want.
   171  - The `version` field is the version of the chart you want.
   172  - The `repository` field is the full URL to the chart repository. Note
   173    that you must also use `helm repo add` to add that repo locally.
   174  
   175  Once you have a dependencies file, you can run `helm dependency update`
   176  and it will use your dependency file to download all of the specified
   177  charts into your `charts/` directory for you.
   178  
   179  ```console
   180  $ helm dep up foochart
   181  Hang tight while we grab the latest from your chart repositories...
   182  ...Successfully got an update from the "local" chart repository
   183  ...Successfully got an update from the "stable" chart repository
   184  ...Successfully got an update from the "example" chart repository
   185  ...Successfully got an update from the "another" chart repository
   186  Update Complete. Happy Helming!
   187  Saving 2 charts
   188  Downloading apache from repo http://example.com/charts
   189  Downloading mysql from repo http://another.example.com/charts
   190  ```
   191  
   192  When `helm dependency update` retrieves charts, it will store them as
   193  chart archives in the `charts/` directory. So for the example above, one
   194  would expect to see the following files in the charts directory:
   195  
   196  ```
   197  charts/
   198    apache-1.2.3.tgz
   199    mysql-3.2.1.tgz
   200  ```
   201  
   202  Managing charts with `requirements.yaml` is a good way to easily keep
   203  charts updated, and also share requirements information throughout a
   204  team.
   205  
   206  #### Tags and Condition fields in requirements.yaml
   207  
   208  In addition to the other fields above, each requirements entry may contain 
   209  the optional fields `tags` and `condition`.
   210  
   211  All charts are loaded by default. If `tags` or `condition` fields are present, 
   212  they will be evaluated and used to control loading for the chart(s) they are applied to. 
   213  
   214  Condition - The condition field holds one or more YAML paths (delimited by commas). 
   215  If this path exists in the top parent's values and resolves to a boolean value, 
   216  the chart will be enabled or disabled based on that boolean value.  Only the first 
   217  valid path found in the list is evaluated and if no paths exist then the condition has no effect.
   218  
   219  Tags - The tags field is a YAML list of labels to associate with this chart. 
   220  In the top parent's values, all charts with tags can be enabled or disabled by 
   221  specifying the tag and a boolean value.
   222  
   223  ````
   224  # parentchart/requirements.yaml
   225  dependencies:
   226        - name: subchart1
   227          repository: http://localhost:10191
   228          version: 0.1.0
   229          condition: subchart1.enabled, global.subchart1.enabled
   230          tags:
   231            - front-end
   232            - subchart1
   233        
   234        - name: subchart2
   235          repository: http://localhost:10191
   236          version: 0.1.0
   237          condition: subchart2.enabled,global.subchart2.enabled
   238          tags:
   239            - back-end
   240            - subchart1
   241  
   242  ````
   243  ````
   244  # parentchart/values.yaml
   245  
   246  subchart1:
   247    enabled: true
   248  tags:
   249    front-end: false
   250    back-end: true
   251  ```` 
   252  
   253  In the above example all charts with the tag `front-end` would be disabled but since the 
   254  `subchart1.enabled` path evaluates to 'true' in the parent's values, the condition will override the 
   255  `front-end` tag and `subchart1` will be enabled.  
   256  
   257  Since `subchart2` is tagged with `back-end` and that tag evaluates to `true`, `subchart2` will be 
   258  enabled. Also note that although `subchart2` has a condition specified in `requirements.yaml`, there 
   259  is no corresponding path and value in the parent's values so that condition has no effect.  
   260  
   261  ##### Using the CLI with Tags and Conditions
   262  
   263  The `--set` parameter can be used as usual to alter tag and condition values.
   264  
   265  ````
   266  helm install --set tags.front-end=true --set subchart2.enabled=false
   267  
   268  ````
   269  
   270  ##### Tags and Condition Resolution
   271  
   272  
   273    * **Conditions (when set in values) always override tags.** The first condition 
   274      path that exists wins and subsequent ones for that chart are ignored.
   275    * Tags are evaluated as 'if any of the chart's tags are true then enable the chart'.
   276    * Tags and conditions values must be set in the top parent's values.
   277    * The `tags:` key in values must be a top level key. Globals and nested `tags:` tables 
   278      are not currently supported.
   279  
   280  ## Templates and Values
   281  
   282  Helm Chart templates are written in the
   283  [Go template language](https://golang.org/pkg/text/template/), with the
   284  addition of 50 or so add-on template
   285  functions [from the Sprig library](https://github.com/Masterminds/sprig) and a
   286  few other [specialized functions](charts_tips_and_tricks.md).
   287  
   288  All template files are stored in a chart's `templates/` folder. When
   289  Helm renders the charts, it will pass every file in that directory
   290  through the template engine.
   291  
   292  Values for the templates are supplied two ways:
   293  
   294    - Chart developers may supply a file called `values.yaml` inside of a
   295      chart. This file can contain default values.
   296    - Chart users may supply a YAML file that contains values. This can be
   297      provided on the command line with `helm install`.
   298  
   299  When a user supplies custom values, these values will override the
   300  values in the chart's `values.yaml` file.
   301  
   302  ### Template Files
   303  
   304  Template files follow the standard conventions for writing Go templates
   305  (see [the text/template Go package documentation](https://golang.org/pkg/text/template/)
   306  for details).
   307  An example template file might look something like this:
   308  
   309  ```yaml
   310  apiVersion: v1
   311  kind: ReplicationController
   312  metadata:
   313    name: deis-database
   314    namespace: deis
   315    labels:
   316      heritage: deis
   317  spec:
   318    replicas: 1
   319    selector:
   320      app: deis-database
   321    template:
   322      metadata:
   323        labels:
   324          app: deis-database
   325      spec:
   326        serviceAccount: deis-database
   327        containers:
   328          - name: deis-database
   329            image: {{.Values.imageRegistry}}/postgres:{{.Values.dockerTag}}
   330            imagePullPolicy: {{.Values.pullPolicy}}
   331            ports:
   332              - containerPort: 5432
   333            env:
   334              - name: DATABASE_STORAGE
   335                value: {{default "minio" .Values.storage}}
   336  ```
   337  
   338  The above example, based loosely on [https://github.com/deis/charts](https://github.com/deis/charts), is a template for a Kubernetes replication controller.
   339  It can use the following four template values (usually defined in a
   340  `values.yaml` file):
   341  
   342  - `imageRegistry`: The source registry for the Docker image.
   343  - `dockerTag`: The tag for the docker image.
   344  - `pullPolicy`: The Kubernetes pull policy.
   345  - `storage`: The storage backend, whose default is set to `"minio"`
   346  
   347  All of these values are defined by the template author. Helm does not
   348  require or dictate parameters.
   349  
   350  To see many working charts, check out the [Kubernetes Charts
   351  project](https://github.com/kubernetes/charts)
   352  
   353  ### Predefined Values
   354  
   355  Values that are supplied via a `values.yaml` file (or via the `--set`
   356  flag) are accessible from the `.Values` object in a template. But there
   357  are other pre-defined pieces of data you can access in your templates.
   358  
   359  The following values are pre-defined, are available to every template, and
   360  cannot be overridden. As with all values, the names are _case
   361  sensitive_.
   362  
   363  - `Release.Name`: The name of the release (not the chart)
   364  - `Release.Time`: The time the chart release was last updated. This will
   365    match the `Last Released` time on a Release object.
   366  - `Release.Namespace`: The namespace the chart was released to.
   367  - `Release.Service`: The service that conducted the release. Usually
   368    this is `Tiller`.
   369  - `Release.IsUpgrade`: This is set to true if the current operation is an upgrade or rollback.
   370  - `Release.IsInstall`: This is set to true if the current operation is an
   371    install.
   372  - `Release.Revision`: The revision number. It begins at 1, and increments with
   373    each `helm upgrade`.
   374  - `Chart`: The contents of the `Chart.yaml`. Thus, the chart version is
   375    obtainable as `Chart.Version` and the maintainers are in
   376    `Chart.Maintainers`.
   377  - `Files`: A map-like object containing all non-special files in the chart. This
   378    will not give you access to templates, but will give you access to additional
   379    files that are present. Files can be accessed using `{{index .Files "file.name"}}`
   380    or using the `{{.Files.Get name}}` or `{{.Files.GetString name}}` functions. You can
   381    also access the contents of the file as `[]byte` using `{{.Files.GetBytes}}`
   382  - `Capabilities`: A map-like object that contains information about the versions
   383    of Kubernetes (`{{.Capabilities.KubeVersion}}`, Tiller
   384    (`{{.Capabilities.TillerVersion}}`, and the supported Kubernetes API versions
   385    (`{{.Capabilities.APIVersions.Has "batch/v1"`)
   386  
   387  **NOTE:** Any unknown Chart.yaml fields will be dropped. They will not
   388  be accessible inside of the `Chart` object. Thus, Chart.yaml cannot be
   389  used to pass arbitrarily structured data into the template. The values
   390  file can be used for that, though.
   391  
   392  ### Values files
   393  
   394  Considering the template in the previous section, a `values.yaml` file
   395  that supplies the necessary values would look like this:
   396  
   397  ```yaml
   398  imageRegistry: "quay.io/deis"
   399  dockerTag: "latest"
   400  pullPolicy: "alwaysPull"
   401  storage: "s3"
   402  ```
   403  
   404  A values file is formatted in YAML. A chart may include a default
   405  `values.yaml` file. The Helm install command allows a user to override
   406  values by supplying additional YAML values:
   407  
   408  ```console
   409  $ helm install --values=myvals.yaml wordpress
   410  ```
   411  
   412  When values are passed in this way, they will be merged into the default
   413  values file. For example, consider a `myvals.yaml` file that looks like
   414  this:
   415  
   416  ```yaml
   417  storage: "gcs"
   418  ```
   419  
   420  When this is merged with the `values.yaml` in the chart, the resulting
   421  generated content will be:
   422  
   423  ```yaml
   424  imageRegistry: "quay.io/deis"
   425  dockerTag: "latest"
   426  pullPolicy: "alwaysPull"
   427  storage: "gcs"
   428  ```
   429  
   430  Note that only the last field was overridden.
   431  
   432  **NOTE:** The default values file included inside of a chart _must_ be named
   433  `values.yaml`. But files specified on the command line can be named
   434  anything.
   435  
   436  **NOTE:** If the `--set` flag is used on `helm install` or `helm upgrade`, those
   437  values are simply converted to YAML on the client side.
   438  
   439  Any of these values are then accessible inside of templates using the
   440  `.Values` object:
   441  
   442  ```yaml
   443  apiVersion: v1
   444  kind: ReplicationController
   445  metadata:
   446    name: deis-database
   447    namespace: deis
   448    labels:
   449      heritage: deis
   450  spec:
   451    replicas: 1
   452    selector:
   453      app: deis-database
   454    template:
   455      metadata:
   456        labels:
   457          app: deis-database
   458      spec:
   459        serviceAccount: deis-database
   460        containers:
   461          - name: deis-database
   462            image: {{.Values.imageRegistry}}/postgres:{{.Values.dockerTag}}
   463            imagePullPolicy: {{.Values.pullPolicy}}
   464            ports:
   465              - containerPort: 5432
   466            env:
   467              - name: DATABASE_STORAGE
   468                value: {{default "minio" .Values.storage}}
   469  
   470  ```
   471  
   472  ### Scope, Dependencies, and Values
   473  
   474  Values files can declare values for the top-level chart, as well as for
   475  any of the charts that are included in that chart's `charts/` directory.
   476  Or, to phrase it differently, a values file can supply values to the
   477  chart as well as to any of its dependencies. For example, the
   478  demonstration Wordpress chart above has both `mysql` and `apache` as
   479  dependencies. The values file could supply values to all of these
   480  components:
   481  
   482  ```yaml
   483  title: "My Wordpress Site" # Sent to the Wordpress template
   484  
   485  mysql:
   486    max_connections: 100 # Sent to MySQL
   487    password: "secret"
   488  
   489  apache:
   490    port: 8080 # Passed to Apache
   491  ```
   492  
   493  Charts at a higher level have access to all of the variables defined
   494  beneath. So the wordpress chart can access the MySQL password as
   495  `.Values.mysql.password`. But lower level charts cannot access things in
   496  parent charts, so MySQL will not be able to access the `title` property. Nor,
   497  for that matter, can it access `apache.port`.
   498  
   499  Values are namespaced, but namespaces are pruned. So for the Wordpress
   500  chart, it can access the MySQL password field as `.Values.mysql.password`. But
   501  for the MySQL chart, the scope of the values has been reduced and the
   502  namespace prefix removed, so it will see the password field simply as
   503  `.Values.password`.
   504  
   505  #### Global Values
   506  
   507  As of 2.0.0-Alpha.2, Helm supports special "global" value. Consider
   508  this modified version of the previous example:
   509  
   510  ```yaml
   511  title: "My Wordpress Site" # Sent to the Wordpress template
   512  
   513  global:
   514    app: MyWordpress
   515  
   516  mysql:
   517    max_connections: 100 # Sent to MySQL
   518    password: "secret"
   519  
   520  apache:
   521    port: 8080 # Passed to Apache
   522  ```
   523  
   524  The above adds a `global` section with the value `app: MyWordpress`.
   525  This value is available to _all_ charts as `.Values.global.app`.
   526  
   527  For example, the `mysql` templates may access `app` as `{{.Values.global.app}}`, and
   528  so can the `apache` chart. Effectively, the values file above is
   529  regenerated like this:
   530  
   531  ```yaml
   532  title: "My Wordpress Site" # Sent to the Wordpress template
   533  
   534  global:
   535    app: MyWordpress
   536  
   537  mysql:
   538    global:
   539      app: MyWordpress
   540    max_connections: 100 # Sent to MySQL
   541    password: "secret"
   542  
   543  apache:
   544    global:
   545      app: MyWordpress
   546    port: 8080 # Passed to Apache
   547  ```
   548  
   549  This provides a way of sharing one top-level variable with all
   550  subcharts, which is useful for things like setting `metadata` properties
   551  like labels.
   552  
   553  If a subchart declares a global variable, that global will be passed
   554  _downward_ (to the subchart's subcharts), but not _upward_ to the parent
   555  chart. There is no way for a subchart to influence the values of the
   556  parent chart.
   557  
   558  _Global sections are restricted to only simple key/value pairs. They do
   559  not support nesting._
   560  
   561  For example, the following is **illegal** and will not work:
   562  
   563  ```yaml
   564  global:
   565    foo:  # It is illegal to nest an object inside of global.
   566      bar: baz
   567  ```
   568  
   569  ### References
   570  
   571  When it comes to writing templates and values files, there are several
   572  standard references that will help you out.
   573  
   574  - [Go templates](https://godoc.org/text/template)
   575  - [Extra template functions](https://godoc.org/github.com/Masterminds/sprig)
   576  - [The YAML format](http://yaml.org/spec/)
   577  
   578  ## Using Helm to Manage Charts
   579  
   580  The `helm` tool has several commands for working with charts.
   581  
   582  It can create a new chart for you:
   583  
   584  ```console
   585  $ helm create mychart
   586  Created mychart/
   587  ```
   588  
   589  Once you have edited a chart, `helm` can package it into a chart archive
   590  for you:
   591  
   592  ```console
   593  $ helm package mychart
   594  Archived mychart-0.1.-.tgz
   595  ```
   596  
   597  You can also use `helm` to help you find issues with your chart's
   598  formatting or information:
   599  
   600  ```console
   601  $ helm lint mychart
   602  No issues found
   603  ```
   604  
   605  ## Chart Repositories
   606  
   607  A _chart repository_ is an HTTP server that houses one or more packaged
   608  charts. While `helm` can be used to manage local chart directories, when
   609  it comes to sharing charts, the preferred mechanism is a chart
   610  repository.
   611  
   612  Any HTTP server that can serve YAML files and tar files and can answer
   613  GET requests can be used as a repository server.
   614  
   615  Helm comes with built-in package server for developer testing (`helm
   616  serve`). The Helm team has tested other servers, including Google Cloud
   617  Storage with website mode enabled, and S3 with website mode enabled.
   618  
   619  A repository is characterized primarily by the presence of a special
   620  file called `index.yaml` that has a list of all of the packages supplied
   621  by the repository, together with metadata that allows retrieving and
   622  verifying those packages.
   623  
   624  On the client side, repositories are managed with the `helm repo`
   625  commands. However, Helm does not provide tools for uploading charts to
   626  remote repository servers. This is because doing so would add
   627  substantial requirements to an implementing server, and thus raise the
   628  barrier for setting up a repository.
   629  
   630  ## Chart Starter Packs
   631  
   632  The `helm create` command takes an optional `--starter` option that lets you
   633  specify a "starter chart".
   634  
   635  Starters are just regular charts, but are located in `$HELM_HOME/starters`.
   636  As a chart developer, you may author charts that are specifically designed
   637  to be used as starters. Such charts should be designed with the following
   638  considerations in mind:
   639  
   640  - The `Chart.yaml` will be overwritten by the generator.
   641  - Users will expect to modify such a chart's contents, so documentation
   642    should indicate how users can do so.
   643  
   644  Currently the only way to add a chart to `$HELM_HOME/starters` is to manually
   645  copy it there. In your chart's documentation, you may want to explain that
   646  process.