skills/k8s-helm-immutable-field-workaround/SKILL.md
Workaround for immutable Kubernetes resource fields that a Helm chart doesn't expose as configurable values. Use when: (1) kubectl patch fails with 'may not change once set' or 'immutable field', (2) a Helm chart renders a resource without a field you need (e.g. loadBalancerClass, storageClassName, claimRef) and there is no chart values key for it, (3) ArgoCD self-heal keeps reverting a manual patch because the chart re-renders without the field. Covers Services, PVCs, and other resources with immutable spec fields.
npx skillsauth add aldengolab/lorist k8s-helm-immutable-field-workaroundInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Some Kubernetes resource fields are immutable after creation. If the Helm chart that owns the resource doesn't expose the field as a configurable value, there is no pure-Helm way to set it — and ArgoCD self-heal will revert any manual patch on the next sync.
Common examples:
Service.spec.loadBalancerClass — controls which LB controller handles the ServicePersistentVolumeClaim.spec.storageClassName — cannot change after PVC creationPersistentVolumeClaim.spec.accessModes — immutable after creationkubectl patch returns: ... is invalid: ...: may not change once set
or Forbidden: ... is immutableThe general pattern: let the chart own a minimal/neutral version of the resource, and own the field you need in a separate, independently-managed resource.
When the chart resource type can be changed to a less specific variant:
ClusterIP instead of LoadBalancer for Services)Example — LoadBalancerClass on a Service the chart doesn't support:
# In chart values: switch to clusterIP
expose:
type: clusterIP
clusterIP:
ports:
httpPort: 80
# In your GitOps apps chart: dedicated LB Service with correct class
apiVersion: v1
kind: Service
metadata:
name: myapp-lb
namespace: myapp
annotations:
tailscale.com/hostname: myapp # optional: Tailscale hostname
spec:
type: LoadBalancer
loadBalancerClass: tailscale
selector:
app: myapp
component: nginx
ports:
- port: 80
targetPort: 8080
When the chart resource cannot be degraded, use an ArgoCD PreSync hook that deletes the resource before sync. The chart then recreates it with the correct values on the same sync.
Full PreSync hook template (including ServiceAccount and RBAC): see
references/delete-and-recreate.md Variant A in this skill directory.
Note: Option B causes a brief outage during sync. Option A is preferred when feasible.
When the field doesn't affect behavior and you just want to stop the
OutOfSync noise, add ignoreDifferences to the ArgoCD Application:
ignoredDifferences:
- group: ""
kind: Service
name: myapp
namespace: myapp
jsonPointers:
- /spec/loadBalancerClass
Use this only when the drift is cosmetic and the live value is correct.
development
Build a UEFI Secure Boot PXE netboot server for Ubuntu autoinstall. Use when: designing or implementing network boot infrastructure for automated Ubuntu provisioning with Secure Boot enabled. Covers the complete chain: signed shim+GRUB selection, TFTP layout, kernel parameters, autoinstall config requirements, and post-install bootstrapping scripts. Also applicable when debugging an existing PXE setup that uses the wrong GRUB binary or config paths.
development
Design pattern for running a persistent PXE/TFTP server that safely coexists with already-installed nodes. Use when: building PXE infrastructure that should stay always-on, designing automated bare-metal provisioning in GitOps/Kubernetes environments, or any PXE setup where UEFI boot order has network boot first. Eliminates boot loops without requiring UEFI firmware changes.
development
This skill governs all prose output — Claude's own responses, documentation, PR descriptions, commit messages, README content, comments, and any text the user asks to draft or edit. It should also be used when the user asks to "review my writing", "edit this for clarity", "make this clearer", "simplify this text", "rewrite this", "check my prose", "tighten this up", or "make this more concise". Based on George Orwell's "Politics and the English Language" (1946).
development
Debug Kubernetes pods using hostNetwork: true that crash with "Address already in use" or "failed to create listening socket for port N". Use when: (1) a hostNetwork pod container is in CrashLoopBackOff and logs show a port bind failure, (2) the port works fine in non-hostNetwork pods but fails with hostNetwork, (3) you need to identify which host-level process holds a port from within Kubernetes (no SSH). Covers /proc/net/udp inspection and kubectl debug node with nsenter.