Working with Helm Values: Common Operations and Best Practices

What Is Helm? 

Helm is a package manager for Kubernetes, designed to streamline the deployment and management of applications on Kubernetes clusters. It simplifies the process of defining, installing, and upgrading even the most complex Kubernetes applications. Helm uses a packaging format called charts, which are collections of files that describe a related set of Kubernetes resources. This allows developers and operations teams to manage Kubernetes applications in a rather straightforward manner.

By using Helm, teams can reduce the complexity of Kubernetes configuration, making it easier to share and distribute applications. Furthermore, Helm manages the lifecycle of Kubernetes applications, enabling versioning, history tracking, and rollbacks. This powerful tool effectively transforms Kubernetes deployments, providing a more manageable and scalable way to handle complex environments.

What Are Helm Values? 

Helm values are a critical component within Helm charts that allow for customization and parameterization. They enable users to specify configuration values that override the default settings defined in a chart’s values.yaml file. This allows for flexibility and control, accommodating various deployment environments and requirements. By defining values in a structured manner, Helm users can ensure consistency and repeatability across deployments.

Values play an essential role in the customization of Helm charts, making it easier to manage configurations across multiple environments, such as development, testing, and production. These values can be passed in through command-line arguments, values files, or set directly in the Helm chart.

This is part of a series of articles about Kubernetes Helm

Common Operations with Helm Values in Kubernetes 

Installing a Base Helm Release

Let’s start by installing a Helm release to serve as an example. We’ll deploy an Apache web server using the helm install command:

$ helm install apache 
oci://registry-1.docker.io/bitnamicharts/apache

Once the release is installed, retrieve its current values using:

$ helm get values -a apache

In this example, the output includes several parameters, such as command, containerPorts, and replicaCount. The replicaCount is initially set to 1.

Updating Values with the –set Flag

The –set flag allows you to update specific values directly from the command line. For example, to change the replicaCount to 3, you can use the following command:

$ helm upgrade apache 
oci://registry-1.docker.io/bitnamicharts/apache --set
replicaCount=3

To confirm the update, you can grep the new value:

$ helm get values -a apache | grep replicaCount

This should show:

replicaCount: 3

For more complex parameters, such as nested dictionaries, you can use dot notation. For example, to change the http port under containerPorts, use:

$ helm upgrade apache 
oci://registry-1.docker.io/bitnamicharts/apache --set
containerPorts.http=2255

Verify the change:

$ helm get values -a apache | yq -o props | grep 
'containerPorts.http '

This will display:

containerPorts.http = 2255

expert-icon-header

Tips from the expert

Itiel Shwartz

Co-Founder & CTO

Itiel is the CTO and co-founder of Komodor. He’s a big believer in dev empowerment and moving fast, has worked at eBay, Forter and Rookout (as the founding engineer). Itiel is a backend and infra developer turned “DevOps”, an avid public speaker that loves talking about things such as cloud infrastructure, Kubernetes, Python, observability, and R&D culture.

In my experience, here are tips that can help you better work with Helm values:

Use version lock for critical settings:

When deploying critical applications, consider locking down specific values to prevent unintended changes. Use a separate, locked-down values file that requires explicit changes only during major upgrades.

Use environment-specific value files:

Maintain separate values files for different environments (e.g.,values-dev.yaml, values-prod.yaml) and leverage Helm’s --values
flag to ensure that environment-specific configurations are consistently applied.

Document your values.yaml files:

Add comments within your values.yaml files to explain the purpose of each value, especially if they are frequently overridden. This documentation will save time for team members and prevent misconfiguration.

Implement value validation:

Use Helm’s schema validation (values.schema.json) to enforce constraints on your values. This can prevent common misconfigurations by ensuring that only valid inputs are accepted during deployments.

Use a centralized values repository:

Create a centralized repository for your Helm values files. This repository can serve as a source of truth, enabling easier auditing, version control, and collaboration among teams.

Updating Values with the –values Flag

When you need to update multiple parameters at once, it’s more efficient to use a values file with the --values (or -f) flag. Here’s how you can do it:

Create a values.yml file with the following content:

containerPorts:
http: 3333
https: 4444
replicaCount: 5

Then apply these values with:

$ helm upgrade apache 
oci://registry-1.docker.io/bitnamicharts/apache --values
values.yml

Check the updated values:

$ helm get values -a apache | yq -o props | grep 
'containerPorts.http\|replicaCount'

This should show:

containerPorts.http = 3333
containerPorts.https = 4444
replicaCount = 5

Using the –set-file Flag for File-Based Values

For lengthy or dynamically generated values, the --set-file flag is useful. It allows you to pass file contents as values. Suppose you have a default_cmd file with the following content:

$ cat default_cmd
["/bin/bash", "-c", "echo 'Home directory:' $HOME"]

To update the command parameter:

$ helm upgrade apache 
oci://registry-1.docker.io/bitnamicharts/apache --set-file
command=default_cmd

Verify the update:

$ helm get values -a apache | yq -o props | grep command

Handling JSON Values with –set-json

For values that require JSON format, the --set-json flag is ideal. Here’s how you can update containerPorts using JSON:

