Banzai Cloud is now part of Cisco

Banzai Cloud Logo Close
Home Products Benefits Blog Company Contact

Manage Helm repositories and deploy charts via REST

Author Laszlo Puskas

The content of this page hasn't been updated for years and might refer to discontinued products and projects.

During the development of our open source Pipeline PaaS, we introduced some handy features to help deal with deployments. We deploy most of our applications as Helm releases, so we needed a way to interact programatically (using gRPC) and to use a UI (RESTful API) with Helm. In order to do that with Pipeline, we introduced a very useful feature that manages Helm repositories and deploys applications with Helm to Kubernetes, using RESTful API calls.

Note that, besides deploying releases, Pipeline has a RESTful API capable of provisioning Kubernetes clusters on all major cloud providers, such as, AWS, Azure AKS and Google GKE.

Introduction to Helm architecture 🔗︎

Helm is the package manager for Kubernetes, and it’s the best way to find, share, and deploy software to k8s. It’s built on three key ingredients:

  • Charts - bundles of information that are necessary to create the instances of Kubernetes applications
  • Config - which contains configuration information that can be merged into a packaged chart to create a releasable object
  • Release - a running instance of a chart, combined with a specific config

Helm is also built on two major architectural components:

The Helm Client, a command line tool with the following responsibilities

  • Interacts with the Tiller server
  • Sends charts to be installed
  • Upgrades or uninstalls existing releases
  • Manages repositories

The Tiller Server, an in-cluster server with the following responsibilities:

  • Interacts with the Helm client
  • Interfaces the Kubernetes API server
  • Combines a chart and configuration to build a release
  • Installs charts and tracks their release
  • Upgrades and uninstalls charts

Both the Helm client and Tiller are written in Go, and use gRPC to interact. Tiller (as the server component running inside Kubernetes) provides a gRPC server in order to connect with the client, and uses the k8s client library to communicate with Kubernetes. It does not require it’s own database, since the information is stored within Kubernetes as ConfigMaps.

Deployments through REST 🔗︎

As you can see, in order to interact with Helm (basically Tiller), you have to use the CLI or write gRPC code and talk directly with Tiller. For the Pipeline PaaS, and for our end users, we needed to build a REST-based API to speak with the Tiller server. This implementation resides within the helm package, and is exposed by Pipeline, using a Gin server. The current authentication is pretty basic, however, once we merge this PR, it will be OAuth2 token based - and the external and the internal access will be based on that. Note that Kubernetes supports OAuth2.

Now lets see how you can access and deploy a Kubernetes application, using the REST endpoints with curl. The first thing you might need is a kubeconfig, that is, if you’d also like to validate the deployment using the Helm CLI. Beside provisioning Kubernetes clusters in the cloud, Pipeline can connect to existing clusters, regardless of whether they’re cloud-based or on-prem.

Get the Kubernetes config

To get the kubeconfig perform the following REST call:

curl --request GET \
  --url 'http://{{url}}/api/v1/orgs/{{org_id}}/clusters/{{cluster_id}}/config' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3BpcGVsaW5lLmJhbnphaWNsb3VkLmNvbSIsImp0aSI6IjdhZjNhOGZkLTYxMjYtNDM0Zi04YzdmLWJkNGMwZTc2YTk4ZCIsImlhdCI6MTUyMzM2Mzk0NiwiaXNzIjoiaHR0cHM6Ly9iYW56YWljbG91ZC5jb20vIiwic3ViIjoiMSIsInNjb3BlIjoiYXBpOmludm9rZSIsInR5cGUiOiJ1c2VyIn0.K6ubOxskphAJGwRv7y3ANxORKXcrV96i4oX8hNfeYSk` \
  --header 'Content-Type: application/json'
Add a Helm repository

You can add any Helm repository from which to deploy releases, via:

curl --request POST \
  --url 'http://{{url}}/api/v1/orgs/{{org_id}}/clusters/{{cluster_id}}/helm/repos' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3BpcGVsaW5lLmJhbnphaWNsb3VkLmNvbSIsImp0aSI6IjdhZjNhOGZkLTYxMjYtNDM0Zi04YzdmLWJkNGMwZTc2YTk4ZCIsImlhdCI6MTUyMzM2Mzk0NiwiaXNzIjoiaHR0cHM6Ly9iYW56YWljbG91ZC5jb20vIiwic3ViIjoiMSIsInNjb3BlIjoiYXBpOmludm9rZSIsInR5cGUiOiJ1c2VyIn0.K6ubOxskphAJGwRv7y3ANxORKXcrV96i4oX8hNfeYSk` \
  --header 'Content-Type: application/json' \
  --data '{"name": "spark-shuffle"}'
