Configuration
Target
formae apply --mode reconcile.
Authentication
Pick anauth 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:
/var/run/secrets/kubernetes.io/serviceaccount/. The pod needs the RBAC to do
whatever the forma describes.
eks:DescribeCluster, and its mapped
Kubernetes RBAC governs what it can do inside the cluster.
certificateAuthority runs that follow-up
automatically before your workload deploys. Auth uses DefaultAzureCredential
(environment variables, then the az CLI, then managed identity).
container.developer at minimum, or
more granular RBAC bound at the cluster level.
~/.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.
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
SetkubernetesVersion 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.
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 setmetadata.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.
