Home > other >  Shell variables in yq 4 using env()
Shell variables in yq 4 using env()

Time:12-03

I want to build a pipeline function that replaces a value in a yaml file. For that I want to make both the pattern and the replacement value variable. I have seen the env-variables-operators article in the yq docs, however I cannot find the relevant section.

I have a yaml file with the following content:

---
spec:
  source:
    helm:
      parameters:
        - name: "image.tag"
          value: "1.0.0"

I now want to build a pipeline function that will replace the value of the value key in the yaml. I can do so with:

$ yq '.spec.source.helm.parameters[0].value = "2.0.0"' myyaml.yml
---
spec:
  source:
    helm:
      parameters:
        - name: "image.tag"
          value: "2.0.0"

Now I want to make this command customizable. What works:

$ VALUE=3.0.0
$ replacement=$VALUE yq '.spec.source.helm.parameters[0].value = env(replacement)' myyaml.yml
---
spec:
  source:
    helm:
      parameters:
        - name: "image.tag"
          value: "3.0.0"

What doesn't work

$ VALUE=3.0.0
$ PATTERN=.spec.source.helm.parameters[0].value
$ replacement=$VALUE pattern=$PATTERN yq 'env(pattern) = env(replacement)'
spec:
  source:
    helm:
      parameters:
        - name: "image.tag"
          value: "1.0.0"

I have also tried to use strenv and wrapping the replacement pattern in quotes, but it is not working. Can anyone help me with the correct syntax?

CodePudding user response:

You can import data with env but not code. You could inject it (note the changes in the quoting), but this is bad practice as it makes your script very vulnerable:

VALUE='3.0.0'
PATTERN='.spec.source.helm.parameters[0].value'
replacement="$VALUE" yq "${PATTERN} = env(replacement)" myyaml.yml
---
spec:
  source:
    helm:
      parameters:
        - name: "image.tag"
          value: "3.0.0"

Better practice would be to import the path in a form that is interpretable by yq, e.g. as an array and using setpath:

VALUE='3.0.0'
PATTERN='["spec","source","helm","parameters",0,"value"]'
replacement="$VALUE" pattern="$PATTERN" yq 'setpath(env(pattern); env(replacement))' myyaml.yml
  • Related