Skip to content

k8s

stable

Generate Kubernetes YAML manifests and validate resource names and label keys for use with kubectl or CI pipelines.

use plugin k8s::{build_deployment_yaml, build_service_yaml, build_configmap_yaml, …}
12 functions Cloud
/ filter jk navigate Esc clear
Functions (12)
  1. build_deployment_yaml Generate a Deployment manifest
  2. build_service_yaml Generate a Service manifest
  3. build_configmap_yaml Generate a ConfigMap manifest
  4. build_secret_yaml Generate a Secret manifest (base64 values)
  5. build_namespace_yaml Generate a Namespace manifest
  6. build_ingress_yaml Generate an Ingress manifest
  7. build_job_yaml Generate a batch Job manifest
  8. build_pvc_yaml Generate a PersistentVolumeClaim manifest
  9. build_labels Render a YAML labels block string
  10. parse_image Parse an image reference into parts
  11. validate_resource_name Validate a Kubernetes resource name
  12. validate_label_key Validate a Kubernetes label key

Overview

k8s is a pure manifest-generation toolkit: every build_* function takes plain arguments (and occasionally a string-keyed table) and returns a ready-to-apply YAML string. There are no handles, no cluster connection, and no state — the plugin never talks to an API server, so the strings it produces are safe to print, write to a file, or pipe into kubectl apply -f -. Use it whenever you want to template Deployments, Services, ConfigMaps, Secrets, Ingresses, Jobs, and PVCs from Zolo code instead of hand-maintaining YAML.

Alongside the builders are two validators (validate_resource_name, validate_label_key) that enforce Kubernetes' RFC 1123 naming rules, and a parse_image helper that decomposes a Docker/OCI image reference into its registry, name, and tag. The mental model is simple: validate your inputs, build each manifest string, then concatenate them (separated by ---) into a single document.

Common patterns

Build a Deployment and its Service together and emit a single multi-document manifest:

use plugin k8s::{build_deployment_yaml, build_service_yaml}

let app = "api-server"
let deploy = build_deployment_yaml(app, "my-registry/api:v1.2", 3, 8080)
let svc = build_service_yaml(app, 80, 8080, "ClusterIP")
print("{deploy}\n---\n{svc}")

Validate a name before generating anything, so bad input never reaches the cluster:

use plugin k8s::{validate_resource_name, build_namespace_yaml}

let name = "team-staging"
if validate_resource_name(name) {
  print(build_namespace_yaml(name))
} else {
  print("invalid resource name: {name}")
}

Inspect an image reference, then template a Job that runs it:

use plugin k8s::{parse_image, build_job_yaml}

let ref = "my-registry.example.com/team/migrator:v2"
let parts = parse_image(ref)
print("running {parts["name"]} ({parts["tag"]}) from {parts["registry"]}")
print(build_job_yaml("db-migrate", ref, ["./migrate", "--run"]))

Generate a Deployment manifest

Generates a apps/v1 Deployment YAML manifest. replicas and port default to 1 and 80 if not provided. The name is used for the metadata name, the app label, and the selector, so a single call wires up a self-consistent Deployment.

use plugin k8s::{build_deployment_yaml}

let yaml = build_deployment_yaml("api-server", "my-registry/api:v1.2", 3, 8080)
print(yaml)

A single-replica internal worker on the default port:

use plugin k8s::{build_deployment_yaml}

let worker = build_deployment_yaml("queue-worker", "my-app/worker:latest", 1, 80)
print(worker)

Generate a Service manifest

Generates a v1 Service manifest. target_port defaults to port. type_str defaults to "ClusterIP". Common types: "ClusterIP", "NodePort", "LoadBalancer". The selector matches the app: <name> label produced by build_deployment_yaml.

use plugin k8s::{build_service_yaml}

let yaml = build_service_yaml("api-server", 80, 8080, "ClusterIP")
print(yaml)

let lb = build_service_yaml("web", 443, 443, "LoadBalancer")
print(lb)

Generate a ConfigMap manifest

Generates a v1 ConfigMap manifest from a string-keyed table of string values. Values containing YAML special characters are automatically quoted.

use plugin k8s::{build_configmap_yaml}

let yaml = build_configmap_yaml("app-config", #{
  "DATABASE_URL": "postgres://db:5432/app",
  "LOG_LEVEL": "info",
  "MAX_CONNECTIONS": "100"
})
print(yaml)

A small feature-flag config; the boolean-looking string is quoted automatically so YAML keeps it a string:

use plugin k8s::{build_configmap_yaml}

let flags = build_configmap_yaml("feature-flags", #{
  "NEW_CHECKOUT": "true",
  "REGION": "us-east"
})
print(flags)

