Ansible weird error : The error was: 'str object' has no attribute 'ip'

Question:

I have a very strange problem with an Ansible playbook.

I use ansible with a Flask API, so I use ansible-runner to pass my variables to my playbook.

My playbook is just a debug of my dictionary and its ip attribute:

- hosts: localhost
  connection: local
  any_errors_fatal: no
  tasks:
    - debug: 
        msg: '{{ device }}' 
    
    - debug: 
        msg: '{{ device["ip"] }}'

And that’s when I don’t understand anything anymore.
My application is in a docker container and this is the error I get when I launch my playbook:

deploy okay [WARNING]: Unable to parse /etc/ansible/hosts as an inventory source
 [WARNING]: No inventory was parsed, only implicit localhost is available
 [WARNING]: provided hosts list is empty, only localhost is available. Note
that the implicit localhost does not match 'all'

PLAY [localhost] ***************************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [shell] *******************************************************************
changed: [localhost]

TASK [Set date and time] *******************************************************
ok: [localhost]

TASK [Define log filepath] *****************************************************
ok: [localhost]

TASK [Create staging folder] ***************************************************
ok: [localhost]

TASK [begin of logging file] ***************************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": {
        "admin_password": "",
        "admin_user": "user",
        "dns1_server_ip": "0.0.0.0",
        "equipement_name": "NEW_EQUIPMENT",
        "hostname": "EQUIPMENT",
        "ip": "127.0.0.1",
        "port": 80
    }
}

TASK [debug] *******************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'str object' has no attribute 'ip'nnThe error appears to have been in '/path/main.yml': line 59, column 9, but maynbe elsewhere in the file depending on the exact syntax problem.nnThe offending line appears to be:nnn      - debug:n        ^ heren"}

PLAY RECAP *********************************************************************
localhost                  : ok=7    changed=2    unreachable=0    failed=1

Except if I run my playbook outside the docker I have no errors, and I use the same versions of python is not possible locally or on my docker.

Do you have any idea what that is?

Ansible 2.7.4

Python 3.5.3

If you need more details don’t hesitate to ask.

Asked By: Genils

||

Answers:

Your error is stating: 'str object' has no attribute 'ip'

So your variable device is a string, not a dict. It happens that this string is the serialization of a json object.

You can fix this by using the from_json filter which will transform your json string to the corresponding data structure.

    - debug: 
        msg: '{{ device | from_json }}' 

    - debug: 
        msg: '{{ (device | from_json)["ip"] }}'

Then you will have to find out why you get a correct json object when you run from localhost and a json formated string when your run from your docker container. But that is an other story….

Answered By: Zeitounator

Try as below

   - debug:
      msg: "{{device.ip}}"

Answered By: Smily