This post discusses how to solve the Ansible error " 'dict object' has no attribute 'stdout_lines" .
This error appears when you are trying to iterate through a list or dictionary incorrectly.
In this post, we will discuss how to iterate through the dictionary and list in the right way and solve your "dict object has no attribute" error.
Some background
Ansible will throw this error when you are trying to display the stdout (or) stderr of a task during playbook runtime.
Generally, we display the stdout (or) stderr of the task at runtime by calling the corresponding task's register within the debug module and with the help of msg as shown below.
- name : Validate Java become: yes become_user: weblogic tags: app command: "java -version" register: javaver - debug: msg: " Java Version Found {{ javaver.stderr }}"
and the output of that debug task would look something like this, as it runs.
TASK [debug] ************************************************************************************************************************************************* ok: [192.168.60.4] => { "msg": " Java Version Found java version \"1.8.0_161\"\nJava(TM) SE Runtime Environment (build 1.8.0_161-b12)\nJava HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)" } ok: [192.168.60.5] => { "msg": " Java Version Found java version \"1.8.0_161\"\nJava(TM) SE Runtime Environment (build 1.8.0_161-b12)\nJava HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)" }
But sometimes, we will get the exception while trying to do the same thing. ( not exactly the same)
Which is trying to display the stdout of the task by invoking the <registername>.stdout
within debug
module's msg
parameter
look at the modified version of the same task with loop iteration.
--- hosts: app tasks: - name: Validate Java shell: "{{ item }}" become_user: weblogic become: yes register: javaout with_items: - "java -version" - "java -d64 -version" - debug: msg: "{{javaout.stderr}}"
What do you think the output of this will be ?.
An Error message states that dict object' has no attribute 'stderr'
Why this error?
To understand why this error is occurring and how Ansible is saying that we are trying to print the dictionary object.
Let us make little modification in our task to print the complete register variable instead of a property (stderr (or) stdout)
The modified playbook with debug module
- name: validate Java version and Data model become: yes become_user: weblogic shell: "{{ item }}" register: javaout with_items: - "java -version" - "java -d64 -version" failed_when: "'error' in javaout.stderr" - debug: msg: "{{javaout}}"
The Output
As mentioned in the preceding image, "results" : [
is a key and value of a dictionar
The Reason the output came in the dictionary format is that we have used "with_items" loop along with register so that we can get the output for each loop iteration (or) item.
Refer this link here for more info
How to resolve
Since the
stdout
andstderr
comes inside the list and since the list cannot be parsed with the "key" only option is to iterate with the list with the help of loop module.
The Resolved Playbook - A Right way to process dict object
- name: validate Java version and Data model become: yes become_user: weblogic shell: "{{ item }}" register: javaout with_items: - "java -version" - "java -d32 -version" failed_when: "'error' in javaout.stderr" - debug: msg: "{{ item.stderr }}" loop: "{{ javaout.results }}" - name: fail if error in javaout output fail: msg: "Not a valid 32bit JVM. Make sure the Java support -d64 data model" when: "'Error' in item.stderr " loop: "{{ javaout.results }}"
As you could notice, we are using the loop module to parse the register.results
and accessing the stderr of the register as item.stderr
As we have a loop with the register, we will the stderr of each item.
In other words, we will see the stderr
of both java commands executed on both machines
The output will clarify the same.
Note*: If you want to access the stdout (or) stdout_lines. Just change the
msg.stderr
tomsg.stdout
(or)msg.stdout_lines
accordingly.
Output
You could see that we were able to print the stderr
of the task without any dictionary related error.
We learnt the correct way to process the loop variables and its contents and how to avoid dict object' has no attribute 'stdout_lines error message
Hope it helps
Thanks,
Sarav AK