There are Deployments that may use a configmap with the name like cm-myapp-*
. How to write a script that looks at all Deployments and reconfigures them from using some of their cm-myapp-*
to the new specific cm-myapp-123
?
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: myapp
spec:
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:2
volumeMounts:
- name: config-volume
mountPath: /etc/myapp/
volumes:
- name: config-volume
configMap:
name: cm-myapp-9375546193
---
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-myapp-123
data:
myapp.conf: |
hi
There is kubectl patch
that accepts 'JSON patches', and there is kubectl edit
that looks like interactive-only. Some kubectl
commands accept go-templates, but they aren't for editing. Dumping the whole config gives some superfluous fields.
Can extract some stuff:
kubectl get deployment -o go-template --template="{{range .items}}{{\$deploymentName := .metadata.name}}{{range .spec.template.spec.volumes}}{{if .configMap}}{{\$deploymentName}} {{.configMap}}:{{end}}{{end}}{{end}}" | tr ':' '\n'
kubectl get deployment myapp -ojsonpath="{.spec.template.spec.volumes[0].configMap.name}}"
Need to patch it (not working):
kubectl patch deployment myapp -p '{ "op": "replace", "path": ".spec.template.spec.volumes[0].name", "value": "cf" }'
So how can it be done? What's the syntax of kubectl patch
?
Outputs an old config name, its index in the 'volumes' array and the name of the deployment. Filters out configs that we aren't interested in, patches all deployments.
#!/bin/bash
In my opinion it would be optimal if you knew the deployments in advance. You should generate your manifests that you apply from some templating solution (I would suggest getting familiar with helm
which is much more then just templates) and then have the configmap managed with the templating.
Here's some kubectl patch
syntax I've used to patch images by container name:
-p "{\"spec\":{\"template\":{\"spec\":{\"volumes\":[{\"name\":\"myapp\",\"image\":\"$imageUri\"}]}}}}"
The same thing might work for you by patching the volumes
key instead:
-p "{\"spec\":{\"template\":{\"spec\":{\"volumes\":[{\"name\":\"config-volume\",\"configMap\":{\"name\":\"myapp-123\"}}]}}}}"
What's the syntax of kubectl patch?
The official documentation is here with examples here. According to that guide, you might try setting --type=json
on your patch
command.
There are two syntax: JSON Patch and JSON Merge Patch.
Use jq, the "awk for json" to tranform the JSON document(s). I'm not sure which fields you want to change exactly, but how to adjust it should be clear from the jq argument.
$ cat x.json
{
"apiVersion": "apps/v1beta1",
"kind": "Deployment",
"foo": "myapp"
"metadata": {
"name": "myapp"
},
"spec": {
"template": {
"metadata": {
"labels": {
"app": "myapp"
}
}
}
}
}
$ jq '
.metadata.name = "cm-myapp-123"
| .spec.template.metadata.labels.app = "cm-myapp-123"
| .
' < x.json
{
"apiVersion": "apps/v1beta1",
"kind": "Deployment",
"foo": "myapp"
"metadata": {
"name": "cm-myapp-123"
},
"spec": {
"template": {
"metadata": {
"labels": {
"app": "cm-myapp-123"
}
}
}
}
}