Package and Deploy Helm Charts task

Azure DevOps Services | Azure DevOps Server 2020 | Azure DevOps Server 2019

Use this task to deploy, configure, or update a Kubernetes cluster in Azure Container Service by running Helm commands. Helm is a tool that streamlines deploying and managing Kubernetes apps using a packaging format called charts.

You can define, version, share, install, and upgrade even the most complex Kubernetes app by using Helm.

  • Helm helps you combine multiple Kubernetes manifests (yaml) such as service, deployments, configmaps, and more into a single unit called Helm Charts. You don't need to either invent or use a tokenization or a templating tool.
  • Helm Charts help you manage application dependencies and deploy as well as rollback as a unit. They are also easy to create, version, publish, and share with other partner teams.

Azure Pipelines has built-in support for Helm charts:

  • The Helm Tool installer task can be used to install the correct version of Helm onto the agents.
  • The Helm package and deploy task can be used to package the app and deploy it to a Kubernetes cluster. You can use the task to install or update Tiller to a Kubernetes namespace, to securely connect to Tiller over TLS for deploying charts, or to run any Helm command such as lint.
  • The Helm task supports connecting to an Azure Kubernetes Service by using an Azure service connection. You can connect to any Kubernetes cluster by using kubeconfig or a service account.
  • Helm deployments can be supplemented by using the Kubectl task; for example, create/update, imagepullsecret, and others.

Service Connection

The task works with two service connection types: Azure Resource Manager and Kubernetes Service Connection.

Note

A service connection isn't required if an environment resource that points to a Kubernetes cluster has already been specified in the pipeline's stage.

Azure Resource Manager

ParametersDescription
connectionType
(Service connection type)
(Required unless an environment resource is already present) Azure Resource Manager to use Azure Kubernetes Service. Kubernetes Service Connection for any other cluster.
Default value: Azure Resource Manager
azureSubscriptionEndpoint
(Azure subscription)
(Required) Name of the Azure service connection.
azureResourceGroup
(Resource group)
(Required) Name of the resource group within the subscription.
kubernetesCluster
(Kubernetes cluster)
(Required) Name of the AKS cluster.
namespace
(Namespace)
(Optional) The namespace on which the kubectl commands are run. If not specified, the default namespace is used.

This YAML example YAML shows how Azure Resource Manager is used to refer to the Kubernetes cluster. This is used with one of the helm commands and the appropriate values required for the command:

variables:
  azureSubscriptionEndpoint: Contoso
  azureContainerRegistry: contoso.azurecr.io
  azureResourceGroup: Contoso
  kubernetesCluster: Contoso

- task: HelmDeploy@0
  displayName: Helm deploy
  inputs:
    connectionType: Azure Resource Manager
    azureSubscriptionEndpoint: $(azureSubscriptionEndpoint)
    azureResourceGroup: $(azureResourceGroup)
    kubernetesCluster: $(kubernetesCluster)

Kubernetes Service Connection

ParametersDescription
kubernetesServiceEndpoint
(Kubernetes service connection)
(Required unless an environment resource is already present) Select a Kubernetes service connection.
namespace
(Namespace)
(Optional) The namespace on which the kubectl commands are run. If not specified, the default namespace is used.

This YAML example YAML shows how Kubernetes service connection is used to refer to the Kubernetes cluster. This is used with one of the helm commands and the appropriate values required for the command:

- task: HelmDeploy@0
  displayName: Helm deploy
  inputs:
    connectionType: Kubernetes Service Connection
    kubernetesServiceEndpoint: Contoso

Command values

The command input accepts one of the following helm commands: create/delete/expose/get/init/install/login/logout/ls/package/rollback/upgrade.

ParametersDescription
command
(Command)
(Required) Select a helm command.
Default value: ls
arguments
(Arguments)
Helm command options.

This YAML example demonstrates the ls command:

- task: HelmDeploy@0
  displayName: Helm list
  inputs:
    azureSubscriptionEndpoint: $(azureSubscriptionEndpoint)
    azureResourceGroup: $(azureResourceGroup)
    kubernetesCluster: $(kubernetesCluster)
    command: ls
    arguments: --all

init command

ParametersDescription
command
(Command)
(Required) Select a helm command.
Default value: ls
canaryimage
(Use canary image version)
Use the canary Tiller image, the latest pre-release version of Tiller.
Default value: false
upgradetiller
(Upgrade Tiller)
Upgrade if Tiller is already installed.
Default value: true
waitForExecution
(Wait)
Block until the command execution completes.
Default value: true
arguments
(Arguments)
Helm command options.

This YAML example demonstrates the init command:

- task: HelmDeploy@0
  displayName: Helm init
  inputs:
    azureSubscriptionEndpoint: $(azureSubscriptionEndpoint)
    azureResourceGroup: $(azureResourceGroup)
    kubernetesCluster: $(kubernetesCluster)
    command: init
    upgradetiller: true
    waitForExecution: true
    arguments: --client-only

install command

