Skip to main content
Deploying to a Kubernetes cluster? Point the K8s plugin at it. You get typed Pkl resources, schemas that match your cluster’s exact version, and auth that works with EKS, AKS, GKE, OKE, or any kubeconfig.

Configuration

Target

Apply it against your current kubectl context with formae apply --mode reconcile.

Authentication

Pick an auth class on k8s.Config and the plugin handles token refresh, request signing, and per-provider quirks. You configure it once and the plugin keeps it valid for every API call the target makes. KubeconfigAuth (local development). The default for kubectl-reachable clusters. With no fields set, the plugin uses whatever your current context points at. Override either field for something specific:
InClusterAuth (formae running as a pod). When the formae agent runs inside the cluster it manages, the plugin reads the ServiceAccount token mounted at /var/run/secrets/kubernetes.io/serviceaccount/. The pod needs the RBAC to do whatever the forma describes.
EKSAuth (AWS EKS). Reference the endpoint, CA, and cluster name from the EKS cluster resource, and formae waits until the cluster exists before reading them. The plugin uses your AWS credentials to fetch a presigned STS token and signs every API call. The AWS principal needs eks:DescribeCluster, and its mapped Kubernetes RBAC governs what it can do inside the cluster.
AKSAuth (Azure AKS). The AKS create API does not return the cluster CA directly, so the plugin makes a follow-up call with the cluster’s admin credentials to fetch it. Referencing certificateAuthority runs that follow-up automatically before your workload deploys. Auth uses DefaultAzureCredential (environment variables, then the az CLI, then managed identity).
GKEAuth (GCP GKE). The plugin uses application-default credentials to mint an OAuth2 access token. The principal needs container.developer at minimum, or more granular RBAC bound at the cluster level.
OCIAuth (Oracle OKE). The plugin signs each API call with your OCI keys (api-key or session token, per ~/.oci/config), so there is no long-lived bearer token. Your OCI user needs the OKE_CLUSTER_USE policy plus Kubernetes RBAC. OKE grants the cluster creator an admin token, so an apply that creates the cluster gets RBAC for free.
Which to use. When formae runs outside the cluster, use KubeconfigAuth for local development, or the matching cloud-native class from CI or when you provisioned the cluster in the same forma (reference the cluster resource so there is no race). When formae runs inside the cluster, use InClusterAuth.

Kubernetes version

Set kubernetesVersion to your cluster’s K8s version (e.g. "1.31"). The plugin matches it to the right schema, so fields that don’t exist in that version of Kubernetes fail at pkl eval time instead of failing against your live cluster.
Skip it and the plugin assumes 1.36 (the newest version it ships schemas for). Set it explicitly for anything older. Each supported minor ships its own schema package and runs its own conformance suite on every push to main. The current supported set is visible in the conformance badges on the plugin’s README.

Set the namespace on every namespaced resource

Every namespaced resource must set metadata.namespace explicitly. The plugin won’t fall back to K8s’ default namespace. Missing values produce an error at apply time. Declare a Namespace in the same forma and reference its name so it lives in one place:
Namespaced kinds use NamespacedObjectMeta. Cluster-scoped kinds (Namespace, ClusterRole, ClusterRoleBinding, PersistentVolume, StorageClass, and so on) use ObjectMeta. Pod templates and PVC templates also use ObjectMeta. Mix them up and pkl eval tells you exactly where.