Ansible Pitfall: Quotes and Strings

There are at least two levels of parsing that happen when Ansible playbooks are run, and the interaction between YAML parsing and Jinja causes a lot of confusion.

A common inductive leap is to see syntax like foo: "{{ bar }}" in existing Ansible code and conclude that Jinja cares whether your value is enclosed in quotes. The truth is that Ansible’s Jinja templating does not know those quotes existed, because they are part of the YAML syntax and do not survive past the initial parsing into a data structure.

- hosts: localhost
  vars:
    foo: this variable
  tasks:
    - debug:
        msg: "{{ foo }} has to be quoted because the YAML value starts with a
         '{', which has syntactical meaning in YAML so without the quotes it's
         ambiguous whether this is a string scalar or a malformed mapping."

    - debug:
        msg: In {{ foo }} the { is not at the beginning, so it doesn't need quotes.

    - debug:
        msg: '"this string" starts with a quotation mark, which again has
          syntactical meaning and the entire string needs to be quoted at the
          YAML level.'
      when: "'this' in foo" # This is most commonly encountered in conditions

    - debug:
        msg: Here the " is not at the beginning, so YAML doesn't require disambiguation.

    - debug:
        msg: |
          {{ foo }} is a style I hate, but is already explicitly a scalar so it
          doesn't need quoting.

    - debug:
        msg: >
          "{{ foo }}" is like the above,
          but folded.
TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "this variable has to be quoted because the YAML value starts with a '{', which has syntactical meaning in YAML so without the quotes it's ambiguous whether this is a string scalar or a malformed mapping."
}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "In this variable the { is not at the beginning, so it doesn't need quotes."
}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "\"this string\" starts with a quotation mark, which again has syntactical meaning and the entire string needs to be quoted at the YAML level."
}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "Here the \" is not at the beginning, so YAML doesn't require disambiguation."
}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "this variable is a style I hate, but is already explicitly a scalar so it\ndoesn't need quoting.\n"
}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "\"this variable\" is like the above, but folded.\n"
}