Helm Interoperability
Helm is the most popular package manager for Kubernetes, and many Kubernetes applications are distributed as Helm charts. Since rewriting all your Helm charts in Anemos may not be practical in short term, Anemos provides a way to use Helm charts in your Anemos applications. This allows you to use existing Helm charts in your Anemos applications while migrating to Anemos at your own pace.
For the migration process, you can define your options as JavaScript objects, then convert these objects to Helm values and pass them to Helm for rendering. You can support your Helm chart as long as you want and update the chart file in Anemos project to keep them in sync. Then when you are ready, you can generate your manifests using Anemos, removing the manifests generated from Helm charts. You can even migrate your templates one by one, replacing the manifests generated from Helm charts with manifests generated by Anemos.
Generating Anemos documents from Helm charts is pretty straightforward. Following example is a complete
Anemos script that generates manifests from a Helm chart, modifies them to remove the helm.sh/chart label,
and add an example label.
- JavaScript
const anemos = require("@ohayocorp/anemos");
const builder = new anemos.Builder();
// You can also use a local file path instead of a URL such as: ./path/to/helloworld-0.2.1.tgz
builder.addHelmChart(
"https://github.com/crowdsecurity/helm-charts/releases/download/helloworld-0.2.1/helloworld-0.2.1.tgz",
"hello-world",
`
replicaCount: 2
image:
repository: hashicorp/http-echo
tag: 1.0.0
`);
builder.onModify(context => {
for (const document of context.getDocumentGroup("hello-world").documents) {
const labels = document.metadata?.labels;
if (labels) {
delete labels["helm.sh/chart"];
}
document.setLabel("example", "value");
}
});
builder.build();
Building this script will generate the following Kubernetes manifests from the specified Helm chart and save them to the Anemos output directory.
- hello-world/deployment.yaml
- hello-world/service.yaml
- hello-world/serviceaccount.yaml
apiVersion: "apps/v1"
kind: "Deployment"
metadata:
name: "hello-world-helloworld"
labels:
app.kubernetes.io/instance: "hello-world"
app.kubernetes.io/managed-by: "Helm"
app.kubernetes.io/name: "helloworld"
app.kubernetes.io/version: "1.16.0"
example: "value"
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/instance: "hello-world"
app.kubernetes.io/name: "helloworld"
template:
metadata:
labels:
app.kubernetes.io/instance: "hello-world"
app.kubernetes.io/name: "helloworld"
spec:
containers:
- name: "helloworld"
image: "hashicorp/http-echo:1.0.0"
imagePullPolicy: "IfNotPresent"
args:
- "-text=helloworld !"
ports:
- name: "http"
containerPort: 5678
protocol: "TCP"
securityContext: {}
resources:
limits:
cpu: "100m"
memory: "128Mi"
requests:
cpu: "100m"
memory: "128Mi"
livenessProbe:
httpGet:
path: "/"
port: 5678
readinessProbe:
httpGet:
path: "/"
port: 5678
serviceAccountName: "helloworld"
securityContext: {}
apiVersion: "v1"
kind: "Service"
metadata:
name: "hello-world-helloworld"
labels:
app.kubernetes.io/instance: "hello-world"
app.kubernetes.io/managed-by: "Helm"
app.kubernetes.io/name: "helloworld"
app.kubernetes.io/version: "1.16.0"
example: "value"
spec:
type: "ClusterIP"
ports:
- port: 5678
targetPort: "http"
protocol: "TCP"
name: "http"
selector:
app.kubernetes.io/instance: "hello-world"
app.kubernetes.io/name: "helloworld"
apiVersion: "v1"
kind: "ServiceAccount"
metadata:
name: "helloworld"
labels:
app.kubernetes.io/instance: "hello-world"
app.kubernetes.io/managed-by: "Helm"
app.kubernetes.io/name: "helloworld"
app.kubernetes.io/version: "1.16.0"
example: "value"