Distributing a ConfigMap#
A TemplateInstance can read one resource and copy it into many — and because the source is watched, every copy updates when the source changes. The worked example is a CA bundle distributed to every workload namespace, but the mechanism suits any cluster-wide value.
Scenario#
Bill maintains a CA bundle in a ConfigMap ca-bundle in the provider namespace, and wants a read-only copy named trusted-ca in every namespace labelled team. Rotating the bundle should update every copy.
The Template#
Two parameters: the source (GET mode — a named objectFieldRef) and the target namespaces (LIST mode). Both are watched, so a change to either re-renders.
apiVersion: templates.v2.stakater.com/v2alpha1
kind: Template
metadata:
name: distribute-ca
namespace: provider
spec:
parameters:
- name: caBundle
required: true
- name: namespaces
required: true
gotemplate: |
{{- range $ns := .parameters.namespaces }}
{{- if and (hasKey (default dict (index $ns.metadata "labels")) "team") (not (hasKey $ns.metadata "deletionTimestamp")) }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: trusted-ca
namespace: {{ $ns.metadata.name }}
data:
ca.crt: {{ $.parameters.caBundle | quote }}
{{- end }}
{{- end }}
sync:
mode: revert # a hand-edit of a copy converges back to the source
apiVersion: templates.v2.stakater.com/v2alpha1
kind: TemplateInstance
metadata:
name: distribute-ca
namespace: provider
spec:
templateRef:
name: distribute-ca
namespace: provider
parameters:
- name: caBundle
valueFrom:
objectFieldRef:
apiVersion: v1
kind: ConfigMap
name: ca-bundle # named -> GET mode
namespace: provider
jsonPath: .data.ca\.crt
- name: namespaces
valueFrom:
objectFieldRef:
apiVersion: v1
kind: Namespace
jsonPath: .items
Inside range, . is the current namespace, so the template reads the bundle through $.parameters. The deletionTimestamp check skips a namespace that is being deleted, so that namespace can finish its deletion.
Update ca-bundle and every trusted-ca copy is re-rendered on the next reconcile.
Don't copy Secret material into ConfigMaps
This copies a public CA bundle. Never read a Secret and render its contents into a ConfigMap (or into status — see outputs); that exposes it. For private key material, deliver it where it is needed with a dedicated mechanism rather than fanning it out. A Secret is also refused as an output source.
See also#
- Rendering to many namespaces for the fan-out half of this pattern.
- Parameters:
objectFieldRefGET vs LIST andvalueFrom.secretKeyReffor reading secret values safely at render time.