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.
- TypeScript
- JavaScript
import * as anemos from "@ohayocorp/anemos";
const builder = new anemos.Builder("1.31", anemos.KubernetesDistribution.Minikube, anemos.EnvironmentType.Development);
builder.onStep(anemos.steps.generateResources, (context: anemos.BuildContext) => {
// Download hello world Helm chart to the directory where the index.js file, that is created
// by the tsc compiler, is located before running this script:
// https://github.com/crowdsecurity/helm-charts/releases/download/helloworld-0.2.1/helloworld-0.2.1.tgz
const chart = new anemos.HelmChart(`${anemos.file.currentScriptDirectory()}/helloworld-0.2.1.tgz`);
const values = anemos.dedent(`
replicaCount: 2
image:
repository: hashicorp/http-echo
tag: 1.0.0
`);
const documentGroup = chart.generate(context, {
releaseName: "hello-world",
namespace: "default",
values: values
});
for (const document of documentGroup.documents) {
document.getLabels()!.remove("helm.sh/chart");
document.setLabel("example", "value");
}
context.addDocumentGroup(documentGroup);
});
builder.build();
const anemos = require("@ohayocorp/anemos");
const builder = new anemos.Builder("1.31", anemos.KubernetesDistribution.Minikube, anemos.EnvironmentType.Development);
builder.onStep(anemos.steps.generateResources, (context) => {
// Download hello world Helm chart to the current script directory before running this script:
// https://github.com/crowdsecurity/helm-charts/releases/download/helloworld-0.2.1/helloworld-0.2.1.tgz
const chart = new anemos.HelmChart(`${anemos.file.currentScriptDirectory()}/helloworld-0.2.1.tgz`);
const values = anemos.dedent(`
replicaCount: 2
image:
repository: hashicorp/http-echo
tag: 1.0.0
`);
const documentGroup = chart.generate(context, {
releaseName: "hello-world",
namespace: "default",
values: values
});
for (const document of documentGroup.documents) {
document.getLabels().remove("helm.sh/chart");
document.setLabel("example", "value");
}
context.addDocumentGroup(documentGroup);
});
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/name: helloworld
app.kubernetes.io/instance: hello-world
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
example: value
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: helloworld
app.kubernetes.io/instance: hello-world
template:
metadata:
labels:
app.kubernetes.io/name: helloworld
app.kubernetes.io/instance: hello-world
spec:
serviceAccountName: helloworld
securityContext: {}
containers:
- name: helloworld
securityContext: {}
image: "hashicorp/http-echo:1.0.0"
imagePullPolicy: IfNotPresent
args:
- "-text=helloworld !"
ports:
- name: http
containerPort: 5678
protocol: TCP
livenessProbe:
httpGet:
path: /
port: 5678
readinessProbe:
httpGet:
path: /
port: 5678
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
apiVersion: v1
kind: Service
metadata:
name: hello-world-helloworld
labels:
app.kubernetes.io/name: helloworld
app.kubernetes.io/instance: hello-world
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
example: value
spec:
type: ClusterIP
ports:
- port: 5678
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: helloworld
app.kubernetes.io/instance: hello-world
apiVersion: v1
kind: ServiceAccount
metadata:
name: helloworld
labels:
app.kubernetes.io/name: helloworld
app.kubernetes.io/instance: hello-world
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
example: value