Generating Kubernetes Manifests
In Anemos, you can define all your Kubernetes manifests in a single file using JavaScript. You can import other local and remote files, use variables, and even create functions to generate complex manifests. You can also use NPM packages and a more structured approach to define your manifests, but that's not the focus of this tutorial.
Let's start with a simple index.js
file that will generate a Kubernetes manifests for us and then
we will inspect how it works.
const anemos = require("@ohayocorp/anemos");
const builder = new anemos.Builder("1.31", anemos.KubernetesDistribution.Minikube, anemos.EnvironmentType.Development);
builder.addDocument(
`pod.yaml`,
`
apiVersion: v1
kind: Pod
metadata:
name: example-app
namespace: default
spec:
containers:
- name: app
image: nginx
ports:
- containerPort: 80
`);
builder.build();
Explaining the Code
const anemos = require("@ohayocorp/anemos");
This line imports the Anemos library. Although imported like any other JavaScript library, the core library is implemented in native code, eliminating the need for dependencies.
const builder = new anemos.Builder("1.31", anemos.KubernetesDistribution.Minikube, anemos.EnvironmentType.Development);
Here, we instantiate the anemos.Builder
class. The Builder
takes information about the target
Kubernetes cluster and the deployment environment (e.g., development, test, production). This context
allows Anemos packages to tailor the generated manifests to the specific environment. For instance, packages can
generate OpenShift Route
s instead of Ingress
definitions if the distribution is OpenShift, or adjust replica
counts based on the environment type.
builder.addDocument(
`pod.yaml`,
`
apiVersion: v1
kind: Pod
metadata:
name: example-app
namespace: default
spec:
containers:
- name: app
image: nginx
ports:
- containerPort: 80
`);
This code snippet defines a Pod manifest using a YAML string. Documents that are added to the Builder
are output as Kubernetes manifests. We will see how to customize these manifests below.
builder.build();
This line invokes the build
method, which orchestrates the manifest generation process.
Generating the Manifests
To generate the Kubernetes manifests, run the following command in your terminal:
anemos build index.js
This command will execute the index.js
file, and Anemos will generate the Kubernetes manifests based on the
defined documents. The output will be written into the output
directory by default. Our pod definition will be
the same as the one defined in the index.js
file, since we did not customize it further.
apiVersion: v1
kind: Pod
metadata:
name: example-app
namespace: default
spec:
containers:
- name: app
image: nginx
ports:
- containerPort: 80
Customizing the Manifests
It is possible to customize the generated manifests in two ways: by using variables when defining the manifests
or by modifying the document during the modify
step.
Using Variables
You can use variables to define dynamic values in your manifests. For example, you can define variables for
name, namespace, and image and use it in your Pod definition. JavaScript template literals, text enclosed
in backticks (``
), allow you to embed expressions within strings (${expression}
), making it easy
to use variables in your manifests.
const anemos = require("@ohayocorp/anemos");
const builder = new anemos.Builder("1.31", anemos.KubernetesDistribution.Minikube, anemos.EnvironmentType.Development);
const name = "example-app";
const namespace = "default";
const image = "nginx";
builder.addDocument(
`pod.yaml`,
`
apiVersion: v1
kind: Pod
metadata:
name: ${name}
namespace: ${namespace}
spec:
containers:
- name: app
image: ${image}
ports:
- containerPort: 80
`);
builder.build();
Modifying the Document
You can also modify the document during the modify
step. This allows you to change the manifest after it has been
generated but before it is output. You can use the onModify
method of the Builder
to add a callback that will
be executed during the modify
step.
The callback receives a context
object that you can use to access the generated documents. Here we get the Pod document
we have defined earlier and add a label to it.
- index.js
- pod.yaml
const anemos = require("@ohayocorp/anemos");
const builder = new anemos.Builder("1.31", anemos.KubernetesDistribution.Minikube, anemos.EnvironmentType.Development);
builder.addDocument(
`pod.yaml`,
`
apiVersion: v1
kind: Pod
metadata:
name: example-app
namespace: default
spec:
containers:
- name: app
image: nginx
ports:
- containerPort: 80
`);
builder.onModify((context) => {
// Add a label to the Pod.
context
.getDocument("pod.yaml")
.setLabel("app", "example-app");
});
builder.build();
apiVersion: v1
kind: Pod
metadata:
name: example-app
namespace: default
labels:
app: example-app
spec:
containers:
- name: app
image: nginx
ports:
- containerPort: 80