yamlyq

How to change a specific YAML value for only certain YAML objects with yq


Let's assume the following YAML file:

---
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: Bucket
metadata:
  name: kratix
  namespace: flux-system
spec:
  interval: 10s
  provider: generic
  bucketName: kratix
  endpoint: a.b.c.d:31337
  insecure: true
  secretRef:
    name: minio-credentials
---
apiVersion: v1
kind: Secret
metadata:
  name: minio-credentials
  namespace: flux-system
type: Opaque
data:
  accesskey: asecretkey
  secretkey: asecretvalue
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: kratix-worker-resources
  namespace: flux-system
spec:
  interval: 3s
  prune: true
  dependsOn:
    - name: kratix-worker-dependencies
  sourceRef:
    kind: Bucket
    name: kratix
  path: ./worker-1/resources
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: kratix-worker-dependencies
  namespace: flux-system
spec:
  interval: 8s
  prune: true
  sourceRef:
    kind: Bucket
    name: kratix
  path: ./worker-1/dependencies

This is what I want to do:

Note: By yq, I mean the Mike Farah version.

For YAML that is kind=Kustomization, I want to be able to modify the value for the .spec.path item from ./worker-1/<whatever> to ./<new value>/<whatever>, using yq. Everything else in the file needs to be copied as-is into the end result.

I have almost zero experience using yq and although I've read the documentation and have tried various things, I have not been able to figure out how to do this. At this early stage, yq is rather confusing.


Solution

  • Please include which implementation of yq you are using. You can employ the sub filter for string replacement in both of them.

    kislyuk/yq:

    yq -y 'select(.kind == "Kustomization").spec.path |= sub("/worker-1/"; "/whatever/")'
    
    # or parametrized:
    yq -y --arg kind Kustomization --arg from worker-1 --arg to whatever \
      'select(.kind == $kind).spec.path |= sub("/\($from)/"; "/\($to)/")'
    

    mikefarah/yq:

    yq 'select(.kind == "Kustomization").spec.path |= sub("/worker-1/", "/whatever/")'
    
    # or parametrized:
    kind=Kustomization from=worker-1 to=whatever yq \
      'select(.kind == strenv(kind)).spec.path |= sub("/\(env(from))/", "/\(env(to))/")'
    

    Output:

    ---
    apiVersion: source.toolkit.fluxcd.io/v1beta2
    kind: Bucket
    metadata:
      name: kratix
      namespace: flux-system
    spec:
      interval: 10s
      provider: generic
      bucketName: kratix
      endpoint: a.b.c.d:31337
      insecure: true
      secretRef:
        name: minio-credentials
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: minio-credentials
      namespace: flux-system
    type: Opaque
    data:
      accesskey: asecretkey
      secretkey: asecretvalue
    ---
    apiVersion: kustomize.toolkit.fluxcd.io/v1
    kind: Kustomization
    metadata:
      name: kratix-worker-resources
      namespace: flux-system
    spec:
      interval: 3s
      prune: true
      dependsOn:
        - name: kratix-worker-dependencies
      sourceRef:
        kind: Bucket
        name: kratix
      path: ./whatever/resources
    ---
    apiVersion: kustomize.toolkit.fluxcd.io/v1
    kind: Kustomization
    metadata:
      name: kratix-worker-dependencies
      namespace: flux-system
    spec:
      interval: 8s
      prune: true
      sourceRef:
        kind: Bucket
        name: kratix
      path: ./whatever/dependencies