Skip to Content
Values reference

Values reference

Every default below lives in platform-library/values.yaml, nested under exports.defaults and exported to the consumer’s root scope by import-values: [defaults]. Set any of these directly in the consumer chart’s own values.yaml — there’s no separate namespace to reach into. Enums, patterns, and required-key rules come from values.schema.reference.json, the schema every generated consumer chart ships as its own values.schema.json.

This page covers the keys teams actually touch. values.yaml is the line-by-line source of truth — every key carries an inline comment there, and blocks with a deep-dive page (Security features, Security model) link out instead of repeating.

Naming & global

KeyDefaultNotes
nameOverride""Overrides the chart-name portion of generated names.
fullnameOverride""Overrides the full release-derived name outright.
global.imageRegistry""Prefixed onto image.registry when set — for a mirror/proxy registry shared across many charts.
global.imagePullPolicy / global.imagePullSecrets"" / []Chart-wide fallback; resource-specific values win (invariant 3, Design invariants).

Image

image: registry: docker.io repository: "" # required tag: "" # tag or digest required — no `latest` fallback digest: "" # wins over tag when both are set pullPolicy: IfNotPresent pullSecrets: []

The schema rejects tag: latest outright — floating tags aren’t a supported deployment story here. Set a digest (sha256:..., preferred, immutable) or a real semver/build tag.

Workload

KeyDefaultNotes
workload.typeDeploymentDeployment, StatefulSet, or DaemonSet (enum).
replicaCount1Ignored for DaemonSet.
revisionHistoryLimit10
minReadySeconds0Omitted from the manifest at 0.
portsone http/8080/TCP entryContainer ports; name is what service.ports[].targetPort and probes reference.
resources{}Standard requests/limits.
resizePolicy[]In-place vertical scaling (InPlacePodVerticalScaling); each entry {resourceName: cpu|memory, restartPolicy: NotRequired|RestartContainer}.
updateStrategyRollingUpdate, 25%/25%Deployment-shaped; StatefulSet/DaemonSet have their own statefulSet.updateStrategy/daemonSet.updateStrategy.
command / args[] / []Overrides the image entrypoint/cmd.

Probes (startupProbe, livenessProbe, readinessProbe) are each enabled: false by default with a sensible httpGet shape pre-filled — flip enabled: true and adjust path/port rather than writing the block from scratch.

Init containers and sidecars (initContainers, sidecars, each {enabled, containers: []}) accept full native container specs under containers; every container in both lists goes through the same hardening pass as the primary container (see Security model).

Service

service: enabled: false type: ClusterIP # ClusterIP | NodePort | LoadBalancer | ExternalName ports: - name: http port: 80 targetPort: http # matches a ports[].name above protocol: TCP

type: ExternalName is a conditional shape in the schema: set externalName and the Service renders only type + externalNameports and the selector are omitted, since an ExternalName Service is a DNS CNAME, not a proxied backend. The dual-stack/traffic-routing long tail (ipFamilies, ipFamilyPolicy, internalTrafficPolicy, trafficDistribution, publishNotReadyAddresses) is unset by default — each field only renders if you set it, and publishNotReadyAddresses also flows into a StatefulSet’s managed headless Service if one is generated.

Ingress & Gateway API

ingress.hostname follows an RFC 1123 DNS label pattern. TLS is opt-in: setting ingress.tls: true with a hostname resolves the Secret name in order — ingress.existingSecret, else the release-managed <fullname>-tls Secret (if tlsSelfSigned.enabled or certificate.enabled), else the conventional <hostname>-tls, which you provision yourself. Serving a hostname with tls: false prints an install-time NOTES warning.

gatewayApi.enabled covers httpRoute and grpcRoute, negotiated independently (see Capability catalog) — each has its own nested enabled, hostnames, parentRefs, matches/filters, backendRefs, and a specOverrides escape hatch. parentRefs entries are schema-validated: kind: Gateway requires name; kind: HTTPRoute (route delegation) forbids it.

TLS & mTLS

Three independent TLS features, don’t confuse them:

BlockPurposeDetail
certificate.*cert-manager Certificate for a real issuer (ACME, internal CA)this page, below
tlsSelfSigned.*dev-only self-signed server cert, plus optional client certs under tlsSelfSigned.mtls.*Security features → mTLS
mtls.* (top level)Istio PeerAuthentication/AuthorizationPolicy mesh policySecurity model

certificate.issuerKind is ClusterIssuer by default (cluster-scoped); switch to Issuer for a namespaced, multi-tenant cert-manager setup — the schema requires issuer to be set whichever kind you pick. certificate and tlsSelfSigned are mutually exclusive when they’d write the same Secret name — enabling both against the same secretName fails closed (row 3½ of the dispatch table).

Autoscaling

autoscaling: enabled: false minReplicas: 2 maxReplicas: 10 targetCPU: 80 targetMemory: "" metrics: [] # custom/external metrics, verbatim behavior: {} # HPA scaling behavior, verbatim verticalAutoscaling: enabled: false updateMode: Auto # Auto | Recreate | Initial | Off resourcePolicy: {}

