6

I'm writing an ansible playbook, which I'm fairly to. I'm having issues with ansible-playbook complaining about my quotes, which from my understanding are correct. I've tried 3 things described at the bottom, one of them is what documentation says I should be doing and the other two are just to try workarounds that work in other playbooks when encountering this error telling me to add quotes when the quotes are already there. Ansible is inconsistent in how it wants variables quoted, any advice on exactly how to quote this or an explanation of Ansible's weirdness regarding quotes would be appreciated.

From my playbook:

  - name: set template_src and template_dest variables
    set_fact:
      template_src: {{ path_to_vm_directory }}/"{{ name_of_vm_to_reset }}"/"{{ name_of_vm_to_reset >
      template_dest: {{ path_to_vm_directory }}/"{{ name_of_vm_to_reset }}"/"{{ name_of_vm_to_reset>

  - name: copy TEMPLATEv1 vdisk to become this VM's current vdisk "{{ name_of_vm_to_reset }}"
    ansible.builtin.copy:
      src: "{{ template_src }}"
      dest: "{{ template_dest }}"
      remote_src: true     #src is on remote filesystem
      mode: 644
      owner: root
      group: root

Which generates the following error message from ansible-playbook (sorry about the code blocks, SE has some wonky parsing of large code blocks):

ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: Expecting value: line 1 column 1 (char 0) Syntax Error while loading YAML did not find expected key. while parsing a block mapping in "<unicode string>", line 81, column 11 did not find expected key in "<unicode string>", line 81, column 51

The error appears to be in '/home/microbot/ansible/test/playbook-metaverse-restore_to_template_BM0_any-vm.yaml': line 81, column 51, but may be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

        set_fact:
          template_src: {{ path_to_vm_directory }}/"{{ name_of_vm_to_reset }}"/"{{ name_of_vm_to_reset }}".qcow2"{{ vdisk_template_filename_suffix }}"
        
                                                  ^ here

Variations I've tried:

  • Quote each variable individually - as far as I am aware, this is correct according to Ansible documentation:

       template_src: "{{ path_to_vm_directory }}"/"{{ name_of_vm_to_reset }}"/"{{ name_of_vm_to_reset }}".qcow2"{{ vdisk_template_filename_suffix }}"
    
  • Quote all but the first variable:
    I've seen before that Ansible doesn't seem to like it when I start a string with a quoted variable - it will throw an error when quoted and no error when unquoted. But that's not happening this time for some reason.

       template_src: {{ path_to_vm_directory }}/"{{ name_of_vm_to_reset }}"/"{{ name_of_vm_to_reset }}".qcow2"{{ vdisk_template_filename_suffix }}"
    
  • Quote nothing:

       template_src: {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    

2 Answers 2

21

Technically speaking, none of this has anything to do with Ansible or with variables. It is basic YAML syntax.

In YAML, quotes around a string are optional as long as the string cannot be confused with a different YAML type.

Going through your options:

{{ path_to_vm_directory }}/"{{ name_of_vm_to_reset }}"/"{{ name_of_vm_to_reset }}".qcow2"{{ vdisk_template_filename_suffix }}"

This is an invalid string because a string cannot start with an opening curly brace ({). This could be confused with a map: { path_to_vm_directory: /srv/vms }.

"{{ path_to_vm_directory }}"/"{{ name_of_vm_to_reset }}"/"{{ name_of_vm_to_reset }}".qcow2"{{ vdisk_template_filename_suffix }}"

This is invalid because a quote starts a string, which then continues until the next quote, which ends the string. So, the string here starts with {{ path_to_vm_directory }} and there comes a random / character which makes no sense to be at this position.

{{ path_to_vm_directory }}/"{{ name_of_vm_to_reset }}"/"{{ name_of_vm_to_reset }}".qcow2"{{ vdisk_template_filename_suffix }}"

Same as option #1, a string cannot start with an opening curly brace ({).

{{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}

Same as options #1 and #3, a string cannot start with an opening curly brace ({).

There are several ways to prevent YAML from interpreting the { as starting a map:

  • Escape the opening curly brace with a backslash (\):
    template_src: \{{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
  • Enclose the string in quotes:
    template_src: '{{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}'
    
    # or
    
    template_src: "{{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}"
    
  • Use Block Scalars:
    template_src: |
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: >
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: |-
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: >-
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: |+
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: >+
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: |2
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: >2
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: |-2
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: >-2
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: |+2
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: >+2
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: |2-
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: >2-
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: |2+
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
    # or
    
    template_src: >2+
      {{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}
    
3

I found the solution. The solution is to quote the whole value of the template_src key as one string value:

template_src: "{{ path_to_vm_directory }}/{{ name_of_vm_to_reset }}/{{ name_of_vm_to_reset }}.qcow2{{ vdisk_template_filename_suffix }}"

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.