---
slug: helm-values
title: Helm Values
description: Holos provides values to multiple charts easily and safely.
sidebar_position: 40
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import YouTube from '@site/src/components/YouTube';
import CodeBlock from '@theme/CodeBlock';

<head>
  <meta property="og:title" content="Helm Values | Holos" />
  <meta property="og:image" content="https://holos.run/img/cards/guides-helm-2.png" />
</head>

# Helm Values

## Overview

Holos simplifies integrating multiple Helm charts by adding valuable
capabilities to Helm and Kustomize:

1. Inject the same value into multiple charts more safely than using Helm alone.
2. Add strong type checking and validation for Helm input values.
3. Implement the [rendered manifests pattern].

In this tutorial, we'll manage the [prometheus] and [blackbox] Helm charts. By
default, the upstream `values.yaml` files are misconfigured, causing Prometheus
to connect to Blackbox at the wrong host and port.

## The Video

The video below enhances this tutorial by offering greater detail on the issue
of poorly integrated Helm charts and the solution we've provided. If you're
looking for a deeper explanation of the code being presented, this video is a great
resource.

{/* cspell:disable-next-line */}
<YouTube id="PSdceGlhHGo"/>

## The Code

### Holos Version

Ensure you have a current version of `holos` installed.  This document was
tested with the following version.

import HolosVersionCommand from '!!raw-loader!./_helm-values/script-01-holos-version/command.sh';
import HolosVersionOutput from '!!raw-loader!./_helm-values/script-01-holos-version/output.txt';

<CodeBlock language="bash">{HolosVersionCommand}</CodeBlock>
<CodeBlock language="txt">{HolosVersionOutput}</CodeBlock>

### Generating the structure

Use `holos` to generate a minimal platform directory structure. First, create
and navigate into a blank directory, then use the `holos init platform` command:

import MkdirAndInit from '!!raw-loader!./_helm-values/script-02-helm-values/mkdir-and-init.sh';

<CodeBlock language="bash">{MkdirAndInit}</CodeBlock>

Make an initial commit to track changes:

import GitInit from '!!raw-loader!./_helm-values/script-02-helm-values/git-init.sh';

<CodeBlock language="bash">{GitInit}</CodeBlock>

### Managing the Components

Create the `prometheus` and `blackbox` component directories, then add each of
the following file contents.

import MkdirComponents from '!!raw-loader!./_helm-values/script-02-helm-values/mkdir-components.sh';
import PrometheusComponentHeader from '!!raw-loader!./_helm-values/script-02-helm-values/prometheus-component-header.sh';
import PrometheusComponentBody from '!!raw-loader!./_helm-values/script-02-helm-values/prometheus-component-body.cue';
import BlackboxComponentHeader from '!!raw-loader!./_helm-values/script-02-helm-values/blackbox-component-header.sh';
import BlackboxComponentBody from '!!raw-loader!./_helm-values/script-02-helm-values/blackbox-component-body.cue';
import EofTrailer from '!!raw-loader!./_helm-values/script-02-helm-values/eof-trailer.sh';


<CodeBlock language="bash">{MkdirComponents}</CodeBlock>

<Tabs groupId="D15A3008-1EFC-4D34-BED1-15BC0C736CC3">
  <TabItem value="prometheus.cue" label="prometheus.cue">
    <CodeBlock language="bash">{PrometheusComponentHeader}</CodeBlock>
    <CodeBlock language="cue" showLineNumbers>{PrometheusComponentBody}</CodeBlock>
    <CodeBlock language="bash">{EofTrailer}</CodeBlock>
  </TabItem>
  <TabItem value="blackbox.cue" label="blackbox.cue">
    <CodeBlock language="bash">{BlackboxComponentHeader}</CodeBlock>
    <CodeBlock language="cue" showLineNumbers>{BlackboxComponentBody}</CodeBlock>
    <CodeBlock language="bash">{EofTrailer}</CodeBlock>
  </TabItem>
</Tabs>

### Register the Components

