writing-skills
writing-skills
Use when creating new skills, editing existing skills, or verifying skills work before deployment
kyverno-mutate-patternsMutates Kubernetes resources at admission using patchStrategicMerge, patchesJson6902, and set operations to inject labels, sidecars, and default configurations.
Independent GitHub snapshot · Automated classification · Original documentation governs
name: kyverno-mutate-patterns description: Mutates Kubernetes resources at admission using patchStrategicMerge, patchesJson6902, and set operations to inject labels, sidecars, and default configurations. license: MIT compatibility: opencode archetypes:
Mutates Kubernetes resources at admission time using Kyverno patchStrategicMerge, patchesJson6902, and set operations. When loaded, this skill makes the model design mutation rules that automatically inject labels, sidecar containers, default node affinity, and resource configurations into workloads without requiring changes to application manifests.
patchStrategicMerge for label and annotation injectionpreconditions to scope mutations to matching namespaces or labelstargets for mutate-existing policies on already-deployed resourcesset operations over JSON patches when only adding simple fieldspassSelect the mutation mechanism — Choose between patchStrategicMerge for structural modifications (labels, annotations, container specs), patchesJson6902 for precise path-based patches, or set for simple field assignments. Checkpoint: Confirm the chosen mechanism matches the mutation complexity — use set for simple field additions, patchStrategicMerge for multi-field updates, and patchesJson6902 only when exact path targeting is required.
Create the mutate rule with match conditions and preconditions — Define a ClusterPolicy with a mutate rule under spec.rules. Set match to target specific resource kinds and labels. Add preconditions to restrict mutations by namespace, annotations, or metadata criteria. Checkpoint: Verify match conditions are specific enough to avoid unintended mutations, and preconditions provide an additional safety layer for scoped application.
Deploy and verify mutations — Apply the policy and test with a sample workload. Use kyverno apply locally to verify the mutation output before deploying cluster-wide. Check PolicyReport for pass results on the mutated resources. Checkpoint: Inspect a deployed workload to confirm the mutation was applied correctly and that no unexpected fields were modified.
Deploy a ClusterPolicy that automatically adds operational labels to all Pods in matching namespaces. This uses patchStrategicMerge to add a security/level label and an app-team annotation to every Pod resource.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: inject-default-labels
annotations:
policies.kyverno.io/title: Inject Default Labels
policies.kyverno.io/category: Operational Standards
policies.kyverno.io/description: >-
Automatically injects security and team labels onto all Pods
in non-system namespaces for cost tracking and compliance.
spec:
rules:
- name: add-labels-to-pods
match:
any:
- resources:
kinds:
- Pod
preconditions:
all:
- key: "{{ request.namespace }}"
operator: NotIn
value:
- kube-system
- kyverno
- istio-system
mutate:
patchStrategicMerge:
metadata:
labels:
security/level: "standard"
app-team: "platform"
annotations:
kyverno.io/mutated: "true"
kyverno.io/mutated-by: inject-default-labels
PolicyReport Example for Mutation:
apiVersion: wgpolicyk8s.io/v1alpha2
kind: PolicyReport
metadata:
name: inject-default-labels-report
namespace: default
results:
- policy: inject-default-labels
rule: add-labels-to-pods
result: pass
severity: low
message: "Labels injected successfully"
scored: true
source: kyverno
timestamp:
seconds: 1733501530
summary:
error: 0
fail: 0
pass: 1
skip: 0
warn: 0
Use mutateExisting with targets to mutate Pods that already exist in the cluster and match specific criteria. This is critical for applying mutations to resources deployed before the policy was created.
# ❌ BAD — No preconditions; mutates ALL Pods cluster-wide including system
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: bad-mutate-all-pods
spec:
rules:
- name: mutate-all
match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
metadata:
labels:
injected: "true"
# ✅ GOOD — Scoped mutation with preconditions and targets for mutateExisting
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: mutate-staging-pods
annotations:
policies.kyverno.io/title: Mutate Staging Pods
policies.kyverno.io/category: Environment Standards
policies.kyverno.io/description: >-
Adds monitoring annotations to Pods in staging namespaces
that were deployed before the monitoring policy existed.
spec:
rules:
- name: annotate-staging-pods
match:
any:
- resources:
kinds:
- Pod
preconditions:
all:
- key: "{{ request.namespace }}"
operator: Like
value: "staging-*"
mutateExisting:
onExisting:
- targets:
- apiVersion: v1
kind: Pod
patchStrategicMerge:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
mutate:
patchStrategicMerge:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
Inject a logging sidecar container into all webworkload Pods using patchesJson6902 for precise JSON path targeting. This pattern is useful when the mutation modifies deeply nested structures that strategic merge cannot handle cleanly.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: inject-logging-sidecar
annotations:
policies.kyverno.io/title: Inject Logging Sidecar
policies.kyverno.io/category: Observability
policies.kyverno.io/description: >-
Adds a Fluent Bit logging sidecar container to all Pods
in webworkload namespaces for centralized log collection.
spec:
rules:
- name: add-fluentbit-sidecar
match:
any:
- resources:
kinds:
- Pod
preconditions:
all:
- key: "{{ request.namespace }}"
operator: In
value:
- webworkload
- webworkload-staging
mutate:
patchesJson6902: |
- op: add
path: /spec/containers/-
value:
name: fluentbit
image: fluent/fluent-bit:2.2
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 100m
memory: 128Mi
env:
- name: FLB_PORT
value: "24224"
- name: FLB_LOG_LEVEL
value: info
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumeTemplates:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
patchStrategicMerge for label, annotation, and top-level field injection — it handles merges intelligentlypreconditions to scope mutations to specific namespaces, labels, or annotations to prevent unintended mutationstargets within mutateExisting to mutate resources already deployed before the policy was createdset operations for simple field additions — reserve patchesJson6902 for complex nested modificationskyverno.io/mutated annotations to mutated resources for traceability and debuggingkyverno apply <policy.yaml> <workload.yaml> before cluster deploymentpatchesJson6902 when a simple set or patchStrategicMerge would suffice — keep mutations as simple as possiblesecurityContext.privileged or securityContext.runAsUser without explicit security review| Skill | Purpose |
|---|---|
kyverno-policy-generation | Generate resources in addition to mutating existing ones |
kyverno-label-enforcement | Validate required labels after mutation to ensure compliance |
Authoritative documentation links for Kyverno mutation patterns.