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
| Parameters | Description |
|---|---|
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
| Parameters | Description |
|---|---|
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.
| Parameters | Description |
|---|---|
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
| Parameters | Description |
|---|---|
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
| Parameters | Description |
|---|---|
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
| Parameters | Description |
|---|---|
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
| Parameters | Description |
|---|---|
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
| Parameters | Description |
|---|---|
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
Download GPG.
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
You'll be prompted for the passphrase. Give the value and click ok.

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
To see the list of public keys
gpg --list-keys
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.gpgYou'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.gpgYou'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.
Feedback
Issottometti u ara feedback għal