List Helm repositories

List the existing Helm repositories, like this:

curl --request GET \
  --url 'http://{{url}}/api/v1/orgs/{{org_id}}/clusters/{{cluster_id}}/helm/repos' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3BpcGVsaW5lLmJhbnphaWNsb3VkLmNvbSIsImp0aSI6IjdhZjNhOGZkLTYxMjYtNDM0Zi04YzdmLWJkNGMwZTc2YTk4ZCIsImlhdCI6MTUyMzM2Mzk0NiwiaXNzIjoiaHR0cHM6Ly9iYW56YWljbG91ZC5jb20vIiwic3ViIjoiMSIsInNjb3BlIjoiYXBpOmludm9rZSIsInR5cGUiOiJ1c2VyIn0.K6ubOxskphAJGwRv7y3ANxORKXcrV96i4oX8hNfeYSk` \
  --header 'Content-Type: application/json' \
Delete a Helm repository

Delete a Helm repository like so:

curl --request DELETE \
  --url 'http://{{url}}/api/v1/orgs/{{org_id}}/clusters/{{cluster_id}}/helm/repos/{{repo_name}}/' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3BpcGVsaW5lLmJhbnphaWNsb3VkLmNvbSIsImp0aSI6IjdhZjNhOGZkLTYxMjYtNDM0Zi04YzdmLWJkNGMwZTc2YTk4ZCIsImlhdCI6MTUyMzM2Mzk0NiwiaXNzIjoiaHR0cHM6Ly9iYW56YWljbG91ZC5jb20vIiwic3ViIjoiMSIsInNjb3BlIjoiYXBpOmludm9rZSIsInR5cGUiOiJ1c2VyIn0.K6ubOxskphAJGwRv7y3ANxORKXcrV96i4oX8hNfeYSk` \
  --header 'Content-Type: application/json' \
Update Helm repositories

Update the Helm repository:

curl --request PUT \
  --url 'http://{{url}}/api/v1/orgs/{{org_id}}/clusters/{{cluster_id}}/helm/repos/{{repo_name}}/update/' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3BpcGVsaW5lLmJhbnphaWNsb3VkLmNvbSIsImp0aSI6IjdhZjNhOGZkLTYxMjYtNDM0Zi04YzdmLWJkNGMwZTc2YTk4ZCIsImlhdCI6MTUyMzM2Mzk0NiwiaXNzIjoiaHR0cHM6Ly9iYW56YWljbG91ZC5jb20vIiwic3ViIjoiMSIsInNjb3BlIjoiYXBpOmludm9rZSIsInR5cGUiOiJ1c2VyIn0.K6ubOxskphAJGwRv7y3ANxORKXcrV96i4oX8hNfeYSk` \
  --header 'Content-Type: application/json' \
List charts within a Helm repository

This is how to list the charts within a Helm repository:

curl --request GET \
  --url 'http://{{url}}/api/v1/orgs/{{{org_id}}}/clusters/{{cluster_id}}/helm/charts/' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3BpcGVsaW5lLmJhbnphaWNsb3VkLmNvbSIsImp0aSI6IjdhZjNhOGZkLTYxMjYtNDM0Zi04YzdmLWJkNGMwZTc2YTk4ZCIsImlhdCI6MTUyMzM2Mzk0NiwiaXNzIjoiaHR0cHM6Ly9iYW56YWljbG91ZC5jb20vIiwic3ViIjoiMSIsInNjb3BlIjoiYXBpOmludm9rZSIsInR5cGUiOiJ1c2VyIn0.K6ubOxskphAJGwRv7y3ANxORKXcrV96i4oX8hNfeYSk` \
  --header 'Content-Type: application/json' \
