When deploying applications to Kubernetes, there are currently a lot of options. One of the most popular options is Helm. For those who are unfamiliar, Helm allows users to create “Charts” that define how to deploy an application. These Charts are made up of templates for things like Deployments
, ConfigMaps
, Secrets
and other Kubernetes resources. When a Chart is installed, users of Helm select a file that defines a set of values (the values file) which are used to replace templated sections of the manifests defined in the Chart.
Helm Charts have become a very common way to define how an application should look from the perspective of Kubernetes. They can be made as static or dynamic as you like and there is a lot of great tooling built around Helm as it has become more stable since its 2.0 release. However, there are still some operational issues that are left as an exercise to the user. At Skuid, the biggest of these issues was what to do with all of our values files. While storing them in a Git repository was an option, we didn’t like the idea of having to manage encryption whenever we needed to update these files. Also, diffs become somewhat useless because encryption obscures the meaningful changes.
Instead of kicking the can down the road and dealing with it later, we developed a Helm plugin called Helm Value Store. Written in Go, this plugin allows users to manage their values files in a “helm native” way. It has subcommands for creating, updating and deleting values and also supports installing a Helm chart using values stored in a remote datastore like DynamoDB or GCP Datastore.
This post is meant to show how Skuid uses Helm Value Store and explain some of the advantages we’ve found while working with it over the last year.
How it works
Helm Value Store (or helm-value-store
) plugs into Helm to add extra functionality around managing values files. By default, helm-value-store
will use DynamoDB as a backing datastore. A helm-value-store
release is made up of a few pieces of information.
- The Helm Chart you want to install. If you can
helm install
the Chart, you can use it withhelm-value-store
. - The version of the chart you want to use.
- The name of the Helm release.
- The namespace to install the release in.
- Any labels you would like to apply. These can be used to apply releases in bulk.
- The values to associate with your release.
The release can simply be created by issuing the following command:
$ helm value-store create --name my-release \
--namespace my-namespace \
--chart myrepo/mychart \
--version 0.1.0 \
--labels environment=prod \
--labels region=us=west-2 \
--values my-values-file.yaml
A record will then be created in your datastore and a unique ID will be assigned to it. You can use this ID to install your charts. If we issue a list
command, we can see all of the releases we currently manage with helm-value-store
.
$ helm value-store list
UniqueId Name Namespace Chart Version Labels Values
6fad4903-58ec-446f-bda4-bd39c4ff96aa alertmanager default skuid/alertmanager 0.1.0 map[region:us-west-2 environment:prod] 1.1K
8795d237-adac-4b91-b55b-bb0f1e258a32 exporter default skuid/prom-node-exporter 0.1.0 map[region:us-west-2 environment:prod] 279B
22c8f1e8-82fc-4eb0-b1f9-2c8d50b2df3b prom1 default skuid/prometheus 0.1.2 map[region:us-west-2 environment:prod] 1.1K
ad01e6d4-05ec-4f18-ba6a-87cd49e6be25 alertmanager default skuid/alertmanager 0.1.0 map[environment:test region:us-west-2] 0
84c28f16-0bc2-4384-9e21-8077e3320aad exporter default skuid/prom-node-exporter 0.1.0 map[environment:test region:us-west-2] 274B
fa718433-d76e-4edd-b263-9c50246c2f80 prom1 default skuid/prometheus 0.1.2 map[environment:test region:us-west-2] 0
080f9a8a-10dd-4c2f-8588-8c3c4980553f alertmanager default skuid/alertmanager 0.1.0 map[region:eu-central-1 environment:prod] 1.3K
49582465-85fd-49ce-9778-4bf9d1162a2e exporter default skuid/prom-node-exporter 0.1.0 map[environment:prod region:eu-central-1] 272B
34754bde-3114-43ca-bb23-1d4e16f12f95 prom1 default skuid/prometheus 0.1.2 map[environment:prod region:eu-central-1] 0
$ helm value-store list -s environment=test
UniqueId Name Namespace Chart Version Labels
ad01e6d4-05ec-4f18-ba6a-87cd49e6be25 alertmanager default skuid/alertmanager 0.1.0 map[environment:test region:us-west-2] 0
84c28f16-0bc2-4384-9e21-8077e3320aad exporter default skuid/prom-node-exporter 0.1.0 map[environment:test region:us-west-2] 274B
fa718433-d76e-4edd-b263-9c50246c2f80 prom1 default skuid/prometheus 0.1.2 map[environment:test region:us-west-2] 0
As you can see, we have multiple relesaes of the same chart for different environments. The chart and version are the same, but the underlying values are different. Installing a chart is as easy, if not easier, than installing your chart with plain ol’ Helm.
# this will install skuid/alertmanager:0.1.0 with the values for environment=test,region=us-west-2
$ helm value-store install --uuid ad01e6d4-05ec-4f18-ba6a-87cd49e6be25
If you ever need to update your values, you can use get-values
to download the values and write them to a file. Once you’ve made your updates, you can then use the update
command to replace them.
$ helm value-store get-values --uuid ad01e6d4-05ec-4f18-ba6a-87cd49e6be25 > alertmanager.values.yaml
$ vim alertmanager.values.yaml # make your edits
$ helm value-store update --uuid ad01e6d4-05ec-4f18-ba6a-87cd49e6be25 -f alertmanager.values.yaml
$ helm value-store install --uuid ad01e6d4-05ec-4f18-ba6a-87cd49e6be25 # rollout your new changes
Under the hood, helm-value-store
is doing everything helm
would do when installing a chart. However, instead of using a local values file, it will download the values from the release store and use those to compile the Chart templates.
Taking it one step further - UI/Server
As we began using helm-value-store
internally, we found that the workflow became a bit cumbersome when rolling changes out to multiple cluster. To use Helm, you need to access to the Tiller server running in your cluster. For us, this meant jumping between VPN servers to install changes in different regions. To make matters worse, iterative edits to values became more difficult to manage as each edit requires 3 steps to roll out. It was also difficult to see, at a glance, the state of these values. We needed a better solution. Fortunately, we work at Skuid.
If you aren’t familiar with Skuid, you can see what we’re about here. Skuid is a cloud based UI/UX platform as a service. You can use Skuid to build apps on top of your data, wherever it lives. Using the power of Skuid and its native DynamoDB integration, we built a custom interface for managing our values across all of our environments. This interface gives our team a common place to make changes and roll them out.
To do this, we added an API server to helm-value-store
. This server exposes a /apply
endpoint which invokes an install
. It accepts the unique ID of your release and installs it into your target environment. We then launched an instance of this server in each of our Kubernetes clusters. To secure our new API, we rely on Google OAuth to authenticate connections to the service. When interacting with our new interface, users authenticate with Google, and subsequent requests to our API add an Authorization
header obtained by Skuid. Authorization is then performed based on the email domain of the user as well as their membership to a specific Google Group. This prevents unauthenticated and unauthorized access which is actually a step above the capabilities of Tiller, Helm’s server side component.
With the introduction of this interface, we’ve been able to transform the way we manage Helm chart installations on a day-to-day basis. We can update values and roll changes out without having to jump between VPNs or issuing a single command.
Conclusion
Helm has been a great tool for us when it comes to managing resource in Kubernetes. Since the majority of those resources do not need CI/CD pipelines, managing them with our UI has made working with them even better. We plan to open source our UI for anyone who wants to use it in the coming weeks. We look forward to sharing the power of Skuid and helm-value-store
with the rest of the Kubernetes community!
If you have any suggestions or would like to see additional functionality in helm-value-store
, please let us know! We are always accepting pull requests!