Ansible error attribute not found due to same variable registration in multiple tasks

て烟熏妆下的殇ゞ 提交于 2021-02-11 13:28:56

问题


Below is my playbook that executes only one of the two raw modules.

   - name: Get Process Dump for tomcat on non-Solaris
     ignore_errors: yes
     block:
       - raw: "ps -ef | grep java | grep -i tomcat | grep -v grep; awk -vrc=$? 'BEGIN{print \"rc=\"rc}'"
         register: tomjavadump
         ignore_errors: yes

       - debug:
           msg: "Tomcat DEBUGGG1: tomjavadump:{{ tomjavadump }}"

     when: ansible_distribution != 'Solaris'


   - name: Get Process Dump for tomcat on Solaris
     ignore_errors: yes
     block:
       - raw: "ps auxwww | grep java | grep -i tomcat | grep -v grep; awk -vrc=$? 'BEGIN{print \"rc=\"rc}'"
         register: tomjavadump
         ignore_errors: yes

       - debug:
           msg: "Tomcat DEBUGGG2: tomjavadump:{{ tomjavadump }}"

     when: ansible_distribution == 'Solaris'


   - debug:
       msg: "Process found"
     when:  tomjavadump.stdout is regex('rc=0')

 

Output with full debug -vvv:

ansible-playbook -i=all, blocktest.yml -vvv
ansible-playbook 2.9.4
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/user1/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 2.7.5 (default, Sep 26 2019, 13:23:47) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
Using /etc/ansible/ansible.cfg as config file
Parsed all, inventory source with host_list plugin
[WARNING]: Found both group and host with same name: all


PLAYBOOK: blocktest.yml ************************************************************************************************************************************************
1 plays in blocktest.yml

PLAY [Play 3- check telnet nodes] **************************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************************
task path: /app/playbook/blocktest.yml:1
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/setup.py
Pipelining is enabled.
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: user1
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python2 && sleep 0'
ok: [localhost]
META: ran handlers

TASK [raw] *************************************************************************************************************************************************************
task path: /app/playbook/blocktest.yml:8
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: user1
<127.0.0.1> EXEC ps -ef | grep tomcat
changed: [localhost] => {
    "changed": true,
    "rc": 0,
    "stderr": "",
    "stderr_lines": [],
    "stdout": "user1   46691  46690  0 05:15 pts/106  00:00:00 /bin/sh -c ps -ef | grep tomcat\nuser1   46693  46691  0 05:15 pts/106  00:00:00 grep tomcat\n",
    "stdout_lines": [
        "user1   46691  46690  0 05:15 pts/106  00:00:00 /bin/sh -c ps -ef | grep tomcat",
        "user1   46693  46691  0 05:15 pts/106  00:00:00 grep tomcat"
    ]
}

TASK [debug] ***********************************************************************************************************************************************************
task path: /app/playbook/blocktest.yml:10
ok: [localhost] => {
    "msg": "TOMCAT DEBUGGGG1: {'stderr_lines': [], 'stdout': u'user1   46691  46690  0 05:15 pts/106  00:00:00 /bin/sh -c ps -ef | grep tomcat\\nuser1   46693  46691  0 05:15 pts/106  00:00:00 grep tomcat\\n', 'changed': True, 'failed': False, 'stderr': u'', 'rc': 0, 'stdout_lines': [u'user1   46691  46690  0 05:15 pts/106  00:00:00 /bin/sh -c ps -ef | grep tomcat', u'user1   46693  46691  0 05:15 pts/106  00:00:00 grep tomcat']}"
}

TASK [raw] *************************************************************************************************************************************************************
task path: /app/playbook/blocktest.yml:19
skipping: [localhost] => {
    "changed": false,
    "skip_reason": "Conditional result was False"
}

TASK [debug] ***********************************************************************************************************************************************************
task path: /app/playbook/blocktest.yml:21
skipping: [localhost] => {}

TASK [debug] ***********************************************************************************************************************************************************
task path: /app/playbook/blocktest.yml:26
fatal: [localhost]: FAILED! => {
    "msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'stdout'\n\nThe error appears to be in '/app/playbook/blocktest.yml': line 26, column 6, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n   - debug:\n     ^ here\n"
}

PLAY RECAP *************************************************************************************************************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=1    skipped=2    rescued=0    ignored=0

Unfortunately, i get "no such Atrribute error" .stdout for the last debug task

Can you please suggest how can we take care of such situation so that the the last debug does not fail whether the OS is solaris or non-solaris and we dont have to use a new variable name for tomjavadump?


回答1:


Following is note from ansible-doc:

If a task fails or is skipped, Ansible still registers a variable with a failure or skipped status, unless the task is skipped based on tags. See Tags for information on adding and using tags.

When you are skipping the first task it is overwriting it with the values.

Simple example:

---

- hosts: localhost
  gather_facts: no

  tasks:
    - name: "Running date command expecting 2020 in stdout and storing to var1"
      raw: date
      args:
        executable: /bin/bash
      register: var1
      when: True

    - debug: var=var1.stdout

    - name: "Running date command expecting 2020 in stdout and storing to var1"
      raw: date
      args:
        executable: /bin/bash
      register: var1
      when: False

    - debug:  var=var1.stdout
    - debug: var=var1

In the above example, 2nd debug would produce the same error as reported by you. However 3rd debug would produce below error, as it can be seen that there is no stdout in it.

ok: [localhost] => {
    "var1": {
        "changed": false,
        "skip_reason": "Conditional result was False",
        "skipped": true
    }
}

Solution:

  1. The solution is suggested by the ansible doc itself, Use tags or use two different variables.
  2. Use Jina2 expression to have only one task for Solaris and non-Solaris remote. By doing this, you do not have to deal with the skipped or failed variable.

Example:

- raw: "{{ 'ps -eaf' if ansible_distribution != 'Solaris' else 'ps auxwww'}} |grep ....bla ...bla...bla" 


来源:https://stackoverflow.com/questions/64326171/ansible-error-attribute-not-found-due-to-same-variable-registration-in-multiple

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!