Refactoring Kubernetes ConfigMaps and Secrets With AI
Sprawling ConfigMaps and inline secrets rot over time. Use AI to consolidate config, split out real secrets, and trigger clean rollouts you verify first.
- #kubernetes
- #configmap
- #secrets
- #ai
Every long-lived Kubernetes app I’ve worked on eventually grows a ConfigMap problem. Config gets added in a hurry, a real secret ends up sitting in a ConfigMap because it was faster, the same value gets duplicated across three Deployments, and nobody is sure which keys are still used. The config sprawls, drifts, and quietly accumulates security risk. Cleaning it up by hand is tedious and easy to get wrong. This is a near-perfect job for an AI model acting as a fast junior engineer: it reads all your config at once, spots the duplication and the misplaced secrets, and drafts a cleaner structure that you review before anything mutates the cluster.
What goes wrong with config over time
Three rot patterns show up again and again:
- Secrets in ConfigMaps. A database password or API token lands in a ConfigMap because it was convenient. ConfigMaps aren’t encrypted at rest the way Secrets can be, and they’re not treated as sensitive by RBAC conventions.
- Duplication. The same
LOG_LEVELorDATABASE_URLis copy-pasted into multiple ConfigMaps, so changing it means hunting down every copy. - Dead keys. Config added for a feature that got removed, never cleaned up, now just noise nobody dares delete.
The model is good at all three because it can hold every ConfigMap and Deployment in context simultaneously and reason across them — something that’s genuinely slow to do by eye.
Export config safely first
I pull the current config to review it, scrubbing secret values before anything goes to the model. The structure is what I want analyzed, not the actual credentials:
kubectl get configmaps -n myapp -o yaml > /tmp/configmaps.yaml
# For secrets, share only KEYS, never decoded values:
kubectl get secrets -n myapp -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{range .data}{" "}{@}{"\n"}{end}{end}'
I never decode and paste real secret values. The model sees ConfigMap structure and secret key names, never the sensitive contents. Running kubectl get is read-only and I run it; the model never holds the kubeconfig.
Ask for a consolidation plan
The prompt frames the model as an auditor, not an executor:
Here are all the ConfigMaps in my namespace and the env references from my Deployments. Identify: (1) any values that look like secrets and should move to a Secret, (2) keys duplicated across ConfigMaps that should be consolidated, (3) keys that no Deployment references and may be dead. Output a proposed structure — do not generate apply commands.
The “do not generate apply commands” instruction keeps the output as a plan I review, not a script I might run on reflex. The model returns something like:
DB_PASSWORDinapp-configis a secret — move to a Secret namedapp-db.LOG_LEVELappears inapp-config,worker-config,cron-config— consolidate into a sharedcommon-config.LEGACY_FEATURE_FLAGinapp-configis referenced by no Deployment — candidate for removal.
Build the refactored manifests
With the plan reviewed, I have the model draft the new manifests. The moved secret goes into a proper Secret using stringData so I’m not hand-encoding base64:
apiVersion: v1
kind: Secret
metadata:
name: app-db
namespace: myapp
type: Opaque
stringData:
# real value filled in by me, never by the model
DB_PASSWORD: "<from vault>"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: common-config
namespace: myapp
data:
LOG_LEVEL: "info"
The actual password I supply myself, ideally via an external secrets workflow so the plaintext never lands in Git or the model’s context. The Deployments get updated to reference the new sources:
envFrom:
- configMapRef:
name: common-config
- secretRef:
name: app-db
Pro Tip: A ConfigMap or Secret change does not restart pods on its own. Unless you mount config as a volume (which updates in place, eventually) or use a checksum annotation, your pods keep running the old values. Plan the rollout explicitly — a “successful” config change with no restart is a classic silent failure.
Trigger the rollout deliberately
To make a Deployment pick up new config, I add a checksum annotation so any config change rolls the pods — this is the pattern Helm charts use:
spec:
template:
metadata:
annotations:
checksum/config: "{{ sha256sum (toYaml .Values.config) }}"
For a plain manifest without Helm, the explicit human action is a restart, run by me after review:
kubectl rollout restart deployment/app -n myapp
kubectl rollout status deployment/app -n myapp
Verify before, during, and after
The verification sequence keeps every mutating step in human hands:
# Validate the refactored manifests offline
kubectl apply --dry-run=client -f refactored/
# Diff against what's live before committing
kubectl diff -f refactored/ -n myapp
kubectl diff is the one I rely on most — it shows exactly what would change against the live cluster without applying anything. I read that diff carefully, because a refactor that accidentally drops a key in use is an outage. Only after the diff looks right do I apply, in staging first, then production by hand.
The mistakes AI makes here
Watch for these on review:
- Dropping a still-used key. The model’s “dead key” call is based on the references you gave it. If a key is read by an app at runtime in a way not visible in the manifests, it’ll wrongly flag it. Confirm against the actual app.
- Base64 confusion. When generating Secrets, models sometimes double-encode or put already-encoded values in
stringData. UsestringDatafor plaintext,datafor base64, never mix them up. - Forgetting the rollout. The model produces clean manifests but often omits the restart step — config changes need an explicit trigger.
Wrap up
Config rot is a slow, low-grade risk that’s tedious to fix manually and easy for AI to help with. Let the model audit your ConfigMaps and Secrets, propose consolidation, and draft cleaner manifests — but keep secret values out of its context, verify every change with kubectl diff, and run the rollout yourself. The model reads structure and writes YAML; it never holds real credentials and never applies to the cluster.
More config hygiene lives in the Kubernetes & Helm guides. Grab refactoring prompts or the Kubernetes prompt pack, and route the refactor PR through the code review dashboard to catch dropped keys before they ship.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.