Raphael
Raphael

Reputation: 10559

Ansible wrongly complains about unquoted values

I have an Ansible setup like this:

roles/myrole/defaults/main.yml
some_flag: "False"
roles/myrole/vars/some_env.yml
SOME_FLAG: "{{ some_flag }}"
roles/myrole/tasks/main.yml
---
- name: Load env
  include_vars:
    file: "vars/some_env.yml"
    name: "some_env"

- name: Some Task
  docker_container:
    name: "some_container"
    image: "some_image"
    env: "{{ some_env }}"

All looks good here, everything is quoted (cf. also this question). Even so, Ansible (2.8.3) complains:

fatal: [myhost]: FAILED! => {"changed": false, "msg": "Non-string value found for env option. Ambiguous env options must be wrapped in quotes to avoid them being interpreted. Key: SOME_FLAG"}

What's going on?

Upvotes: 3

Views: 2964

Answers (2)

Xiangkun
Xiangkun

Reputation: 1107

"True", 'True', "False" and 'False' (case sensitive) are string in YAML, but boolean in Ansible.

"true", "false", "TRUE", "FALSE" and others are string in both YAML and Ansible.

Test it with the following playbook:

# test.yml
---
- hosts: localhost
  gather_facts: no
  vars:
    b: "True"
    s: "true"
  tasks:
    - name: var:b
      debug:
        var: b

    - name: var:s
      debug:
        var: s

And check the result:

$ ansible-playbook test.yml 
PLAY [localhost] ****************

TASK [var:b] ********************
ok: [localhost] => {
    "b": true
}

TASK [var:s] ********************
ok: [localhost] => {
    "s": "true"
}

PLAY RECAP **********************
localhost                  : ok=2

So to answer your question, if possible, use some_flag: "false" instead of some_flag: "False".

If you have to use "False", then you will need "{{ some_flag | string }}" when referencing it.

Note that quote filter won't work, as it's designed to quote variable for shell use when necessary, instead of simply quoting variable and escaping quotes inside.

Upvotes: 3

Raphael
Raphael

Reputation: 10559

I don't know exactly what's happening where, but apparently somewhere in the replacement pipeline, "False" is parsed into a boolean.

Adding an extra set of escaped quotes helps:

roles/myrole/defaults/main.yml
some_flag: "\"False\""

Upvotes: 1

Related Questions