Home > Enterprise >  Ansible is converting automatically a string (json) to dict with new affectation?
Ansible is converting automatically a string (json) to dict with new affectation?

Time:10-30

I do some tests with json file and I have seen that I don't understand its behaviour, is it normal or a bug?

My json file:

{
    "interfaces": {
        "GigabitEthernet0/0": {
            "duplex_code": "auto",
            "port_speed": "a-100",
            "status": "connected",
            "type": "10/100/1000BaseTX",
            "vlan": "1"
        }
    }
}

Tasks:

- name: load the Json data to a Variable as a Fact
  command: cat "{{ _jsonfile }}"
  vars:
    _jsonfile: 'file.json'
  register: output

- name: output is string
  debug: msg="output is string"
  when: output  is string
- name: output.stdout is string
  debug: msg="output.stdout is string"
  when: output.stdout is string

- set_fact:
    out: "{{ output.stdout }}"

- name: out is string
  debug: msg="out is string"
  when: out  is string

As you could see, I load a JSON with a cat command and check if the registered output an output.stdout are strings.
The result:

TASK [**output is string**] *********************************************
Friday 29 October 2021  15:15:35  0000 (0:00:00.347)       0:00:00.412 ******** 
**skipping**: [localhost]

TASK [**output.stdout is string**] *****************************************************************
Friday 29 October 2021  15:15:36  0000 (0:00:00.028)       0:00:00.440 ******** 
ok: [localhost] => 
  **msg: output.stdout is string**

TASK [set_fact] **************************************************************************
Friday 29 October 2021  15:15:36  0000 (0:00:00.029)       0:00:00.470 ******** 
ok: [localhost]

TASK [**out is string**] *********************************************************************
Friday 29 October 2021  15:15:36  0000 (0:00:00.031)       0:00:00.502 ******** 
**skipping: [localhost]**

output.stdout is a string, it's normal, but when I trap output.stdout in another variable, named out, this variable is not a string, but a dictionary that I can iterate out.interfaces, so, I'd like to understand that.

Is it normal that the type of a variable changes with new affectation?

CodePudding user response:

Yes, that's actually very common ansible behavior, auto-coercing things to dict or list — it thinks that's "helping" you.

To stop that behavior, you can just make the first character not one of the JSON-y ones, and it'll leave it a string, or usually explicitly sending the pipeline through | string works, too, if the leading whitespace is important to some downstream task:

- set_fact:
    out: " {{ output.stdout }}"
- set_fact:
    out: "{{ output.stdout | string }}"

Just watch out, because — just like the presence of jinja2 moustaches — ansible applies those coercion rules anytime it can, so one must be especially careful as text travels through the various evaluation pipelines

  • Related