$ helm upgrade apache 
oci://registry-1.docker.io/bitnamicharts/apache --set-json
containerPorts='{"http":3333, "https":4444}'

Check the updated ports:

$ helm get values -a apache | yq -o props | grep 
containerPorts.http

The output should show:

containerPorts.http = 3333
containerPorts.https = 4444

Using –set-string for Enforcing String Values

The --set-string flag forces the value to be interpreted as a string. Be cautious with parameters that expect other data types, like integers. Attempting to set replicaCount as a string will result in an error:

$ helm upgrade apache 
oci://registry-1.docker.io/bitnamicharts/apache --set-string
replicaCount=3

This command fails with the following error:

Error: UPGRADE FAILED: values don't meet the specifications of the schema(s) in the following chart(s):
apache:
- replicaCount: Invalid type. Expected: integer, given: string

Managing Literal Values with –set-literal

When dealing with values containing special characters, use --set-literal. For example, to update a secret:

$ helm upgrade apache 
oci://registry-1.docker.io/bitnamicharts/apache --set-literal
secret=my\!Pass0Word

Verify the result:

$ helm get values -a apache | grep secret

The output should be:

secret: my!Pass0Word

This command ensures that special characters are properly handled, unlike --set or --set-string, which might not escape them correctly.

Best Practices for Using Helm Values 

Naming Conventions

Establishing clear and consistent naming conventions in Helm values is crucial for maintaining readability and avoiding conflicts within your Helm charts. Variables should always start with a lowercase letter and follow camelCase for multi-word names. 

This convention is not just a stylistic preference but also a practical one; it helps prevent potential naming collisions with built-in Helm variables, which typically start with an uppercase letter. For example, built-ins like .Release.Name or .Capabilities.KubeVersion are capitalized to distinguish them from user-defined variables.

Incorrect naming practices, such as using hyphens (my-special-value: true) or starting variable names with an uppercase letter (Myvalue: true), should be avoided. Hyphens are particularly problematic because they can lead to parsing issues and are generally discouraged in YAML.

Flat or Nested Values

In Helm charts, values can be organized in either a flat or nested structure, each with its own advantages and challenges. A flat structure, where each value is defined at the top level (e.g., serverName: busybox and serverPort: 80), is often preferred for its simplicity and ease of use. 

This approach reduces the complexity of template logic, as flat values require fewer checks during template rendering. For instance, with flat values, you can directly access and use the values in templates without needing to verify the existence of multiple nested keys. This not only makes the templates easier to read and understand but also minimizes the risk of errors.

However, there are situations where nested values may be more appropriate, especially when dealing with groups of related variables. For example, if you have several configurations related to a server, nesting them under a server key might improve clarity:

server:
name: busybox
port: 80

Make Types Clear

YAML, the configuration format used by Helm, has type coercion rules that can sometimes produce unexpected results, leading to subtle bugs and deployment issues. For instance, YAML might interpret myValue: false as a boolean value, while myValue: "false" would be treated as a string. This difference in interpretation can cause problems if the chart expects a specific type. 

Similarly, large integers like myValue: 9999999 might be automatically converted to scientific notation in some environments.

To avoid these issues, follow these practices:

  • Be explicit about types in your Helm values. For example, always use myValue: "false" instead of myValue: false if you intend the value to be a string.
  • For numerical values, especially large integers, it can be beneficial to store them as strings (e.g., foo: "99999999") and then convert them back to integers in the templates using {{ int $value }}.
  • In some cases, you can use YAML’s explicit type tags, such as !!string, to enforce a specific type, like this: myValue: !!string 488976

Note: Some YAML parsers may strip away explicit type tags after the first parse, so they should be used cautiously.

Related content: Read our guide to Kubernetes Helm tutorial (coming soon)

Visualizing and Managing Helm Charts With Komodor

Komodor’s platform streamlines the day-to-day operations and troubleshooting process of your Kubernetes apps. Specifically when it comes to Helm Charts, Komodor’s platform provides you with a visual dashboard to view the installed Helm charts, see their revision history and corresponding k8s resources. It also allows you to perform actions such as rolling back to a revision or upgrading to a newer version.

At its core, the platform gives you a real-time, high-level view of your cluster’s health, configurations, and resource utilization. This abstraction is particularly useful for routine tasks like rolling out updates, scaling applications, and managing resources. You can easily identify bottlenecks, underutilized nodes, or configuration drift, and then make informed decisions without needing to sift through YAML files or execute a dozen kubectl commands.

Beyond just observation, Komodor integrates with your existing CI/CD pipelines and configuration management tools to make routine tasks more seamless. The platform offers a streamlined way to enact changes, such as scaling deployments or updating configurations, directly through its interface. It can even auto-detect and integrate with CD tools like Argo or Flux to support a GitOps approach! Komodor’s “app-centric” approach to Kubernetes management is a game-changer for daily operational tasks, making it easier for both seasoned DevOps engineers and those new to Kubernetes to keep their clusters running smoothly, and their applications maintaining high-availability.

To learn more about how Komodor can make it easier to empower you and your teams to manage & troubleshoot K8s, sign up for our free trial.