Register the components with the platform by adding the following file to the platform directory.

import RegisterComponentsHeader from '!!raw-loader!./_helm-values/script-02-helm-values/register-components-header.sh';
import RegisterComponentsBody from '!!raw-loader!./_helm-values/script-02-helm-values/register-components-body.cue';

<CodeBlock language="bash">{RegisterComponentsHeader}</CodeBlock>
<CodeBlock language="cue" showLineNumbers>{RegisterComponentsBody}</CodeBlock>
<CodeBlock language="bash">{EofTrailer}</CodeBlock>

Render the platform.

import RenderCommand from '!!raw-loader!./_helm-values/script-02-helm-values/render.sh';
import RegisterComponentsRenderOutput from '!!raw-loader!./_helm-values/script-02-helm-values/register-components-output.txt';

<Tabs groupId="33D6BFED-62D8-4A42-A26A-F3121D57C4E5">
  <TabItem value="command" label="Command">
    <CodeBlock language="bash">{RenderCommand}</CodeBlock>
  </TabItem>
  <TabItem value="output" label="Output">
    <CodeBlock language="txt">{RegisterComponentsRenderOutput}</CodeBlock>
  </TabItem>
</Tabs>

Commit the results.

import GitCommitRegisterComponents from '!!raw-loader!./_helm-values/script-02-helm-values/register-components-git-commit.sh';
import RegisterComponentsGitOutput from '!!raw-loader!./_helm-values/script-02-helm-values/register-components-git-commit-output.txt';

<Tabs groupId="446CC550-A634-45C0-BEC7-992E5C56D4FA">
  <TabItem value="command" label="Command">
    <CodeBlock language="bash">{GitCommitRegisterComponents}</CodeBlock>
  </TabItem>
  <TabItem value="output" label="Output">
    <CodeBlock language="txt">{RegisterComponentsGitOutput}</CodeBlock>
  </TabItem>
</Tabs>

### Importing Helm Values

Holos renders Helm charts with their default values. We can import these default
values into CUE to work with them as structured data instead of text markup.

import ImportPrometheusValues from '!!raw-loader!./_helm-values/script-02-helm-values/import-prometheus-values.sh';
import ImportBlackboxValues from '!!raw-loader!./_helm-values/script-02-helm-values/import-blackbox-values.sh';

<CodeBlock language="bash">{ImportPrometheusValues}</CodeBlock>
<CodeBlock language="bash">{ImportBlackboxValues}</CodeBlock>

These commands convert the YAML data into CUE code and nest the values under the
`Values` field of the `Helm` struct.

:::important
CUE unifies `values.cue` with the other `\*.cue` files in the same directory.
:::

Render the platform using `holos render platform` and commit the results.

import ImportValuesRenderOutput from '!!raw-loader!./_helm-values/script-02-helm-values/import-values-render-output.txt';
import ImportValuesGitCommit from '!!raw-loader!./_helm-values/script-02-helm-values/import-values-git-commit.sh';
import ImportValuesGitOutput from '!!raw-loader!./_helm-values/script-02-helm-values/import-values-git-output.txt';

<Tabs groupId="BDDCD65A-2E9D-4BA6-AAE2-8099494D5E4B">
  <TabItem value="command" label="Command">
    <CodeBlock language="bash">{RenderCommand}</CodeBlock>
  </TabItem>
  <TabItem value="output" label="Output">
    <CodeBlock language="txt">{ImportValuesRenderOutput}</CodeBlock>
  </TabItem>
</Tabs>

<Tabs groupId="1636C619-258E-4D49-8052-F64B588C9177">
  <TabItem value="command" label="Command">
    <CodeBlock language="bash">{ImportValuesGitCommit}</CodeBlock>
  </TabItem>
  <TabItem value="output" label="Output">
    <CodeBlock language="txt">{ImportValuesGitOutput}</CodeBlock>
  </TabItem>
</Tabs>

### Managing Common Configuration

To manage shared configuration for both Helm charts, define a structure that
holds the common configuration values. Create a `config` directory at the root
of the repository, and place the configuration file there to ensure it is
accessible to all components.