Enabling both HPA and VPA to act on CPU/memory at the same time fails closed unless verticalAutoscaling.updateMode: "Off" (recommend-only mode) — see Design invariants. VPA is CRD-backed (autoscaling.k8s.io/v1) and gated like any other optional Kind.

PDB, NetworkPolicy, ResourceQuota, LimitRange

podDisruptionBudget.minAvailable/maxUnavailable are mutually exclusive — set exactly one, or leave both empty for the library’s default (minAvailable: 1). networkPolicy.policyTypes defaults to [Ingress, Egress]; ingress/egress are verbatim rule-list passthroughs. resourceQuota.hard and limitRange.{default,defaultRequest,max,min} are opt-in namespace-QoS governance — the library doesn’t size these for you, they’re a verbatim spec passthrough sized off your own workload.

ServiceAccount & RBAC

A dedicated ServiceAccount is created by default (serviceAccount.create: true) with automountServiceAccountToken: false — apps that call the Kubernetes API must opt in explicitly. serviceAccount.name follows the same RFC 1123 pattern as other generated names. rbac.enabled: true with an empty rules list fails closed (an empty Role is a silent 403 discovered later, not a template-time error) — and RBAC here is namespaced only by design; cluster-scoped grants go through extraObjects + allowClusterScopedExtras. The schema also rejects nonResourceURLs on these rules — that’s a ClusterRole-only field, and this block only ever renders a namespaced Role.

Jobs & CronJob

jobs.preInstall/jobs.postInstall are Helm hook Jobs (hookWeight: -5 and 5 respectively) — each needs script, scriptFile, or command to do anything. The hook Job’s image inherits from the top-level image: block when jobs.image.* is left empty (digest inherits only when the repository matches). cronJob.* is a separate, always-standalone CronJob — schedule (cron syntax), concurrencyPolicy (Allow/Forbid/Replace), and history/suspend controls.

Persistence, StatefulSet, DaemonSet

persistence.enabled adds a PVC (accessModes: [ReadWriteOnce], size: 8Gi by default) or an existingClaim reference. statefulSet.* covers serviceName (auto-managed headless Service if left unset — see Architecture), podManagementPolicy, and persistentVolumeClaimRetentionPolicy (Retain/Delete per whenDeleted/whenScaled, defaulting to the Kubernetes Retain/Retain behavior when unset). daemonSet.* covers its own updateStrategy and scheduling fields.

Monitors (Prometheus Operator)

serviceMonitor, podMonitor, and prometheusRule are each independent, CRD-gated (monitoring.coreos.com/v1) opt-ins — port/path for the first two, a verbatim groups passthrough (alerting + recording rules) for the third. All three accept an optional scheme, Prometheus Operator tlsConfig (for scraping mTLS-protected targets — pairs naturally with this library’s mtls.* or tlsSelfSigned.mtls.*), and sampleLimit.

Admission webhooks & generated secrets

Both are 2.x feature blocks with their own deep-dive pages in Security features: webhooks.* (ValidatingWebhookConfiguration/MutatingWebhookConfiguration, fails closed on a missing name/path/rules) and generatedSecrets (a list of cluster-generated credential Secrets, reconciled per-key on upgrade).

Labels, annotations & precedence

commonLabels/commonAnnotations apply chart-wide; labels/annotations apply to the workload object specifically; podLabels/podAnnotations apply to the pod template. On a key collision, resource-specific always wins over common*, which wins over any global value a consumer sets — see Design invariants for the precedence rule and Conventions & tricks for the template idiom that implements it correctly.

Any annotation value can opt into template expansion by starting with tpl:: the prefix is stripped and the remainder is rendered with tpl against the release context, so vault.example/role: 'tpl:{{ .Release.Name }}-app' resolves to the release name. This covers commonAnnotations and every resource-specific annotations/podAnnotations field the library emits — the workload object, the pod template, serviceAccount.annotations, and every other generated object’s own annotations (Service, Ingress, ConfigMap, Secret, RBAC, webhooks, TLS Secrets, generatedSecrets, Gateway API routes, CronJob, and the monitoring CRDs) — plus envVars map-form values. Values without the prefix pass through byte-identical, including literal-brace text like summary: 'Pod {{ $labels.pod }} down' — precedence still resolves on the raw strings first (above), only the winning value gets expanded. envVars in slice form is always a raw passthrough and never checked. A literal value that must itself start with tpl: is escaped as tpl:{{ "tpl:..." }} so the sentinel no longer matches. Worked example: Examples & recipes.

Capability negotiation & the long tail

capabilities.apiVersions force-assumes API groups for offline renders (full mechanics: Capability catalog). extraObjects (a map of Kind -> [specs]) and extraManifests (a raw list) are the tier-2/tier-3 escape hatches — see Architecture for the renderer contract and Examples & recipes for a worked extraObjects entry. allowClusterScopedExtras: false by default — a namespaced app chart granting itself a cluster-scoped object is a deliberate, reviewed opt-in, not a default. Every extraObjects entry renders verbatim unless it carries template: true, which opts that one entry into tpl expansion against the release context before rendering — see Examples & recipes for the syntax and the literal-{{-escaping caveat.

Last updated on