5

I have a file with three configmaps in it, like the one below.

apiVersion: v1
data:
  TEST: "one"
kind: ConfigMap
metadata:
  name: test-config-one
---
apiVersion: v1
data:
  TEST: "two"
kind: ConfigMap
metadata:
  name: test-config-two
---
apiVersion: v1
data:
  TEST: "three"
kind: ConfigMap
metadata:
  name: test-config-three

I'm trying to apply only test-config-three to the cluster. I know I can break that out into its own file and run kubectl apply -f test-config-three.yaml, but is there a way to do that without having to create a new file?

I was hoping to be able to do something like:

cat file.yml | yq <get only test-config-three> | kubectl apply -f -

But yq doesn't seem to support finding a single resource in a file. I also looked at tools like kubesplit but they tend to output all resources to separate files.

Is there a way to isolate and output a single resource from a yaml file containing multiple resources without creating a new file?

Update

Thanks to @Inian's answer below, I was able to get this full command working.

cat file.yml | yq e 'select(.data.TEST == "three")' - | kubectl apply -f -
dan
  • 1,944
  • 1
  • 15
  • 22
  • Which version of `yq` are you using? The Python or the Go version? Post the output of `yq --version` – Inian Jan 30 '21 at 08:17
  • I can't believe that someone out there had a use-case exactly as that of mine. This helped me out! Thank you so much OP and @Inian – Abhinav Thakur Jul 29 '21 at 06:51

2 Answers2

4

There are two versions of yq implemented, one in Python and one in Go as I've highlighted in my answer at How can I parse a YAML file from a Linux shell script?

Using the Python version - kislyuk/yq

yq -y 'select(.data.TEST == "three")' yaml

Go version - mikefarah/yq

yq e 'select(.data.TEST == "three")' yaml
Inian
  • 80,270
  • 14
  • 142
  • 161
1

If you have python you can try following

export MYFILE=file.yml
export DOC_NUMBER=2

python3 -c "import yaml; print(yaml.dump(list(yaml.safe_load_all(open('"$MYFILE"')))["$DOC_NUMBER"]))" | kubectl apply -f -

yaml.safe_load_all(open('"$MYFILE"')) loads all the documents in the yaml file into a list. Then you are selecting "$DOC_NUMBER" document with ["$DOC_NUMBER"].

yaml.dump would dump the loaded object back into yaml format which is then printed.

Shashank V
  • 10,007
  • 2
  • 25
  • 41