Generate a Secret manifest (base64 values)

Generates a v1 Secret manifest of type Opaque. All values are automatically base64-encoded, so pass the plaintext and let the plugin handle the encoding.

use plugin k8s::{build_secret_yaml}

let yaml = build_secret_yaml("app-secrets", #{
  "DB_PASSWORD": "s3cr3t",
  "API_KEY": "abc123xyz"
})
print(yaml)

Generate a Namespace manifest

Generates a minimal v1 Namespace manifest.

use plugin k8s::{build_namespace_yaml}

let yaml = build_namespace_yaml("staging")
print(yaml)

Generate an Ingress manifest

Generates a networking.k8s.io/v1 Ingress manifest with a single host/path rule of pathType: Prefix. path defaults to "/". The rule routes traffic to the named Service on service_port.

use plugin k8s::{build_ingress_yaml}

let yaml = build_ingress_yaml("web-ingress", "app.example.com", "/", "web-service", 80)
print(yaml)

Route an API subpath to a dedicated backend Service:

use plugin k8s::{build_ingress_yaml}

let api = build_ingress_yaml("api-ingress", "app.example.com", "/api", "api-service", 8080)
print(api)

Generate a batch Job manifest

Generates a batch/v1 Job manifest with restartPolicy: Never and backoffLimit: 4. commands is an array of strings used as the container command. Omit it or pass an empty table to use the image's default entrypoint.

use plugin k8s::{build_job_yaml}

let yaml = build_job_yaml("db-migrate", "my-app:latest", ["./migrate", "--run"])
print(yaml)

Run a one-off backup job using the image's own entrypoint by passing an empty command list:

use plugin k8s::{build_job_yaml}

let backup = build_job_yaml("nightly-backup", "my-app/backup:latest", [])
print(backup)

Generate a PersistentVolumeClaim manifest

Generates a v1 PersistentVolumeClaim manifest. access_mode defaults to "ReadWriteOnce". storage_class is optional and is omitted from the output entirely when not supplied.

use plugin k8s::{build_pvc_yaml}

let yaml = build_pvc_yaml("data-volume", "10Gi")
print(yaml)

let ssd = build_pvc_yaml("fast-volume", "50Gi", "ReadWriteOnce", "ssd")
print(ssd)

A shared volume mounted by several pods uses ReadWriteMany:

use plugin k8s::{build_pvc_yaml}

let shared = build_pvc_yaml("shared-assets", "20Gi", "ReadWriteMany", "nfs")
print(shared)

Render a YAML labels block string

Renders a YAML labels: block from a string-keyed table, with each entry indented two spaces under a labels: line. Values needing quoting are escaped. Useful for embedding into hand-written manifests.

use plugin k8s::{build_labels}

let block = build_labels(#{
  "app": "api",
  "env": "production",
  "version": "v2"
})
print(block)

Parse an image reference into parts

Parses a Docker/OCI image reference into a table with registry, name, and tag fields. The tag defaults to "latest" when absent, digests (@sha256:...) are recognized, and registry is empty for Docker Hub images. A leading component is treated as a registry only when it contains a . or : (host or port).

use plugin k8s::{parse_image}

let parts = parse_image("my-registry.example.com/team/app:v1.5")
print(parts["registry"])
print(parts["name"])
print(parts["tag"])

let hub = parse_image("nginx:alpine")
print(hub["registry"])
print(hub["name"])
print(hub["tag"])

A bare image name with no tag falls back to latest:

use plugin k8s::{parse_image}

let p = parse_image("busybox")
print("{p["name"]}:{p["tag"]}")

Validate a Kubernetes resource name

Returns true if name is a valid Kubernetes resource name per RFC 1123 subdomain rules: lowercase alphanumeric characters and - or ., max 253 characters, must start and end with an alphanumeric character.

use plugin k8s::{validate_resource_name}

print(validate_resource_name("my-app"))
print(validate_resource_name("My_App"))
print(validate_resource_name(""))

Gate a generated manifest on a valid name so invalid input is caught early:

use plugin k8s::{validate_resource_name, build_namespace_yaml}

let name = "Prod-Env"
if validate_resource_name(name) {
  print(build_namespace_yaml(name))
} else {
  print("rejected: {name}")
}

Validate a Kubernetes label key

Returns true if key is a valid Kubernetes label key. Keys may have an optional DNS subdomain prefix separated by / (e.g. app.kubernetes.io/name). The name part must be 63 characters or fewer, the optional prefix 253 or fewer, and both must start and end with an alphanumeric character.

use plugin k8s::{validate_label_key}

print(validate_label_key("app"))
print(validate_label_key("app.kubernetes.io/name"))
print(validate_label_key("INVALID_KEY"))
enespt-br