Deploy Helm Charts with Spinnaker

Spinnaker + Helm = ❤️

As the Kubernetes community has continued to explore CI/CD solutions for the space, some exciting patterns have emerged. Of these patterns, one of the most useful has been the templating Kubernetes manifests and using those templates to create consistent environments through the application lifecycle. There are many tools that aim to solve this problem, but only one has clearly defined themselves as the leader: Helm.

In this blog post I’ll talk a bit about what Helm is and what makes it a great solution for its problem space, and then I’ll talk about how you can utilize the power of Helm’s templating and the best-in-class deployment tool, Spinnaker, to get the most out of your application delivery to Kubernetes!

What is Helm?

Helm is a purpose-built tool for packaging Kubernetes manifests for easy templating and reuse. It does this by packaging templated Kubernetes manifests into Charts and allows users to supply simplified template "Values". Helm then uses these values to render the manifests into their final form which are then sent to its server side component, Tiller. As application requirements change, these Charts and Values are updated and then deployed by running helm install [chart-name] or helm upgrade [release-name] [chart-name].

Why Spinnaker and not Helm?

As a templating tool, Helm is fantastic. It provides the Kubernetes community with an extremely powerful way to package, share and manage complicated application architectures. However, the story around deploying these Charts is still as complicated as it is when deploying vanilla Kubernetes manifests. Once your deployment reaches beyond what helm install can accomodate, you have to find other ways to orchestrate your rollout. Unfortunately, Helm itself doesn't support advanced use cases such as Canary or Blue/Green deployments which means it's left up to the user to implement. Spinnaker, on the other hand, has had support for these advanced deployment strategies since its inception which puts it in a prime position to solve this problem.

Templating Strategies

Before we talk about how to use Helm with Spinnaker we need to talk about the different ways we can template Kubernetes manifests. There are 2 different approaches we can take when templating our manifests with Helm and they both involve the time at which the templates are rendered.

Deploy Time (JIT, Just in Time)
This is the most common way Helm charts are used. Just before a Helm chart is deployed, a file with template values is provided and the manifests are evaluated. The downside with this approach is that any errors in your templating or manifests won't be caught until a deployment has failed. In some cases, these errors may cause downtime if the manifest syntax is technically correct, but not what was intended. These types of errors are more difficult to track down because Helm doesn't do a great job of communicating what's actually been rendered and installed.

Build Time (Predeployment)
Another strategy for templating manifests involves treating the output of your rendered Chart as an artifact of your build process. When using this strategy, instead of deploying your Helm chart, you simply render the Helm chart (using your values file) and store the resulting manifests somewhere for retrieval and deployment at a later time. Currently, this is the most well supported approach for use within Spinnaker as it treats your manifests as another artifact in the pipeline.
Ideally, Spinnaker will support both strategies out of the box so that Helm users have an easier time adopting Spinnaker than they would otherwise.

Using Helm with Spinnaker

Based the above use cases, we can now define two ways of using Helm with Spinnaker.

  1. Storing your manifests as artifacts

    As mentioned above, during the build stage of a CI pipeline, you can render your Helm charts using something like helm-template and store those manifests in a separate artifact store like AWS S3 or Google GCS. Since Spinnaker supports retrieving Kubernetes manifests from these sources natively, your pipeline can take over and deploy them whenever they change. By setting up a Pub/Sub trigger for when bucket contents change, you can make the transition from build to deployment seamlessly.

  2. Using the Bake (Manifest) Stage - Coming Soon

    As part of a larger templating effort within the Spinnaker community, we are currently exploring what it looks like to integrate popular templating tools like Helm, Jsonnet/Ksonnet, Jinja etc. Currently, there is work being done to add a Bake (Manifest) stage that will allow users to pull a Helm chart directly from their Chart repository and evaluate it, with values, as part of their pipeline execution. In a manner similar to the above, Charts and values are treated as artifacts and evaulated by Rosco (the image/manifest bakery) using the desired templating engine. The manifests generated as part of this stage can then be deployed in a Deploy (Manifest) stage.

As Spinnaker starts to converge on existing Kubernetes practices, it's important that the community looks at what is working and aim to support it. In this case, Helm is a widely used tool for deploying to Kubernetes that works really well for managing multi-environment configuration of similar resources. By pairing Helm and Spinnaker together we achieve best-in-class templating and best-in-class deployments while supporting pre-existing workflows. Who says you can't have your cake and eat it too?