import BlackboxCommonConfigMkdir from '!!raw-loader!./_helm-values/script-02-helm-values/mkdir-common-config.sh';
import BlackboxCommonConfigHeader from '!!raw-loader!./_helm-values/script-02-helm-values/blackbox-common-config-header.sh';
import BlackboxCommonConfigBody from '!!raw-loader!./_helm-values/script-02-helm-values/blackbox-common-config-body.cue';

<CodeBlock language="bash">{BlackboxCommonConfigMkdir}</CodeBlock>
<CodeBlock language="bash">{BlackboxCommonConfigHeader}</CodeBlock>
<CodeBlock language="cue" showLineNumbers>{BlackboxCommonConfigBody}</CodeBlock>
<CodeBlock language="bash" showLineNumbers>{EofTrailer}</CodeBlock>

:::important
1. CUE loads and unifies all `*.cue` files from the root directory containing
`cue.mod` to the leaf component path directory.
2. CUE validates types _and_ constraints.  Validation with CUE is better than
languages with only type checking.
:::

Add and commit the configuration.

import BlackboxCommonConfigGit from '!!raw-loader!./_helm-values/script-02-helm-values/blackbox-common-config-git-commit.sh';
import BlackboxCommonConfigGitOutput from '!!raw-loader!./_helm-values/script-02-helm-values/blackbox-common-config-git-output.txt';

<Tabs groupId="A738CCE4-F0C6-4CC7-BE1F-2B92F0E86FDC">
  <TabItem value="command" label="Command">
    <CodeBlock language="bash">{BlackboxCommonConfigGit}</CodeBlock>
  </TabItem>
  <TabItem value="output" label="Output">
    <CodeBlock language="bash">{BlackboxCommonConfigGitOutput}</CodeBlock>
  </TabItem>
</Tabs>

### Using Common Configuration Across Components

Referencing common configuration across multiple components is straightforward
and reliable using Holos and CUE. Configuration can be imported where necessary
following [CUE module standards], which are similar to Golang.

To apply the common configuration, patch the two `values.cue` files, or manually
edit them to import the configuration and reference `prometheus.blackbox.host`
and `prometheus.blackbox.port`.

import CommonConfigPatchCommand from '!!raw-loader!./_helm-values/script-02-helm-values/common-config-patch.sh';
import CommonConfigPatchDiff from '!!raw-loader!./_helm-values/script-02-helm-values/values.patch';
import CommonConfigPatchOutput from '!!raw-loader!./_helm-values/script-02-helm-values/common-config-patch.txt';

<Tabs groupId="5FFCE892-B8D4-4F5B-B2E2-39EC9E9F87A4">
  <TabItem value="command" label="Command">
    <CodeBlock language="bash">{CommonConfigPatchCommand}</CodeBlock>
  </TabItem>
  <TabItem value="patch" label="values.patch">
    <CodeBlock language="diff">{CommonConfigPatchDiff}</CodeBlock>
  </TabItem>
  <TabItem value="output" label="Output">
    <CodeBlock language="txt">{CommonConfigPatchOutput}</CodeBlock>
  </TabItem>
</Tabs>

:::important
Both charts now use the same values in lock step.  Holos and CUE integrate them
safely and easily.
:::

Remove the patch file, then commit the changes.

import CommonConfigPatchRm from '!!raw-loader!./_helm-values/script-02-helm-values/common-config-rm.sh';
import CommonConfigPatchGitCommit from '!!raw-loader!./_helm-values/script-02-helm-values/common-config-git.sh';
import CommonConfigPatchGitCommitOutput from '!!raw-loader!./_helm-values/script-02-helm-values/common-config-git-output.txt';

<Tabs groupId="6498B00E-FADA-4EB2-885C-808F1D22E04D">
  <TabItem value="command" label="Command">
    <CodeBlock language="bash">{CommonConfigPatchRm}</CodeBlock>
    <CodeBlock language="bash">{CommonConfigPatchGitCommit}</CodeBlock>
  </TabItem>
  <TabItem value="output" label="Output">
    <CodeBlock language="txt">{CommonConfigPatchGitCommitOutput}</CodeBlock>
  </TabItem>
