After deploying a Helm chart into Kubernetes, it's easy to query the resources using kubectl with JSONPath expressions. That's not always an option, though. I recently needed to calculate the total CPU, memory, and storage allocated for a production sized deployment that wasn't deployed yet, but I didn't have a non-production environment large enough to deploy and then query. Wouldn't it be nice if you could query Helm charts using JSON?
The solution is to chain these 3 steps together:
helm templateto produce the YAML for the resources.
- Use Python to convert the YAML to JSON.
- Query the JSON using jq, a command-line JSON processor.
Start by installing jq. On FreeBSD, it's as simple as running
pkg install jq.
Next, create an alias to convert YAML documents into JSON. I'm not taking credit for this code snippet—it's pretty much what you'll find all over the web if you search for ways to convert YAML to JSON—although I had to tweak it to make it work for me. Note that the alias is named yamls2json (plural) because it expects multiple YAML documents as input, which is what
helm template provides. Copy this snippet into your ~/.bashrc file:
alias yamls2json="python2 -c 'import json, sys, yaml; from yaml import Loader as sl; docs = list(yaml.load_all(sys.stdin.read(), Loader=sl)); print "\""["\""; for i in range(len(docs)): json.dump(docs[i], sys.stdout); if i != len(docs) - 1: print "\"",\\n "\""; print "\"\\n"]\\n"\""; '"
Then source the file so the alias is available in your current shell:
Now you can run queries against Helm charts without deploying (and even specify one or more values files):
helm template my-blog bitnami/wordpress -f dev-sizing.yaml | yamls2json | jq -r '. | map(select(.spec.template.spec.containers != null)) | .metadata.name as $pod | .spec.template.spec.containers | [ $pod, .name, (.resources.limits.cpu | tostring), (.resources.requests.cpu | tostring), .resources.limits.memory, .resources.requests.memory ] | @csv' "my-blog-wordpress","wordpress","null","300m",,"512Mi" "my-blog-mariadb","mariadb","null","null",,
The output can be redirected to a CSV file with the following columns:
- Pod name
- Container name
- CPU limits
- CPU requests
- Memory limits
- Memory requests
To query persistent volume claims, use the following:
helm template my-blog bitnami/wordpress -f dev-sizing.yaml | yamls2json | jq -r '. | map(select(.spec.volumeClaimTemplates != null)) | .metadata.name as $pod | .spec.volumeClaimTemplates | [ $pod, .metadata.name, .spec.resources.requests.storage ] | @csv' "my-blog-mariadb","data","8Gi"
Output columns are:
- Pod name
- PVC name
- Storage requested
This is a very simple example, but I've found this little trick can save a lot of time when working with charts that have many subcharts and a lot of deployed resources. It also makes it much easier to compare sizing of different environments with multiple deployment options enabled or disabled.
Of course, you can query anything you want from the resources—it's not limited to sizing. Output the raw JSON to find the fields you want to query:
helm template my-blog bitnami/wordpress -f dev-sizing.yaml | yamls2json | jq '.'
Use the examples above to get started writing your own JSON queries for Helm charts.