ParametersDescription
command
(Command)
(Required) Select a helm command.
Default value: ls
chartType
(Chart Type)
(Required) Select how you want to enter chart information. You can provide either the name of the chart or the folder/file path to the chart.
Available options: Name, FilePath. Default value: Name
chartName
(Chart Name)
(Required) Chart reference to install, this can be a url or a chart name. For example, if chart name is stable/mysql, the task will run helm install stable/mysql
releaseName
(Release Name)
(Optional) Release name. If not specified, it will be autogenerated. releaseName input is only valid for 'install' and 'upgrade' commands
overrideValues
(Set Values)
(Optional) Set values on the command line. You can specify multiple values by separating values with commas. For example, key1=val1,key2=val2. You can also specify multiple values by delimiting them with newline as so:
key1=val1
key2=val2

Please note that if you have a value which itself contains newlines, use the valueFile option, else the task will treat the newline as a delimiter. The task will construct the helm command by using these set values. For example, helm install --set key1=val1 ./redis
valueFile
(Value File)
(Optional) Specify values in a YAML file or a URL. For example, specifying myvalues.yaml will result in helm install --values=myvalues.yaml
updatedependency
(Update Dependency)
(Optional) Run helm dependency update before installing the chart. Update dependencies from requirements.yaml to the charts/ directory before packaging.
Default value: false
waitForExecution
(Wait)
(Optional) Block until command execution completes.
Default value: true
arguments
(Arguments)
Helm command options

This YAML example demonstrates the install command:

- task: HelmDeploy@0
  displayName: Helm install
  inputs:
    azureSubscriptionEndpoint: $(azureSubscriptionEndpoint)
    azureResourceGroup: $(azureResourceGroup)
    kubernetesCluster: $(kubernetesCluster)
    command: install
    chartType: FilePath
    chartPath: Application/charts/sampleapp

package command

ParametersDescription
command
(Command)
(Required) Select a helm command.
Default value: ls
chartPath
(Chart Path)
(Required) Path to the chart to install. This can be a path to a packaged chart or a path to an unpacked chart directory. For example, if ./redis is specified the task will run helm install ./redis. If you are consuming a chart which is published as an artifact then the path will be $(System.DefaultWorkingDirectory)/ARTIFACT-NAME/Charts/CHART-NAME
version
(Version)
(Optional) Specify the exact chart version to install. If this is not specified, the latest version is installed. Set the version on the chart to this semver version.
destination
(Destination)
(Optional) Specify values in a YAML file or a URL.
Default value: $(Build.ArtifactStagingDirectory)
updatedependency
(Update Dependency)
(Optional) Run helm dependency update before installing the chart. Update dependencies from requirements.yaml to the charts/ directory before packaging.
Default value: false
save
(Save)
(Optional) Save packaged chart to local chart repository.
Default value: true
arguments
(Arguments)
Helm command options.

This YAML example demonstrates the package command:

- task: HelmDeploy@0
  displayName: Helm package
  inputs:
    command: package
    chartPath: Application/charts/sampleapp
    destination: $(Build.ArtifactStagingDirectory)

upgrade command

ParametersDescription
command
(Command)
(Required) Select a helm command.
Default value: ls
chartType
(Chart Type)
(Required) Select how you want to enter chart information. You can provide either the name of the chart or the folder/file path to the chart.
Available options: Name, FilePath. Default value: Name
chartName
(Chart Name)
(Required if chartType is Name) Chart reference to install, this can be a URL or a chart name. For example, if chart name is stable/mysql, the task will run helm install stable/mysql
chartPath
(Chart Path)
(Required if chartType is FilePath) Path to the chart to install. This can be a path to a packaged chart or a path to an unpacked chart directory. For example, if ./redis is specified, the task will run helm upgrade ./redis. If you're consuming a chart that's published as an artifact, then the path will be $(System.DefaultWorkingDirectory)/ARTIFACT-NAME/Charts/CHART-NAME
releaseName
(Release Name)
(Optional) Release name. If not specified, it will be autogenerated.
overrideValues
(Set Values)
(Optional) Set values on the command line. You can specify multiple values by separating values with commas. For example, key1=val1,key2=val2. You can also specify multiple values by delimiting them with newline as so:
key1=val1
key2=val2

Please note that if you have a value which itself contains newlines, use the valueFile option, else the task will treat the newline as a delimiter. The task will construct the helm command by using these set values. For example, helm install --set key1=val1 ./redis
valueFile
(Value File)
(Optional) Specify values in a YAML file or a URL. For example, specifying myvalues.yaml will result in helm install --values=myvalues.yaml
install
(Install if release not present)
(Optional) If a release by this name does not already exist, start an installation.
Default value: true
recreate
(Recreate Pods)
(Optional) Performs pods restart for the resource if applicable.
Default value: false
resetValues
(Reset Values)
(Optional) Reset the values to the ones built into the chart.
Default value: false
force
(Force)
(Optional) Force resource update through delete/recreate if required.
Default value: false
waitForExecution
(Wait)
(Optional) Block until command execution completes.
Default value: true​
arguments
(Arguments)
Helm command options

This YAML example demonstrates the upgrade command:

