0

How can I replace the Image used in a Kubernetes Deployment manifest with jq?

For example:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myapp
  name: myapp-deployment
spec:
  replicas: 1
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:v1

I tried using something like this jq '.spec.template.spec.containers[0].image = "myapp:v2"'. However, it always ends with a syntax or parse error.

peak
  • 105,803
  • 17
  • 152
  • 177
Frederik
  • 1,221
  • 2
  • 13
  • 22
  • 1
    JQ is for parsing JSON. You are looking for YQ – oguz ismail Jan 10 '21 at 10:15
  • https://stackoverflow.com/questions/42716734/modify-a-key-value-in-a-json-using-jq-in-place suggests otherwise – Frederik Jan 10 '21 at 10:38
  • 2
    As @ogus ismael suggests: jq can not parse yaml. If you really want to use jq you would need to convert yaml to json, e.g. with https://github.com/wakeful/yaml2json - and convert it back afterwards e.g. with https://github.com/brancz/gojsontoyaml. But I wouldn’t recommend to be honest. – cvoigt Jan 10 '21 at 10:45
  • Kubernetes-native tools like Helm or Kustomize might also be able to help with this particular case. – David Maze Jan 10 '21 at 12:45
  • Got a bit confused and thought that yaml is valid json – Frederik Jan 10 '21 at 15:16
  • @Pascal Backwards. YAML is a proper superset of JSON, so JSON is valid YAML, but not all YAML is valid JSON. What you posted is not valid [JSON](https://www.json.org/) – ikegami Jan 11 '21 at 06:07

1 Answers1

3

Using yq, you can simply write:

yq -y '.spec.template.spec.containers[0].image = "foo:latest"' pod.yml

Which produces:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myapp
  name: myapp-deployment
spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: myapp
          image: foo:latest

But I would use kustomize for something like this, as @DavidMaze suggested.

larsks
  • 277,717
  • 41
  • 399
  • 399