Helm

helm is a package manager for Kubernetes that helps you manage Kubernetes applications. Skaffold natively supports iterative development for projects configured to use helm.

Configuring your Helm Project with Skaffold

Skaffold supports projects set up to deploy with Helm, but certain aspects of the project need to be configured correctly in order for Skaffold to work properly. This guide should demystify some of the nuance around using Skaffold with Helm to help you get started quickly.

Image Configuration

The normal Helm convention for defining image references is through the values.yaml file. Often, image information is configured through an image stanza in the values file, which might look something like this:

project_root/values.yaml

image:
  repository: gcr.io/my-project/
  name: my-image
  tag: v1.2.0
  pullPolicy: IfNotPresent

This image would then be referenced in a templated resource file, maybe like this:

project_root/templates/deployment.yaml:

spec:
  template:
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: {{ .Values.image.repository }}{{ .Values.image.name }}:{{ .Values.image.tag}}
          imagePullPolicy: {{ .Values.image.pullPolicy }}

Unfortunately, because of the way Skaffold continuously tags rebuilt images and hydrates Kubernetes resources before sending them to the cluster, it doesn’t know how to handle images defined in this way.

IMPORTANT: To get Skaffold to work with Helm, your image needs to be defined directly as a Helm value in the skaffold.yaml.

This allows Skaffold to track the image being built, and correctly substitute it in the proper resource definition before sending it to Helm to be deployed to your cluster. In practice, this looks something like this:

deploy:
  helm:
    releases:
    - name: my-release
      artifactOverrides:
        image: gcr.io/my-project/my-image # no tag present!
        # Skaffold continuously tags your image, so no need to put one here.

By configuring your project this way, note that you may need to rewrite any templates referencing your image to reflect this new value! Using the above templated deployment.yaml as an example, we would need to rewrite the template like so:

project_root/templates/deployment.yaml:

spec:
  template:
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: {{ .Values.image }} # this value comes from the skaffold.yaml

          # this imagePullPolicy value is now invalid,
          # because it was overwritten through the `image` value from the skaffold.yaml!

          # let's redefine it in the `values.yaml` so we can keep it here.
          imagePullPolicy: {{ .Values.imageConfig.pullPolicy }}

and quickly redefining the imagePullPolicy in the project_root/values.yaml:

imageConfig:
  pullPolicy: IfNotPresent

Helm Build Dependencies

The skipBuildDependencies flag toggles whether dependencies of the Helm chart are built with the helm dep build command. This command manipulates files inside the charts subfolder of the specified Helm chart.

If skipBuildDependencies is false then skaffold dev does not watch the charts subfolder of the Helm chart, in order to prevent a build loop - the actions of helm dep build always trigger another build.

If skipBuildDependencies is true then skaffold dev watches all files inside the Helm chart.

skaffold.yaml Configuration

The helm type offers the following options:

Option Description
releases Required a list of Helm releases.
flags additional option flags that are passed on the command line to helm.

Each release includes the following fields:

Option Description Default
name Required name of the Helm release.
chartPath Required path to the Helm chart.
valuesFiles paths to the Helm values files. []
artifactOverrides key value pairs. If present, Skaffold will send --set-string flag to Helm CLI and append all pairs after the flag.
namespace Kubernetes namespace.
version version of the chart.
setValues key-value pairs. If present, Skaffold will send --set flag to Helm CLI and append all pairs after the flag.
setValueTemplates key-value pairs. If present, Skaffold will try to parse the value part of each key-value pair using environment variables in the system, then send --set flag to Helm CLI and append all parsed pairs after the flag.
setFiles key-value pairs. If present, Skaffold will send --set-file flag to Helm CLI and append all pairs after the flag. {}
wait if true, Skaffold will send --wait flag to Helm CLI. false
recreatePods if true, Skaffold will send --recreate-pods flag to Helm CLI when upgrading a new version of a chart in subsequent dev loop deploy. false
skipBuildDependencies should build dependencies be skipped. Ignored when remote: true. false
useHelmSecrets instructs skaffold to use secrets plugin on deployment. false
remote specifies whether the chart path is remote, or exists on the host filesystem. false
upgradeOnChange specifies whether to upgrade helm chart on code changes. Default is true when helm chart is local (remote: false). Default is false if remote: true.
overrides key-value pairs. If present, Skaffold will build a Helm values file that overrides the original and use it to call Helm CLI (--f flag).
packaged parameters for packaging helm chart (helm package).
imageStrategy adds image configurations to the Helm values file.