</Tabs>

## Reviewing Changes

Holos makes it easy to view and review platform-wide changes. Render the
platform to observe how both Prometheus and Blackbox update in sync.

import ReviewingChangesRenderOutput from '!!raw-loader!./_helm-values/script-02-helm-values/reviewing-changes-render-output.txt';

<Tabs groupId="E7F6D8B1-22FA-4075-9B44-D9F2815FE0D3">
  <TabItem value="command" label="Command">
    <CodeBlock language="bash">{RenderCommand}</CodeBlock>
  </TabItem>
  <TabItem value="output" label="Output">
    <CodeBlock language="txt">{ReviewingChangesRenderOutput}</CodeBlock>
  </TabItem>
</Tabs>

Changes are easily visible in version control.

import GitDiffCommand from '!!raw-loader!./_helm-values/script-02-helm-values/git-diff.sh';
import GitDiff from '!!raw-loader!./_helm-values/script-02-helm-values/git.diff';

<Tabs groupId="9789A0EF-24D4-4FB9-978A-3895C2778789">
  <TabItem value="command" label="Command">
    <CodeBlock language="bash">{GitDiffCommand}</CodeBlock>
  </TabItem>
  <TabItem value="output" label="Output">
    <CodeBlock language="diff">{GitDiff}</CodeBlock>
  </TabItem>
</Tabs>

From the diff, we can see this change will:

1. Reconfigure the Blackbox Exporter host from `prometheus-blackbox-exporter` to `blackbox`.
2. Have no effect on the Blackbox service port, as it was already using the default `9115`.
3. Reconfigure Prometheus to query the Blackbox Exporter at the correct host and port, `blackbox:9115`.

Without this change, Prometheus incorrectly assumed Blackbox was listening at
`blackbox` on port `80` when it was actually listening at
`prometheus-blackbox-exporter` on port `9115`. Going forward, changing the
Blackbox host or port will reconfigure both charts correctly.

Commit the changes and proceed to deploy them.

import ReviewingChangesGitCommit from '!!raw-loader!./_helm-values/script-02-helm-values/reviewing-changes-git-commit.sh';
import ReviewingChangesGitOutput from '!!raw-loader!./_helm-values/script-02-helm-values/reviewing-changes-git-output.txt';

<Tabs groupId="F8C9A98D-DE1E-4EF6-92C1-017A9166F6C7">
  <TabItem value="command" label="Command">
    <CodeBlock language="bash">{ReviewingChangesGitCommit}</CodeBlock>
  </TabItem>
  <TabItem value="output" label="Output">
    <CodeBlock language="txt">{ReviewingChangesGitOutput}</CodeBlock>
  </TabItem>
</Tabs>

## Trying Locally

Optionally, apply the manifests rendered by Holos to a [Local Cluster].

## Next Steps

In this tutorial, we learned how Holos simplifies the holistic integration of
the [prometheus] and [blackbox] charts, ensuring they are configured
consistently. By using Holos, we overcome the limitations of relying solely on
Helm, which lacks an effective method to configure both charts to use the same
service endpoint.

[rendered manifests pattern]: https://akuity.io/blog/the-rendered-manifests-pattern
[prometheus]: https://github.com/prometheus-community/helm-charts/tree/prometheus-25.27.0/charts/prometheus
[blackbox]: https://github.com/prometheus-community/helm-charts/tree/prometheus-blackbox-exporter-9.0.1/charts/prometheus-blackbox-exporter
[httpbin]: https://github.com/mccutchen/go-httpbin/tree/v2.15.0
[CUE module standards]: https://cuelang.org/docs/concept/modules-packages-instances/
[Config Schema]: #config-schema

[Technical Overview]: ./overview.mdx
[Local Cluster]: ../topics/local-cluster.mdx
