Search code examples
ansibleyamlyq

how to use yq with ansible to generate quotes around inserted items?


I am trying to add some items in an YAML file, calling yq (v4.43.1) from ansible (core 2.16.5). It inserts the values correctly, but without the quotes that would make it a valid yaml file. Now I am using ansible.builtin.replace to add quotes around my strings, but I am looking for a better solution.

Here is the playbook, it assumes that ansible and yq are already on the machine:

---
- name: Customize cluster.yaml
  hosts: localhost
  vars:
    rook_tag: "v1.14.0"
    ceph_datapath:
      rpi4b-1: "sda3"
      rpi4b-2: "sda3"
      rpi4b-3: "sda3"
      rpi4b-4: "sda3"
      rpi4b-5: "sda3"
      rock3a: "nvme0n1p3"
      vim4: "nvme0n1"
      nanopct6: "mmcblk0p3"
      opi5p: "mmcblk0p3"
      rock5b: "mmcblk0p3"
  tasks:
    - name: Download cluster.yaml manifest from Internet
      ansible.builtin.get_url:
        url: "https://raw.githubusercontent.com/rook/rook/{{ 'release-' + '.'.join(''.join(rook_tag.split('v')[1:]).split('.')[:2]) }}/deploy/examples/cluster.yaml"
        dest: ./cluster.yaml
        mode: '0664'

    - name: Set spec.storage.config.nodes
      ansible.builtin.shell: >
        /usr/local/bin/yq -i '.spec.storage.config.nodes += [{"name": "{{ item.key }}", "devices": [{"name": "{{ item.value }}"}]}]' cluster.yaml
      with_dict: "{{ ceph_datapath }}"
      register: command_output
      changed_when: command_output.rc == 0

The relevant section of the generated cluster.yaml file is:

config:
      nodes:
        - name: rpi4b-1
          devices:
            - name: sda3
        - name: rpi4b-2
          devices:
            - name: sda3
        - name: rpi4b-3
          devices:
            - name: sda3
        - name: rpi4b-4
          devices:
            - name: sda3
        - name: rpi4b-5
          devices:
            - name: sda3
        - name: rock3a
          devices:
            - name: nvme0n1p3
        - name: vim4
          devices:
            - name: nvme0n1
        - name: nanopct6
          devices:
            - name: mmcblk0p3
        - name: opi5p
          devices:
            - name: mmcblk0p3
        - name: rock5b
          devices:
            - name: mmcblk0p3

How can I add quotes around the names using yq?

Thank you!


Solution

  • As stated in the comments, this is (in most cases) just aesthetics. But if you definitely want to restyle a YAML file, there's the YAML processor mikefarah/yq which you use to set a node's style to the single or double quoting style. First, traverse to the desired node(s), then apply, e.g., style = "double".

    For example, to style all the values under .config.nodes[].name (which traverses to config, then to node, then iterates over all children, and finally descends to the name nodes):

    yq '.config.nodes[].name style = "single"' file.yaml
    
    config:
      nodes:
        - name: 'rpi4b-1'
          devices:
            - name: sda3
        - name: 'rpi4b-2'
          devices:
            - name: sda3
        - name: 'rpi4b-3'
          devices:
            - name: sda3
    ...
    

    Alternatively, use the recursive descent operator .. to reach all items:

    yq '.. style = "double"' file.yaml
    
    config:
      nodes:
        - name: "rpi4b-1"
          devices:
            - name: "sda3"
        - name: "rpi4b-2"
          devices:
            - name: "sda3"
        - name: "rpi4b-3"
          devices:
            - name: "sda3"
    ...