- task: HelmDeploy@0
  displayName: Helm upgrade
  inputs:
    azureSubscriptionEndpoint: $(azureSubscriptionEndpoint)
    azureResourceGroup: $(azureResourceGroup)
    kubernetesCluster: $(kubernetesCluster)
    command: upgrade
    chartType: filepath
    chartPath: $(Build.ArtifactStagingDirectory)/sampleapp-v0.2.0.tgz
    releaseName: azuredevopsdemo
    install: true
    waitForExecution: false

save command

ParametersDescription
command
(Command)
(Required) Select a helm command.
Default value: ls
chartNameForACR
(Chart Name For Azure Container Registry)
(Required) Chart name with which the chart will be stored in Azure Container Registry.
chartPathForACR
(Chart Path for Azure Container Registry)
(Required) Path to the chart directory.
azureSubscriptionEndpointForACR
(Azure subscription for Container Registry)
(Required) Select an Azure subscription, which has your Azure Container Registry.
azureResourceGroupForACR
(Resource group)
(Required) Select an Azure Resource Group, which has your Container Registry.
azureContainerRegistry
(Azure Container Registry)
(Required) Select an Azure Container Registry which will be used for pushing helm charts.
arguments
(Arguments)
Helm command options

This YAML example demonstrates the save command:

- task: HelmDeploy@0
  displayName: Helm save
  inputs:
    command: save
    chartNameForACR: mycontainerregistry.azurecr.io/helm/hello-world:v1
    chartPathForACR: Application/charts/sampleapp
    azureSubscriptionEndpointForACR: $(azureSubscriptionEndpointForACR)
    azureResourceGroupForACR: $(azureResourceGroupForACR)
    azureContainerRegistry: $(azureContainerRegistry)

Package and sign Helm charts

In this section you'll learn how to package and sign Helm charts in a pipeline.

Generate a private-public key pair to sign the helm chart using GPG

  1. Download GPG.

  2. Launch the command prompt in an administrator mode. Run the following command to generate a private-public key pair to sign the helm chart using gpg. While creating the key, you'll be prompted for the username and email address. The "name email address" is later used to name the private-public key pair that is created.

    gpg --full-generate-key
    

    Generate Key

  3. You'll be prompted for the passphrase. Give the value and click ok.

    Screenshot that shows giving the passphrase.

  4. After creating the key, you can see the list of keys which contains both private and public using the following command.

    • To see list of private keys

      gpg --list-secret-keys
      

      Private Keys

    • To see the list of public keys

      gpg --list-keys
      

      Public Keys

  5. Store the private and public keys in 2 different files with the extension gpg as shown below.

    • For a private key
    gpg --export-secret-key 94325E18E53EDD99DD8339C3CFD9DAF0707CB788 contoso@microsoft.com > C:/somepath/privatekeys.gpg
    

    You'll see the privatekeys.gpg file exported to the path which was mentioned above.

    • For a public key
    gpg --export-key 94325E18E53EDD99DD8339C3CFD9DAF0707CB788 contoso@microsoft.com > C:/somepath/publickey.gpg
    

    You'll see the publickey.gpg file exported to the path which was mentioned above.

In Azure DevOps, save the privatekey.gpg file in the library secure files section.

Example

pool:
  name: Hosted Ubuntu 1604

variables:
  # The below variable should be secure
  HelmKeyPassphrase: contoso@123
  keyName: contoso contoso@microsoft.com
  azureSubscriptionEndpoint: contoso
  azureResourceGroup: contoso
  kubernetesCluster: contoso

steps:
- task: DownloadSecureFile@1
  displayName: Download Secure file
  inputs:
    secureFile: privatekey.gpg
  name: privateKeyRing

- task: HelmInstaller@0
  displayName: Install Helm 2.12.0
  inputs:
    helmVersion: 2.12.0

- task: HelmDeploy@0
  displayName: helm init
  inputs:
    azureSubscriptionEndpoint: $(azureSubscriptionEndpoint)
    azureResourceGroup: $(azureResourceGroup)
    kubernetesCluster: $(kubernetesCluster)
    command: init
    arguments: --client-only

- task: HelmDeploy@0
  displayName: helm package
  inputs:
    command: package
    chartPath: Application/charts/sampleapp
    arguments: --sign --key "$(keyName)" --keyring $(privateKeyRing.secureFilePath)
  env:
    HelmKeyPassphrase: $(HelmKeyPassphrase)

Troubleshooting

HelmDeploy task throws error 'unknown flag: --wait' while running 'helm init --wait --client-only' on Helm 3.0.2 version.

There are some breaking changes between Helm 2 and Helm 3. One of them includes removal of tiller, and hence helm init command is no longer supported. Remove command: init when you use Helm 3.0+ versions.

When using Helm 3, if System.debug is set to true and Helm upgrade is the command being used, the pipeline fails even though the upgrade was successful.

This is a known issue with Helm 3, as it writes some logs to stderr. Helm Deploy Task is marked as failed if there are logs to stderr or exit code is non-zero. Set the task input failOnStderr: false to ignore the logs printed to stderr.

Open source

This task is open source on GitHub. Feedback and contributions are welcome.