Post a deployment

Now you can add a deployment with the following REST call:

curl --request POST \
  --url 'http://{{url}}/api/v1/orgs/{{org_id}}/clusters/{{cluster_id}}/deployments' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3BpcGVsaW5lLmJhbnphaWNsb3VkLmNvbSIsImp0aSI6IjdhZjNhOGZkLTYxMjYtNDM0Zi04YzdmLWJkNGMwZTc2YTk4ZCIsImlhdCI6MTUyMzM2Mzk0NiwiaXNzIjoiaHR0cHM6Ly9iYW56YWljbG91ZC5jb20vIiwic3ViIjoiMSIsInNjb3BlIjoiYXBpOmludm9rZSIsInR5cGUiOiJ1c2VyIn0.K6ubOxskphAJGwRv7y3ANxORKXcrV96i4oX8hNfeYSk` \
  --header 'Content-Type: application/json' \
  --data '{
      "name": "stable",
      "url": "https://kubernetes-charts.storage.googleapis.com"
    }'
Check deployment status

Once the deployment is posted, you can check its status with this HEAD call:

curl --request HEAD \
  --url 'http://{{url}}/api/v1/orgs/{{org_id}}/clusters/{{cluster_id}}/deployments/{{deployment_name}}' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3BpcGVsaW5lLmJhbnphaWNsb3VkLmNvbSIsImp0aSI6IjdhZjNhOGZkLTYxMjYtNDM0Zi04YzdmLWJkNGMwZTc2YTk4ZCIsImlhdCI6MTUyMzM2Mzk0NiwiaXNzIjoiaHR0cHM6Ly9iYW56YWljbG91ZC5jb20vIiwic3ViIjoiMSIsInNjb3BlIjoiYXBpOmludm9rZSIsInR5cGUiOiJ1c2VyIn0.K6ubOxskphAJGwRv7y3ANxORKXcrV96i4oX8hNfeYSk` \
  --header 'Content-Type: application/json'
Upgrade a deployment

Deployments can be upgraded with the following PUT call:

curl --request PUT \
  --url 'http://{{url}}/api/v1/orgs/{{org_id}}/clusters/{{cluster_id}}/deployments/{{deployment_name}}' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3BpcGVsaW5lLmJhbnphaWNsb3VkLmNvbSIsImp0aSI6IjdhZjNhOGZkLTYxMjYtNDM0Zi04YzdmLWJkNGMwZTc2YTk4ZCIsImlhdCI6MTUyMzM2Mzk0NiwiaXNzIjoiaHR0cHM6Ly9iYW56YWljbG91ZC5jb20vIiwic3ViIjoiMSIsInNjb3BlIjoiYXBpOmludm9rZSIsInR5cGUiOiJ1c2VyIn0.K6ubOxskphAJGwRv7y3ANxORKXcrV96i4oX8hNfeYSk` \
  --header 'Content-Type: application/x-www-form-urlencoded'
Delete a deployment

Finally, a deployment can be deleted as well:

curl --request DELETE \
  --url 'http://{{url}}/api/v1/orgs/{{org_id}}/clusters/{{cluster_id}}/deployments/{{deployment_name}}' \
  --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwczovL3BpcGVsaW5lLmJhbnphaWNsb3VkLmNvbSIsImp0aSI6IjdhZjNhOGZkLTYxMjYtNDM0Zi04YzdmLWJkNGMwZTc2YTk4ZCIsImlhdCI6MTUyMzM2Mzk0NiwiaXNzIjoiaHR0cHM6Ly9iYW56YWljbG91ZC5jb20vIiwic3ViIjoiMSIsInNjb3BlIjoiYXBpOmludm9rZSIsInR5cGUiOiJ1c2VyIn0.K6ubOxskphAJGwRv7y3ANxORKXcrV96i4oX8hNfeYSk` \
  --header 'Content-Type: application/x-www-form-urlencoded'

We use these REST API calls, too, and have collected them in a Postman collection:

Run in Postman

Additionally, we have created a Docker image that can be used to run the collection in a containerized manner. You can build the image from our GitHub repository or pull it from the Docker Hub.

Learn more about Helm: